Rev 1126 | Rev 1182 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1126 | Rev 1179 | ||
---|---|---|---|
Line 156... | Line 156... | ||
156 | 156 | ||
157 | static void radeon_crtc_destroy(struct drm_crtc *crtc) |
157 | static void radeon_crtc_destroy(struct drm_crtc *crtc) |
158 | { |
158 | { |
Line 159... | Line -... | ||
159 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
- | |
160 | - | ||
161 | if (radeon_crtc->mode_set.mode) { |
- | |
162 | drm_mode_destroy(crtc->dev, radeon_crtc->mode_set.mode); |
159 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
163 | } |
160 | |
164 | drm_crtc_cleanup(crtc); |
161 | drm_crtc_cleanup(crtc); |
Line 165... | Line 162... | ||
165 | kfree(radeon_crtc); |
162 | kfree(radeon_crtc); |
166 | } |
163 | } |
167 | 164 | ||
168 | static const struct drm_crtc_funcs radeon_crtc_funcs = { |
165 | static const struct drm_crtc_funcs radeon_crtc_funcs = { |
169 | // .cursor_set = radeon_crtc_cursor_set, |
166 | // .cursor_set = radeon_crtc_cursor_set, |
170 | // .cursor_move = radeon_crtc_cursor_move, |
167 | .cursor_move = radeon_crtc_cursor_move, |
171 | .gamma_set = radeon_crtc_gamma_set, |
168 | .gamma_set = radeon_crtc_gamma_set, |
Line 177... | Line 174... | ||
177 | { |
174 | { |
178 | struct radeon_device *rdev = dev->dev_private; |
175 | struct radeon_device *rdev = dev->dev_private; |
179 | struct radeon_crtc *radeon_crtc; |
176 | struct radeon_crtc *radeon_crtc; |
180 | int i; |
177 | int i; |
Line 181... | Line -... | ||
181 | - | ||
182 | ENTRY(); |
- | |
183 | 178 | ||
184 | radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); |
179 | radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); |
185 | if (radeon_crtc == NULL) |
180 | if (radeon_crtc == NULL) |
Line 186... | Line 181... | ||
186 | return; |
181 | return; |
Line 187... | Line 182... | ||
187 | 182 | ||
188 | drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); |
183 | drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); |
- | 184 | ||
Line -... | Line 185... | ||
- | 185 | drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); |
|
189 | 186 | radeon_crtc->crtc_id = index; |
|
190 | drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); |
187 | rdev->mode_info.crtcs[index] = radeon_crtc; |
191 | radeon_crtc->crtc_id = index; |
188 | |
- | 189 | #if 0 |
|
Line 192... | Line 190... | ||
192 | 190 | radeon_crtc->mode_set.crtc = &radeon_crtc->base; |
|
193 | radeon_crtc->mode_set.crtc = &radeon_crtc->base; |
191 | radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); |
194 | radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); |
192 | radeon_crtc->mode_set.num_connectors = 0; |
195 | radeon_crtc->mode_set.num_connectors = 0; |
193 | #endif |
Line 202... | Line 200... | ||
202 | 200 | ||
203 | if (rdev->is_atom_bios && (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom)) |
201 | if (rdev->is_atom_bios && (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom)) |
204 | radeon_atombios_init_crtc(dev, radeon_crtc); |
202 | radeon_atombios_init_crtc(dev, radeon_crtc); |
205 | else |
203 | else |
206 | radeon_legacy_init_crtc(dev, radeon_crtc); |
- | |
207 | - | ||
208 | LEAVE(); |
204 | radeon_legacy_init_crtc(dev, radeon_crtc); |
Line 209... | Line 205... | ||
209 | } |
205 | } |
210 | 206 | ||
211 | static const char *encoder_names[34] = { |
207 | static const char *encoder_names[34] = { |
Line 314... | Line 310... | ||
314 | } |
310 | } |
315 | i++; |
311 | i++; |
316 | } |
312 | } |
317 | } |
313 | } |
Line 318... | Line 314... | ||
318 | 314 | ||
319 | bool radeon_setup_enc_conn(struct drm_device *dev) |
315 | static bool radeon_setup_enc_conn(struct drm_device *dev) |
320 | { |
316 | { |
321 | struct radeon_device *rdev = dev->dev_private; |
317 | struct radeon_device *rdev = dev->dev_private; |
322 | struct drm_connector *drm_connector; |
318 | struct drm_connector *drm_connector; |
Line 323... | Line -... | ||
323 | bool ret = false; |
- | |
324 | - | ||
325 | ENTRY(); |
319 | bool ret = false; |
326 | 320 | ||
327 | if (rdev->bios) { |
321 | if (rdev->bios) { |
328 | if (rdev->is_atom_bios) { |
322 | if (rdev->is_atom_bios) { |
329 | if (rdev->family >= CHIP_R600) |
323 | if (rdev->family >= CHIP_R600) |
Line 339... | Line 333... | ||
339 | if (ret) { |
333 | if (ret) { |
340 | radeon_print_display_setup(dev); |
334 | radeon_print_display_setup(dev); |
341 | list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) |
335 | list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) |
342 | radeon_ddc_dump(drm_connector); |
336 | radeon_ddc_dump(drm_connector); |
343 | } |
337 | } |
344 | LEAVE(); |
- | |
Line 345... | Line 338... | ||
345 | 338 | ||
346 | return ret; |
339 | return ret; |
Line 347... | Line 340... | ||
347 | } |
340 | } |
Line 351... | Line 344... | ||
351 | struct edid *edid; |
344 | struct edid *edid; |
352 | int ret = 0; |
345 | int ret = 0; |
Line 353... | Line 346... | ||
353 | 346 | ||
354 | if (!radeon_connector->ddc_bus) |
347 | if (!radeon_connector->ddc_bus) |
- | 348 | return -1; |
|
355 | return -1; |
349 | if (!radeon_connector->edid) { |
356 | radeon_i2c_do_lock(radeon_connector, 1); |
350 | radeon_i2c_do_lock(radeon_connector, 1); |
357 | edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
351 | edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
- | 352 | radeon_i2c_do_lock(radeon_connector, 0); |
|
- | 353 | } else |
|
- | 354 | edid = radeon_connector->edid; |
|
358 | radeon_i2c_do_lock(radeon_connector, 0); |
355 | |
359 | if (edid) { |
356 | if (edid) { |
360 | /* update digital bits here */ |
357 | /* update digital bits here */ |
361 | if (edid->input & DRM_EDID_INPUT_DIGITAL) |
358 | if (edid->input & DRM_EDID_INPUT_DIGITAL) |
362 | radeon_connector->use_digital = 1; |
359 | radeon_connector->use_digital = 1; |
Line 366... | Line 363... | ||
366 | ret = drm_add_edid_modes(&radeon_connector->base, edid); |
363 | ret = drm_add_edid_modes(&radeon_connector->base, edid); |
367 | kfree(edid); |
364 | kfree(edid); |
368 | return ret; |
365 | return ret; |
369 | } |
366 | } |
370 | drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); |
367 | drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); |
371 | return -1; |
368 | return 0; |
372 | } |
369 | } |
Line 373... | Line 370... | ||
373 | 370 | ||
374 | static int radeon_ddc_dump(struct drm_connector *connector) |
371 | static int radeon_ddc_dump(struct drm_connector *connector) |
375 | { |
372 | { |
Line 496... | Line 493... | ||
496 | frac_feedback_div = (min_frac_feed_div + max_frac_feed_div) / 2; |
493 | frac_feedback_div = (min_frac_feed_div + max_frac_feed_div) / 2; |
497 | tmp = (uint64_t)pll->reference_freq * 10000 * feedback_div; |
494 | tmp = (uint64_t)pll->reference_freq * 10000 * feedback_div; |
498 | tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div; |
495 | tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div; |
499 | current_freq = radeon_div(tmp, ref_div * post_div); |
496 | current_freq = radeon_div(tmp, ref_div * post_div); |
Line -... | Line 497... | ||
- | 497 | ||
- | 498 | if (flags & RADEON_PLL_PREFER_CLOSEST_LOWER) { |
|
- | 499 | error = freq - current_freq; |
|
- | 500 | error = error < 0 ? 0xffffffff : error; |
|
500 | 501 | } else |
|
501 | error = abs(current_freq - freq); |
502 | error = abs(current_freq - freq); |
Line 502... | Line 503... | ||
502 | vco_diff = abs(vco - best_vco); |
503 | vco_diff = abs(vco - best_vco); |
503 | 504 | ||
Line 554... | Line 555... | ||
554 | *frac_fb_div_p = best_frac_feedback_div; |
555 | *frac_fb_div_p = best_frac_feedback_div; |
555 | *ref_div_p = best_ref_div; |
556 | *ref_div_p = best_ref_div; |
556 | *post_div_p = best_post_div; |
557 | *post_div_p = best_post_div; |
557 | } |
558 | } |
Line 558... | Line -... | ||
558 | - | ||
559 | 559 | ||
560 | static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) |
560 | static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) |
561 | { |
561 | { |
562 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); |
562 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); |
Line 588... | Line 588... | ||
588 | static const struct drm_framebuffer_funcs radeon_fb_funcs = { |
588 | static const struct drm_framebuffer_funcs radeon_fb_funcs = { |
589 | .destroy = radeon_user_framebuffer_destroy, |
589 | .destroy = radeon_user_framebuffer_destroy, |
590 | .create_handle = radeon_user_framebuffer_create_handle, |
590 | .create_handle = radeon_user_framebuffer_create_handle, |
591 | }; |
591 | }; |
Line 592... | Line -... | ||
592 | - | ||
593 | 592 | ||
594 | struct drm_framebuffer * |
593 | struct drm_framebuffer * |
595 | radeon_framebuffer_create(struct drm_device *dev, |
594 | radeon_framebuffer_create(struct drm_device *dev, |
596 | struct drm_mode_fb_cmd *mode_cmd, |
595 | struct drm_mode_fb_cmd *mode_cmd, |
597 | struct drm_gem_object *obj) |
596 | struct drm_gem_object *obj) |
Line 620... | Line 619... | ||
620 | // obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); |
619 | // obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); |
621 | // |
620 | // |
622 | // return radeon_framebuffer_create(dev, mode_cmd, obj); |
621 | // return radeon_framebuffer_create(dev, mode_cmd, obj); |
623 | } |
622 | } |
Line 624... | Line -... | ||
624 | - | ||
625 | 623 | ||
626 | static const struct drm_mode_config_funcs radeon_mode_funcs = { |
624 | static const struct drm_mode_config_funcs radeon_mode_funcs = { |
627 | // .fb_create = radeon_user_framebuffer_create, |
625 | // .fb_create = radeon_user_framebuffer_create, |
628 | .fb_changed = radeonfb_probe, |
626 | .fb_changed = radeonfb_probe, |
Line -... | Line 627... | ||
- | 627 | }; |
|
- | 628 | ||
- | 629 | struct drm_prop_enum_list { |
|
- | 630 | int type; |
|
- | 631 | char *name; |
|
- | 632 | }; |
|
- | 633 | ||
- | 634 | static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] = |
|
- | 635 | { { 0, "driver" }, |
|
- | 636 | { 1, "bios" }, |
|
- | 637 | }; |
|
- | 638 | ||
- | 639 | static struct drm_prop_enum_list radeon_tv_std_enum_list[] = |
|
- | 640 | { { TV_STD_NTSC, "ntsc" }, |
|
- | 641 | { TV_STD_PAL, "pal" }, |
|
- | 642 | { TV_STD_PAL_M, "pal-m" }, |
|
- | 643 | { TV_STD_PAL_60, "pal-60" }, |
|
- | 644 | { TV_STD_NTSC_J, "ntsc-j" }, |
|
- | 645 | { TV_STD_SCART_PAL, "scart-pal" }, |
|
- | 646 | { TV_STD_PAL_CN, "pal-cn" }, |
|
- | 647 | { TV_STD_SECAM, "secam" }, |
|
629 | }; |
648 | }; |
630 | 649 | ||
- | 650 | int radeon_modeset_create_props(struct radeon_device *rdev) |
|
- | 651 | { |
|
- | 652 | int i, sz; |
|
- | 653 | ||
- | 654 | if (rdev->is_atom_bios) { |
|
- | 655 | rdev->mode_info.coherent_mode_property = |
|
- | 656 | drm_property_create(rdev->ddev, |
|
- | 657 | DRM_MODE_PROP_RANGE, |
|
- | 658 | "coherent", 2); |
|
- | 659 | if (!rdev->mode_info.coherent_mode_property) |
|
- | 660 | return -ENOMEM; |
|
- | 661 | ||
- | 662 | rdev->mode_info.coherent_mode_property->values[0] = 0; |
|
- | 663 | rdev->mode_info.coherent_mode_property->values[0] = 1; |
|
- | 664 | } |
|
- | 665 | ||
- | 666 | if (!ASIC_IS_AVIVO(rdev)) { |
|
- | 667 | sz = ARRAY_SIZE(radeon_tmds_pll_enum_list); |
|
- | 668 | rdev->mode_info.tmds_pll_property = |
|
- | 669 | drm_property_create(rdev->ddev, |
|
- | 670 | DRM_MODE_PROP_ENUM, |
|
- | 671 | "tmds_pll", sz); |
|
- | 672 | for (i = 0; i < sz; i++) { |
|
- | 673 | drm_property_add_enum(rdev->mode_info.tmds_pll_property, |
|
- | 674 | i, |
|
- | 675 | radeon_tmds_pll_enum_list[i].type, |
|
- | 676 | radeon_tmds_pll_enum_list[i].name); |
|
Line -... | Line 677... | ||
- | 677 | } |
|
- | 678 | } |
|
- | 679 | ||
- | 680 | rdev->mode_info.load_detect_property = |
|
- | 681 | drm_property_create(rdev->ddev, |
|
- | 682 | DRM_MODE_PROP_RANGE, |
|
- | 683 | "load detection", 2); |
|
- | 684 | if (!rdev->mode_info.load_detect_property) |
|
- | 685 | return -ENOMEM; |
|
- | 686 | rdev->mode_info.load_detect_property->values[0] = 0; |
|
- | 687 | rdev->mode_info.load_detect_property->values[0] = 1; |
|
- | 688 | ||
- | 689 | drm_mode_create_scaling_mode_property(rdev->ddev); |
|
- | 690 | ||
- | 691 | sz = ARRAY_SIZE(radeon_tv_std_enum_list); |
|
- | 692 | rdev->mode_info.tv_std_property = |
|
- | 693 | drm_property_create(rdev->ddev, |
|
- | 694 | DRM_MODE_PROP_ENUM, |
|
- | 695 | "tv standard", sz); |
|
- | 696 | for (i = 0; i < sz; i++) { |
|
631 | int radeon_modeset_init(struct radeon_device *rdev) |
697 | drm_property_add_enum(rdev->mode_info.tv_std_property, |
- | 698 | i, |
|
- | 699 | radeon_tv_std_enum_list[i].type, |
|
- | 700 | radeon_tv_std_enum_list[i].name); |
|
- | 701 | } |
|
Line -... | Line 702... | ||
- | 702 | ||
- | 703 | return 0; |
|
632 | { |
704 | } |
633 | 705 | ||
Line 634... | Line 706... | ||
634 | dbgprintf("%s\n",__FUNCTION__); |
706 | int radeon_modeset_init(struct radeon_device *rdev) |
635 | 707 | { |
|
Line 649... | Line 721... | ||
649 | rdev->ddev->mode_config.max_height = 4096; |
721 | rdev->ddev->mode_config.max_height = 4096; |
650 | } |
722 | } |
Line 651... | Line 723... | ||
651 | 723 | ||
Line -... | Line 724... | ||
- | 724 | rdev->ddev->mode_config.fb_base = rdev->mc.aper_base; |
|
- | 725 | ||
- | 726 | ret = radeon_modeset_create_props(rdev); |
|
- | 727 | if (ret) { |
|
652 | rdev->ddev->mode_config.fb_base = rdev->mc.aper_base; |
728 | return ret; |
653 | 729 | } |
|
654 | /* allocate crtcs - TODO single crtc */ |
730 | /* allocate crtcs - TODO single crtc */ |
655 | for (i = 0; i < num_crtc; i++) { |
731 | for (i = 0; i < num_crtc; i++) { |
Line 660... | Line 736... | ||
660 | ret = radeon_setup_enc_conn(rdev->ddev); |
736 | ret = radeon_setup_enc_conn(rdev->ddev); |
661 | if (!ret) { |
737 | if (!ret) { |
662 | return ret; |
738 | return ret; |
663 | } |
739 | } |
664 | drm_helper_initial_config(rdev->ddev); |
740 | drm_helper_initial_config(rdev->ddev); |
665 | - | ||
666 | dbgprintf("done %s\n",__FUNCTION__); |
- | |
667 | - | ||
668 | return 0; |
741 | return 0; |
669 | } |
742 | } |
Line 670... | Line 743... | ||
670 | 743 | ||
671 | void radeon_modeset_fini(struct radeon_device *rdev) |
744 | void radeon_modeset_fini(struct radeon_device *rdev) |
Line 674... | Line 747... | ||
674 | drm_mode_config_cleanup(rdev->ddev); |
747 | drm_mode_config_cleanup(rdev->ddev); |
675 | rdev->mode_info.mode_config_initialized = false; |
748 | rdev->mode_info.mode_config_initialized = false; |
676 | } |
749 | } |
677 | } |
750 | } |
Line 678... | Line 751... | ||
678 | 751 | ||
- | 752 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
|
- | 753 | struct drm_display_mode *mode, |
|
679 | void radeon_init_disp_bandwidth(struct drm_device *dev) |
754 | struct drm_display_mode *adjusted_mode) |
680 | { |
755 | { |
681 | struct radeon_device *rdev = dev->dev_private; |
- | |
682 | struct drm_display_mode *modes[2]; |
- | |
683 | int pixel_bytes[2]; |
756 | struct drm_device *dev = crtc->dev; |
684 | struct drm_crtc *crtc; |
- | |
685 | - | ||
686 | pixel_bytes[0] = pixel_bytes[1] = 0; |
- | |
687 | modes[0] = modes[1] = NULL; |
- | |
688 | - | ||
689 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
757 | struct drm_encoder *encoder; |
- | 758 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
|
- | 759 | struct radeon_encoder *radeon_encoder; |
|
Line -... | Line 760... | ||
- | 760 | bool first = true; |
|
- | 761 | ||
690 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
762 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
- | 763 | radeon_encoder = to_radeon_encoder(encoder); |
|
- | 764 | if (encoder->crtc != crtc) |
|
- | 765 | continue; |
|
691 | 766 | if (first) { |
|
- | 767 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; |
|
- | 768 | memcpy(&radeon_crtc->native_mode, |
|
- | 769 | &radeon_encoder->native_mode, |
|
- | 770 | sizeof(struct radeon_native_mode)); |
|
692 | if (crtc->enabled && crtc->fb) { |
771 | first = false; |
- | 772 | } else { |
|
- | 773 | if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { |
|
- | 774 | /* WARNING: Right now this can't happen but |
|
- | 775 | * in the future we need to check that scaling |
|
- | 776 | * are consistent accross different encoder |
|
- | 777 | * (ie all encoder can work with the same |
|
- | 778 | * scaling). |
|
- | 779 | */ |
|
693 | modes[radeon_crtc->crtc_id] = &crtc->mode; |
780 | DRM_ERROR("Scaling not consistent accross encoder.\n"); |
694 | pixel_bytes[radeon_crtc->crtc_id] = crtc->fb->bits_per_pixel / 8; |
781 | return false; |
695 | } |
782 | } |
696 | } |
783 | } |
697 | 784 | } |
|
698 | if (ASIC_IS_AVIVO(rdev)) { |
785 | if (radeon_crtc->rmx_type != RMX_OFF) { |
- | 786 | fixed20_12 a, b; |
|
699 | radeon_init_disp_bw_avivo(dev, |
787 | a.full = rfixed_const(crtc->mode.vdisplay); |
700 | modes[0], |
788 | b.full = rfixed_const(radeon_crtc->native_mode.panel_xres); |
- | 789 | radeon_crtc->vsc.full = rfixed_div(a, b); |
|
701 | pixel_bytes[0], |
790 | a.full = rfixed_const(crtc->mode.hdisplay); |
702 | modes[1], |
791 | b.full = rfixed_const(radeon_crtc->native_mode.panel_yres); |
703 | pixel_bytes[1]); |
792 | radeon_crtc->hsc.full = rfixed_div(a, b); |
704 | } else { |
- | |
705 | radeon_init_disp_bw_legacy(dev, |
- | |
706 | modes[0], |
- | |
707 | pixel_bytes[0], |
793 | } else { |
708 | modes[1], |
794 | radeon_crtc->vsc.full = rfixed_const(1); |
- | 795 | radeon_crtc->hsc.full = rfixed_const(1); |
|
709 | pixel_bytes[1]); |
796 | } |