summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/display/drm_hdmi_state_helper.c20
-rw-r--r--drivers/gpu/drm/drm_atomic.c5
-rw-r--r--drivers/gpu/drm/drm_connector.c20
-rw-r--r--drivers/gpu/drm/tests/drm_connector_test.c12
4 files changed, 52 insertions, 5 deletions
diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index 1e92c1108d23..82293d93b5f8 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -18,6 +18,10 @@
void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
struct drm_connector_state *new_conn_state)
{
+ unsigned int max_bpc = connector->max_bpc;
+
+ new_conn_state->max_bpc = max_bpc;
+ new_conn_state->max_requested_bpc = max_bpc;
}
EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
@@ -36,6 +40,22 @@ EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
struct drm_atomic_state *state)
{
+ struct drm_connector_state *old_conn_state =
+ drm_atomic_get_old_connector_state(state, connector);
+ struct drm_connector_state *new_conn_state =
+ drm_atomic_get_new_connector_state(state, connector);
+
+ if (old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc) {
+ struct drm_crtc *crtc = new_conn_state->crtc;
+ struct drm_crtc_state *crtc_state;
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
+
+ crtc_state->mode_changed = true;
+ }
+
return 0;
}
EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index a91737adf8e7..4e11cfb4518b 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1143,6 +1143,11 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc);
drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace));
+ if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+ connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
+ drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
+ }
+
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
if (state->writeback_job && state->writeback_job->fb)
drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 8c471bdfbfff..e5c840987854 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -459,6 +459,7 @@ EXPORT_SYMBOL(drmm_connector_init);
* @funcs: callbacks for this connector
* @connector_type: user visible type of the connector
* @ddc: optional pointer to the associated ddc adapter
+ * @max_bpc: Maximum bits per char the HDMI connector supports
*
* Initialises a preallocated HDMI connector. Connectors can be
* subclassed as part of driver connector objects.
@@ -475,7 +476,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
struct drm_connector *connector,
const struct drm_connector_funcs *funcs,
int connector_type,
- struct i2c_adapter *ddc)
+ struct i2c_adapter *ddc,
+ unsigned int max_bpc)
{
int ret;
@@ -483,10 +485,26 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
connector_type == DRM_MODE_CONNECTOR_HDMIB))
return -EINVAL;
+ if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12))
+ return -EINVAL;
+
ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
if (ret)
return ret;
+ /*
+ * drm_connector_attach_max_bpc_property() requires the
+ * connector to have a state.
+ */
+ if (connector->funcs->reset)
+ connector->funcs->reset(connector);
+
+ drm_connector_attach_max_bpc_property(connector, 8, max_bpc);
+ connector->max_bpc = max_bpc;
+
+ if (max_bpc > 8)
+ drm_connector_attach_hdr_output_metadata_property(connector);
+
return 0;
}
EXPORT_SYMBOL(drmm_connector_hdmi_init);
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 261d4109946d..2661eb64a5cd 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -184,7 +184,8 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test)
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
DRM_MODE_CONNECTOR_HDMIA,
- &priv->ddc);
+ &priv->ddc,
+ 8);
KUNIT_EXPECT_EQ(test, ret, 0);
}
@@ -200,7 +201,8 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
DRM_MODE_CONNECTOR_HDMIA,
- NULL);
+ NULL,
+ 8);
KUNIT_EXPECT_EQ(test, ret, 0);
}
@@ -217,7 +219,8 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
connector_type,
- &priv->ddc);
+ &priv->ddc,
+ 8);
KUNIT_EXPECT_EQ(test, ret, 0);
}
@@ -248,7 +251,8 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
&dummy_funcs,
connector_type,
- &priv->ddc);
+ &priv->ddc,
+ 8);
KUNIT_EXPECT_LT(test, ret, 0);
}