dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] drm/edid: Store all supported hdmi deep color modes in drm_display_info
@ 2014-06-05 14:16 Alex Deucher
  2014-06-05 14:16 ` [PATCH 2/2] drm/radeon: hdmi deep color modes must obey clock limit of sink Alex Deucher
  0 siblings, 1 reply; 2+ messages in thread
From: Alex Deucher @ 2014-06-05 14:16 UTC (permalink / raw)
  To: dri-devel; +Cc: Alex Deucher

From: Mario Kleiner <mario.kleiner.de@gmail.com>

HDMI deep color setup must know which modes are supported if
it needs to degrade gracefully, as only 12 bpc / dc_36 is
guaranteed, but 10 bpc / dc_30 is optional. The maximum bpc
is not sufficient for this.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/drm_edid.c | 3 +++
 include/drm/drm_crtc.h     | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 7be2178..dfa9769 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3471,18 +3471,21 @@ static bool drm_assign_hdmi_deep_color_info(struct edid *edid,
 
 			if (hdmi[6] & DRM_EDID_HDMI_DC_30) {
 				dc_bpc = 10;
+				info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30;
 				DRM_DEBUG("%s: HDMI sink does deep color 30.\n",
 						  connector->name);
 			}
 
 			if (hdmi[6] & DRM_EDID_HDMI_DC_36) {
 				dc_bpc = 12;
+				info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36;
 				DRM_DEBUG("%s: HDMI sink does deep color 36.\n",
 						  connector->name);
 			}
 
 			if (hdmi[6] & DRM_EDID_HDMI_DC_48) {
 				dc_bpc = 16;
+				info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48;
 				DRM_DEBUG("%s: HDMI sink does deep color 48.\n",
 						  connector->name);
 			}
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 6c295df..d5288b2 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -120,6 +120,9 @@ struct drm_display_info {
 	enum subpixel_order subpixel_order;
 	u32 color_formats;
 
+	/* Mask of supported hdmi deep color modes */
+	u8 edid_hdmi_dc_modes;
+
 	u8 cea_rev;
 };
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] drm/radeon: hdmi deep color modes must obey clock limit of sink.
  2014-06-05 14:16 [PATCH 1/2] drm/edid: Store all supported hdmi deep color modes in drm_display_info Alex Deucher
@ 2014-06-05 14:16 ` Alex Deucher
  0 siblings, 0 replies; 2+ messages in thread
From: Alex Deucher @ 2014-06-05 14:16 UTC (permalink / raw)
  To: dri-devel; +Cc: Alex Deucher

From: Mario Kleiner <mario.kleiner.de@gmail.com>

Make sure that a hdmi deep color mode can't exceed the max tmds
clock limit of a hdmi sink if such a limit is defined by edid.

If requested deep color bpc would exceed the limit given the mode
to be set, try to degrade gracefully to lower supported deep color
bpc or to standard 8 bpc if needed.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/radeon/atombios_crtc.c     |  3 +++
 drivers/gpu/drm/radeon/radeon_connectors.c | 31 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/radeon_mode.h       |  1 +
 3 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 967d193..460122b 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -964,6 +964,9 @@ static bool atombios_crtc_prepare_pll(struct drm_crtc *crtc, struct drm_display_
 		struct radeon_connector_atom_dig *dig_connector =
 			radeon_connector->con_priv;
 		int dp_clock;
+
+		/* Assign mode clock for hdmi deep color max clock limit check */
+		radeon_connector->pixelclock_for_modeset = mode->clock;
 		radeon_crtc->bpc = radeon_get_monitor_bpc(connector);
 
 		switch (encoder_mode) {
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 4522f7d..933c5c3 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -101,6 +101,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 	struct radeon_connector_atom_dig *dig_connector;
 	int bpc = 8;
+	int mode_clock, max_tmds_clock;
 
 	switch (connector->connector_type) {
 	case DRM_MODE_CONNECTOR_DVII:
@@ -166,6 +167,36 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
 					  connector->name, bpc);
 			bpc = 12;
 		}
+
+		/* Any defined maximum tmds clock limit we must not exceed? */
+		if (connector->max_tmds_clock > 0) {
+			/* mode_clock is clock in kHz for mode to be modeset on this connector */
+			mode_clock = radeon_connector->pixelclock_for_modeset;
+
+			/* Maximum allowable input clock in kHz */
+			max_tmds_clock = connector->max_tmds_clock * 1000;
+
+			DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz.\n",
+					  connector->name, mode_clock, max_tmds_clock);
+
+			/* Check if bpc is within clock limit. Try to degrade gracefully otherwise */
+			if ((bpc == 12) && (mode_clock * 3/2 > max_tmds_clock)) {
+				if ((connector->display_info.edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
+					(mode_clock * 5/4 <= max_tmds_clock))
+					bpc = 10;
+				else
+					bpc = 8;
+
+				DRM_DEBUG("%s: HDMI deep color 12 bpc exceeds max tmds clock. Using %d bpc.\n",
+						  connector->name, bpc);
+			}
+
+			if ((bpc == 10) && (mode_clock * 5/4 > max_tmds_clock)) {
+				bpc = 8;
+				DRM_DEBUG("%s: HDMI deep color 10 bpc exceeds max tmds clock. Using %d bpc.\n",
+						  connector->name, bpc);
+			}
+		}
 	}
 
 	DRM_DEBUG("%s: Display bpc=%d, returned bpc=%d\n",
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index ea72ad8..ad0e4b8 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -506,6 +506,7 @@ struct radeon_connector {
 	struct radeon_i2c_chan *router_bus;
 	enum radeon_connector_audio audio;
 	enum radeon_connector_dither dither;
+	int pixelclock_for_modeset;
 };
 
 struct radeon_framebuffer {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-06-05 14:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-05 14:16 [PATCH 1/2] drm/edid: Store all supported hdmi deep color modes in drm_display_info Alex Deucher
2014-06-05 14:16 ` [PATCH 2/2] drm/radeon: hdmi deep color modes must obey clock limit of sink Alex Deucher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox