diff options
author | Vincent Abriou <vincent.abriou@st.com> | 2016-02-10 11:24:28 +0100 |
---|---|---|
committer | Vincent Abriou <vincent.abriou@st.com> | 2016-02-26 10:06:20 +0100 |
commit | 5671cefbf280bb75341a783c5f6050e0fde8e83f (patch) | |
tree | ff6d0d75887e97da5c93f5bb36d7ad783e89ad63 | |
parent | e42e7bd7eebcb46bae933ce4057cca1ebbb69542 (diff) |
drm/sti: add colorspace property to the HDMI connector
Make the value of the colorspace of the HDMI infoframe configurable.
HDMI colorspace could be: RGB, YUV422 or YUV444
Signed-off-by: Vincent Abriou <vincent.abriou@st.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
-rw-r--r-- | drivers/gpu/drm/sti/sti_hdmi.c | 68 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_hdmi.h | 12 |
2 files changed, 79 insertions, 1 deletions
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index 34e33a12984d..1f37dc4f3b85 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c @@ -128,6 +128,7 @@ struct sti_hdmi_connector { struct drm_connector drm_connector; struct drm_encoder *encoder; struct sti_hdmi *hdmi; + struct drm_property *colorspace_property; }; #define to_sti_hdmi_connector(x) \ @@ -408,7 +409,7 @@ static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi) } /* fixed infoframe configuration not linked to the mode */ - infoframe.colorspace = HDMI_COLORSPACE_RGB; + infoframe.colorspace = hdmi->colorspace; infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT; infoframe.colorimetry = HDMI_COLORIMETRY_NONE; @@ -771,12 +772,74 @@ static void sti_hdmi_connector_destroy(struct drm_connector *connector) kfree(hdmi_connector); } +static void sti_hdmi_connector_init_property(struct drm_device *drm_dev, + struct drm_connector *connector) +{ + struct sti_hdmi_connector *hdmi_connector + = to_sti_hdmi_connector(connector); + struct sti_hdmi *hdmi = hdmi_connector->hdmi; + struct drm_property *prop; + + /* colorspace property */ + hdmi->colorspace = DEFAULT_COLORSPACE_MODE; + prop = drm_property_create_enum(drm_dev, 0, "colorspace", + colorspace_mode_names, + ARRAY_SIZE(colorspace_mode_names)); + if (!prop) { + DRM_ERROR("fails to create colorspace property\n"); + return; + } + hdmi_connector->colorspace_property = prop; + drm_object_attach_property(&connector->base, prop, hdmi->colorspace); +} + +static int +sti_hdmi_connector_set_property(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val) +{ + struct sti_hdmi_connector *hdmi_connector + = to_sti_hdmi_connector(connector); + struct sti_hdmi *hdmi = hdmi_connector->hdmi; + + if (property == hdmi_connector->colorspace_property) { + hdmi->colorspace = val; + return 0; + } + + DRM_ERROR("failed to set hdmi connector property\n"); + return -EINVAL; +} + +static int +sti_hdmi_connector_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + struct sti_hdmi_connector *hdmi_connector + = to_sti_hdmi_connector(connector); + struct sti_hdmi *hdmi = hdmi_connector->hdmi; + + if (property == hdmi_connector->colorspace_property) { + *val = hdmi->colorspace; + return 0; + } + + DRM_ERROR("failed to get hdmi connector property\n"); + return -EINVAL; +} + static const struct drm_connector_funcs sti_hdmi_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = sti_hdmi_connector_detect, .destroy = sti_hdmi_connector_destroy, .reset = drm_atomic_helper_connector_reset, + .set_property = drm_atomic_helper_connector_set_property, + .atomic_set_property = sti_hdmi_connector_set_property, + .atomic_get_property = sti_hdmi_connector_get_property, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; @@ -836,6 +899,9 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data) drm_connector_helper_add(drm_connector, &sti_hdmi_connector_helper_funcs); + /* initialise property */ + sti_hdmi_connector_init_property(drm_dev, drm_connector); + err = drm_connector_register(drm_connector); if (err) goto err_connector; diff --git a/drivers/gpu/drm/sti/sti_hdmi.h b/drivers/gpu/drm/sti/sti_hdmi.h index 3d22390e1f3b..f621cd73b0b8 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.h +++ b/drivers/gpu/drm/sti/sti_hdmi.h @@ -7,6 +7,7 @@ #ifndef _STI_HDMI_H_ #define _STI_HDMI_H_ +#include <linux/hdmi.h> #include <linux/platform_device.h> #include <drm/drmP.h> @@ -24,6 +25,14 @@ struct hdmi_phy_ops { void (*stop)(struct sti_hdmi *hdmi); }; +static const struct drm_prop_enum_list colorspace_mode_names[] = { + { HDMI_COLORSPACE_RGB, "rgb" }, + { HDMI_COLORSPACE_YUV422, "yuv422" }, + { HDMI_COLORSPACE_YUV444, "yuv444" }, +}; + +#define DEFAULT_COLORSPACE_MODE HDMI_COLORSPACE_RGB + /** * STI hdmi structure * @@ -44,6 +53,8 @@ struct hdmi_phy_ops { * @wait_event: wait event * @event_received: wait event status * @reset: reset control of the hdmi phy + * @ddc_adapt: i2c ddc adapter + * @colorspace: current colorspace selected */ struct sti_hdmi { struct device dev; @@ -64,6 +75,7 @@ struct sti_hdmi { bool event_received; struct reset_control *reset; struct i2c_adapter *ddc_adapt; + enum hdmi_colorspace colorspace; }; u32 hdmi_read(struct sti_hdmi *hdmi, int offset); |