This patch series add bus format negotiation support for Cadence MHDP8546 bridge driver.
The patch series has four patches in the below sequence: 1. drm: bridge: cdns-mhdp8546: Modify atomic_get_input_bus_format bridge function. Return all the input formats supported. 2. drm: bridge: cdns-mhdp8546: Remove setting of bus format using connector info Remove the bus format configuration using connector info structure. 3. drm: bridge: cdns-mhdp8546: Retrieve the pixel format and bpc based on bus format Get the pixel format and bpc based on negotiated output bus format.
This patch series is dependent on tidss series [1] for the new connector model support.
[1] https://patchwork.kernel.org/project/dri-devel/cover/20201201121830.29704-1-...
Version History:
v3: - Modify the atomic_get_input_bus_fmts to return the MEDIA_BUS_FMT_RGB121212_1X36 as default format.along as tidss currently supports only this format.
v2: - Remove the Add output bus format negotiation patch from the series, as we use ouput format as MEDIA_BUS_FMT_FIXED and that is the default value if atomic_get_output_bus_fmts function is not implemented. - Return NULL if output format is not MEDIA_BUS_FMT_FIXED. - Return the supported color formats based on the display info structure.
Yuti Amonkar (3): drm: bridge: cdns-mhdp8546: Modify atomic_get_input_bus_format bridge function drm: bridge: cdns-mhdp8546: Remove setting of bus format using connector info drm: bridge: cdns-mhdp8546: Retrieve the pixel format and bpc based on bus format
.../drm/bridge/cadence/cdns-mhdp8546-core.c | 171 ++++++++++++++---- 1 file changed, 138 insertions(+), 33 deletions(-)
Modify atomic_get_input_bus_format function to return input formats supported instead of using hardcoded value.
Signed-off-by: Yuti Amonkar yamonkar@cadence.com --- .../drm/bridge/cadence/cdns-mhdp8546-core.c | 83 +++++++++++++++++-- 1 file changed, 74 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c index d0ed950f4f87..5ef6adb8bc82 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c @@ -2095,27 +2095,92 @@ cdns_mhdp_bridge_atomic_reset(struct drm_bridge *bridge) return &cdns_mhdp_state->base; }
+#define MAX_INPUT_FORMAT 11 + static u32 *cdns_mhdp_get_input_bus_fmts(struct drm_bridge *bridge, - struct drm_bridge_state *bridge_state, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state, - u32 output_fmt, - unsigned int *num_input_fmts) -{ + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + struct drm_connector *conn = conn_state->connector; + struct drm_display_info *info = &conn->display_info; u32 *input_fmts; u32 default_bus_format = MEDIA_BUS_FMT_RGB121212_1X36; + unsigned int i = 0;
*num_input_fmts = 0;
if (output_fmt != MEDIA_BUS_FMT_FIXED) return NULL;
- input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kcalloc(MAX_INPUT_FORMAT, + sizeof(*input_fmts), GFP_KERNEL); if (!input_fmts) return NULL;
- *num_input_fmts = 1; - input_fmts[0] = default_bus_format; + input_fmts[i++] = default_bus_format; + + if (info->color_formats & DRM_COLOR_FORMAT_RGB444) { + if (info->bpc == 16) { + input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; + input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + } + + if (info->bpc == 12) { + input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + } + + if (info->bpc == 10) { + input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + } + + input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + } + + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) { + if (info->bpc == 16) { + input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; + input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; + input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + } + + if (info->bpc == 12) { + input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; + input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + } + + if (info->bpc == 10) { + input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; + input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + } + + input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + } + + if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) { + if (info->bpc == 12) { + input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; + input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; + input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; + } + + if (info->bpc == 10) { + input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; + input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; + } + + input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; + } + + *num_input_fmts = i; + return input_fmts; }
As we are using bus negotiations for selecting bus format remove the setting of bus format using the connector info structure.
Signed-off-by: Yuti Amonkar yamonkar@cadence.com --- drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c index 5ef6adb8bc82..d9f7eb8249e8 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c @@ -1648,7 +1648,6 @@ static const struct drm_connector_funcs cdns_mhdp_conn_funcs = {
static int cdns_mhdp_connector_init(struct cdns_mhdp_device *mhdp) { - u32 bus_format = MEDIA_BUS_FMT_RGB121212_1X36; struct drm_connector *conn = &mhdp->connector; struct drm_bridge *bridge = &mhdp->bridge; int ret; @@ -1669,11 +1668,6 @@ static int cdns_mhdp_connector_init(struct cdns_mhdp_device *mhdp)
drm_connector_helper_add(conn, &cdns_mhdp_conn_helper_funcs);
- ret = drm_display_info_set_bus_formats(&conn->display_info, - &bus_format, 1); - if (ret) - return ret; - ret = drm_connector_attach_encoder(conn, bridge->encoder); if (ret) { dev_err(mhdp->dev, "Failed to attach connector to encoder\n");
Get the pixel format and bpc based on the output bus format negotiated instead of hardcoding the values.
Signed-off-by: Yuti Amonkar yamonkar@cadence.com --- .../drm/bridge/cadence/cdns-mhdp8546-core.c | 82 +++++++++++++++---- 1 file changed, 64 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c index d9f7eb8249e8..2ad5cad46599 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c @@ -1530,24 +1530,8 @@ static int cdns_mhdp_get_modes(struct drm_connector *connector)
drm_connector_update_edid_property(connector, edid); num_modes = drm_add_edid_modes(connector, edid); - kfree(edid);
- /* - * HACK: Warn about unsupported display formats until we deal - * with them correctly. - */ - if (connector->display_info.color_formats && - !(connector->display_info.color_formats & - mhdp->display_fmt.color_format)) - dev_warn(mhdp->dev, - "%s: No supported color_format found (0x%08x)\n", - __func__, connector->display_info.color_formats); - - if (connector->display_info.bpc && - connector->display_info.bpc < mhdp->display_fmt.bpc) - dev_warn(mhdp->dev, "%s: Display bpc only %d < %d\n", - __func__, connector->display_info.bpc, - mhdp->display_fmt.bpc); + kfree(edid);
return num_modes; } @@ -1706,6 +1690,66 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge, return 0; }
+static void cdns_mhdp_get_display_fmt(struct cdns_mhdp_device *mhdp, + struct drm_bridge_state *state) +{ + u32 bus_fmt, bpc, pxlfmt; + + bus_fmt = state->output_bus_cfg.format; + switch (bus_fmt) { + case MEDIA_BUS_FMT_RGB161616_1X48: + pxlfmt = DRM_COLOR_FORMAT_RGB444; + bpc = 16; + break; + case MEDIA_BUS_FMT_YUV16_1X48: + pxlfmt = DRM_COLOR_FORMAT_YCRCB444; + bpc = 16; + break; + case MEDIA_BUS_FMT_RGB121212_1X36: + pxlfmt = DRM_COLOR_FORMAT_RGB444; + bpc = 12; + break; + case MEDIA_BUS_FMT_UYVY12_1X24: + pxlfmt = DRM_COLOR_FORMAT_YCRCB422; + bpc = 12; + break; + case MEDIA_BUS_FMT_YUV12_1X36: + pxlfmt = DRM_COLOR_FORMAT_YCRCB444; + bpc = 12; + break; + case MEDIA_BUS_FMT_RGB101010_1X30: + pxlfmt = DRM_COLOR_FORMAT_RGB444; + bpc = 10; + break; + case MEDIA_BUS_FMT_UYVY10_1X20: + pxlfmt = DRM_COLOR_FORMAT_YCRCB422; + bpc = 10; + break; + case MEDIA_BUS_FMT_YUV10_1X30: + pxlfmt = DRM_COLOR_FORMAT_YCRCB444; + bpc = 10; + break; + case MEDIA_BUS_FMT_RGB888_1X24: + pxlfmt = DRM_COLOR_FORMAT_RGB444; + bpc = 8; + break; + case MEDIA_BUS_FMT_UYVY8_1X16: + pxlfmt = DRM_COLOR_FORMAT_YCRCB422; + bpc = 8; + break; + case MEDIA_BUS_FMT_YUV8_1X24: + pxlfmt = DRM_COLOR_FORMAT_YCRCB444; + bpc = 8; + break; + default: + pxlfmt = DRM_COLOR_FORMAT_RGB444; + bpc = 8; + } + + mhdp->display_fmt.color_format = pxlfmt; + mhdp->display_fmt.bpc = bpc; +} + static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, const struct drm_display_mode *mode) { @@ -2186,6 +2230,8 @@ static int cdns_mhdp_atomic_check(struct drm_bridge *bridge, struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge); const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+ cdns_mhdp_get_display_fmt(mhdp, bridge_state); + mutex_lock(&mhdp->link_mutex);
if (!cdns_mhdp_bandwidth_ok(mhdp, mode, mhdp->link.num_lanes, @@ -2499,7 +2545,7 @@ static int cdns_mhdp_probe(struct platform_device *pdev) mhdp->link.rate = mhdp->host.link_rate; mhdp->link.num_lanes = mhdp->host.lanes_cnt;
- /* The only currently supported format */ + /* Initialize color format bpc and y_only to default values*/ mhdp->display_fmt.y_only = false; mhdp->display_fmt.color_format = DRM_COLOR_FORMAT_RGB444; mhdp->display_fmt.bpc = 8;
dri-devel@lists.freedesktop.org