Skip to content

Commit 1a24c36

Browse files
committed
drm/displayid: add new displayid section/block iterators
Iterating DisplayID blocks across sections (in EDID extensions) is unnecessarily complicated for the caller. Implement DisplayID iterators to go through all blocks in all sections. Usage example: const struct displayid_block *block; struct displayid_iter iter; displayid_iter_edid_begin(edid, &iter); displayid_iter_for_each(block, &iter) { /* operate on block */ } displayid_iter_end(&iter); When DisplayID is stored in EDID extensions, the DisplayID sections map to extensions as described in VESA DisplayID v1.3 Appendix B: DisplayID as an EDID Extension. This is implemented here. When DisplayID is stored in its dedicated DDC device 0xA4, according to VESA E-DDC v1.3, different rules apply for the structure. This is not implemented here, as we don't currently use it, but the idea is you'd have a different call for beginning the iteration, for example simply: displayid_iter_begin(displayid, &iter); instead of displayid_iter_edid_begin(), and everything else would be hidden away in the iterator functions. v2: - sizeof(struct displayid_block) -> sizeof(*block) (Ville) - remove __ prefix from displayid_iter_block Reviewed-by: Ville Syrjälä <[email protected]> Signed-off-by: Jani Nikula <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/da3dead1752ab16c061f7bd248ac1a4268f7fefb.1617024940.git.jani.nikula@intel.com
1 parent 4cc4f09 commit 1a24c36

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

drivers/gpu/drm/drm_displayid.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,77 @@ const u8 *drm_find_displayid_extension(const struct edid *edid,
5757

5858
return displayid;
5959
}
60+
61+
void displayid_iter_edid_begin(const struct edid *edid,
62+
struct displayid_iter *iter)
63+
{
64+
memset(iter, 0, sizeof(*iter));
65+
66+
iter->edid = edid;
67+
}
68+
69+
static const struct displayid_block *
70+
displayid_iter_block(const struct displayid_iter *iter)
71+
{
72+
const struct displayid_block *block;
73+
74+
if (!iter->section)
75+
return NULL;
76+
77+
block = (const struct displayid_block *)&iter->section[iter->idx];
78+
79+
if (iter->idx + sizeof(*block) <= iter->length &&
80+
iter->idx + sizeof(*block) + block->num_bytes <= iter->length &&
81+
block->num_bytes > 0)
82+
return block;
83+
84+
return NULL;
85+
}
86+
87+
const struct displayid_block *
88+
__displayid_iter_next(struct displayid_iter *iter)
89+
{
90+
const struct displayid_block *block;
91+
92+
if (!iter->edid)
93+
return NULL;
94+
95+
if (iter->section) {
96+
/* current block should always be valid */
97+
block = displayid_iter_block(iter);
98+
if (WARN_ON(!block)) {
99+
iter->section = NULL;
100+
iter->edid = NULL;
101+
return NULL;
102+
}
103+
104+
/* next block in section */
105+
iter->idx += sizeof(*block) + block->num_bytes;
106+
107+
block = displayid_iter_block(iter);
108+
if (block)
109+
return block;
110+
}
111+
112+
for (;;) {
113+
iter->section = drm_find_displayid_extension(iter->edid,
114+
&iter->length,
115+
&iter->idx,
116+
&iter->ext_index);
117+
if (!iter->section) {
118+
iter->edid = NULL;
119+
return NULL;
120+
}
121+
122+
iter->idx += sizeof(struct displayid_hdr);
123+
124+
block = displayid_iter_block(iter);
125+
if (block)
126+
return block;
127+
}
128+
}
129+
130+
void displayid_iter_end(struct displayid_iter *iter)
131+
{
132+
memset(iter, 0, sizeof(*iter));
133+
}

include/drm/drm_displayid.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,22 @@ const u8 *drm_find_displayid_extension(const struct edid *edid,
108108
int *length, int *idx,
109109
int *ext_index);
110110

111+
/* DisplayID iteration */
112+
struct displayid_iter {
113+
const struct edid *edid;
114+
115+
const u8 *section;
116+
int length;
117+
int idx;
118+
int ext_index;
119+
};
120+
121+
void displayid_iter_edid_begin(const struct edid *edid,
122+
struct displayid_iter *iter);
123+
const struct displayid_block *
124+
__displayid_iter_next(struct displayid_iter *iter);
125+
#define displayid_iter_for_each(__block, __iter) \
126+
while (((__block) = __displayid_iter_next(__iter)))
127+
void displayid_iter_end(struct displayid_iter *iter);
128+
111129
#endif

0 commit comments

Comments
 (0)