diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/display/drm_hdmi_state_helper.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_connector.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/tests/drm_connector_test.c | 12 |
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); } |