[PATCH v2 3/9] drm/ast: astdp: Use struct drm_edid and helpers
Jocelyn Falempe
jfalempe at redhat.com
Tue Aug 13 13:18:43 UTC 2024
On 12/08/2024 11:30, Thomas Zimmermann wrote:
> Convert ASTDP support to struct drm_edid and its helpers. Simplifies
> and modernizes the EDID handling.
>
> The driver reads 4 bytes at once, but the overall read length is now
> variable. Therefore update the EDID read loop to never return more than
> the requested bytes.
>
> The device does not seem to support EDID extensions, as the driver
> actively clears any such information from the main EDID header. As
> the new interface allows for reading extension blocks for EDID, make
> sure that the block is always 0 (i.e., the main header). A later
> update might fix that.
>
> v2:
> - fix reading if len is not a multiple of 4
Thanks, it looks good to me.
Reviewed-by: Jocelyn Falempe <jfalempe at redhat.com>
>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> ---
> drivers/gpu/drm/ast/ast_dp.c | 55 +++++++++++++++++++-----------------
> 1 file changed, 29 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c
> index 217c155f0874..22c4f2a126e9 100644
> --- a/drivers/gpu/drm/ast/ast_dp.c
> +++ b/drivers/gpu/drm/ast/ast_dp.c
> @@ -20,11 +20,15 @@ static bool ast_astdp_is_connected(struct ast_device *ast)
> return true;
> }
>
> -static int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
> +static int ast_astdp_read_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
> {
> - struct ast_device *ast = to_ast_device(dev);
> + struct ast_device *ast = data;
> + size_t rdlen = round_up(len, 4);
> int ret = 0;
> - u8 i;
> + unsigned int i;
> +
> + if (block > 0)
> + return -EIO; /* extension headers not supported */
>
> /*
> * Protect access to I/O registers from concurrent modesetting
> @@ -35,13 +39,23 @@ static int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
> /* Start reading EDID data */
> ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe5, (u8)~AST_IO_VGACRE5_EDID_READ_DONE, 0x00);
>
> - for (i = 0; i < 32; i++) {
> + for (i = 0; i < rdlen; i += 4) {
> + unsigned int offset;
> unsigned int j;
> + u8 ediddata[4];
> + u8 vgacre4;
> +
> + offset = (i + block * EDID_LENGTH) / 4;
> + if (offset >= 64) {
> + ret = -EIO;
> + goto out;
> + }
> + vgacre4 = offset;
>
> /*
> * CRE4[7:0]: Read-Pointer for EDID (Unit: 4bytes); valid range: 0~64
> */
> - ast_set_index_reg(ast, AST_IO_VGACRI, 0xe4, i);
> + ast_set_index_reg(ast, AST_IO_VGACRI, 0xe4, vgacre4);
>
> /*
> * CRD7[b0]: valid flag for EDID
> @@ -65,7 +79,7 @@ static int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
> vgacrd7 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd7);
> if (vgacrd7 & AST_IO_VGACRD7_EDID_VALID_FLAG) {
> vgacrd6 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd6);
> - if (vgacrd6 == i)
> + if (vgacrd6 == offset)
> break;
> }
> }
> @@ -93,7 +107,8 @@ static int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
> ediddata[2] = 0;
> }
>
> - ediddata += 4;
> + memcpy(buf, ediddata, min((len - i), 4));
> + buf += 4;
> }
>
> out:
> @@ -330,29 +345,17 @@ static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = {
>
> static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
> {
> - void *edid;
> - int succ;
> + struct drm_device *dev = connector->dev;
> + struct ast_device *ast = to_ast_device(dev);
> + const struct drm_edid *drm_edid;
> int count;
>
> - edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
> - if (!edid)
> - goto err_drm_connector_update_edid_property;
> -
> - succ = ast_astdp_read_edid(connector->dev, edid);
> - if (succ < 0)
> - goto err_kfree;
> -
> - drm_connector_update_edid_property(connector, edid);
> - count = drm_add_edid_modes(connector, edid);
> - kfree(edid);
> + drm_edid = drm_edid_read_custom(connector, ast_astdp_read_edid_block, ast);
> + drm_edid_connector_update(connector, drm_edid);
> + count = drm_edid_connector_add_modes(connector);
> + drm_edid_free(drm_edid);
>
> return count;
> -
> -err_kfree:
> - kfree(edid);
> -err_drm_connector_update_edid_property:
> - drm_connector_update_edid_property(connector, NULL);
> - return 0;
> }
>
> static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector,
More information about the dri-devel
mailing list