Skip to content

Commit 0e35457

Browse files
committed
drm/ast: astdp: Use struct drm_edid and helpers
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 Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240815151953.184679-5-tzimmermann@suse.de
1 parent f89001e commit 0e35457

1 file changed

Lines changed: 29 additions & 26 deletions

File tree

drivers/gpu/drm/ast/ast_dp.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@ static bool ast_astdp_is_connected(struct ast_device *ast)
2020
return true;
2121
}
2222

23-
static int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
23+
static int ast_astdp_read_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
2424
{
25-
struct ast_device *ast = to_ast_device(dev);
25+
struct ast_device *ast = data;
26+
size_t rdlen = round_up(len, 4);
2627
int ret = 0;
27-
u8 i;
28+
unsigned int i;
29+
30+
if (block > 0)
31+
return -EIO; /* extension headers not supported */
2832

2933
/*
3034
* 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)
3539
/* Start reading EDID data */
3640
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe5, (u8)~AST_IO_VGACRE5_EDID_READ_DONE, 0x00);
3741

38-
for (i = 0; i < 32; i++) {
42+
for (i = 0; i < rdlen; i += 4) {
43+
unsigned int offset;
3944
unsigned int j;
45+
u8 ediddata[4];
46+
u8 vgacre4;
47+
48+
offset = (i + block * EDID_LENGTH) / 4;
49+
if (offset >= 64) {
50+
ret = -EIO;
51+
goto out;
52+
}
53+
vgacre4 = offset;
4054

4155
/*
4256
* CRE4[7:0]: Read-Pointer for EDID (Unit: 4bytes); valid range: 0~64
4357
*/
44-
ast_set_index_reg(ast, AST_IO_VGACRI, 0xe4, i);
58+
ast_set_index_reg(ast, AST_IO_VGACRI, 0xe4, vgacre4);
4559

4660
/*
4761
* CRD7[b0]: valid flag for EDID
@@ -65,7 +79,7 @@ static int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
6579
vgacrd7 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd7);
6680
if (vgacrd7 & AST_IO_VGACRD7_EDID_VALID_FLAG) {
6781
vgacrd6 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd6);
68-
if (vgacrd6 == i)
82+
if (vgacrd6 == offset)
6983
break;
7084
}
7185
}
@@ -93,7 +107,8 @@ static int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
93107
ediddata[2] = 0;
94108
}
95109

96-
ediddata += 4;
110+
memcpy(buf, ediddata, min((len - i), 4));
111+
buf += 4;
97112
}
98113

99114
out:
@@ -331,29 +346,17 @@ static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = {
331346

332347
static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
333348
{
334-
void *edid;
335-
int succ;
349+
struct drm_device *dev = connector->dev;
350+
struct ast_device *ast = to_ast_device(dev);
351+
const struct drm_edid *drm_edid;
336352
int count;
337353

338-
edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
339-
if (!edid)
340-
goto err_drm_connector_update_edid_property;
341-
342-
succ = ast_astdp_read_edid(connector->dev, edid);
343-
if (succ < 0)
344-
goto err_kfree;
345-
346-
drm_connector_update_edid_property(connector, edid);
347-
count = drm_add_edid_modes(connector, edid);
348-
kfree(edid);
354+
drm_edid = drm_edid_read_custom(connector, ast_astdp_read_edid_block, ast);
355+
drm_edid_connector_update(connector, drm_edid);
356+
count = drm_edid_connector_add_modes(connector);
357+
drm_edid_free(drm_edid);
349358

350359
return count;
351-
352-
err_kfree:
353-
kfree(edid);
354-
err_drm_connector_update_edid_property:
355-
drm_connector_update_edid_property(connector, NULL);
356-
return 0;
357360
}
358361

359362
static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector,

0 commit comments

Comments
 (0)