aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorMario Kleiner <mario.kleiner.de@gmail.com>2014-06-05 09:58:24 -0400
committerAlex Deucher <alexander.deucher@amd.com>2014-06-09 22:06:50 -0400
commitea29286146db6c72683af76bc8297cebeeec6d13 (patch)
treec4dd125dd02988879b4c131ab22198c994f205d8 /drivers/gpu/drm/radeon
parent5d02626d3167cd4214bf611362e08dfd1e98c62e (diff)
drm/radeon: hdmi deep color modes must obey clock limit of sink.
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>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c31
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h1
3 files changed, 35 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 76c30f2da3fb..26c12a3fe430 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -962,6 +962,9 @@ static bool atombios_crtc_prepare_pll(struct drm_crtc *crtc, struct drm_display_
962 struct radeon_connector_atom_dig *dig_connector = 962 struct radeon_connector_atom_dig *dig_connector =
963 radeon_connector->con_priv; 963 radeon_connector->con_priv;
964 int dp_clock; 964 int dp_clock;
965
966 /* Assign mode clock for hdmi deep color max clock limit check */
967 radeon_connector->pixelclock_for_modeset = mode->clock;
965 radeon_crtc->bpc = radeon_get_monitor_bpc(connector); 968 radeon_crtc->bpc = radeon_get_monitor_bpc(connector);
966 969
967 switch (encoder_mode) { 970 switch (encoder_mode) {
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 4522f7dce653..933c5c39654d 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)
101 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 101 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
102 struct radeon_connector_atom_dig *dig_connector; 102 struct radeon_connector_atom_dig *dig_connector;
103 int bpc = 8; 103 int bpc = 8;
104 int mode_clock, max_tmds_clock;
104 105
105 switch (connector->connector_type) { 106 switch (connector->connector_type) {
106 case DRM_MODE_CONNECTOR_DVII: 107 case DRM_MODE_CONNECTOR_DVII:
@@ -166,6 +167,36 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
166 connector->name, bpc); 167 connector->name, bpc);
167 bpc = 12; 168 bpc = 12;
168 } 169 }
170
171 /* Any defined maximum tmds clock limit we must not exceed? */
172 if (connector->max_tmds_clock > 0) {
173 /* mode_clock is clock in kHz for mode to be modeset on this connector */
174 mode_clock = radeon_connector->pixelclock_for_modeset;
175
176 /* Maximum allowable input clock in kHz */
177 max_tmds_clock = connector->max_tmds_clock * 1000;
178
179 DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz.\n",
180 connector->name, mode_clock, max_tmds_clock);
181
182 /* Check if bpc is within clock limit. Try to degrade gracefully otherwise */
183 if ((bpc == 12) && (mode_clock * 3/2 > max_tmds_clock)) {
184 if ((connector->display_info.edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
185 (mode_clock * 5/4 <= max_tmds_clock))
186 bpc = 10;
187 else
188 bpc = 8;
189
190 DRM_DEBUG("%s: HDMI deep color 12 bpc exceeds max tmds clock. Using %d bpc.\n",
191 connector->name, bpc);
192 }
193
194 if ((bpc == 10) && (mode_clock * 5/4 > max_tmds_clock)) {
195 bpc = 8;
196 DRM_DEBUG("%s: HDMI deep color 10 bpc exceeds max tmds clock. Using %d bpc.\n",
197 connector->name, bpc);
198 }
199 }
169 } 200 }
170 201
171 DRM_DEBUG("%s: Display bpc=%d, returned bpc=%d\n", 202 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 ea72ad889a11..ad0e4b8cc7e3 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -506,6 +506,7 @@ struct radeon_connector {
506 struct radeon_i2c_chan *router_bus; 506 struct radeon_i2c_chan *router_bus;
507 enum radeon_connector_audio audio; 507 enum radeon_connector_audio audio;
508 enum radeon_connector_dither dither; 508 enum radeon_connector_dither dither;
509 int pixelclock_for_modeset;
509}; 510};
510 511
511struct radeon_framebuffer { 512struct radeon_framebuffer {