From: Thomas Zimmermann Date: Mon, 7 Feb 2022 14:15:43 +0000 (+0100) Subject: drm/ast: Move DP501-based connector code into separate helpers X-Git-Tag: v6.1-rc5~617^2^2~597 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ab26eddc67a67579a2b52f908b69cbc253f5ff3;p=platform%2Fkernel%2Flinux-starfive.git drm/ast: Move DP501-based connector code into separate helpers Add helpers for DP501-based connectors. DP501 provides output via DisplayPort. This used to be handled by the VGA connector code. If a DP501 chip has been detected, ast will now create a DisplayPort connector instead of a VGA connector. Remove the DP501 code from ast_vga_connector_helper_get_modes(). Also remove the call to drm_connector_update_edid_property(), which is performed by drm_get_edid(). Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20220207141544.30015-9-tzimmermann@suse.de --- diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index cda50fb..420d19d 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -165,6 +165,10 @@ struct ast_private { struct drm_encoder encoder; struct ast_vga_connector vga_connector; } vga; + struct { + struct drm_encoder encoder; + struct drm_connector connector; + } dp501; } output; bool support_wide_screen; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 09995a3..12dbf5b 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -1259,30 +1260,22 @@ static int ast_crtc_init(struct drm_device *dev) static int ast_vga_connector_helper_get_modes(struct drm_connector *connector) { struct ast_vga_connector *ast_vga_connector = to_ast_vga_connector(connector); - struct ast_private *ast = to_ast_private(connector->dev); - struct edid *edid = NULL; - bool flags = false; - int ret; + struct edid *edid; + int count; - if (ast->tx_chip_type == AST_TX_DP501) { - edid = kmalloc(128, GFP_KERNEL); - if (!edid) - return -ENOMEM; + if (!ast_vga_connector->i2c) + goto err_drm_connector_update_edid_property; - flags = ast_dp501_read_edid(connector->dev, (u8 *)edid); - if (!flags) { - kfree(edid); - edid = NULL; - } - } - if (!flags && ast_vga_connector->i2c) - edid = drm_get_edid(connector, &ast_vga_connector->i2c->adapter); - if (edid) { - drm_connector_update_edid_property(connector, edid); - ret = drm_add_edid_modes(connector, edid); - kfree(edid); - return ret; - } + edid = drm_get_edid(connector, &ast_vga_connector->i2c->adapter); + if (!edid) + goto err_drm_connector_update_edid_property; + + count = drm_add_edid_modes(connector, edid); + kfree(edid); + + return count; + +err_drm_connector_update_edid_property: drm_connector_update_edid_property(connector, NULL); return 0; } @@ -1355,6 +1348,92 @@ static int ast_vga_output_init(struct ast_private *ast) } /* + * DP501 Connector + */ + +static int ast_dp501_connector_helper_get_modes(struct drm_connector *connector) +{ + void *edid; + bool succ; + int count; + + edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (!edid) + goto err_drm_connector_update_edid_property; + + succ = ast_dp501_read_edid(connector->dev, edid); + if (!succ) + goto err_kfree; + + drm_connector_update_edid_property(connector, edid); + count = drm_add_edid_modes(connector, edid); + kfree(edid); + + return count; + +err_kfree: + kfree(edid); +err_drm_connector_update_edid_property: + drm_connector_update_edid_property(connector, NULL); + return 0; +} + +static const struct drm_connector_helper_funcs ast_dp501_connector_helper_funcs = { + .get_modes = ast_dp501_connector_helper_get_modes, +}; + +static const struct drm_connector_funcs ast_dp501_connector_funcs = { + .reset = drm_atomic_helper_connector_reset, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector *connector) +{ + int ret; + + ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs, + DRM_MODE_CONNECTOR_DisplayPort); + if (ret) + return ret; + + drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs); + + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + + connector->polled = DRM_CONNECTOR_POLL_CONNECT; + + return 0; +} + +static int ast_dp501_output_init(struct ast_private *ast) +{ + struct drm_device *dev = &ast->base; + struct drm_crtc *crtc = &ast->crtc; + struct drm_encoder *encoder = &ast->output.dp501.encoder; + struct drm_connector *connector = &ast->output.dp501.connector; + int ret; + + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS); + if (ret) + return ret; + encoder->possible_crtcs = drm_crtc_mask(crtc); + + ret = ast_dp501_connector_init(dev, connector); + if (ret) + return ret; + + ret = drm_connector_attach_encoder(connector, encoder); + if (ret) + return ret; + + return 0; +} + +/* * Mode config */ @@ -1414,10 +1493,13 @@ int ast_mode_config_init(struct ast_private *ast) switch (ast->tx_chip_type) { case AST_TX_NONE: case AST_TX_SIL164: - case AST_TX_DP501: ret = ast_vga_output_init(ast); break; + case AST_TX_DP501: + ret = ast_dp501_output_init(ast); + break; } + if (ret) return ret;