diff options
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 73 |
1 files changed, 64 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 6a2b0296adff..c44871c80aba 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "drm_crtc_helper.h" | 28 | #include "drm_crtc_helper.h" |
29 | #include "radeon_drm.h" | 29 | #include "radeon_drm.h" |
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "atom.h" | ||
31 | 32 | ||
32 | extern void | 33 | extern void |
33 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, | 34 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, |
@@ -174,6 +175,50 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode | |||
174 | return mode; | 175 | return mode; |
175 | } | 176 | } |
176 | 177 | ||
178 | static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_connector *connector) | ||
179 | { | ||
180 | struct drm_device *dev = encoder->dev; | ||
181 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
182 | struct drm_display_mode *mode = NULL; | ||
183 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | ||
184 | int i; | ||
185 | struct mode_size { | ||
186 | int w; | ||
187 | int h; | ||
188 | } common_modes[17] = { | ||
189 | { 640, 480}, | ||
190 | { 720, 480}, | ||
191 | { 800, 600}, | ||
192 | { 848, 480}, | ||
193 | {1024, 768}, | ||
194 | {1152, 768}, | ||
195 | {1280, 720}, | ||
196 | {1280, 800}, | ||
197 | {1280, 854}, | ||
198 | {1280, 960}, | ||
199 | {1280, 1024}, | ||
200 | {1440, 900}, | ||
201 | {1400, 1050}, | ||
202 | {1680, 1050}, | ||
203 | {1600, 1200}, | ||
204 | {1920, 1080}, | ||
205 | {1920, 1200} | ||
206 | }; | ||
207 | |||
208 | for (i = 0; i < 17; i++) { | ||
209 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
210 | if (common_modes[i].w >= native_mode->panel_xres && | ||
211 | common_modes[i].h >= native_mode->panel_yres) | ||
212 | continue; | ||
213 | } | ||
214 | if (common_modes[i].w < 320 || common_modes[i].h < 200) | ||
215 | continue; | ||
216 | |||
217 | mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false); | ||
218 | drm_mode_probed_add(connector, mode); | ||
219 | } | ||
220 | } | ||
221 | |||
177 | int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, | 222 | int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, |
178 | uint64_t val) | 223 | uint64_t val) |
179 | { | 224 | { |
@@ -205,6 +250,10 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) | |||
205 | ret = 1; | 250 | ret = 1; |
206 | drm_mode_probed_add(connector, mode); | 251 | drm_mode_probed_add(connector, mode); |
207 | } | 252 | } |
253 | |||
254 | /* add scaled modes */ | ||
255 | radeon_add_common_modes(encoder, connector); | ||
256 | |||
208 | return ret; | 257 | return ret; |
209 | } | 258 | } |
210 | 259 | ||
@@ -306,21 +355,27 @@ struct drm_connector_funcs radeon_vga_connector_funcs = { | |||
306 | .set_property = radeon_connector_set_property, | 355 | .set_property = radeon_connector_set_property, |
307 | }; | 356 | }; |
308 | 357 | ||
309 | static struct drm_display_mode tv_fixed_mode = { | ||
310 | DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 38250, 800, 832, | ||
311 | 912, 1024, 0, 600, 603, 607, 624, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC), | ||
312 | }; | ||
313 | |||
314 | static int radeon_tv_get_modes(struct drm_connector *connector) | 358 | static int radeon_tv_get_modes(struct drm_connector *connector) |
315 | { | 359 | { |
316 | struct drm_device *dev = connector->dev; | 360 | struct drm_device *dev = connector->dev; |
361 | struct radeon_device *rdev = dev->dev_private; | ||
317 | struct drm_display_mode *tv_mode; | 362 | struct drm_display_mode *tv_mode; |
363 | struct drm_encoder *encoder; | ||
318 | 364 | ||
319 | tv_mode = drm_mode_duplicate(dev, &tv_fixed_mode); | 365 | encoder = radeon_best_single_encoder(connector); |
320 | tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; | 366 | if (!encoder) |
321 | 367 | return 0; | |
322 | drm_mode_probed_add(connector, tv_mode); | ||
323 | 368 | ||
369 | /* avivo chips can scale any mode */ | ||
370 | if (rdev->family >= CHIP_RS600) | ||
371 | /* add scaled modes */ | ||
372 | radeon_add_common_modes(encoder, connector); | ||
373 | else { | ||
374 | /* only 800x600 is supported right now on pre-avivo chips */ | ||
375 | tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false); | ||
376 | tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; | ||
377 | drm_mode_probed_add(connector, tv_mode); | ||
378 | } | ||
324 | return 1; | 379 | return 1; |
325 | } | 380 | } |
326 | 381 | ||