Commit b20f9bef authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms: check modes against max pixel clock

Filter out modes that are higher than the max pixel
clock.
Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 618c75e4
...@@ -165,6 +165,7 @@ struct radeon_clock { ...@@ -165,6 +165,7 @@ struct radeon_clock {
uint32_t default_sclk; uint32_t default_sclk;
uint32_t default_dispclk; uint32_t default_dispclk;
uint32_t dp_extclk; uint32_t dp_extclk;
uint32_t max_pixel_clock;
}; };
/* /*
......
...@@ -1246,6 +1246,10 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) ...@@ -1246,6 +1246,10 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
} }
*dcpll = *p1pll; *dcpll = *p1pll;
rdev->clock.max_pixel_clock = le16_to_cpu(firmware_info->info.usMaxPixelClock);
if (rdev->clock.max_pixel_clock == 0)
rdev->clock.max_pixel_clock = 40000;
return true; return true;
} }
......
...@@ -117,7 +117,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) ...@@ -117,7 +117,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev)
p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff; p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
if (p1pll->reference_div < 2) if (p1pll->reference_div < 2)
p1pll->reference_div = 12; p1pll->reference_div = 12;
p2pll->reference_div = p1pll->reference_div; p2pll->reference_div = p1pll->reference_div;
/* These aren't in the device-tree */ /* These aren't in the device-tree */
if (rdev->family >= CHIP_R420) { if (rdev->family >= CHIP_R420) {
...@@ -139,6 +139,8 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) ...@@ -139,6 +139,8 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev)
p2pll->pll_out_min = 12500; p2pll->pll_out_min = 12500;
p2pll->pll_out_max = 35000; p2pll->pll_out_max = 35000;
} }
/* not sure what the max should be in all cases */
rdev->clock.max_pixel_clock = 35000;
spll->reference_freq = mpll->reference_freq = p1pll->reference_freq; spll->reference_freq = mpll->reference_freq = p1pll->reference_freq;
spll->reference_div = mpll->reference_div = spll->reference_div = mpll->reference_div =
...@@ -151,7 +153,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) ...@@ -151,7 +153,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev)
else else
rdev->clock.default_sclk = rdev->clock.default_sclk =
radeon_legacy_get_engine_clock(rdev); radeon_legacy_get_engine_clock(rdev);
val = of_get_property(dp, "ATY,MCLK", NULL); val = of_get_property(dp, "ATY,MCLK", NULL);
if (val && *val) if (val && *val)
rdev->clock.default_mclk = (*val) / 10; rdev->clock.default_mclk = (*val) / 10;
...@@ -160,7 +162,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) ...@@ -160,7 +162,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev)
radeon_legacy_get_memory_clock(rdev); radeon_legacy_get_memory_clock(rdev);
DRM_INFO("Using device-tree clock info\n"); DRM_INFO("Using device-tree clock info\n");
return true; return true;
} }
#else #else
......
...@@ -866,6 +866,11 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) ...@@ -866,6 +866,11 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
rdev->clock.default_sclk = sclk; rdev->clock.default_sclk = sclk;
rdev->clock.default_mclk = mclk; rdev->clock.default_mclk = mclk;
if (RBIOS32(pll_info + 0x16))
rdev->clock.max_pixel_clock = RBIOS32(pll_info + 0x16);
else
rdev->clock.max_pixel_clock = 35000; /* might need something asic specific */
return true; return true;
} }
return false; return false;
......
...@@ -626,8 +626,14 @@ static int radeon_vga_get_modes(struct drm_connector *connector) ...@@ -626,8 +626,14 @@ static int radeon_vga_get_modes(struct drm_connector *connector)
static int radeon_vga_mode_valid(struct drm_connector *connector, static int radeon_vga_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct drm_device *dev = connector->dev;
struct radeon_device *rdev = dev->dev_private;
/* XXX check mode bandwidth */ /* XXX check mode bandwidth */
/* XXX verify against max DAC output frequency */
if ((mode->clock / 10) > rdev->clock.max_pixel_clock)
return MODE_CLOCK_HIGH;
return MODE_OK; return MODE_OK;
} }
...@@ -1015,6 +1021,11 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, ...@@ -1015,6 +1021,11 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector,
} else } else
return MODE_CLOCK_HIGH; return MODE_CLOCK_HIGH;
} }
/* check against the max pixel clock */
if ((mode->clock / 10) > rdev->clock.max_pixel_clock)
return MODE_CLOCK_HIGH;
return MODE_OK; return MODE_OK;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment