EDID 1.4 digital monitors report the bit depth supported in the input field. Add support for parsing this out and storing the info in the display_info structure for use by drivers.
Signed-off-by: Jesse Barnes jbarnes@virtuousgeek.org --- drivers/gpu/drm/drm_edid.c | 55 ++++++++++++++++++++++++++++++++++++++++++- include/drm/drm_crtc.h | 1 + include/drm/drm_edid.h | 17 ++++++++++++- 3 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index adc9358..3518e1e 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1413,6 +1413,58 @@ end: EXPORT_SYMBOL(drm_detect_monitor_audio);
/** + * drm_add_display_info - pull display info out if present + * @edid: EDID data + * @info: display info (attached to connector) + * + * Grab any available display info and stuff it into the drm_display_info + * structure that's part of the connector. Useful for tracking bpp and + * color spaces. + */ +static void drm_add_display_info(struct edid *edid, + struct drm_display_info *info) +{ + info->width_mm = edid->width_cm * 10; + info->height_mm = edid->height_cm * 10; + + /* driver figures it out in this case */ + info->bpc = 0; + info->color_formats = 0; + + /* Only defined for 1.4 with digital displays */ + if (edid->revision < 4) + return; + + if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) + return; + + switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) { + case DRM_EDID_DIGITAL_DEPTH_6: + info->bpc = 6; + break; + case DRM_EDID_DIGITAL_DEPTH_8: + info->bpc = 8; + break; + case DRM_EDID_DIGITAL_DEPTH_10: + info->bpc = 10; + break; + case DRM_EDID_DIGITAL_DEPTH_12: + info->bpc = 12; + break; + case DRM_EDID_DIGITAL_DEPTH_14: + info->bpc = 14; + break; + case DRM_EDID_DIGITAL_DEPTH_16: + info->bpc = 16; + break; + case DRM_EDID_DIGITAL_DEPTH_UNDEF: + default: + info->bpc = 0; + break; + } +} + +/** * drm_add_edid_modes - add modes from EDID data, if available * @connector: connector we're probing * @edid: edid data @@ -1460,8 +1512,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) edid_fixup_preferred(connector, quirks);
- connector->display_info.width_mm = edid->width_cm * 10; - connector->display_info.height_mm = edid->height_cm * 10; + drm_add_display_info(edid, &connector->display_info);
return num_modes; } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index aaec097..4d8fbb0 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -198,6 +198,7 @@ struct drm_display_info { unsigned int min_vfreq, max_vfreq; unsigned int min_hfreq, max_hfreq; unsigned int pixel_clock; + unsigned int bpc;
enum subpixel_order subpixel_order;
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 5881fad..9b9bf94 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -155,7 +155,22 @@ struct detailed_timing { #define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3) #define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 4) #define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 5) -#define DRM_EDID_INPUT_DIGITAL (1 << 7) /* bits below must be zero if set */ +#define DRM_EDID_INPUT_DIGITAL (1 << 7) +#define DRM_EDID_DIGITAL_DEPTH_MASK (7 << 4) +#define DRM_EDID_DIGITAL_DEPTH_UNDEF (0 << 4) +#define DRM_EDID_DIGITAL_DEPTH_6 (1 << 4) +#define DRM_EDID_DIGITAL_DEPTH_8 (2 << 4) +#define DRM_EDID_DIGITAL_DEPTH_10 (3 << 4) +#define DRM_EDID_DIGITAL_DEPTH_12 (4 << 4) +#define DRM_EDID_DIGITAL_DEPTH_14 (5 << 4) +#define DRM_EDID_DIGITAL_DEPTH_16 (6 << 4) +#define DRM_EDID_DIGITAL_DEPTH_RSVD (7 << 4) +#define DRM_EDID_DIGITAL_TYPE_UNDEF (0) +#define DRM_EDID_DIGITAL_TYPE_DVI (1) +#define DRM_EDID_DIGITAL_TYPE_HDMI_A (2) +#define DRM_EDID_DIGITAL_TYPE_HDMI_B (3) +#define DRM_EDID_DIGITAL_TYPE_MDDI (4) +#define DRM_EDID_DIGITAL_TYPE_DP (5)
#define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 0) #define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 1)
EDID 1.4 digital displays report the color spaces they support in the features block. Add support for grabbing this data and stuffing it into the display_info struct for driver use.
Signed-off-by: Jesse Barnes jbarnes@virtuousgeek.org --- drivers/gpu/drm/drm_edid.c | 6 ++++++ include/drm/drm_crtc.h | 5 ++++- include/drm/drm_edid.h | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 3518e1e..0a9357c 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1462,6 +1462,12 @@ static void drm_add_display_info(struct edid *edid, info->bpc = 0; break; } + + info->color_formats = DRM_COLOR_FORMAT_RGB444; + if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB444) + info->color_formats = DRM_COLOR_FORMAT_YCRCB444; + if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB422) + info->color_formats = DRM_COLOR_FORMAT_YCRCB422; }
/** diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 4d8fbb0..d20aecb 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -183,7 +183,9 @@ enum subpixel_order { SubPixelNone, };
- +#define DRM_COLOR_FORMAT_RGB444 (1<<0) +#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) +#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) /* * Describes a given display (e.g. CRT or flat panel) and its limitations. */ @@ -201,6 +203,7 @@ struct drm_display_info { unsigned int bpc;
enum subpixel_order subpixel_order; + unsigned long color_formats;
char *raw_edid; /* if any */ }; diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 9b9bf94..eacb415 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -175,7 +175,15 @@ struct detailed_timing { #define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 0) #define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 1) #define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 2) +/* If analog */ #define DRM_EDID_FEATURE_DISPLAY_TYPE (3 << 3) /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ +/* If digital */ +#define DRM_EDID_FEATURE_COLOR_MASK (3 << 3) +#define DRM_EDID_FEATURE_RGB (0 << 3) +#define DRM_EDID_FEATURE_RGB_YCRCB444 (1 << 3) +#define DRM_EDID_FEATURE_RGB_YCRCB422 (2 << 3) +#define DRM_EDID_FEATURE_RGB_YCRCB (3 << 3) /* both 4:4:4 and 4:2:2 */ + #define DRM_EDID_FEATURE_PM_ACTIVE_OFF (1 << 5) #define DRM_EDID_FEATURE_PM_SUSPEND (1 << 6) #define DRM_EDID_FEATURE_PM_STANDBY (1 << 7)
+#define DRM_COLOR_FORMAT_RGB444 (1<<0) +#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) +#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) /* * Describes a given display (e.g. CRT or flat panel) and its limitations. */ @@ -201,6 +203,7 @@ struct drm_display_info { unsigned int bpc;
enum subpixel_order subpixel_order;
- unsigned long color_formats;
^ wtf?
unsigned long? its 2011.
Dave.
On Sat, 16 Apr 2011 06:10:07 +1000 Dave Airlie airlied@gmail.com wrote:
+#define DRM_COLOR_FORMAT_RGB444 (1<<0) +#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) +#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) /* * Describes a given display (e.g. CRT or flat panel) and its limitations. */ @@ -201,6 +203,7 @@ struct drm_display_info { unsigned int bpc;
enum subpixel_order subpixel_order;
- unsigned long color_formats;
^ wtf?
unsigned long? its 2011.
That doesn't tell me much about what you'd prefer... I figured a bitfield would be fairly extensible if new surface formats were added. Maybe you're thinking it's not enough to support all the misc ones out there though?
On Sat, Apr 16, 2011 at 6:39 AM, Jesse Barnes jbarnes@virtuousgeek.org wrote:
On Sat, 16 Apr 2011 06:10:07 +1000 Dave Airlie airlied@gmail.com wrote:
+#define DRM_COLOR_FORMAT_RGB444 (1<<0) +#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) +#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) /* * Describes a given display (e.g. CRT or flat panel) and its limitations. */ @@ -201,6 +203,7 @@ struct drm_display_info { unsigned int bpc;
enum subpixel_order subpixel_order;
- unsigned long color_formats;
^ wtf?
unsigned long? its 2011.
That doesn't tell me much about what you'd prefer... I figured a bitfield would be fairly extensible if new surface formats were added. Maybe you're thinking it's not enough to support all the misc ones out there though?
Its unsigned long, its a different size on 32 and 64-bit, not something I want to fall over when you add the 33rd bit field.
Dave.
On Sat, 16 Apr 2011 06:42:44 +1000 Dave Airlie airlied@gmail.com wrote:
On Sat, Apr 16, 2011 at 6:39 AM, Jesse Barnes jbarnes@virtuousgeek.org wrote:
On Sat, 16 Apr 2011 06:10:07 +1000 Dave Airlie airlied@gmail.com wrote:
+#define DRM_COLOR_FORMAT_RGB444 (1<<0) +#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) +#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) /* * Describes a given display (e.g. CRT or flat panel) and its limitations. */ @@ -201,6 +203,7 @@ struct drm_display_info { unsigned int bpc;
enum subpixel_order subpixel_order;
- unsigned long color_formats;
^ wtf?
unsigned long? its 2011.
That doesn't tell me much about what you'd prefer... I figured a bitfield would be fairly extensible if new surface formats were added. Maybe you're thinking it's not enough to support all the misc ones out there though?
Its unsigned long, its a different size on 32 and 64-bit, not something I want to fall over when you add the 33rd bit field.
I hope we don't get to more than 32, but sure I'll change it to u32 to match some of the other flags.
On Sat, 16 Apr 2011 06:42:44 +1000 Dave Airlie airlied@gmail.com wrote:
On Sat, Apr 16, 2011 at 6:39 AM, Jesse Barnes jbarnes@virtuousgeek.org wrote:
On Sat, 16 Apr 2011 06:10:07 +1000 Dave Airlie airlied@gmail.com wrote:
+#define DRM_COLOR_FORMAT_RGB444 (1<<0) +#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) +#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) /* * Describes a given display (e.g. CRT or flat panel) and its limitations. */ @@ -201,6 +203,7 @@ struct drm_display_info { unsigned int bpc;
enum subpixel_order subpixel_order;
- unsigned long color_formats;
^ wtf?
unsigned long? its 2011.
That doesn't tell me much about what you'd prefer... I figured a bitfield would be fairly extensible if new surface formats were added. Maybe you're thinking it's not enough to support all the misc ones out there though?
Its unsigned long, its a different size on 32 and 64-bit, not something I want to fall over when you add the 33rd bit field.
Ok, I sent an update for this one. Also note that all these are kernel internal structures, so we can change the format field to an array or something later if we want to...
Any other changes you'd like? Or do the patches look ok now (though I probably should have made the subject drm/edid rather than just drm).
Thanks,
On Sat, Apr 23, 2011 at 6:17 AM, Jesse Barnes jbarnes@virtuousgeek.org wrote:
On Sat, 16 Apr 2011 06:42:44 +1000 Dave Airlie airlied@gmail.com wrote:
On Sat, Apr 16, 2011 at 6:39 AM, Jesse Barnes jbarnes@virtuousgeek.org wrote:
On Sat, 16 Apr 2011 06:10:07 +1000 Dave Airlie airlied@gmail.com wrote:
+#define DRM_COLOR_FORMAT_RGB444 (1<<0) +#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) +#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) /* * Describes a given display (e.g. CRT or flat panel) and its limitations. */ @@ -201,6 +203,7 @@ struct drm_display_info { unsigned int bpc;
enum subpixel_order subpixel_order;
- unsigned long color_formats;
^ wtf?
unsigned long? its 2011.
That doesn't tell me much about what you'd prefer... I figured a bitfield would be fairly extensible if new surface formats were added. Maybe you're thinking it's not enough to support all the misc ones out there though?
Its unsigned long, its a different size on 32 and 64-bit, not something I want to fall over when you add the 33rd bit field.
Ok, I sent an update for this one. Also note that all these are kernel internal structures, so we can change the format field to an array or something later if we want to...
Any other changes you'd like? Or do the patches look ok now (though I probably should have made the subject drm/edid rather than just drm).
Was going to put them in -next as soon as I open it, its holidays I for one won't be doing squat until next Wednesday.
Dave.
Any other changes you'd like? Or do the patches look ok now (though I probably should have made the subject drm/edid rather than just drm).
Was going to put them in -next as soon as I open it, its holidays I for one won't be doing squat until next Wednesday.
Np, thanks. Just wanted to make sure you didn't want other changes.
On Fri, Apr 22, 2011 at 4:17 PM, Jesse Barnes jbarnes@virtuousgeek.org wrote:
On Sat, 16 Apr 2011 06:42:44 +1000 Dave Airlie airlied@gmail.com wrote:
On Sat, Apr 16, 2011 at 6:39 AM, Jesse Barnes jbarnes@virtuousgeek.org wrote:
On Sat, 16 Apr 2011 06:10:07 +1000 Dave Airlie airlied@gmail.com wrote:
+#define DRM_COLOR_FORMAT_RGB444 (1<<0) +#define DRM_COLOR_FORMAT_YCRCB444 (1<<1) +#define DRM_COLOR_FORMAT_YCRCB422 (1<<2) /* * Describes a given display (e.g. CRT or flat panel) and its limitations. */ @@ -201,6 +203,7 @@ struct drm_display_info { unsigned int bpc;
enum subpixel_order subpixel_order;
- unsigned long color_formats;
^ wtf?
unsigned long? its 2011.
That doesn't tell me much about what you'd prefer... I figured a bitfield would be fairly extensible if new surface formats were added. Maybe you're thinking it's not enough to support all the misc ones out there though?
Its unsigned long, its a different size on 32 and 64-bit, not something I want to fall over when you add the 33rd bit field.
Ok, I sent an update for this one. Also note that all these are kernel internal structures, so we can change the format field to an array or something later if we want to...
Any other changes you'd like? Or do the patches look ok now (though I probably should have made the subject drm/edid rather than just drm).
FWIW, you may want to combine the two patches (drm: parse color format support for digital displays, drm: add bit depth parsing) as they are dependant and don't build individually. That said, I'm already using the patches for some radeon display handling updates and they work great.
Reviewed-by: Alex Deucher alexdeucher@gmail.com
Thanks,
Jesse Barnes, Intel Open Source Technology Center _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
dri-devel@lists.freedesktop.org