* [PATCH 1/5] drm/displayid: Enhance version reporting
2016-05-03 20:36 [rfc] drm/edid: add support for displayid timings Dave Airlie
@ 2016-05-03 20:36 ` Dave Airlie
2016-05-04 9:10 ` Ville Syrjälä
2016-05-03 20:36 ` [PATCH 2/5] drm/displayid: Iterate over all DisplayID blocks Dave Airlie
` (3 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Dave Airlie @ 2016-05-03 20:36 UTC (permalink / raw)
To: dri-devel
From: Tomas Bzatek <tomas@bzatek.net>
Cosmetic change, let's report more precise revisions and IDs.
https://bugs.freedesktop.org/show_bug.cgi?id=95207
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
drivers/gpu/drm/drm_edid.c | 6 +++---
include/drm/drm_displayid.h | 6 ++++--
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9a9be9a..c8a3a55 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4168,8 +4168,8 @@ static int drm_parse_display_id(struct drm_connector *connector,
base = (struct displayid_hdr *)&displayid[idx];
- DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
- base->rev, base->bytes, base->prod_id, base->ext_count);
+ DRM_DEBUG_KMS("base revision v%d.%d, edid length %d, bytes %d, prod_id %d ext_count %d\n",
+ base->ver, base->rev, length, base->bytes, base->prod_id, base->ext_count);
if (base->bytes + 5 > length - idx)
return -EINVAL;
@@ -4183,7 +4183,7 @@ static int drm_parse_display_id(struct drm_connector *connector,
}
block = (struct displayid_block *)&displayid[idx + 4];
- DRM_DEBUG_KMS("block id %d, rev %d, len %d\n",
+ DRM_DEBUG_KMS("block id 0x%x, rev %d, len %d\n",
block->tag, block->rev, block->num_bytes);
switch (block->tag) {
diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
index 623b4e9..042f9fc 100644
--- a/include/drm/drm_displayid.h
+++ b/include/drm/drm_displayid.h
@@ -52,7 +52,8 @@
#define PRODUCT_TYPE_DIRECT_DRIVE 6
struct displayid_hdr {
- u8 rev;
+ u8 rev:4;
+ u8 ver:4;
u8 bytes;
u8 prod_id;
u8 ext_count;
@@ -60,7 +61,8 @@ struct displayid_hdr {
struct displayid_block {
u8 tag;
- u8 rev;
+ u8 rev:3;
+ u8 reserved:5;
u8 num_bytes;
} __packed;
--
2.5.5
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH 1/5] drm/displayid: Enhance version reporting
2016-05-03 20:36 ` [PATCH 1/5] drm/displayid: Enhance version reporting Dave Airlie
@ 2016-05-04 9:10 ` Ville Syrjälä
2016-05-09 9:52 ` Michel Dänzer
0 siblings, 1 reply; 12+ messages in thread
From: Ville Syrjälä @ 2016-05-04 9:10 UTC (permalink / raw)
To: Dave Airlie; +Cc: dri-devel
On Wed, May 04, 2016 at 06:36:48AM +1000, Dave Airlie wrote:
> From: Tomas Bzatek <tomas@bzatek.net>
>
> Cosmetic change, let's report more precise revisions and IDs.
>
> https://bugs.freedesktop.org/show_bug.cgi?id=95207
>
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> ---
> drivers/gpu/drm/drm_edid.c | 6 +++---
> include/drm/drm_displayid.h | 6 ++++--
> 2 files changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 9a9be9a..c8a3a55 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4168,8 +4168,8 @@ static int drm_parse_display_id(struct drm_connector *connector,
>
> base = (struct displayid_hdr *)&displayid[idx];
>
> - DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
> - base->rev, base->bytes, base->prod_id, base->ext_count);
> + DRM_DEBUG_KMS("base revision v%d.%d, edid length %d, bytes %d, prod_id %d ext_count %d\n",
> + base->ver, base->rev, length, base->bytes, base->prod_id, base->ext_count);
>
> if (base->bytes + 5 > length - idx)
> return -EINVAL;
> @@ -4183,7 +4183,7 @@ static int drm_parse_display_id(struct drm_connector *connector,
> }
>
> block = (struct displayid_block *)&displayid[idx + 4];
> - DRM_DEBUG_KMS("block id %d, rev %d, len %d\n",
> + DRM_DEBUG_KMS("block id 0x%x, rev %d, len %d\n",
> block->tag, block->rev, block->num_bytes);
>
> switch (block->tag) {
> diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
> index 623b4e9..042f9fc 100644
> --- a/include/drm/drm_displayid.h
> +++ b/include/drm/drm_displayid.h
> @@ -52,7 +52,8 @@
> #define PRODUCT_TYPE_DIRECT_DRIVE 6
>
> struct displayid_hdr {
> - u8 rev;
> + u8 rev:4;
> + u8 ver:4;
> u8 bytes;
> u8 prod_id;
> u8 ext_count;
> @@ -60,7 +61,8 @@ struct displayid_hdr {
>
> struct displayid_block {
> u8 tag;
> - u8 rev;
> + u8 rev:3;
> + u8 reserved:5;
> u8 num_bytes;
> } __packed;
Using bitfields in an architecture independent structure doesn't
feel like an entirely good idea to me.
--
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 1/5] drm/displayid: Enhance version reporting
2016-05-04 9:10 ` Ville Syrjälä
@ 2016-05-09 9:52 ` Michel Dänzer
2016-05-10 1:16 ` Dave Airlie
0 siblings, 1 reply; 12+ messages in thread
From: Michel Dänzer @ 2016-05-09 9:52 UTC (permalink / raw)
To: Ville Syrjälä, Dave Airlie; +Cc: dri-devel
On 04.05.2016 18:10, Ville Syrjälä wrote:
> On Wed, May 04, 2016 at 06:36:48AM +1000, Dave Airlie wrote:
>> From: Tomas Bzatek <tomas@bzatek.net>
>>
>> Cosmetic change, let's report more precise revisions and IDs.
>>
>> https://bugs.freedesktop.org/show_bug.cgi?id=95207
>>
>> Signed-off-by: Dave Airlie <airlied@redhat.com>
>> ---
>> drivers/gpu/drm/drm_edid.c | 6 +++---
>> include/drm/drm_displayid.h | 6 ++++--
>> 2 files changed, 7 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index 9a9be9a..c8a3a55 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -4168,8 +4168,8 @@ static int drm_parse_display_id(struct drm_connector *connector,
>>
>> base = (struct displayid_hdr *)&displayid[idx];
>>
>> - DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
>> - base->rev, base->bytes, base->prod_id, base->ext_count);
>> + DRM_DEBUG_KMS("base revision v%d.%d, edid length %d, bytes %d, prod_id %d ext_count %d\n",
>> + base->ver, base->rev, length, base->bytes, base->prod_id, base->ext_count);
>>
>> if (base->bytes + 5 > length - idx)
>> return -EINVAL;
>> @@ -4183,7 +4183,7 @@ static int drm_parse_display_id(struct drm_connector *connector,
>> }
>>
>> block = (struct displayid_block *)&displayid[idx + 4];
>> - DRM_DEBUG_KMS("block id %d, rev %d, len %d\n",
>> + DRM_DEBUG_KMS("block id 0x%x, rev %d, len %d\n",
>> block->tag, block->rev, block->num_bytes);
>>
>> switch (block->tag) {
>> diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
>> index 623b4e9..042f9fc 100644
>> --- a/include/drm/drm_displayid.h
>> +++ b/include/drm/drm_displayid.h
>> @@ -52,7 +52,8 @@
>> #define PRODUCT_TYPE_DIRECT_DRIVE 6
>>
>> struct displayid_hdr {
>> - u8 rev;
>> + u8 rev:4;
>> + u8 ver:4;
>> u8 bytes;
>> u8 prod_id;
>> u8 ext_count;
>> @@ -60,7 +61,8 @@ struct displayid_hdr {
>>
>> struct displayid_block {
>> u8 tag;
>> - u8 rev;
>> + u8 rev:3;
>> + u8 reserved:5;
>> u8 num_bytes;
>> } __packed;
>
> Using bitfields in an architecture independent structure doesn't
> feel like an entirely good idea to me.
Yeah, this won't work as expected on some architectures.
--
Earthling Michel Dänzer | http://www.amd.com
Libre software enthusiast | Mesa and X developer
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 1/5] drm/displayid: Enhance version reporting
2016-05-09 9:52 ` Michel Dänzer
@ 2016-05-10 1:16 ` Dave Airlie
0 siblings, 0 replies; 12+ messages in thread
From: Dave Airlie @ 2016-05-10 1:16 UTC (permalink / raw)
To: Michel Dänzer; +Cc: dri-devel
>>> index 623b4e9..042f9fc 100644
>>> --- a/include/drm/drm_displayid.h
>>> +++ b/include/drm/drm_displayid.h
>>> @@ -52,7 +52,8 @@
>>> #define PRODUCT_TYPE_DIRECT_DRIVE 6
>>>
>>> struct displayid_hdr {
>>> - u8 rev;
>>> + u8 rev:4;
>>> + u8 ver:4;
>>> u8 bytes;
>>> u8 prod_id;
>>> u8 ext_count;
>>> @@ -60,7 +61,8 @@ struct displayid_hdr {
>>>
>>> struct displayid_block {
>>> u8 tag;
>>> - u8 rev;
>>> + u8 rev:3;
>>> + u8 reserved:5;
>>> u8 num_bytes;
>>> } __packed;
>>
>> Using bitfields in an architecture independent structure doesn't
>> feel like an entirely good idea to me.
>
> Yeah, this won't work as expected on some architectures.
>
Indeed, I'll drop this for now.
Dave.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/5] drm/displayid: Iterate over all DisplayID blocks
2016-05-03 20:36 [rfc] drm/edid: add support for displayid timings Dave Airlie
2016-05-03 20:36 ` [PATCH 1/5] drm/displayid: Enhance version reporting Dave Airlie
@ 2016-05-03 20:36 ` Dave Airlie
2016-05-03 20:36 ` [PATCH 3/5] drm/edid: move displayid tiled block parsing into separate function Dave Airlie
` (2 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: Dave Airlie @ 2016-05-03 20:36 UTC (permalink / raw)
To: dri-devel
From: Tomas Bzatek <tomas@bzatek.net>
This will iterate over all DisplayID blocks found in the buffer.
Previously only the first block was parsed.
https://bugs.freedesktop.org/show_bug.cgi?id=95207
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
drivers/gpu/drm/drm_edid.c | 124 ++++++++++++++++++++++++---------------------
1 file changed, 65 insertions(+), 59 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index c8a3a55..1a364b3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4182,66 +4182,72 @@ static int drm_parse_display_id(struct drm_connector *connector,
return -EINVAL;
}
- block = (struct displayid_block *)&displayid[idx + 4];
- DRM_DEBUG_KMS("block id 0x%x, rev %d, len %d\n",
- block->tag, block->rev, block->num_bytes);
-
- switch (block->tag) {
- case DATA_BLOCK_TILED_DISPLAY: {
- struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
-
- u16 w, h;
- u8 tile_v_loc, tile_h_loc;
- u8 num_v_tile, num_h_tile;
- struct drm_tile_group *tg;
-
- w = tile->tile_size[0] | tile->tile_size[1] << 8;
- h = tile->tile_size[2] | tile->tile_size[3] << 8;
-
- num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
- num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
- tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
- tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
-
- connector->has_tile = true;
- if (tile->tile_cap & 0x80)
- connector->tile_is_single_monitor = true;
-
- connector->num_h_tile = num_h_tile + 1;
- connector->num_v_tile = num_v_tile + 1;
- connector->tile_h_loc = tile_h_loc;
- connector->tile_v_loc = tile_v_loc;
- connector->tile_h_size = w + 1;
- connector->tile_v_size = h + 1;
-
- DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
- DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
- DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
- num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
- DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
-
- tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
- if (!tg) {
- tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
- }
- if (!tg)
- return -ENOMEM;
-
- if (connector->tile_group != tg) {
- /* if we haven't got a pointer,
- take the reference, drop ref to old tile group */
- if (connector->tile_group) {
- drm_mode_put_tile_group(connector->dev, connector->tile_group);
+ idx += sizeof(struct displayid_hdr);
+ while (block = (struct displayid_block *)&displayid[idx],
+ idx + sizeof(struct displayid_block) <= length &&
+ idx + sizeof(struct displayid_block) + block->num_bytes <= length &&
+ block->num_bytes > 0) {
+ idx += block->num_bytes + sizeof(struct displayid_block);
+ DRM_DEBUG_KMS("block id 0x%x, rev %d, len %d\n",
+ block->tag, block->rev, block->num_bytes);
+
+ switch (block->tag) {
+ case DATA_BLOCK_TILED_DISPLAY: {
+ struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
+
+ u16 w, h;
+ u8 tile_v_loc, tile_h_loc;
+ u8 num_v_tile, num_h_tile;
+ struct drm_tile_group *tg;
+
+ w = tile->tile_size[0] | tile->tile_size[1] << 8;
+ h = tile->tile_size[2] | tile->tile_size[3] << 8;
+
+ num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
+ num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
+ tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
+ tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
+
+ connector->has_tile = true;
+ if (tile->tile_cap & 0x80)
+ connector->tile_is_single_monitor = true;
+
+ connector->num_h_tile = num_h_tile + 1;
+ connector->num_v_tile = num_v_tile + 1;
+ connector->tile_h_loc = tile_h_loc;
+ connector->tile_v_loc = tile_v_loc;
+ connector->tile_h_size = w + 1;
+ connector->tile_v_size = h + 1;
+
+ DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
+ DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
+ DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
+ num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
+ DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
+
+ tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
+ if (!tg) {
+ tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
}
- connector->tile_group = tg;
- } else
- /* if same tile group, then release the ref we just took. */
- drm_mode_put_tile_group(connector->dev, tg);
- }
- break;
- default:
- printk("unknown displayid tag %d\n", block->tag);
- break;
+ if (!tg)
+ return -ENOMEM;
+
+ if (connector->tile_group != tg) {
+ /* if we haven't got a pointer,
+ take the reference, drop ref to old tile group */
+ if (connector->tile_group) {
+ drm_mode_put_tile_group(connector->dev, connector->tile_group);
+ }
+ connector->tile_group = tg;
+ } else
+ /* if same tile group, then release the ref we just took. */
+ drm_mode_put_tile_group(connector->dev, tg);
+ }
+ break;
+ default:
+ DRM_DEBUG_KMS("found DisplayID tag 0x%x, unhandled\n", block->tag);
+ break;
+ }
}
return 0;
}
--
2.5.5
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 3/5] drm/edid: move displayid tiled block parsing into separate function.
2016-05-03 20:36 [rfc] drm/edid: add support for displayid timings Dave Airlie
2016-05-03 20:36 ` [PATCH 1/5] drm/displayid: Enhance version reporting Dave Airlie
2016-05-03 20:36 ` [PATCH 2/5] drm/displayid: Iterate over all DisplayID blocks Dave Airlie
@ 2016-05-03 20:36 ` Dave Airlie
2016-05-04 8:04 ` Jani Nikula
2016-05-03 20:36 ` [PATCH 4/5] drm/edid: move displayid validation to it's own function Dave Airlie
2016-05-03 20:36 ` [PATCH 5/5] drm/edid: add displayid detailed 1 timings to the modelist Dave Airlie
4 siblings, 1 reply; 12+ messages in thread
From: Dave Airlie @ 2016-05-03 20:36 UTC (permalink / raw)
To: dri-devel
From: Dave Airlie <airlied@redhat.com>
This just makes the code easier to follow.
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
drivers/gpu/drm/drm_edid.c | 110 ++++++++++++++++++++++++---------------------
1 file changed, 59 insertions(+), 51 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 1a364b3..e4c681f 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4152,6 +4152,60 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
}
EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);
+static int drm_parse_tiled_block(struct drm_connector *connector,
+ struct displayid_block *block)
+{
+ struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
+ u16 w, h;
+ u8 tile_v_loc, tile_h_loc;
+ u8 num_v_tile, num_h_tile;
+ struct drm_tile_group *tg;
+
+ w = tile->tile_size[0] | tile->tile_size[1] << 8;
+ h = tile->tile_size[2] | tile->tile_size[3] << 8;
+
+ num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
+ num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
+ tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
+ tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
+
+ connector->has_tile = true;
+ if (tile->tile_cap & 0x80)
+ connector->tile_is_single_monitor = true;
+
+ connector->num_h_tile = num_h_tile + 1;
+ connector->num_v_tile = num_v_tile + 1;
+ connector->tile_h_loc = tile_h_loc;
+ connector->tile_v_loc = tile_v_loc;
+ connector->tile_h_size = w + 1;
+ connector->tile_v_size = h + 1;
+
+ DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
+ DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
+ DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
+ num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
+ DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
+
+ tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
+ if (!tg) {
+ tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
+ }
+ if (!tg)
+ return -ENOMEM;
+
+ if (connector->tile_group != tg) {
+ /* if we haven't got a pointer,
+ take the reference, drop ref to old tile group */
+ if (connector->tile_group) {
+ drm_mode_put_tile_group(connector->dev, connector->tile_group);
+ }
+ connector->tile_group = tg;
+ } else
+ /* if same tile group, then release the ref we just took. */
+ drm_mode_put_tile_group(connector->dev, tg);
+ return 0;
+}
+
static int drm_parse_display_id(struct drm_connector *connector,
u8 *displayid, int length,
bool is_edid_extension)
@@ -4162,6 +4216,7 @@ static int drm_parse_display_id(struct drm_connector *connector,
struct displayid_block *block;
u8 csum = 0;
int i;
+ int ret;
if (is_edid_extension)
idx = 1;
@@ -4192,57 +4247,10 @@ static int drm_parse_display_id(struct drm_connector *connector,
block->tag, block->rev, block->num_bytes);
switch (block->tag) {
- case DATA_BLOCK_TILED_DISPLAY: {
- struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
-
- u16 w, h;
- u8 tile_v_loc, tile_h_loc;
- u8 num_v_tile, num_h_tile;
- struct drm_tile_group *tg;
-
- w = tile->tile_size[0] | tile->tile_size[1] << 8;
- h = tile->tile_size[2] | tile->tile_size[3] << 8;
-
- num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
- num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
- tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
- tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
-
- connector->has_tile = true;
- if (tile->tile_cap & 0x80)
- connector->tile_is_single_monitor = true;
-
- connector->num_h_tile = num_h_tile + 1;
- connector->num_v_tile = num_v_tile + 1;
- connector->tile_h_loc = tile_h_loc;
- connector->tile_v_loc = tile_v_loc;
- connector->tile_h_size = w + 1;
- connector->tile_v_size = h + 1;
-
- DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
- DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
- DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
- num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
- DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
-
- tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
- if (!tg) {
- tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
- }
- if (!tg)
- return -ENOMEM;
-
- if (connector->tile_group != tg) {
- /* if we haven't got a pointer,
- take the reference, drop ref to old tile group */
- if (connector->tile_group) {
- drm_mode_put_tile_group(connector->dev, connector->tile_group);
- }
- connector->tile_group = tg;
- } else
- /* if same tile group, then release the ref we just took. */
- drm_mode_put_tile_group(connector->dev, tg);
- }
+ case DATA_BLOCK_TILED_DISPLAY:
+ ret = drm_parse_tiled_block(connector, block);
+ if (ret)
+ return ret;
break;
default:
DRM_DEBUG_KMS("found DisplayID tag 0x%x, unhandled\n", block->tag);
--
2.5.5
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH 3/5] drm/edid: move displayid tiled block parsing into separate function.
2016-05-03 20:36 ` [PATCH 3/5] drm/edid: move displayid tiled block parsing into separate function Dave Airlie
@ 2016-05-04 8:04 ` Jani Nikula
0 siblings, 0 replies; 12+ messages in thread
From: Jani Nikula @ 2016-05-04 8:04 UTC (permalink / raw)
To: Dave Airlie, dri-devel
On Tue, 03 May 2016, Dave Airlie <airlied@gmail.com> wrote:
> From: Dave Airlie <airlied@redhat.com>
>
> This just makes the code easier to follow.
Swapping the order of patches 2 and 3 would make the patch series easier
to follow. ;)
BR,
Jani.
>
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> ---
> drivers/gpu/drm/drm_edid.c | 110 ++++++++++++++++++++++++---------------------
> 1 file changed, 59 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 1a364b3..e4c681f 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -4152,6 +4152,60 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
> }
> EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);
>
> +static int drm_parse_tiled_block(struct drm_connector *connector,
> + struct displayid_block *block)
> +{
> + struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
> + u16 w, h;
> + u8 tile_v_loc, tile_h_loc;
> + u8 num_v_tile, num_h_tile;
> + struct drm_tile_group *tg;
> +
> + w = tile->tile_size[0] | tile->tile_size[1] << 8;
> + h = tile->tile_size[2] | tile->tile_size[3] << 8;
> +
> + num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
> + num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
> + tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
> + tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
> +
> + connector->has_tile = true;
> + if (tile->tile_cap & 0x80)
> + connector->tile_is_single_monitor = true;
> +
> + connector->num_h_tile = num_h_tile + 1;
> + connector->num_v_tile = num_v_tile + 1;
> + connector->tile_h_loc = tile_h_loc;
> + connector->tile_v_loc = tile_v_loc;
> + connector->tile_h_size = w + 1;
> + connector->tile_v_size = h + 1;
> +
> + DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
> + DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
> + DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
> + num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
> + DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
> +
> + tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
> + if (!tg) {
> + tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
> + }
> + if (!tg)
> + return -ENOMEM;
> +
> + if (connector->tile_group != tg) {
> + /* if we haven't got a pointer,
> + take the reference, drop ref to old tile group */
> + if (connector->tile_group) {
> + drm_mode_put_tile_group(connector->dev, connector->tile_group);
> + }
> + connector->tile_group = tg;
> + } else
> + /* if same tile group, then release the ref we just took. */
> + drm_mode_put_tile_group(connector->dev, tg);
> + return 0;
> +}
> +
> static int drm_parse_display_id(struct drm_connector *connector,
> u8 *displayid, int length,
> bool is_edid_extension)
> @@ -4162,6 +4216,7 @@ static int drm_parse_display_id(struct drm_connector *connector,
> struct displayid_block *block;
> u8 csum = 0;
> int i;
> + int ret;
>
> if (is_edid_extension)
> idx = 1;
> @@ -4192,57 +4247,10 @@ static int drm_parse_display_id(struct drm_connector *connector,
> block->tag, block->rev, block->num_bytes);
>
> switch (block->tag) {
> - case DATA_BLOCK_TILED_DISPLAY: {
> - struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
> -
> - u16 w, h;
> - u8 tile_v_loc, tile_h_loc;
> - u8 num_v_tile, num_h_tile;
> - struct drm_tile_group *tg;
> -
> - w = tile->tile_size[0] | tile->tile_size[1] << 8;
> - h = tile->tile_size[2] | tile->tile_size[3] << 8;
> -
> - num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
> - num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
> - tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
> - tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
> -
> - connector->has_tile = true;
> - if (tile->tile_cap & 0x80)
> - connector->tile_is_single_monitor = true;
> -
> - connector->num_h_tile = num_h_tile + 1;
> - connector->num_v_tile = num_v_tile + 1;
> - connector->tile_h_loc = tile_h_loc;
> - connector->tile_v_loc = tile_v_loc;
> - connector->tile_h_size = w + 1;
> - connector->tile_v_size = h + 1;
> -
> - DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
> - DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
> - DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
> - num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
> - DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
> -
> - tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
> - if (!tg) {
> - tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
> - }
> - if (!tg)
> - return -ENOMEM;
> -
> - if (connector->tile_group != tg) {
> - /* if we haven't got a pointer,
> - take the reference, drop ref to old tile group */
> - if (connector->tile_group) {
> - drm_mode_put_tile_group(connector->dev, connector->tile_group);
> - }
> - connector->tile_group = tg;
> - } else
> - /* if same tile group, then release the ref we just took. */
> - drm_mode_put_tile_group(connector->dev, tg);
> - }
> + case DATA_BLOCK_TILED_DISPLAY:
> + ret = drm_parse_tiled_block(connector, block);
> + if (ret)
> + return ret;
> break;
> default:
> DRM_DEBUG_KMS("found DisplayID tag 0x%x, unhandled\n", block->tag);
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 4/5] drm/edid: move displayid validation to it's own function.
2016-05-03 20:36 [rfc] drm/edid: add support for displayid timings Dave Airlie
` (2 preceding siblings ...)
2016-05-03 20:36 ` [PATCH 3/5] drm/edid: move displayid tiled block parsing into separate function Dave Airlie
@ 2016-05-03 20:36 ` Dave Airlie
2016-05-03 20:36 ` [PATCH 5/5] drm/edid: add displayid detailed 1 timings to the modelist Dave Airlie
4 siblings, 0 replies; 12+ messages in thread
From: Dave Airlie @ 2016-05-03 20:36 UTC (permalink / raw)
To: dri-devel
From: Dave Airlie <airlied@redhat.com>
We need to use this for validating modeline additions.
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
drivers/gpu/drm/drm_edid.c | 45 +++++++++++++++++++++++++++------------------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e4c681f..e85d828 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3901,6 +3901,30 @@ static void drm_add_display_info(struct edid *edid,
info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
}
+static int validate_displayid(u8 *displayid, int length, int idx)
+{
+ int i;
+ u8 csum = 0;
+ struct displayid_hdr *base;
+
+ base = (struct displayid_hdr *)&displayid[idx];
+
+ DRM_DEBUG_KMS("base revision v%d.%d, edid length %d, bytes %d, prod_id %d ext_count %d\n",
+ base->ver, base->rev, length, base->bytes, base->prod_id,
+ base->ext_count);
+
+ if (base->bytes + 5 > length - idx)
+ return -EINVAL;
+ for (i = idx; i <= base->bytes + 5; i++) {
+ csum += displayid[i];
+ }
+ if (csum) {
+ DRM_ERROR("DisplayID checksum invalid, remainder is %d\n", csum);
+ return -EINVAL;
+ }
+ return 0;
+}
+
/**
* drm_add_edid_modes - add modes from EDID data, if available
* @connector: connector we're probing
@@ -4212,30 +4236,15 @@ static int drm_parse_display_id(struct drm_connector *connector,
{
/* if this is an EDID extension the first byte will be 0x70 */
int idx = 0;
- struct displayid_hdr *base;
struct displayid_block *block;
- u8 csum = 0;
- int i;
int ret;
if (is_edid_extension)
idx = 1;
- base = (struct displayid_hdr *)&displayid[idx];
-
- DRM_DEBUG_KMS("base revision v%d.%d, edid length %d, bytes %d, prod_id %d ext_count %d\n",
- base->ver, base->rev, length, base->bytes, base->prod_id, base->ext_count);
-
- if (base->bytes + 5 > length - idx)
- return -EINVAL;
-
- for (i = idx; i <= base->bytes + 5; i++) {
- csum += displayid[i];
- }
- if (csum) {
- DRM_ERROR("DisplayID checksum invalid, remainder is %d\n", csum);
- return -EINVAL;
- }
+ ret = validate_displayid(displayid, length, idx);
+ if (ret)
+ return ret;
idx += sizeof(struct displayid_hdr);
while (block = (struct displayid_block *)&displayid[idx],
--
2.5.5
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 5/5] drm/edid: add displayid detailed 1 timings to the modelist.
2016-05-03 20:36 [rfc] drm/edid: add support for displayid timings Dave Airlie
` (3 preceding siblings ...)
2016-05-03 20:36 ` [PATCH 4/5] drm/edid: move displayid validation to it's own function Dave Airlie
@ 2016-05-03 20:36 ` Dave Airlie
2016-05-04 8:10 ` Jani Nikula
4 siblings, 1 reply; 12+ messages in thread
From: Dave Airlie @ 2016-05-03 20:36 UTC (permalink / raw)
To: dri-devel
From: Dave Airlie <airlied@redhat.com>
The tiled 5K Dell monitor appears to be hiding it's tiled mode
inside the displayid timings block, this patch parses this
blocks and adds the modes to the modelist.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95207
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
drivers/gpu/drm/drm_edid.c | 105 ++++++++++++++++++++++++++++++++++++++++++++
include/drm/drm_displayid.h | 17 +++++++
2 files changed, 122 insertions(+)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e85d828..aca9e25 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3925,6 +3925,110 @@ static int validate_displayid(u8 *displayid, int length, int idx)
return 0;
}
+static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev,
+ struct displayid_detailed_timings_1 *timings)
+{
+ struct drm_display_mode *mode;
+ unsigned pixel_clock = (timings->pixel_clock[0] |
+ (timings->pixel_clock[1] << 8) |
+ (timings->pixel_clock[2] << 16));
+ unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1;
+ unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1;
+ unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1;
+ unsigned hsync_width = (timings->hsw[0] | timings->hsw[1] << 8) + 1;
+ unsigned vactive = (timings->vactive[0] | timings->vactive[1] << 8) + 1;
+ unsigned vblank = (timings->vblank[0] | timings->vblank[1] << 8) + 1;
+ unsigned vsync = (timings->vsync[0] | (timings->vsync[1] & 0x7f) << 8) + 1;
+ unsigned vsync_width = (timings->vsw[0] | timings->vsw[1] << 8) + 1;
+ bool hsync_positive = (timings->hsync[1] >> 7) & 0x1;
+ bool vsync_positive = (timings->vsync[1] >> 7) & 0x1;
+ mode = drm_mode_create(dev);
+ if (!mode)
+ return NULL;
+
+ mode->clock = pixel_clock * 10;
+ mode->hdisplay = hactive;
+ mode->hsync_start = mode->hdisplay + hsync;
+ mode->hsync_end = mode->hsync_start + hsync_width;
+ mode->htotal = mode->hdisplay + hblank;
+
+ mode->vdisplay = vactive;
+ mode->vsync_start = mode->vdisplay + vsync;
+ mode->vsync_end = mode->vsync_start + vsync_width;
+ mode->vtotal = mode->vdisplay + vblank;
+
+ mode->flags = 0;
+ mode->flags |= hsync_positive ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
+ mode->flags |= vsync_positive ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
+ mode->type = DRM_MODE_TYPE_DRIVER;
+
+ if (timings->flags & 0x80)
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+ mode->vrefresh = drm_mode_vrefresh(mode);
+ drm_mode_set_name(mode);
+
+ return mode;
+}
+
+static int add_displayid_detailed_1_modes(struct drm_connector *connector,
+ struct displayid_block *block)
+{
+ struct displayid_detailed_timing_block *det = (struct displayid_detailed_timing_block *)block;
+ int i;
+ int num_timings;
+ struct drm_display_mode *newmode;
+ int num_modes = 0;
+ /* blocks must be multiple of 20 bytes length */
+ if (block->num_bytes % 20)
+ return 0;
+
+ num_timings = block->num_bytes / 20;
+ for (i = 0; i < num_timings; i++) {
+ struct displayid_detailed_timings_1 *timings = &det->timings[i];
+
+ newmode = drm_mode_displayid_detailed(connector->dev, timings);
+ if (!newmode)
+ continue;
+
+ drm_mode_probed_add(connector, newmode);
+ num_modes++;
+ }
+ return num_modes;
+}
+
+static int add_displayid_detailed_modes(struct drm_connector *connector,
+ struct edid *edid)
+{
+ u8 *displayid;
+ int ret;
+ int idx = 1;
+ int length = EDID_LENGTH;
+ struct displayid_block *block;
+ int num_modes = 0;
+
+ displayid = drm_find_displayid_extension(edid);
+ if (!displayid)
+ return 0;
+
+ ret = validate_displayid(displayid, length, idx);
+ if (ret)
+ return 0;
+
+ idx += sizeof(struct displayid_hdr);
+ while (block = (struct displayid_block *)&displayid[idx],
+ idx + sizeof(struct displayid_block) <= length &&
+ idx + sizeof(struct displayid_block) + block->num_bytes <= length &&
+ block->num_bytes > 0) {
+ idx += block->num_bytes + sizeof(struct displayid_block);
+ switch (block->tag) {
+ case DATA_BLOCK_TYPE_1_DETAILED_TIMING:
+ num_modes += add_displayid_detailed_1_modes(connector, block);
+ break;
+ }
+ }
+ return num_modes;
+}
+
/**
* drm_add_edid_modes - add modes from EDID data, if available
* @connector: connector we're probing
@@ -3970,6 +4074,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
num_modes += add_established_modes(connector, edid);
num_modes += add_cea_modes(connector, edid);
num_modes += add_alternate_cea_modes(connector, edid);
+ num_modes += add_displayid_detailed_modes(connector, edid);
if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
num_modes += add_inferred_modes(connector, edid);
diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
index 042f9fc..edef51d 100644
--- a/include/drm/drm_displayid.h
+++ b/include/drm/drm_displayid.h
@@ -75,4 +75,21 @@ struct displayid_tiled_block {
u8 topology_id[8];
} __packed;
+struct displayid_detailed_timings_1 {
+ u8 pixel_clock[3];
+ u8 flags;
+ u8 hactive[2];
+ u8 hblank[2];
+ u8 hsync[2];
+ u8 hsw[2];
+ u8 vactive[2];
+ u8 vblank[2];
+ u8 vsync[2];
+ u8 vsw[2];
+};
+
+struct displayid_detailed_timing_block {
+ struct displayid_block base;
+ struct displayid_detailed_timings_1 timings[0];
+};
#endif
--
2.5.5
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH 5/5] drm/edid: add displayid detailed 1 timings to the modelist.
2016-05-03 20:36 ` [PATCH 5/5] drm/edid: add displayid detailed 1 timings to the modelist Dave Airlie
@ 2016-05-04 8:10 ` Jani Nikula
2016-05-10 1:18 ` Dave Airlie
0 siblings, 1 reply; 12+ messages in thread
From: Jani Nikula @ 2016-05-04 8:10 UTC (permalink / raw)
To: Dave Airlie, dri-devel
On Tue, 03 May 2016, Dave Airlie <airlied@gmail.com> wrote:
> From: Dave Airlie <airlied@redhat.com>
>
> The tiled 5K Dell monitor appears to be hiding it's tiled mode
> inside the displayid timings block, this patch parses this
> blocks and adds the modes to the modelist.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95207
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> ---
> drivers/gpu/drm/drm_edid.c | 105 ++++++++++++++++++++++++++++++++++++++++++++
> include/drm/drm_displayid.h | 17 +++++++
> 2 files changed, 122 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index e85d828..aca9e25 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -3925,6 +3925,110 @@ static int validate_displayid(u8 *displayid, int length, int idx)
> return 0;
> }
>
> +static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev,
> + struct displayid_detailed_timings_1 *timings)
> +{
> + struct drm_display_mode *mode;
> + unsigned pixel_clock = (timings->pixel_clock[0] |
> + (timings->pixel_clock[1] << 8) |
> + (timings->pixel_clock[2] << 16));
> + unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1;
> + unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1;
> + unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1;
> + unsigned hsync_width = (timings->hsw[0] | timings->hsw[1] << 8) + 1;
> + unsigned vactive = (timings->vactive[0] | timings->vactive[1] << 8) + 1;
> + unsigned vblank = (timings->vblank[0] | timings->vblank[1] << 8) + 1;
> + unsigned vsync = (timings->vsync[0] | (timings->vsync[1] & 0x7f) << 8) + 1;
> + unsigned vsync_width = (timings->vsw[0] | timings->vsw[1] << 8) + 1;
> + bool hsync_positive = (timings->hsync[1] >> 7) & 0x1;
> + bool vsync_positive = (timings->vsync[1] >> 7) & 0x1;
> + mode = drm_mode_create(dev);
> + if (!mode)
> + return NULL;
> +
> + mode->clock = pixel_clock * 10;
> + mode->hdisplay = hactive;
> + mode->hsync_start = mode->hdisplay + hsync;
> + mode->hsync_end = mode->hsync_start + hsync_width;
> + mode->htotal = mode->hdisplay + hblank;
> +
> + mode->vdisplay = vactive;
> + mode->vsync_start = mode->vdisplay + vsync;
> + mode->vsync_end = mode->vsync_start + vsync_width;
> + mode->vtotal = mode->vdisplay + vblank;
> +
> + mode->flags = 0;
> + mode->flags |= hsync_positive ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
> + mode->flags |= vsync_positive ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
> + mode->type = DRM_MODE_TYPE_DRIVER;
> +
> + if (timings->flags & 0x80)
> + mode->type |= DRM_MODE_TYPE_PREFERRED;
> + mode->vrefresh = drm_mode_vrefresh(mode);
> + drm_mode_set_name(mode);
> +
> + return mode;
> +}
> +
> +static int add_displayid_detailed_1_modes(struct drm_connector *connector,
> + struct displayid_block *block)
> +{
> + struct displayid_detailed_timing_block *det = (struct displayid_detailed_timing_block *)block;
> + int i;
> + int num_timings;
> + struct drm_display_mode *newmode;
> + int num_modes = 0;
> + /* blocks must be multiple of 20 bytes length */
> + if (block->num_bytes % 20)
> + return 0;
> +
> + num_timings = block->num_bytes / 20;
> + for (i = 0; i < num_timings; i++) {
> + struct displayid_detailed_timings_1 *timings = &det->timings[i];
> +
> + newmode = drm_mode_displayid_detailed(connector->dev, timings);
> + if (!newmode)
> + continue;
> +
> + drm_mode_probed_add(connector, newmode);
> + num_modes++;
> + }
> + return num_modes;
> +}
> +
> +static int add_displayid_detailed_modes(struct drm_connector *connector,
> + struct edid *edid)
> +{
> + u8 *displayid;
> + int ret;
> + int idx = 1;
> + int length = EDID_LENGTH;
> + struct displayid_block *block;
> + int num_modes = 0;
> +
> + displayid = drm_find_displayid_extension(edid);
> + if (!displayid)
> + return 0;
> +
> + ret = validate_displayid(displayid, length, idx);
> + if (ret)
> + return 0;
> +
> + idx += sizeof(struct displayid_hdr);
> + while (block = (struct displayid_block *)&displayid[idx],
> + idx + sizeof(struct displayid_block) <= length &&
> + idx + sizeof(struct displayid_block) + block->num_bytes <= length &&
> + block->num_bytes > 0) {
> + idx += block->num_bytes + sizeof(struct displayid_block);
> + switch (block->tag) {
> + case DATA_BLOCK_TYPE_1_DETAILED_TIMING:
> + num_modes += add_displayid_detailed_1_modes(connector, block);
> + break;
> + }
> + }
> + return num_modes;
> +}
> +
> /**
> * drm_add_edid_modes - add modes from EDID data, if available
> * @connector: connector we're probing
> @@ -3970,6 +4074,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
> num_modes += add_established_modes(connector, edid);
> num_modes += add_cea_modes(connector, edid);
> num_modes += add_alternate_cea_modes(connector, edid);
> + num_modes += add_displayid_detailed_modes(connector, edid);
> if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
> num_modes += add_inferred_modes(connector, edid);
>
> diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
> index 042f9fc..edef51d 100644
> --- a/include/drm/drm_displayid.h
> +++ b/include/drm/drm_displayid.h
> @@ -75,4 +75,21 @@ struct displayid_tiled_block {
> u8 topology_id[8];
> } __packed;
>
> +struct displayid_detailed_timings_1 {
> + u8 pixel_clock[3];
> + u8 flags;
> + u8 hactive[2];
> + u8 hblank[2];
> + u8 hsync[2];
> + u8 hsw[2];
> + u8 vactive[2];
> + u8 vblank[2];
> + u8 vsync[2];
> + u8 vsw[2];
An alternative would be to declare these fields as __le16, and you could
read them in drm_mode_displayid_detailed() using le16_to_cpu().
Anyway, these structs should be __packed.
BR,
Jani.
> +};
> +
> +struct displayid_detailed_timing_block {
> + struct displayid_block base;
> + struct displayid_detailed_timings_1 timings[0];
> +};
> #endif
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 5/5] drm/edid: add displayid detailed 1 timings to the modelist.
2016-05-04 8:10 ` Jani Nikula
@ 2016-05-10 1:18 ` Dave Airlie
0 siblings, 0 replies; 12+ messages in thread
From: Dave Airlie @ 2016-05-10 1:18 UTC (permalink / raw)
To: Jani Nikula; +Cc: dri-devel
>>
>> +struct displayid_detailed_timings_1 {
>> + u8 pixel_clock[3];
>> + u8 flags;
>> + u8 hactive[2];
>> + u8 hblank[2];
>> + u8 hsync[2];
>> + u8 hsw[2];
>> + u8 vactive[2];
>> + u8 vblank[2];
>> + u8 vsync[2];
>> + u8 vsw[2];
>
> An alternative would be to declare these fields as __le16, and you could
> read them in drm_mode_displayid_detailed() using le16_to_cpu().
We don't do that for the EDID structs, so I'd rather avoid it here as well.
The spec is always in terms of 8-bit values.
>
> Anyway, these structs should be __packed.
Indeed.
Dave.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 12+ messages in thread