aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_display.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c145
1 files changed, 133 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index c85df4afcb7a..a133b833e45d 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -250,6 +250,16 @@ static const char *connector_names[13] = {
250 "HDMI-B", 250 "HDMI-B",
251}; 251};
252 252
253static const char *hpd_names[7] = {
254 "NONE",
255 "HPD1",
256 "HPD2",
257 "HPD3",
258 "HPD4",
259 "HPD5",
260 "HPD6",
261};
262
253static void radeon_print_display_setup(struct drm_device *dev) 263static void radeon_print_display_setup(struct drm_device *dev)
254{ 264{
255 struct drm_connector *connector; 265 struct drm_connector *connector;
@@ -264,16 +274,18 @@ static void radeon_print_display_setup(struct drm_device *dev)
264 radeon_connector = to_radeon_connector(connector); 274 radeon_connector = to_radeon_connector(connector);
265 DRM_INFO("Connector %d:\n", i); 275 DRM_INFO("Connector %d:\n", i);
266 DRM_INFO(" %s\n", connector_names[connector->connector_type]); 276 DRM_INFO(" %s\n", connector_names[connector->connector_type]);
277 if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
278 DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]);
267 if (radeon_connector->ddc_bus) 279 if (radeon_connector->ddc_bus)
268 DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", 280 DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
269 radeon_connector->ddc_bus->rec.mask_clk_reg, 281 radeon_connector->ddc_bus->rec.mask_clk_reg,
270 radeon_connector->ddc_bus->rec.mask_data_reg, 282 radeon_connector->ddc_bus->rec.mask_data_reg,
271 radeon_connector->ddc_bus->rec.a_clk_reg, 283 radeon_connector->ddc_bus->rec.a_clk_reg,
272 radeon_connector->ddc_bus->rec.a_data_reg, 284 radeon_connector->ddc_bus->rec.a_data_reg,
273 radeon_connector->ddc_bus->rec.put_clk_reg, 285 radeon_connector->ddc_bus->rec.en_clk_reg,
274 radeon_connector->ddc_bus->rec.put_data_reg, 286 radeon_connector->ddc_bus->rec.en_data_reg,
275 radeon_connector->ddc_bus->rec.get_clk_reg, 287 radeon_connector->ddc_bus->rec.y_clk_reg,
276 radeon_connector->ddc_bus->rec.get_data_reg); 288 radeon_connector->ddc_bus->rec.y_data_reg);
277 DRM_INFO(" Encoders:\n"); 289 DRM_INFO(" Encoders:\n");
278 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 290 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
279 radeon_encoder = to_radeon_encoder(encoder); 291 radeon_encoder = to_radeon_encoder(encoder);
@@ -324,6 +336,7 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
324 ret = radeon_get_legacy_connector_info_from_table(dev); 336 ret = radeon_get_legacy_connector_info_from_table(dev);
325 } 337 }
326 if (ret) { 338 if (ret) {
339 radeon_setup_encoder_clones(dev);
327 radeon_print_display_setup(dev); 340 radeon_print_display_setup(dev);
328 list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) 341 list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head)
329 radeon_ddc_dump(drm_connector); 342 radeon_ddc_dump(drm_connector);
@@ -336,12 +349,17 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
336{ 349{
337 int ret = 0; 350 int ret = 0;
338 351
352 if (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
353 struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
354 if (dig->dp_i2c_bus)
355 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter);
356 }
339 if (!radeon_connector->ddc_bus) 357 if (!radeon_connector->ddc_bus)
340 return -1; 358 return -1;
341 if (!radeon_connector->edid) { 359 if (!radeon_connector->edid) {
342 radeon_i2c_do_lock(radeon_connector, 1); 360 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
343 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); 361 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
344 radeon_i2c_do_lock(radeon_connector, 0); 362 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
345 } 363 }
346 364
347 if (radeon_connector->edid) { 365 if (radeon_connector->edid) {
@@ -361,9 +379,9 @@ static int radeon_ddc_dump(struct drm_connector *connector)
361 379
362 if (!radeon_connector->ddc_bus) 380 if (!radeon_connector->ddc_bus)
363 return -1; 381 return -1;
364 radeon_i2c_do_lock(radeon_connector, 1); 382 radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
365 edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); 383 edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
366 radeon_i2c_do_lock(radeon_connector, 0); 384 radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
367 if (edid) { 385 if (edid) {
368 kfree(edid); 386 kfree(edid);
369 } 387 }
@@ -542,6 +560,98 @@ void radeon_compute_pll(struct radeon_pll *pll,
542 *post_div_p = best_post_div; 560 *post_div_p = best_post_div;
543} 561}
544 562
563void radeon_compute_pll_avivo(struct radeon_pll *pll,
564 uint64_t freq,
565 uint32_t *dot_clock_p,
566 uint32_t *fb_div_p,
567 uint32_t *frac_fb_div_p,
568 uint32_t *ref_div_p,
569 uint32_t *post_div_p,
570 int flags)
571{
572 fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq;
573 fixed20_12 pll_out_max, pll_out_min;
574 fixed20_12 pll_in_max, pll_in_min;
575 fixed20_12 reference_freq;
576 fixed20_12 error, ffreq, a, b;
577
578 pll_out_max.full = rfixed_const(pll->pll_out_max);
579 pll_out_min.full = rfixed_const(pll->pll_out_min);
580 pll_in_max.full = rfixed_const(pll->pll_in_max);
581 pll_in_min.full = rfixed_const(pll->pll_in_min);
582 reference_freq.full = rfixed_const(pll->reference_freq);
583 do_div(freq, 10);
584 ffreq.full = rfixed_const(freq);
585 error.full = rfixed_const(100 * 100);
586
587 /* max p */
588 p.full = rfixed_div(pll_out_max, ffreq);
589 p.full = rfixed_floor(p);
590
591 /* min m */
592 m.full = rfixed_div(reference_freq, pll_in_max);
593 m.full = rfixed_ceil(m);
594
595 while (1) {
596 n.full = rfixed_div(ffreq, reference_freq);
597 n.full = rfixed_mul(n, m);
598 n.full = rfixed_mul(n, p);
599
600 f_vco.full = rfixed_div(n, m);
601 f_vco.full = rfixed_mul(f_vco, reference_freq);
602
603 f_pclk.full = rfixed_div(f_vco, p);
604
605 if (f_pclk.full > ffreq.full)
606 error.full = f_pclk.full - ffreq.full;
607 else
608 error.full = ffreq.full - f_pclk.full;
609 error.full = rfixed_div(error, f_pclk);
610 a.full = rfixed_const(100 * 100);
611 error.full = rfixed_mul(error, a);
612
613 a.full = rfixed_mul(m, p);
614 a.full = rfixed_div(n, a);
615 best_freq.full = rfixed_mul(reference_freq, a);
616
617 if (rfixed_trunc(error) < 25)
618 break;
619
620 a.full = rfixed_const(1);
621 m.full = m.full + a.full;
622 a.full = rfixed_div(reference_freq, m);
623 if (a.full >= pll_in_min.full)
624 continue;
625
626 m.full = rfixed_div(reference_freq, pll_in_max);
627 m.full = rfixed_ceil(m);
628 a.full= rfixed_const(1);
629 p.full = p.full - a.full;
630 a.full = rfixed_mul(p, ffreq);
631 if (a.full >= pll_out_min.full)
632 continue;
633 else {
634 DRM_ERROR("Unable to find pll dividers\n");
635 break;
636 }
637 }
638
639 a.full = rfixed_const(10);
640 b.full = rfixed_mul(n, a);
641
642 frac_n.full = rfixed_floor(n);
643 frac_n.full = rfixed_mul(frac_n, a);
644 frac_n.full = b.full - frac_n.full;
645
646 *dot_clock_p = rfixed_trunc(best_freq);
647 *fb_div_p = rfixed_trunc(n);
648 *frac_fb_div_p = rfixed_trunc(frac_n);
649 *ref_div_p = rfixed_trunc(m);
650 *post_div_p = rfixed_trunc(p);
651
652 DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
653}
654
545static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) 655static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
546{ 656{
547 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); 657 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
@@ -642,7 +752,7 @@ int radeon_modeset_create_props(struct radeon_device *rdev)
642 return -ENOMEM; 752 return -ENOMEM;
643 753
644 rdev->mode_info.coherent_mode_property->values[0] = 0; 754 rdev->mode_info.coherent_mode_property->values[0] = 0;
645 rdev->mode_info.coherent_mode_property->values[0] = 1; 755 rdev->mode_info.coherent_mode_property->values[1] = 1;
646 } 756 }
647 757
648 if (!ASIC_IS_AVIVO(rdev)) { 758 if (!ASIC_IS_AVIVO(rdev)) {
@@ -666,7 +776,7 @@ int radeon_modeset_create_props(struct radeon_device *rdev)
666 if (!rdev->mode_info.load_detect_property) 776 if (!rdev->mode_info.load_detect_property)
667 return -ENOMEM; 777 return -ENOMEM;
668 rdev->mode_info.load_detect_property->values[0] = 0; 778 rdev->mode_info.load_detect_property->values[0] = 0;
669 rdev->mode_info.load_detect_property->values[0] = 1; 779 rdev->mode_info.load_detect_property->values[1] = 1;
670 780
671 drm_mode_create_scaling_mode_property(rdev->ddev); 781 drm_mode_create_scaling_mode_property(rdev->ddev);
672 782
@@ -723,6 +833,8 @@ int radeon_modeset_init(struct radeon_device *rdev)
723 if (!ret) { 833 if (!ret) {
724 return ret; 834 return ret;
725 } 835 }
836 /* initialize hpd */
837 radeon_hpd_init(rdev);
726 drm_helper_initial_config(rdev->ddev); 838 drm_helper_initial_config(rdev->ddev);
727 return 0; 839 return 0;
728} 840}
@@ -730,6 +842,7 @@ int radeon_modeset_init(struct radeon_device *rdev)
730void radeon_modeset_fini(struct radeon_device *rdev) 842void radeon_modeset_fini(struct radeon_device *rdev)
731{ 843{
732 if (rdev->mode_info.mode_config_initialized) { 844 if (rdev->mode_info.mode_config_initialized) {
845 radeon_hpd_fini(rdev);
733 drm_mode_config_cleanup(rdev->ddev); 846 drm_mode_config_cleanup(rdev->ddev);
734 rdev->mode_info.mode_config_initialized = false; 847 rdev->mode_info.mode_config_initialized = false;
735 } 848 }
@@ -750,9 +863,17 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
750 if (encoder->crtc != crtc) 863 if (encoder->crtc != crtc)
751 continue; 864 continue;
752 if (first) { 865 if (first) {
753 radeon_crtc->rmx_type = radeon_encoder->rmx_type; 866 /* set scaling */
867 if (radeon_encoder->rmx_type == RMX_OFF)
868 radeon_crtc->rmx_type = RMX_OFF;
869 else if (mode->hdisplay < radeon_encoder->native_mode.hdisplay ||
870 mode->vdisplay < radeon_encoder->native_mode.vdisplay)
871 radeon_crtc->rmx_type = radeon_encoder->rmx_type;
872 else
873 radeon_crtc->rmx_type = RMX_OFF;
874 /* copy native mode */
754 memcpy(&radeon_crtc->native_mode, 875 memcpy(&radeon_crtc->native_mode,
755 &radeon_encoder->native_mode, 876 &radeon_encoder->native_mode,
756 sizeof(struct drm_display_mode)); 877 sizeof(struct drm_display_mode));
757 first = false; 878 first = false;
758 } else { 879 } else {