Skip to content

Commit

Permalink
drm/displayid: add new displayid section/block iterators
Browse files Browse the repository at this point in the history
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ä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/da3dead1752ab16c061f7bd248ac1a4268f7fefb.1617024940.git.jani.nikula@intel.com
  • Loading branch information
Jani Nikula committed Mar 31, 2021
1 parent 4cc4f09 commit 1a24c36
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
74 changes: 74 additions & 0 deletions drivers/gpu/drm/drm_displayid.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,77 @@ const u8 *drm_find_displayid_extension(const struct edid *edid,

return displayid;
}

void displayid_iter_edid_begin(const struct edid *edid,
struct displayid_iter *iter)
{
memset(iter, 0, sizeof(*iter));

iter->edid = edid;
}

static const struct displayid_block *
displayid_iter_block(const struct displayid_iter *iter)
{
const struct displayid_block *block;

if (!iter->section)
return NULL;

block = (const struct displayid_block *)&iter->section[iter->idx];

if (iter->idx + sizeof(*block) <= iter->length &&
iter->idx + sizeof(*block) + block->num_bytes <= iter->length &&
block->num_bytes > 0)
return block;

return NULL;
}

const struct displayid_block *
__displayid_iter_next(struct displayid_iter *iter)
{
const struct displayid_block *block;

if (!iter->edid)
return NULL;

if (iter->section) {
/* current block should always be valid */
block = displayid_iter_block(iter);
if (WARN_ON(!block)) {
iter->section = NULL;
iter->edid = NULL;
return NULL;
}

/* next block in section */
iter->idx += sizeof(*block) + block->num_bytes;

block = displayid_iter_block(iter);
if (block)
return block;
}

for (;;) {
iter->section = drm_find_displayid_extension(iter->edid,
&iter->length,
&iter->idx,
&iter->ext_index);
if (!iter->section) {
iter->edid = NULL;
return NULL;
}

iter->idx += sizeof(struct displayid_hdr);

block = displayid_iter_block(iter);
if (block)
return block;
}
}

void displayid_iter_end(struct displayid_iter *iter)
{
memset(iter, 0, sizeof(*iter));
}
18 changes: 18 additions & 0 deletions include/drm/drm_displayid.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,22 @@ const u8 *drm_find_displayid_extension(const struct edid *edid,
int *length, int *idx,
int *ext_index);

/* DisplayID iteration */
struct displayid_iter {
const struct edid *edid;

const u8 *section;
int length;
int idx;
int ext_index;
};

void displayid_iter_edid_begin(const struct edid *edid,
struct displayid_iter *iter);
const struct displayid_block *
__displayid_iter_next(struct displayid_iter *iter);
#define displayid_iter_for_each(__block, __iter) \
while (((__block) = __displayid_iter_next(__iter)))
void displayid_iter_end(struct displayid_iter *iter);

#endif

0 comments on commit 1a24c36

Please sign in to comment.