diff options
55 files changed, 3549 insertions, 1510 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 1e0a9e17c31d..f94d4c818fc7 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -1448,8 +1448,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | |||
1448 | case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, | 1448 | case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, |
1449 | * most likely via hotkey. */ | 1449 | * most likely via hotkey. */ |
1450 | acpi_bus_generate_proc_event(device, event, 0); | 1450 | acpi_bus_generate_proc_event(device, event, 0); |
1451 | if (!acpi_notifier_call_chain(device, event, 0)) | 1451 | keycode = KEY_SWITCHVIDEOMODE; |
1452 | keycode = KEY_SWITCHVIDEOMODE; | ||
1453 | break; | 1452 | break; |
1454 | 1453 | ||
1455 | case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video | 1454 | case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video |
@@ -1479,8 +1478,9 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | |||
1479 | break; | 1478 | break; |
1480 | } | 1479 | } |
1481 | 1480 | ||
1482 | if (event != ACPI_VIDEO_NOTIFY_SWITCH) | 1481 | if (acpi_notifier_call_chain(device, event, 0)) |
1483 | acpi_notifier_call_chain(device, event, 0); | 1482 | /* Something vetoed the keypress. */ |
1483 | keycode = 0; | ||
1484 | 1484 | ||
1485 | if (keycode) { | 1485 | if (keycode) { |
1486 | input_report_key(input, keycode, 1); | 1486 | input_report_key(input, keycode, 1); |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 2817101fb167..96184d02c8d9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -83,25 +83,19 @@ static void atombios_scaler_setup(struct drm_crtc *crtc) | |||
83 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 83 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
84 | ENABLE_SCALER_PS_ALLOCATION args; | 84 | ENABLE_SCALER_PS_ALLOCATION args; |
85 | int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); | 85 | int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); |
86 | 86 | struct radeon_encoder *radeon_encoder = | |
87 | to_radeon_encoder(radeon_crtc->encoder); | ||
87 | /* fixme - fill in enc_priv for atom dac */ | 88 | /* fixme - fill in enc_priv for atom dac */ |
88 | enum radeon_tv_std tv_std = TV_STD_NTSC; | 89 | enum radeon_tv_std tv_std = TV_STD_NTSC; |
89 | bool is_tv = false, is_cv = false; | 90 | bool is_tv = false, is_cv = false; |
90 | struct drm_encoder *encoder; | ||
91 | 91 | ||
92 | if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) | 92 | if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) |
93 | return; | 93 | return; |
94 | 94 | ||
95 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 95 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { |
96 | /* find tv std */ | 96 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
97 | if (encoder->crtc == crtc) { | 97 | tv_std = tv_dac->tv_std; |
98 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 98 | is_tv = true; |
99 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { | ||
100 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
101 | tv_std = tv_dac->tv_std; | ||
102 | is_tv = true; | ||
103 | } | ||
104 | } | ||
105 | } | 99 | } |
106 | 100 | ||
107 | memset(&args, 0, sizeof(args)); | 101 | memset(&args, 0, sizeof(args)); |
@@ -533,99 +527,87 @@ union adjust_pixel_clock { | |||
533 | }; | 527 | }; |
534 | 528 | ||
535 | static u32 atombios_adjust_pll(struct drm_crtc *crtc, | 529 | static u32 atombios_adjust_pll(struct drm_crtc *crtc, |
536 | struct drm_display_mode *mode, | 530 | struct drm_display_mode *mode) |
537 | struct radeon_pll *pll, | ||
538 | bool ss_enabled, | ||
539 | struct radeon_atom_ss *ss) | ||
540 | { | 531 | { |
532 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
541 | struct drm_device *dev = crtc->dev; | 533 | struct drm_device *dev = crtc->dev; |
542 | struct radeon_device *rdev = dev->dev_private; | 534 | struct radeon_device *rdev = dev->dev_private; |
543 | struct drm_encoder *encoder = NULL; | 535 | struct drm_encoder *encoder = radeon_crtc->encoder; |
544 | struct radeon_encoder *radeon_encoder = NULL; | 536 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
545 | struct drm_connector *connector = NULL; | 537 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
546 | u32 adjusted_clock = mode->clock; | 538 | u32 adjusted_clock = mode->clock; |
547 | int encoder_mode = 0; | 539 | int encoder_mode = atombios_get_encoder_mode(encoder); |
548 | u32 dp_clock = mode->clock; | 540 | u32 dp_clock = mode->clock; |
549 | int bpc = 8; | 541 | int bpc = radeon_get_monitor_bpc(connector); |
550 | bool is_duallink = false; | 542 | bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); |
551 | 543 | ||
552 | /* reset the pll flags */ | 544 | /* reset the pll flags */ |
553 | pll->flags = 0; | 545 | radeon_crtc->pll_flags = 0; |
554 | 546 | ||
555 | if (ASIC_IS_AVIVO(rdev)) { | 547 | if (ASIC_IS_AVIVO(rdev)) { |
556 | if ((rdev->family == CHIP_RS600) || | 548 | if ((rdev->family == CHIP_RS600) || |
557 | (rdev->family == CHIP_RS690) || | 549 | (rdev->family == CHIP_RS690) || |
558 | (rdev->family == CHIP_RS740)) | 550 | (rdev->family == CHIP_RS740)) |
559 | pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ | 551 | radeon_crtc->pll_flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ |
560 | RADEON_PLL_PREFER_CLOSEST_LOWER); | 552 | RADEON_PLL_PREFER_CLOSEST_LOWER); |
561 | 553 | ||
562 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ | 554 | if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ |
563 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 555 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
564 | else | 556 | else |
565 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 557 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
566 | 558 | ||
567 | if (rdev->family < CHIP_RV770) | 559 | if (rdev->family < CHIP_RV770) |
568 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | 560 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; |
569 | /* use frac fb div on APUs */ | 561 | /* use frac fb div on APUs */ |
570 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | 562 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) |
571 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 563 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
572 | } else { | 564 | } else { |
573 | pll->flags |= RADEON_PLL_LEGACY; | 565 | radeon_crtc->pll_flags |= RADEON_PLL_LEGACY; |
574 | 566 | ||
575 | if (mode->clock > 200000) /* range limits??? */ | 567 | if (mode->clock > 200000) /* range limits??? */ |
576 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 568 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
577 | else | 569 | else |
578 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 570 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
579 | } | 571 | } |
580 | 572 | ||
581 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 573 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
582 | if (encoder->crtc == crtc) { | 574 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { |
583 | radeon_encoder = to_radeon_encoder(encoder); | 575 | if (connector) { |
584 | connector = radeon_get_connector_for_encoder(encoder); | 576 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
585 | bpc = radeon_get_monitor_bpc(connector); | 577 | struct radeon_connector_atom_dig *dig_connector = |
586 | encoder_mode = atombios_get_encoder_mode(encoder); | 578 | radeon_connector->con_priv; |
587 | is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); | ||
588 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || | ||
589 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { | ||
590 | if (connector) { | ||
591 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
592 | struct radeon_connector_atom_dig *dig_connector = | ||
593 | radeon_connector->con_priv; | ||
594 | |||
595 | dp_clock = dig_connector->dp_clock; | ||
596 | } | ||
597 | } | ||
598 | 579 | ||
599 | /* use recommended ref_div for ss */ | 580 | dp_clock = dig_connector->dp_clock; |
600 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 581 | } |
601 | if (ss_enabled) { | 582 | } |
602 | if (ss->refdiv) { | ||
603 | pll->flags |= RADEON_PLL_USE_REF_DIV; | ||
604 | pll->reference_div = ss->refdiv; | ||
605 | if (ASIC_IS_AVIVO(rdev)) | ||
606 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | ||
607 | } | ||
608 | } | ||
609 | } | ||
610 | 583 | ||
611 | if (ASIC_IS_AVIVO(rdev)) { | 584 | /* use recommended ref_div for ss */ |
612 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 585 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
613 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 586 | if (radeon_crtc->ss_enabled) { |
614 | adjusted_clock = mode->clock * 2; | 587 | if (radeon_crtc->ss.refdiv) { |
615 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | 588 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
616 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; | 589 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; |
617 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | 590 | if (ASIC_IS_AVIVO(rdev)) |
618 | pll->flags |= RADEON_PLL_IS_LCD; | 591 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
619 | } else { | ||
620 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | ||
621 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; | ||
622 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) | ||
623 | pll->flags |= RADEON_PLL_USE_REF_DIV; | ||
624 | } | 592 | } |
625 | break; | ||
626 | } | 593 | } |
627 | } | 594 | } |
628 | 595 | ||
596 | if (ASIC_IS_AVIVO(rdev)) { | ||
597 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | ||
598 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | ||
599 | adjusted_clock = mode->clock * 2; | ||
600 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | ||
601 | radeon_crtc->pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; | ||
602 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
603 | radeon_crtc->pll_flags |= RADEON_PLL_IS_LCD; | ||
604 | } else { | ||
605 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | ||
606 | radeon_crtc->pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; | ||
607 | if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) | ||
608 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; | ||
609 | } | ||
610 | |||
629 | /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock | 611 | /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock |
630 | * accordingly based on the encoder/transmitter to work around | 612 | * accordingly based on the encoder/transmitter to work around |
631 | * special hw requirements. | 613 | * special hw requirements. |
@@ -650,7 +632,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
650 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 632 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
651 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; | 633 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
652 | args.v1.ucEncodeMode = encoder_mode; | 634 | args.v1.ucEncodeMode = encoder_mode; |
653 | if (ss_enabled && ss->percentage) | 635 | if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage) |
654 | args.v1.ucConfig |= | 636 | args.v1.ucConfig |= |
655 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; | 637 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; |
656 | 638 | ||
@@ -663,7 +645,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
663 | args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; | 645 | args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; |
664 | args.v3.sInput.ucEncodeMode = encoder_mode; | 646 | args.v3.sInput.ucEncodeMode = encoder_mode; |
665 | args.v3.sInput.ucDispPllConfig = 0; | 647 | args.v3.sInput.ucDispPllConfig = 0; |
666 | if (ss_enabled && ss->percentage) | 648 | if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage) |
667 | args.v3.sInput.ucDispPllConfig |= | 649 | args.v3.sInput.ucDispPllConfig |= |
668 | DISPPLL_CONFIG_SS_ENABLE; | 650 | DISPPLL_CONFIG_SS_ENABLE; |
669 | if (ENCODER_MODE_IS_DP(encoder_mode)) { | 651 | if (ENCODER_MODE_IS_DP(encoder_mode)) { |
@@ -695,14 +677,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
695 | index, (uint32_t *)&args); | 677 | index, (uint32_t *)&args); |
696 | adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; | 678 | adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; |
697 | if (args.v3.sOutput.ucRefDiv) { | 679 | if (args.v3.sOutput.ucRefDiv) { |
698 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 680 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
699 | pll->flags |= RADEON_PLL_USE_REF_DIV; | 681 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
700 | pll->reference_div = args.v3.sOutput.ucRefDiv; | 682 | radeon_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv; |
701 | } | 683 | } |
702 | if (args.v3.sOutput.ucPostDiv) { | 684 | if (args.v3.sOutput.ucPostDiv) { |
703 | pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 685 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
704 | pll->flags |= RADEON_PLL_USE_POST_DIV; | 686 | radeon_crtc->pll_flags |= RADEON_PLL_USE_POST_DIV; |
705 | pll->post_div = args.v3.sOutput.ucPostDiv; | 687 | radeon_crtc->pll_post_div = args.v3.sOutput.ucPostDiv; |
706 | } | 688 | } |
707 | break; | 689 | break; |
708 | default: | 690 | default: |
@@ -837,7 +819,10 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc, | |||
837 | args.v3.ucFracFbDiv = frac_fb_div; | 819 | args.v3.ucFracFbDiv = frac_fb_div; |
838 | args.v3.ucPostDiv = post_div; | 820 | args.v3.ucPostDiv = post_div; |
839 | args.v3.ucPpll = pll_id; | 821 | args.v3.ucPpll = pll_id; |
840 | args.v3.ucMiscInfo = (pll_id << 2); | 822 | if (crtc_id == ATOM_CRTC2) |
823 | args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2; | ||
824 | else | ||
825 | args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1; | ||
841 | if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK)) | 826 | if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK)) |
842 | args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; | 827 | args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; |
843 | args.v3.ucTransmitterId = encoder_id; | 828 | args.v3.ucTransmitterId = encoder_id; |
@@ -907,58 +892,29 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc, | |||
907 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 892 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
908 | } | 893 | } |
909 | 894 | ||
910 | static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | 895 | static bool atombios_crtc_prepare_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
911 | { | 896 | { |
912 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 897 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
913 | struct drm_device *dev = crtc->dev; | 898 | struct drm_device *dev = crtc->dev; |
914 | struct radeon_device *rdev = dev->dev_private; | 899 | struct radeon_device *rdev = dev->dev_private; |
915 | struct drm_encoder *encoder = NULL; | 900 | struct radeon_encoder *radeon_encoder = |
916 | struct radeon_encoder *radeon_encoder = NULL; | 901 | to_radeon_encoder(radeon_crtc->encoder); |
917 | u32 pll_clock = mode->clock; | 902 | int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder); |
918 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | ||
919 | struct radeon_pll *pll; | ||
920 | u32 adjusted_clock; | ||
921 | int encoder_mode = 0; | ||
922 | struct radeon_atom_ss ss; | ||
923 | bool ss_enabled = false; | ||
924 | int bpc = 8; | ||
925 | 903 | ||
926 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 904 | radeon_crtc->bpc = 8; |
927 | if (encoder->crtc == crtc) { | 905 | radeon_crtc->ss_enabled = false; |
928 | radeon_encoder = to_radeon_encoder(encoder); | ||
929 | encoder_mode = atombios_get_encoder_mode(encoder); | ||
930 | break; | ||
931 | } | ||
932 | } | ||
933 | |||
934 | if (!radeon_encoder) | ||
935 | return; | ||
936 | |||
937 | switch (radeon_crtc->pll_id) { | ||
938 | case ATOM_PPLL1: | ||
939 | pll = &rdev->clock.p1pll; | ||
940 | break; | ||
941 | case ATOM_PPLL2: | ||
942 | pll = &rdev->clock.p2pll; | ||
943 | break; | ||
944 | case ATOM_DCPLL: | ||
945 | case ATOM_PPLL_INVALID: | ||
946 | default: | ||
947 | pll = &rdev->clock.dcpll; | ||
948 | break; | ||
949 | } | ||
950 | 906 | ||
951 | if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || | 907 | if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
952 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { | 908 | (radeon_encoder_get_dp_bridge_encoder_id(radeon_crtc->encoder) != ENCODER_OBJECT_ID_NONE)) { |
953 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 909 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
954 | struct drm_connector *connector = | 910 | struct drm_connector *connector = |
955 | radeon_get_connector_for_encoder(encoder); | 911 | radeon_get_connector_for_encoder(radeon_crtc->encoder); |
956 | struct radeon_connector *radeon_connector = | 912 | struct radeon_connector *radeon_connector = |
957 | to_radeon_connector(connector); | 913 | to_radeon_connector(connector); |
958 | struct radeon_connector_atom_dig *dig_connector = | 914 | struct radeon_connector_atom_dig *dig_connector = |
959 | radeon_connector->con_priv; | 915 | radeon_connector->con_priv; |
960 | int dp_clock; | 916 | int dp_clock; |
961 | bpc = radeon_get_monitor_bpc(connector); | 917 | radeon_crtc->bpc = radeon_get_monitor_bpc(connector); |
962 | 918 | ||
963 | switch (encoder_mode) { | 919 | switch (encoder_mode) { |
964 | case ATOM_ENCODER_MODE_DP_MST: | 920 | case ATOM_ENCODER_MODE_DP_MST: |
@@ -966,45 +922,54 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
966 | /* DP/eDP */ | 922 | /* DP/eDP */ |
967 | dp_clock = dig_connector->dp_clock / 10; | 923 | dp_clock = dig_connector->dp_clock / 10; |
968 | if (ASIC_IS_DCE4(rdev)) | 924 | if (ASIC_IS_DCE4(rdev)) |
969 | ss_enabled = | 925 | radeon_crtc->ss_enabled = |
970 | radeon_atombios_get_asic_ss_info(rdev, &ss, | 926 | radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss, |
971 | ASIC_INTERNAL_SS_ON_DP, | 927 | ASIC_INTERNAL_SS_ON_DP, |
972 | dp_clock); | 928 | dp_clock); |
973 | else { | 929 | else { |
974 | if (dp_clock == 16200) { | 930 | if (dp_clock == 16200) { |
975 | ss_enabled = | 931 | radeon_crtc->ss_enabled = |
976 | radeon_atombios_get_ppll_ss_info(rdev, &ss, | 932 | radeon_atombios_get_ppll_ss_info(rdev, |
933 | &radeon_crtc->ss, | ||
977 | ATOM_DP_SS_ID2); | 934 | ATOM_DP_SS_ID2); |
978 | if (!ss_enabled) | 935 | if (!radeon_crtc->ss_enabled) |
979 | ss_enabled = | 936 | radeon_crtc->ss_enabled = |
980 | radeon_atombios_get_ppll_ss_info(rdev, &ss, | 937 | radeon_atombios_get_ppll_ss_info(rdev, |
938 | &radeon_crtc->ss, | ||
981 | ATOM_DP_SS_ID1); | 939 | ATOM_DP_SS_ID1); |
982 | } else | 940 | } else |
983 | ss_enabled = | 941 | radeon_crtc->ss_enabled = |
984 | radeon_atombios_get_ppll_ss_info(rdev, &ss, | 942 | radeon_atombios_get_ppll_ss_info(rdev, |
943 | &radeon_crtc->ss, | ||
985 | ATOM_DP_SS_ID1); | 944 | ATOM_DP_SS_ID1); |
986 | } | 945 | } |
987 | break; | 946 | break; |
988 | case ATOM_ENCODER_MODE_LVDS: | 947 | case ATOM_ENCODER_MODE_LVDS: |
989 | if (ASIC_IS_DCE4(rdev)) | 948 | if (ASIC_IS_DCE4(rdev)) |
990 | ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, | 949 | radeon_crtc->ss_enabled = |
991 | dig->lcd_ss_id, | 950 | radeon_atombios_get_asic_ss_info(rdev, |
992 | mode->clock / 10); | 951 | &radeon_crtc->ss, |
952 | dig->lcd_ss_id, | ||
953 | mode->clock / 10); | ||
993 | else | 954 | else |
994 | ss_enabled = radeon_atombios_get_ppll_ss_info(rdev, &ss, | 955 | radeon_crtc->ss_enabled = |
995 | dig->lcd_ss_id); | 956 | radeon_atombios_get_ppll_ss_info(rdev, |
957 | &radeon_crtc->ss, | ||
958 | dig->lcd_ss_id); | ||
996 | break; | 959 | break; |
997 | case ATOM_ENCODER_MODE_DVI: | 960 | case ATOM_ENCODER_MODE_DVI: |
998 | if (ASIC_IS_DCE4(rdev)) | 961 | if (ASIC_IS_DCE4(rdev)) |
999 | ss_enabled = | 962 | radeon_crtc->ss_enabled = |
1000 | radeon_atombios_get_asic_ss_info(rdev, &ss, | 963 | radeon_atombios_get_asic_ss_info(rdev, |
964 | &radeon_crtc->ss, | ||
1001 | ASIC_INTERNAL_SS_ON_TMDS, | 965 | ASIC_INTERNAL_SS_ON_TMDS, |
1002 | mode->clock / 10); | 966 | mode->clock / 10); |
1003 | break; | 967 | break; |
1004 | case ATOM_ENCODER_MODE_HDMI: | 968 | case ATOM_ENCODER_MODE_HDMI: |
1005 | if (ASIC_IS_DCE4(rdev)) | 969 | if (ASIC_IS_DCE4(rdev)) |
1006 | ss_enabled = | 970 | radeon_crtc->ss_enabled = |
1007 | radeon_atombios_get_asic_ss_info(rdev, &ss, | 971 | radeon_atombios_get_asic_ss_info(rdev, |
972 | &radeon_crtc->ss, | ||
1008 | ASIC_INTERNAL_SS_ON_HDMI, | 973 | ASIC_INTERNAL_SS_ON_HDMI, |
1009 | mode->clock / 10); | 974 | mode->clock / 10); |
1010 | break; | 975 | break; |
@@ -1014,43 +979,80 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
1014 | } | 979 | } |
1015 | 980 | ||
1016 | /* adjust pixel clock as needed */ | 981 | /* adjust pixel clock as needed */ |
1017 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); | 982 | radeon_crtc->adjusted_clock = atombios_adjust_pll(crtc, mode); |
983 | |||
984 | return true; | ||
985 | } | ||
986 | |||
987 | static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | ||
988 | { | ||
989 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
990 | struct drm_device *dev = crtc->dev; | ||
991 | struct radeon_device *rdev = dev->dev_private; | ||
992 | struct radeon_encoder *radeon_encoder = | ||
993 | to_radeon_encoder(radeon_crtc->encoder); | ||
994 | u32 pll_clock = mode->clock; | ||
995 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | ||
996 | struct radeon_pll *pll; | ||
997 | int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder); | ||
998 | |||
999 | switch (radeon_crtc->pll_id) { | ||
1000 | case ATOM_PPLL1: | ||
1001 | pll = &rdev->clock.p1pll; | ||
1002 | break; | ||
1003 | case ATOM_PPLL2: | ||
1004 | pll = &rdev->clock.p2pll; | ||
1005 | break; | ||
1006 | case ATOM_DCPLL: | ||
1007 | case ATOM_PPLL_INVALID: | ||
1008 | default: | ||
1009 | pll = &rdev->clock.dcpll; | ||
1010 | break; | ||
1011 | } | ||
1012 | |||
1013 | /* update pll params */ | ||
1014 | pll->flags = radeon_crtc->pll_flags; | ||
1015 | pll->reference_div = radeon_crtc->pll_reference_div; | ||
1016 | pll->post_div = radeon_crtc->pll_post_div; | ||
1018 | 1017 | ||
1019 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) | 1018 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
1020 | /* TV seems to prefer the legacy algo on some boards */ | 1019 | /* TV seems to prefer the legacy algo on some boards */ |
1021 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 1020 | radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock, |
1022 | &ref_div, &post_div); | 1021 | &fb_div, &frac_fb_div, &ref_div, &post_div); |
1023 | else if (ASIC_IS_AVIVO(rdev)) | 1022 | else if (ASIC_IS_AVIVO(rdev)) |
1024 | radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 1023 | radeon_compute_pll_avivo(pll, radeon_crtc->adjusted_clock, &pll_clock, |
1025 | &ref_div, &post_div); | 1024 | &fb_div, &frac_fb_div, &ref_div, &post_div); |
1026 | else | 1025 | else |
1027 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 1026 | radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock, |
1028 | &ref_div, &post_div); | 1027 | &fb_div, &frac_fb_div, &ref_div, &post_div); |
1029 | 1028 | ||
1030 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); | 1029 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, |
1030 | radeon_crtc->crtc_id, &radeon_crtc->ss); | ||
1031 | 1031 | ||
1032 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | 1032 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
1033 | encoder_mode, radeon_encoder->encoder_id, mode->clock, | 1033 | encoder_mode, radeon_encoder->encoder_id, mode->clock, |
1034 | ref_div, fb_div, frac_fb_div, post_div, bpc, ss_enabled, &ss); | 1034 | ref_div, fb_div, frac_fb_div, post_div, |
1035 | radeon_crtc->bpc, radeon_crtc->ss_enabled, &radeon_crtc->ss); | ||
1035 | 1036 | ||
1036 | if (ss_enabled) { | 1037 | if (radeon_crtc->ss_enabled) { |
1037 | /* calculate ss amount and step size */ | 1038 | /* calculate ss amount and step size */ |
1038 | if (ASIC_IS_DCE4(rdev)) { | 1039 | if (ASIC_IS_DCE4(rdev)) { |
1039 | u32 step_size; | 1040 | u32 step_size; |
1040 | u32 amount = (((fb_div * 10) + frac_fb_div) * ss.percentage) / 10000; | 1041 | u32 amount = (((fb_div * 10) + frac_fb_div) * radeon_crtc->ss.percentage) / 10000; |
1041 | ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK; | 1042 | radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK; |
1042 | ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) & | 1043 | radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) & |
1043 | ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK; | 1044 | ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK; |
1044 | if (ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD) | 1045 | if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD) |
1045 | step_size = (4 * amount * ref_div * (ss.rate * 2048)) / | 1046 | step_size = (4 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) / |
1046 | (125 * 25 * pll->reference_freq / 100); | 1047 | (125 * 25 * pll->reference_freq / 100); |
1047 | else | 1048 | else |
1048 | step_size = (2 * amount * ref_div * (ss.rate * 2048)) / | 1049 | step_size = (2 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) / |
1049 | (125 * 25 * pll->reference_freq / 100); | 1050 | (125 * 25 * pll->reference_freq / 100); |
1050 | ss.step = step_size; | 1051 | radeon_crtc->ss.step = step_size; |
1051 | } | 1052 | } |
1052 | 1053 | ||
1053 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); | 1054 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, |
1055 | radeon_crtc->crtc_id, &radeon_crtc->ss); | ||
1054 | } | 1056 | } |
1055 | } | 1057 | } |
1056 | 1058 | ||
@@ -1479,85 +1481,251 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc) | |||
1479 | } | 1481 | } |
1480 | } | 1482 | } |
1481 | 1483 | ||
1484 | /** | ||
1485 | * radeon_get_pll_use_mask - look up a mask of which pplls are in use | ||
1486 | * | ||
1487 | * @crtc: drm crtc | ||
1488 | * | ||
1489 | * Returns the mask of which PPLLs (Pixel PLLs) are in use. | ||
1490 | */ | ||
1491 | static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc) | ||
1492 | { | ||
1493 | struct drm_device *dev = crtc->dev; | ||
1494 | struct drm_crtc *test_crtc; | ||
1495 | struct radeon_crtc *test_radeon_crtc; | ||
1496 | u32 pll_in_use = 0; | ||
1497 | |||
1498 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | ||
1499 | if (crtc == test_crtc) | ||
1500 | continue; | ||
1501 | |||
1502 | test_radeon_crtc = to_radeon_crtc(test_crtc); | ||
1503 | if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) | ||
1504 | pll_in_use |= (1 << test_radeon_crtc->pll_id); | ||
1505 | } | ||
1506 | return pll_in_use; | ||
1507 | } | ||
1508 | |||
1509 | /** | ||
1510 | * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP | ||
1511 | * | ||
1512 | * @crtc: drm crtc | ||
1513 | * | ||
1514 | * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is | ||
1515 | * also in DP mode. For DP, a single PPLL can be used for all DP | ||
1516 | * crtcs/encoders. | ||
1517 | */ | ||
1518 | static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) | ||
1519 | { | ||
1520 | struct drm_device *dev = crtc->dev; | ||
1521 | struct drm_crtc *test_crtc; | ||
1522 | struct radeon_crtc *test_radeon_crtc; | ||
1523 | |||
1524 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | ||
1525 | if (crtc == test_crtc) | ||
1526 | continue; | ||
1527 | test_radeon_crtc = to_radeon_crtc(test_crtc); | ||
1528 | if (test_radeon_crtc->encoder && | ||
1529 | ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) { | ||
1530 | /* for DP use the same PLL for all */ | ||
1531 | if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) | ||
1532 | return test_radeon_crtc->pll_id; | ||
1533 | } | ||
1534 | } | ||
1535 | return ATOM_PPLL_INVALID; | ||
1536 | } | ||
1537 | |||
1538 | /** | ||
1539 | * radeon_get_shared_nondp_ppll - return the PPLL used by another non-DP crtc | ||
1540 | * | ||
1541 | * @crtc: drm crtc | ||
1542 | * @encoder: drm encoder | ||
1543 | * | ||
1544 | * Returns the PPLL (Pixel PLL) used by another non-DP crtc/encoder which can | ||
1545 | * be shared (i.e., same clock). | ||
1546 | */ | ||
1547 | static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc) | ||
1548 | { | ||
1549 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1550 | struct drm_device *dev = crtc->dev; | ||
1551 | struct drm_crtc *test_crtc; | ||
1552 | struct radeon_crtc *test_radeon_crtc; | ||
1553 | u32 adjusted_clock, test_adjusted_clock; | ||
1554 | |||
1555 | adjusted_clock = radeon_crtc->adjusted_clock; | ||
1556 | |||
1557 | if (adjusted_clock == 0) | ||
1558 | return ATOM_PPLL_INVALID; | ||
1559 | |||
1560 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | ||
1561 | if (crtc == test_crtc) | ||
1562 | continue; | ||
1563 | test_radeon_crtc = to_radeon_crtc(test_crtc); | ||
1564 | if (test_radeon_crtc->encoder && | ||
1565 | !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) { | ||
1566 | /* check if we are already driving this connector with another crtc */ | ||
1567 | if (test_radeon_crtc->connector == radeon_crtc->connector) { | ||
1568 | /* if we are, return that pll */ | ||
1569 | if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) | ||
1570 | return test_radeon_crtc->pll_id; | ||
1571 | } | ||
1572 | /* for non-DP check the clock */ | ||
1573 | test_adjusted_clock = test_radeon_crtc->adjusted_clock; | ||
1574 | if ((crtc->mode.clock == test_crtc->mode.clock) && | ||
1575 | (adjusted_clock == test_adjusted_clock) && | ||
1576 | (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) && | ||
1577 | (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)) | ||
1578 | return test_radeon_crtc->pll_id; | ||
1579 | } | ||
1580 | } | ||
1581 | return ATOM_PPLL_INVALID; | ||
1582 | } | ||
1583 | |||
1584 | /** | ||
1585 | * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc. | ||
1586 | * | ||
1587 | * @crtc: drm crtc | ||
1588 | * | ||
1589 | * Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors | ||
1590 | * a single PPLL can be used for all DP crtcs/encoders. For non-DP | ||
1591 | * monitors a dedicated PPLL must be used. If a particular board has | ||
1592 | * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming | ||
1593 | * as there is no need to program the PLL itself. If we are not able to | ||
1594 | * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to | ||
1595 | * avoid messing up an existing monitor. | ||
1596 | * | ||
1597 | * Asic specific PLL information | ||
1598 | * | ||
1599 | * DCE 6.1 | ||
1600 | * - PPLL2 is only available to UNIPHYA (both DP and non-DP) | ||
1601 | * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP) | ||
1602 | * | ||
1603 | * DCE 6.0 | ||
1604 | * - PPLL0 is available to all UNIPHY (DP only) | ||
1605 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC | ||
1606 | * | ||
1607 | * DCE 5.0 | ||
1608 | * - DCPLL is available to all UNIPHY (DP only) | ||
1609 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC | ||
1610 | * | ||
1611 | * DCE 3.0/4.0/4.1 | ||
1612 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC | ||
1613 | * | ||
1614 | */ | ||
1482 | static int radeon_atom_pick_pll(struct drm_crtc *crtc) | 1615 | static int radeon_atom_pick_pll(struct drm_crtc *crtc) |
1483 | { | 1616 | { |
1484 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1617 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1485 | struct drm_device *dev = crtc->dev; | 1618 | struct drm_device *dev = crtc->dev; |
1486 | struct radeon_device *rdev = dev->dev_private; | 1619 | struct radeon_device *rdev = dev->dev_private; |
1487 | struct drm_encoder *test_encoder; | 1620 | struct radeon_encoder *radeon_encoder = |
1488 | struct drm_crtc *test_crtc; | 1621 | to_radeon_encoder(radeon_crtc->encoder); |
1489 | uint32_t pll_in_use = 0; | 1622 | u32 pll_in_use; |
1623 | int pll; | ||
1490 | 1624 | ||
1491 | if (ASIC_IS_DCE61(rdev)) { | 1625 | if (ASIC_IS_DCE61(rdev)) { |
1492 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | 1626 | struct radeon_encoder_atom_dig *dig = |
1493 | if (test_encoder->crtc && (test_encoder->crtc == crtc)) { | 1627 | radeon_encoder->enc_priv; |
1494 | struct radeon_encoder *test_radeon_encoder = | 1628 | |
1495 | to_radeon_encoder(test_encoder); | 1629 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && |
1496 | struct radeon_encoder_atom_dig *dig = | 1630 | (dig->linkb == false)) |
1497 | test_radeon_encoder->enc_priv; | 1631 | /* UNIPHY A uses PPLL2 */ |
1498 | 1632 | return ATOM_PPLL2; | |
1499 | if ((test_radeon_encoder->encoder_id == | 1633 | else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { |
1500 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && | 1634 | /* UNIPHY B/C/D/E/F */ |
1501 | (dig->linkb == false)) /* UNIPHY A uses PPLL2 */ | 1635 | if (rdev->clock.dp_extclk) |
1502 | return ATOM_PPLL2; | 1636 | /* skip PPLL programming if using ext clock */ |
1637 | return ATOM_PPLL_INVALID; | ||
1638 | else { | ||
1639 | /* use the same PPLL for all DP monitors */ | ||
1640 | pll = radeon_get_shared_dp_ppll(crtc); | ||
1641 | if (pll != ATOM_PPLL_INVALID) | ||
1642 | return pll; | ||
1503 | } | 1643 | } |
1644 | } else { | ||
1645 | /* use the same PPLL for all monitors with the same clock */ | ||
1646 | pll = radeon_get_shared_nondp_ppll(crtc); | ||
1647 | if (pll != ATOM_PPLL_INVALID) | ||
1648 | return pll; | ||
1504 | } | 1649 | } |
1505 | /* UNIPHY B/C/D/E/F */ | 1650 | /* UNIPHY B/C/D/E/F */ |
1506 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | 1651 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1507 | struct radeon_crtc *radeon_test_crtc; | 1652 | if (!(pll_in_use & (1 << ATOM_PPLL0))) |
1508 | |||
1509 | if (crtc == test_crtc) | ||
1510 | continue; | ||
1511 | |||
1512 | radeon_test_crtc = to_radeon_crtc(test_crtc); | ||
1513 | if ((radeon_test_crtc->pll_id == ATOM_PPLL0) || | ||
1514 | (radeon_test_crtc->pll_id == ATOM_PPLL1)) | ||
1515 | pll_in_use |= (1 << radeon_test_crtc->pll_id); | ||
1516 | } | ||
1517 | if (!(pll_in_use & 4)) | ||
1518 | return ATOM_PPLL0; | 1653 | return ATOM_PPLL0; |
1519 | return ATOM_PPLL1; | 1654 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
1655 | return ATOM_PPLL1; | ||
1656 | DRM_ERROR("unable to allocate a PPLL\n"); | ||
1657 | return ATOM_PPLL_INVALID; | ||
1520 | } else if (ASIC_IS_DCE4(rdev)) { | 1658 | } else if (ASIC_IS_DCE4(rdev)) { |
1521 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | 1659 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, |
1522 | if (test_encoder->crtc && (test_encoder->crtc == crtc)) { | 1660 | * depending on the asic: |
1523 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, | 1661 | * DCE4: PPLL or ext clock |
1524 | * depending on the asic: | 1662 | * DCE5: PPLL, DCPLL, or ext clock |
1525 | * DCE4: PPLL or ext clock | 1663 | * DCE6: PPLL, PPLL0, or ext clock |
1526 | * DCE5: DCPLL or ext clock | 1664 | * |
1527 | * | 1665 | * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip |
1528 | * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip | 1666 | * PPLL/DCPLL programming and only program the DP DTO for the |
1529 | * PPLL/DCPLL programming and only program the DP DTO for the | 1667 | * crtc virtual pixel clock. |
1530 | * crtc virtual pixel clock. | 1668 | */ |
1531 | */ | 1669 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { |
1532 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | 1670 | if (rdev->clock.dp_extclk) |
1533 | if (rdev->clock.dp_extclk) | 1671 | /* skip PPLL programming if using ext clock */ |
1534 | return ATOM_PPLL_INVALID; | 1672 | return ATOM_PPLL_INVALID; |
1535 | else if (ASIC_IS_DCE6(rdev)) | 1673 | else if (ASIC_IS_DCE6(rdev)) |
1536 | return ATOM_PPLL0; | 1674 | /* use PPLL0 for all DP */ |
1537 | else if (ASIC_IS_DCE5(rdev)) | 1675 | return ATOM_PPLL0; |
1538 | return ATOM_DCPLL; | 1676 | else if (ASIC_IS_DCE5(rdev)) |
1539 | } | 1677 | /* use DCPLL for all DP */ |
1678 | return ATOM_DCPLL; | ||
1679 | else { | ||
1680 | /* use the same PPLL for all DP monitors */ | ||
1681 | pll = radeon_get_shared_dp_ppll(crtc); | ||
1682 | if (pll != ATOM_PPLL_INVALID) | ||
1683 | return pll; | ||
1540 | } | 1684 | } |
1685 | } else { | ||
1686 | /* use the same PPLL for all monitors with the same clock */ | ||
1687 | pll = radeon_get_shared_nondp_ppll(crtc); | ||
1688 | if (pll != ATOM_PPLL_INVALID) | ||
1689 | return pll; | ||
1541 | } | 1690 | } |
1542 | 1691 | /* all other cases */ | |
1543 | /* otherwise, pick one of the plls */ | 1692 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1544 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | 1693 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
1545 | struct radeon_crtc *radeon_test_crtc; | 1694 | return ATOM_PPLL2; |
1546 | 1695 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | |
1547 | if (crtc == test_crtc) | ||
1548 | continue; | ||
1549 | |||
1550 | radeon_test_crtc = to_radeon_crtc(test_crtc); | ||
1551 | if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && | ||
1552 | (radeon_test_crtc->pll_id <= ATOM_PPLL2)) | ||
1553 | pll_in_use |= (1 << radeon_test_crtc->pll_id); | ||
1554 | } | ||
1555 | if (!(pll_in_use & 1)) | ||
1556 | return ATOM_PPLL1; | 1696 | return ATOM_PPLL1; |
1557 | return ATOM_PPLL2; | 1697 | DRM_ERROR("unable to allocate a PPLL\n"); |
1558 | } else | 1698 | return ATOM_PPLL_INVALID; |
1559 | return radeon_crtc->crtc_id; | 1699 | } else { |
1560 | 1700 | if (ASIC_IS_AVIVO(rdev)) { | |
1701 | /* in DP mode, the DP ref clock can come from either PPLL | ||
1702 | * depending on the asic: | ||
1703 | * DCE3: PPLL1 or PPLL2 | ||
1704 | */ | ||
1705 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { | ||
1706 | /* use the same PPLL for all DP monitors */ | ||
1707 | pll = radeon_get_shared_dp_ppll(crtc); | ||
1708 | if (pll != ATOM_PPLL_INVALID) | ||
1709 | return pll; | ||
1710 | } else { | ||
1711 | /* use the same PPLL for all monitors with the same clock */ | ||
1712 | pll = radeon_get_shared_nondp_ppll(crtc); | ||
1713 | if (pll != ATOM_PPLL_INVALID) | ||
1714 | return pll; | ||
1715 | } | ||
1716 | /* all other cases */ | ||
1717 | pll_in_use = radeon_get_pll_use_mask(crtc); | ||
1718 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
1719 | return ATOM_PPLL2; | ||
1720 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | ||
1721 | return ATOM_PPLL1; | ||
1722 | DRM_ERROR("unable to allocate a PPLL\n"); | ||
1723 | return ATOM_PPLL_INVALID; | ||
1724 | } else { | ||
1725 | /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ | ||
1726 | return radeon_crtc->crtc_id; | ||
1727 | } | ||
1728 | } | ||
1561 | } | 1729 | } |
1562 | 1730 | ||
1563 | void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev) | 1731 | void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev) |
@@ -1588,18 +1756,13 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1588 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1756 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1589 | struct drm_device *dev = crtc->dev; | 1757 | struct drm_device *dev = crtc->dev; |
1590 | struct radeon_device *rdev = dev->dev_private; | 1758 | struct radeon_device *rdev = dev->dev_private; |
1591 | struct drm_encoder *encoder; | 1759 | struct radeon_encoder *radeon_encoder = |
1760 | to_radeon_encoder(radeon_crtc->encoder); | ||
1592 | bool is_tvcv = false; | 1761 | bool is_tvcv = false; |
1593 | 1762 | ||
1594 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1763 | if (radeon_encoder->active_device & |
1595 | /* find tv std */ | 1764 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
1596 | if (encoder->crtc == crtc) { | 1765 | is_tvcv = true; |
1597 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1598 | if (radeon_encoder->active_device & | ||
1599 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
1600 | is_tvcv = true; | ||
1601 | } | ||
1602 | } | ||
1603 | 1766 | ||
1604 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1767 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1605 | 1768 | ||
@@ -1626,8 +1789,34 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
1626 | const struct drm_display_mode *mode, | 1789 | const struct drm_display_mode *mode, |
1627 | struct drm_display_mode *adjusted_mode) | 1790 | struct drm_display_mode *adjusted_mode) |
1628 | { | 1791 | { |
1792 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1793 | struct drm_device *dev = crtc->dev; | ||
1794 | struct drm_encoder *encoder; | ||
1795 | |||
1796 | /* assign the encoder to the radeon crtc to avoid repeated lookups later */ | ||
1797 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
1798 | if (encoder->crtc == crtc) { | ||
1799 | radeon_crtc->encoder = encoder; | ||
1800 | radeon_crtc->connector = radeon_get_connector_for_encoder(encoder); | ||
1801 | break; | ||
1802 | } | ||
1803 | } | ||
1804 | if ((radeon_crtc->encoder == NULL) || (radeon_crtc->connector == NULL)) { | ||
1805 | radeon_crtc->encoder = NULL; | ||
1806 | radeon_crtc->connector = NULL; | ||
1807 | return false; | ||
1808 | } | ||
1629 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) | 1809 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
1630 | return false; | 1810 | return false; |
1811 | if (!atombios_crtc_prepare_pll(crtc, adjusted_mode)) | ||
1812 | return false; | ||
1813 | /* pick pll */ | ||
1814 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); | ||
1815 | /* if we can't get a PPLL for a non-DP encoder, fail */ | ||
1816 | if ((radeon_crtc->pll_id == ATOM_PPLL_INVALID) && | ||
1817 | !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) | ||
1818 | return false; | ||
1819 | |||
1631 | return true; | 1820 | return true; |
1632 | } | 1821 | } |
1633 | 1822 | ||
@@ -1638,8 +1827,6 @@ static void atombios_crtc_prepare(struct drm_crtc *crtc) | |||
1638 | struct radeon_device *rdev = dev->dev_private; | 1827 | struct radeon_device *rdev = dev->dev_private; |
1639 | 1828 | ||
1640 | radeon_crtc->in_mode_set = true; | 1829 | radeon_crtc->in_mode_set = true; |
1641 | /* pick pll */ | ||
1642 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); | ||
1643 | 1830 | ||
1644 | /* disable crtc pair power gating before programming */ | 1831 | /* disable crtc pair power gating before programming */ |
1645 | if (ASIC_IS_DCE6(rdev)) | 1832 | if (ASIC_IS_DCE6(rdev)) |
@@ -1697,7 +1884,10 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
1697 | break; | 1884 | break; |
1698 | } | 1885 | } |
1699 | done: | 1886 | done: |
1700 | radeon_crtc->pll_id = -1; | 1887 | radeon_crtc->pll_id = ATOM_PPLL_INVALID; |
1888 | radeon_crtc->adjusted_clock = 0; | ||
1889 | radeon_crtc->encoder = NULL; | ||
1890 | radeon_crtc->connector = NULL; | ||
1701 | } | 1891 | } |
1702 | 1892 | ||
1703 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | 1893 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { |
@@ -1746,6 +1936,9 @@ void radeon_atombios_init_crtc(struct drm_device *dev, | |||
1746 | else | 1936 | else |
1747 | radeon_crtc->crtc_offset = 0; | 1937 | radeon_crtc->crtc_offset = 0; |
1748 | } | 1938 | } |
1749 | radeon_crtc->pll_id = -1; | 1939 | radeon_crtc->pll_id = ATOM_PPLL_INVALID; |
1940 | radeon_crtc->adjusted_clock = 0; | ||
1941 | radeon_crtc->encoder = NULL; | ||
1942 | radeon_crtc->connector = NULL; | ||
1750 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); | 1943 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); |
1751 | } | 1944 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 6e8803a1170c..806cbcc94fdd 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -28,9 +28,251 @@ | |||
28 | #include "radeon_drm.h" | 28 | #include "radeon_drm.h" |
29 | #include "radeon.h" | 29 | #include "radeon.h" |
30 | #include "atom.h" | 30 | #include "atom.h" |
31 | #include <linux/backlight.h> | ||
31 | 32 | ||
32 | extern int atom_debug; | 33 | extern int atom_debug; |
33 | 34 | ||
35 | static u8 | ||
36 | radeon_atom_get_backlight_level_from_reg(struct radeon_device *rdev) | ||
37 | { | ||
38 | u8 backlight_level; | ||
39 | u32 bios_2_scratch; | ||
40 | |||
41 | if (rdev->family >= CHIP_R600) | ||
42 | bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); | ||
43 | else | ||
44 | bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH); | ||
45 | |||
46 | backlight_level = ((bios_2_scratch & ATOM_S2_CURRENT_BL_LEVEL_MASK) >> | ||
47 | ATOM_S2_CURRENT_BL_LEVEL_SHIFT); | ||
48 | |||
49 | return backlight_level; | ||
50 | } | ||
51 | |||
52 | static void | ||
53 | radeon_atom_set_backlight_level_to_reg(struct radeon_device *rdev, | ||
54 | u8 backlight_level) | ||
55 | { | ||
56 | u32 bios_2_scratch; | ||
57 | |||
58 | if (rdev->family >= CHIP_R600) | ||
59 | bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); | ||
60 | else | ||
61 | bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH); | ||
62 | |||
63 | bios_2_scratch &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK; | ||
64 | bios_2_scratch |= ((backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) & | ||
65 | ATOM_S2_CURRENT_BL_LEVEL_MASK); | ||
66 | |||
67 | if (rdev->family >= CHIP_R600) | ||
68 | WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch); | ||
69 | else | ||
70 | WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch); | ||
71 | } | ||
72 | |||
73 | u8 | ||
74 | atombios_get_backlight_level(struct radeon_encoder *radeon_encoder) | ||
75 | { | ||
76 | struct drm_device *dev = radeon_encoder->base.dev; | ||
77 | struct radeon_device *rdev = dev->dev_private; | ||
78 | |||
79 | if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU)) | ||
80 | return 0; | ||
81 | |||
82 | return radeon_atom_get_backlight_level_from_reg(rdev); | ||
83 | } | ||
84 | |||
85 | void | ||
86 | atombios_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level) | ||
87 | { | ||
88 | struct drm_encoder *encoder = &radeon_encoder->base; | ||
89 | struct drm_device *dev = radeon_encoder->base.dev; | ||
90 | struct radeon_device *rdev = dev->dev_private; | ||
91 | struct radeon_encoder_atom_dig *dig; | ||
92 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; | ||
93 | int index; | ||
94 | |||
95 | if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU)) | ||
96 | return; | ||
97 | |||
98 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) && | ||
99 | radeon_encoder->enc_priv) { | ||
100 | dig = radeon_encoder->enc_priv; | ||
101 | dig->backlight_level = level; | ||
102 | radeon_atom_set_backlight_level_to_reg(rdev, dig->backlight_level); | ||
103 | |||
104 | switch (radeon_encoder->encoder_id) { | ||
105 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
106 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
107 | index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); | ||
108 | if (dig->backlight_level == 0) { | ||
109 | args.ucAction = ATOM_LCD_BLOFF; | ||
110 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
111 | } else { | ||
112 | args.ucAction = ATOM_LCD_BL_BRIGHTNESS_CONTROL; | ||
113 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
114 | args.ucAction = ATOM_LCD_BLON; | ||
115 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
116 | } | ||
117 | break; | ||
118 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
119 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
120 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
121 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
122 | if (dig->backlight_level == 0) | ||
123 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); | ||
124 | else { | ||
125 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_BL_BRIGHTNESS_CONTROL, 0, 0); | ||
126 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); | ||
127 | } | ||
128 | break; | ||
129 | default: | ||
130 | break; | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | ||
136 | |||
137 | static u8 radeon_atom_bl_level(struct backlight_device *bd) | ||
138 | { | ||
139 | u8 level; | ||
140 | |||
141 | /* Convert brightness to hardware level */ | ||
142 | if (bd->props.brightness < 0) | ||
143 | level = 0; | ||
144 | else if (bd->props.brightness > RADEON_MAX_BL_LEVEL) | ||
145 | level = RADEON_MAX_BL_LEVEL; | ||
146 | else | ||
147 | level = bd->props.brightness; | ||
148 | |||
149 | return level; | ||
150 | } | ||
151 | |||
152 | static int radeon_atom_backlight_update_status(struct backlight_device *bd) | ||
153 | { | ||
154 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | ||
155 | struct radeon_encoder *radeon_encoder = pdata->encoder; | ||
156 | |||
157 | atombios_set_backlight_level(radeon_encoder, radeon_atom_bl_level(bd)); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int radeon_atom_backlight_get_brightness(struct backlight_device *bd) | ||
163 | { | ||
164 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | ||
165 | struct radeon_encoder *radeon_encoder = pdata->encoder; | ||
166 | struct drm_device *dev = radeon_encoder->base.dev; | ||
167 | struct radeon_device *rdev = dev->dev_private; | ||
168 | |||
169 | return radeon_atom_get_backlight_level_from_reg(rdev); | ||
170 | } | ||
171 | |||
172 | static const struct backlight_ops radeon_atom_backlight_ops = { | ||
173 | .get_brightness = radeon_atom_backlight_get_brightness, | ||
174 | .update_status = radeon_atom_backlight_update_status, | ||
175 | }; | ||
176 | |||
177 | void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, | ||
178 | struct drm_connector *drm_connector) | ||
179 | { | ||
180 | struct drm_device *dev = radeon_encoder->base.dev; | ||
181 | struct radeon_device *rdev = dev->dev_private; | ||
182 | struct backlight_device *bd; | ||
183 | struct backlight_properties props; | ||
184 | struct radeon_backlight_privdata *pdata; | ||
185 | struct radeon_encoder_atom_dig *dig; | ||
186 | u8 backlight_level; | ||
187 | |||
188 | if (!radeon_encoder->enc_priv) | ||
189 | return; | ||
190 | |||
191 | if (!rdev->is_atom_bios) | ||
192 | return; | ||
193 | |||
194 | if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU)) | ||
195 | return; | ||
196 | |||
197 | pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL); | ||
198 | if (!pdata) { | ||
199 | DRM_ERROR("Memory allocation failed\n"); | ||
200 | goto error; | ||
201 | } | ||
202 | |||
203 | memset(&props, 0, sizeof(props)); | ||
204 | props.max_brightness = RADEON_MAX_BL_LEVEL; | ||
205 | props.type = BACKLIGHT_RAW; | ||
206 | bd = backlight_device_register("radeon_bl", &drm_connector->kdev, | ||
207 | pdata, &radeon_atom_backlight_ops, &props); | ||
208 | if (IS_ERR(bd)) { | ||
209 | DRM_ERROR("Backlight registration failed\n"); | ||
210 | goto error; | ||
211 | } | ||
212 | |||
213 | pdata->encoder = radeon_encoder; | ||
214 | |||
215 | backlight_level = radeon_atom_get_backlight_level_from_reg(rdev); | ||
216 | |||
217 | dig = radeon_encoder->enc_priv; | ||
218 | dig->bl_dev = bd; | ||
219 | |||
220 | bd->props.brightness = radeon_atom_backlight_get_brightness(bd); | ||
221 | bd->props.power = FB_BLANK_UNBLANK; | ||
222 | backlight_update_status(bd); | ||
223 | |||
224 | DRM_INFO("radeon atom DIG backlight initialized\n"); | ||
225 | |||
226 | return; | ||
227 | |||
228 | error: | ||
229 | kfree(pdata); | ||
230 | return; | ||
231 | } | ||
232 | |||
233 | static void radeon_atom_backlight_exit(struct radeon_encoder *radeon_encoder) | ||
234 | { | ||
235 | struct drm_device *dev = radeon_encoder->base.dev; | ||
236 | struct radeon_device *rdev = dev->dev_private; | ||
237 | struct backlight_device *bd = NULL; | ||
238 | struct radeon_encoder_atom_dig *dig; | ||
239 | |||
240 | if (!radeon_encoder->enc_priv) | ||
241 | return; | ||
242 | |||
243 | if (!rdev->is_atom_bios) | ||
244 | return; | ||
245 | |||
246 | if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU)) | ||
247 | return; | ||
248 | |||
249 | dig = radeon_encoder->enc_priv; | ||
250 | bd = dig->bl_dev; | ||
251 | dig->bl_dev = NULL; | ||
252 | |||
253 | if (bd) { | ||
254 | struct radeon_legacy_backlight_privdata *pdata; | ||
255 | |||
256 | pdata = bl_get_data(bd); | ||
257 | backlight_device_unregister(bd); | ||
258 | kfree(pdata); | ||
259 | |||
260 | DRM_INFO("radeon atom LVDS backlight unloaded\n"); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | #else /* !CONFIG_BACKLIGHT_CLASS_DEVICE */ | ||
265 | |||
266 | void radeon_atom_backlight_init(struct radeon_encoder *encoder) | ||
267 | { | ||
268 | } | ||
269 | |||
270 | static void radeon_atom_backlight_exit(struct radeon_encoder *encoder) | ||
271 | { | ||
272 | } | ||
273 | |||
274 | #endif | ||
275 | |||
34 | /* evil but including atombios.h is much worse */ | 276 | /* evil but including atombios.h is much worse */ |
35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | 277 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
36 | struct drm_display_mode *mode); | 278 | struct drm_display_mode *mode); |
@@ -209,6 +451,32 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) | |||
209 | 451 | ||
210 | } | 452 | } |
211 | 453 | ||
454 | static u8 radeon_atom_get_bpc(struct drm_encoder *encoder) | ||
455 | { | ||
456 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
457 | int bpc = 8; | ||
458 | |||
459 | if (connector) | ||
460 | bpc = radeon_get_monitor_bpc(connector); | ||
461 | |||
462 | switch (bpc) { | ||
463 | case 0: | ||
464 | return PANEL_BPC_UNDEFINE; | ||
465 | case 6: | ||
466 | return PANEL_6BIT_PER_COLOR; | ||
467 | case 8: | ||
468 | default: | ||
469 | return PANEL_8BIT_PER_COLOR; | ||
470 | case 10: | ||
471 | return PANEL_10BIT_PER_COLOR; | ||
472 | case 12: | ||
473 | return PANEL_12BIT_PER_COLOR; | ||
474 | case 16: | ||
475 | return PANEL_16BIT_PER_COLOR; | ||
476 | } | ||
477 | } | ||
478 | |||
479 | |||
212 | union dvo_encoder_control { | 480 | union dvo_encoder_control { |
213 | ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds; | 481 | ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds; |
214 | DVO_ENCODER_CONTROL_PS_ALLOCATION dvo; | 482 | DVO_ENCODER_CONTROL_PS_ALLOCATION dvo; |
@@ -406,7 +674,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
406 | return ATOM_ENCODER_MODE_DP; | 674 | return ATOM_ENCODER_MODE_DP; |
407 | 675 | ||
408 | /* DVO is always DVO */ | 676 | /* DVO is always DVO */ |
409 | if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO) | 677 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DVO1) || |
678 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)) | ||
410 | return ATOM_ENCODER_MODE_DVO; | 679 | return ATOM_ENCODER_MODE_DVO; |
411 | 680 | ||
412 | connector = radeon_get_connector_for_encoder(encoder); | 681 | connector = radeon_get_connector_for_encoder(encoder); |
@@ -535,7 +804,6 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
535 | int dp_clock = 0; | 804 | int dp_clock = 0; |
536 | int dp_lane_count = 0; | 805 | int dp_lane_count = 0; |
537 | int hpd_id = RADEON_HPD_NONE; | 806 | int hpd_id = RADEON_HPD_NONE; |
538 | int bpc = 8; | ||
539 | 807 | ||
540 | if (connector) { | 808 | if (connector) { |
541 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 809 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -545,7 +813,6 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
545 | dp_clock = dig_connector->dp_clock; | 813 | dp_clock = dig_connector->dp_clock; |
546 | dp_lane_count = dig_connector->dp_lane_count; | 814 | dp_lane_count = dig_connector->dp_lane_count; |
547 | hpd_id = radeon_connector->hpd.hpd; | 815 | hpd_id = radeon_connector->hpd.hpd; |
548 | bpc = radeon_get_monitor_bpc(connector); | ||
549 | } | 816 | } |
550 | 817 | ||
551 | /* no dig encoder assigned */ | 818 | /* no dig encoder assigned */ |
@@ -612,37 +879,17 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
612 | else | 879 | else |
613 | args.v3.ucEncoderMode = atombios_get_encoder_mode(encoder); | 880 | args.v3.ucEncoderMode = atombios_get_encoder_mode(encoder); |
614 | 881 | ||
615 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 882 | if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode)) |
616 | args.v3.ucLaneNum = dp_lane_count; | 883 | args.v3.ucLaneNum = dp_lane_count; |
617 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) | 884 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
618 | args.v3.ucLaneNum = 8; | 885 | args.v3.ucLaneNum = 8; |
619 | else | 886 | else |
620 | args.v3.ucLaneNum = 4; | 887 | args.v3.ucLaneNum = 4; |
621 | 888 | ||
622 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000)) | 889 | if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode) && (dp_clock == 270000)) |
623 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | 890 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; |
624 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | 891 | args.v3.acConfig.ucDigSel = dig->dig_encoder; |
625 | switch (bpc) { | 892 | args.v3.ucBitPerColor = radeon_atom_get_bpc(encoder); |
626 | case 0: | ||
627 | args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
628 | break; | ||
629 | case 6: | ||
630 | args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
631 | break; | ||
632 | case 8: | ||
633 | default: | ||
634 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
635 | break; | ||
636 | case 10: | ||
637 | args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
638 | break; | ||
639 | case 12: | ||
640 | args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
641 | break; | ||
642 | case 16: | ||
643 | args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
644 | break; | ||
645 | } | ||
646 | break; | 893 | break; |
647 | case 4: | 894 | case 4: |
648 | args.v4.ucAction = action; | 895 | args.v4.ucAction = action; |
@@ -652,41 +899,21 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
652 | else | 899 | else |
653 | args.v4.ucEncoderMode = atombios_get_encoder_mode(encoder); | 900 | args.v4.ucEncoderMode = atombios_get_encoder_mode(encoder); |
654 | 901 | ||
655 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 902 | if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode)) |
656 | args.v4.ucLaneNum = dp_lane_count; | 903 | args.v4.ucLaneNum = dp_lane_count; |
657 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) | 904 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
658 | args.v4.ucLaneNum = 8; | 905 | args.v4.ucLaneNum = 8; |
659 | else | 906 | else |
660 | args.v4.ucLaneNum = 4; | 907 | args.v4.ucLaneNum = 4; |
661 | 908 | ||
662 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) { | 909 | if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode)) { |
663 | if (dp_clock == 270000) | 910 | if (dp_clock == 270000) |
664 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; | 911 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; |
665 | else if (dp_clock == 540000) | 912 | else if (dp_clock == 540000) |
666 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; | 913 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; |
667 | } | 914 | } |
668 | args.v4.acConfig.ucDigSel = dig->dig_encoder; | 915 | args.v4.acConfig.ucDigSel = dig->dig_encoder; |
669 | switch (bpc) { | 916 | args.v4.ucBitPerColor = radeon_atom_get_bpc(encoder); |
670 | case 0: | ||
671 | args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
672 | break; | ||
673 | case 6: | ||
674 | args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
675 | break; | ||
676 | case 8: | ||
677 | default: | ||
678 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
679 | break; | ||
680 | case 10: | ||
681 | args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
682 | break; | ||
683 | case 12: | ||
684 | args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
685 | break; | ||
686 | case 16: | ||
687 | args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
688 | break; | ||
689 | } | ||
690 | if (hpd_id == RADEON_HPD_NONE) | 917 | if (hpd_id == RADEON_HPD_NONE) |
691 | args.v4.ucHPD_ID = 0; | 918 | args.v4.ucHPD_ID = 0; |
692 | else | 919 | else |
@@ -799,8 +1026,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
799 | args.v1.asMode.ucLaneSet = lane_set; | 1026 | args.v1.asMode.ucLaneSet = lane_set; |
800 | } else { | 1027 | } else { |
801 | if (is_dp) | 1028 | if (is_dp) |
802 | args.v1.usPixelClock = | 1029 | args.v1.usPixelClock = cpu_to_le16(dp_clock / 10); |
803 | cpu_to_le16(dp_clock / 10); | ||
804 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) | 1030 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
805 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 1031 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
806 | else | 1032 | else |
@@ -857,8 +1083,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
857 | args.v2.asMode.ucLaneSet = lane_set; | 1083 | args.v2.asMode.ucLaneSet = lane_set; |
858 | } else { | 1084 | } else { |
859 | if (is_dp) | 1085 | if (is_dp) |
860 | args.v2.usPixelClock = | 1086 | args.v2.usPixelClock = cpu_to_le16(dp_clock / 10); |
861 | cpu_to_le16(dp_clock / 10); | ||
862 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) | 1087 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
863 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 1088 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
864 | else | 1089 | else |
@@ -900,8 +1125,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
900 | args.v3.asMode.ucLaneSet = lane_set; | 1125 | args.v3.asMode.ucLaneSet = lane_set; |
901 | } else { | 1126 | } else { |
902 | if (is_dp) | 1127 | if (is_dp) |
903 | args.v3.usPixelClock = | 1128 | args.v3.usPixelClock = cpu_to_le16(dp_clock / 10); |
904 | cpu_to_le16(dp_clock / 10); | ||
905 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) | 1129 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
906 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 1130 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
907 | else | 1131 | else |
@@ -960,8 +1184,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
960 | args.v4.asMode.ucLaneSet = lane_set; | 1184 | args.v4.asMode.ucLaneSet = lane_set; |
961 | } else { | 1185 | } else { |
962 | if (is_dp) | 1186 | if (is_dp) |
963 | args.v4.usPixelClock = | 1187 | args.v4.usPixelClock = cpu_to_le16(dp_clock / 10); |
964 | cpu_to_le16(dp_clock / 10); | ||
965 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) | 1188 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
966 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 1189 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
967 | else | 1190 | else |
@@ -1147,7 +1370,6 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1147 | int dp_lane_count = 0; | 1370 | int dp_lane_count = 0; |
1148 | int connector_object_id = 0; | 1371 | int connector_object_id = 0; |
1149 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | 1372 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; |
1150 | int bpc = 8; | ||
1151 | 1373 | ||
1152 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | 1374 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) |
1153 | connector = radeon_get_connector_for_encoder_init(encoder); | 1375 | connector = radeon_get_connector_for_encoder_init(encoder); |
@@ -1163,7 +1385,6 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1163 | dp_lane_count = dig_connector->dp_lane_count; | 1385 | dp_lane_count = dig_connector->dp_lane_count; |
1164 | connector_object_id = | 1386 | connector_object_id = |
1165 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | 1387 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; |
1166 | bpc = radeon_get_monitor_bpc(connector); | ||
1167 | } | 1388 | } |
1168 | 1389 | ||
1169 | memset(&args, 0, sizeof(args)); | 1390 | memset(&args, 0, sizeof(args)); |
@@ -1221,27 +1442,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1221 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; | 1442 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; |
1222 | break; | 1443 | break; |
1223 | } | 1444 | } |
1224 | switch (bpc) { | 1445 | args.v3.sExtEncoder.ucBitPerColor = radeon_atom_get_bpc(encoder); |
1225 | case 0: | ||
1226 | args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
1227 | break; | ||
1228 | case 6: | ||
1229 | args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
1230 | break; | ||
1231 | case 8: | ||
1232 | default: | ||
1233 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
1234 | break; | ||
1235 | case 10: | ||
1236 | args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
1237 | break; | ||
1238 | case 12: | ||
1239 | args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
1240 | break; | ||
1241 | case 16: | ||
1242 | args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
1243 | break; | ||
1244 | } | ||
1245 | break; | 1446 | break; |
1246 | default: | 1447 | default: |
1247 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | 1448 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); |
@@ -2286,6 +2487,8 @@ static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = { | |||
2286 | void radeon_enc_destroy(struct drm_encoder *encoder) | 2487 | void radeon_enc_destroy(struct drm_encoder *encoder) |
2287 | { | 2488 | { |
2288 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 2489 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
2490 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | ||
2491 | radeon_atom_backlight_exit(radeon_encoder); | ||
2289 | kfree(radeon_encoder->enc_priv); | 2492 | kfree(radeon_encoder->enc_priv); |
2290 | drm_encoder_cleanup(encoder); | 2493 | drm_encoder_cleanup(encoder); |
2291 | kfree(radeon_encoder); | 2494 | kfree(radeon_encoder); |
@@ -2295,7 +2498,7 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = { | |||
2295 | .destroy = radeon_enc_destroy, | 2498 | .destroy = radeon_enc_destroy, |
2296 | }; | 2499 | }; |
2297 | 2500 | ||
2298 | struct radeon_encoder_atom_dac * | 2501 | static struct radeon_encoder_atom_dac * |
2299 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | 2502 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) |
2300 | { | 2503 | { |
2301 | struct drm_device *dev = radeon_encoder->base.dev; | 2504 | struct drm_device *dev = radeon_encoder->base.dev; |
@@ -2309,7 +2512,7 @@ radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | |||
2309 | return dac; | 2512 | return dac; |
2310 | } | 2513 | } |
2311 | 2514 | ||
2312 | struct radeon_encoder_atom_dig * | 2515 | static struct radeon_encoder_atom_dig * |
2313 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | 2516 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) |
2314 | { | 2517 | { |
2315 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | 2518 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e93b80a6d4e9..c4ded396b78d 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -37,6 +37,16 @@ | |||
37 | #define EVERGREEN_PFP_UCODE_SIZE 1120 | 37 | #define EVERGREEN_PFP_UCODE_SIZE 1120 |
38 | #define EVERGREEN_PM4_UCODE_SIZE 1376 | 38 | #define EVERGREEN_PM4_UCODE_SIZE 1376 |
39 | 39 | ||
40 | static const u32 crtc_offsets[6] = | ||
41 | { | ||
42 | EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
43 | EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
44 | EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
45 | EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
46 | EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
47 | EVERGREEN_CRTC5_REGISTER_OFFSET | ||
48 | }; | ||
49 | |||
40 | static void evergreen_gpu_init(struct radeon_device *rdev); | 50 | static void evergreen_gpu_init(struct radeon_device *rdev); |
41 | void evergreen_fini(struct radeon_device *rdev); | 51 | void evergreen_fini(struct radeon_device *rdev); |
42 | void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | 52 | void evergreen_pcie_gen2_enable(struct radeon_device *rdev); |
@@ -109,17 +119,19 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) | |||
109 | */ | 119 | */ |
110 | void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) | 120 | void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) |
111 | { | 121 | { |
112 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; | ||
113 | int i; | 122 | int i; |
114 | 123 | ||
115 | if (RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_MASTER_EN) { | 124 | if (crtc >= rdev->num_crtc) |
125 | return; | ||
126 | |||
127 | if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN) { | ||
116 | for (i = 0; i < rdev->usec_timeout; i++) { | 128 | for (i = 0; i < rdev->usec_timeout; i++) { |
117 | if (!(RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK)) | 129 | if (!(RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)) |
118 | break; | 130 | break; |
119 | udelay(1); | 131 | udelay(1); |
120 | } | 132 | } |
121 | for (i = 0; i < rdev->usec_timeout; i++) { | 133 | for (i = 0; i < rdev->usec_timeout; i++) { |
122 | if (RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK) | 134 | if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) |
123 | break; | 135 | break; |
124 | udelay(1); | 136 | udelay(1); |
125 | } | 137 | } |
@@ -314,6 +326,64 @@ void sumo_pm_init_profile(struct radeon_device *rdev) | |||
314 | } | 326 | } |
315 | 327 | ||
316 | /** | 328 | /** |
329 | * btc_pm_init_profile - Initialize power profiles callback. | ||
330 | * | ||
331 | * @rdev: radeon_device pointer | ||
332 | * | ||
333 | * Initialize the power states used in profile mode | ||
334 | * (BTC, cayman). | ||
335 | * Used for profile mode only. | ||
336 | */ | ||
337 | void btc_pm_init_profile(struct radeon_device *rdev) | ||
338 | { | ||
339 | int idx; | ||
340 | |||
341 | /* default */ | ||
342 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; | ||
343 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; | ||
344 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; | ||
345 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; | ||
346 | /* starting with BTC, there is one state that is used for both | ||
347 | * MH and SH. Difference is that we always use the high clock index for | ||
348 | * mclk. | ||
349 | */ | ||
350 | if (rdev->flags & RADEON_IS_MOBILITY) | ||
351 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | ||
352 | else | ||
353 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
354 | /* low sh */ | ||
355 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; | ||
356 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; | ||
357 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; | ||
358 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; | ||
359 | /* mid sh */ | ||
360 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; | ||
361 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; | ||
362 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; | ||
363 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; | ||
364 | /* high sh */ | ||
365 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; | ||
366 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; | ||
367 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; | ||
368 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; | ||
369 | /* low mh */ | ||
370 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; | ||
371 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; | ||
372 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; | ||
373 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; | ||
374 | /* mid mh */ | ||
375 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; | ||
376 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; | ||
377 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; | ||
378 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; | ||
379 | /* high mh */ | ||
380 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; | ||
381 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; | ||
382 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; | ||
383 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; | ||
384 | } | ||
385 | |||
386 | /** | ||
317 | * evergreen_pm_misc - set additional pm hw parameters callback. | 387 | * evergreen_pm_misc - set additional pm hw parameters callback. |
318 | * | 388 | * |
319 | * @rdev: radeon_device pointer | 389 | * @rdev: radeon_device pointer |
@@ -1109,7 +1179,7 @@ void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
1109 | } | 1179 | } |
1110 | } | 1180 | } |
1111 | 1181 | ||
1112 | int evergreen_pcie_gart_enable(struct radeon_device *rdev) | 1182 | static int evergreen_pcie_gart_enable(struct radeon_device *rdev) |
1113 | { | 1183 | { |
1114 | u32 tmp; | 1184 | u32 tmp; |
1115 | int r; | 1185 | int r; |
@@ -1168,7 +1238,7 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) | |||
1168 | return 0; | 1238 | return 0; |
1169 | } | 1239 | } |
1170 | 1240 | ||
1171 | void evergreen_pcie_gart_disable(struct radeon_device *rdev) | 1241 | static void evergreen_pcie_gart_disable(struct radeon_device *rdev) |
1172 | { | 1242 | { |
1173 | u32 tmp; | 1243 | u32 tmp; |
1174 | 1244 | ||
@@ -1193,7 +1263,7 @@ void evergreen_pcie_gart_disable(struct radeon_device *rdev) | |||
1193 | radeon_gart_table_vram_unpin(rdev); | 1263 | radeon_gart_table_vram_unpin(rdev); |
1194 | } | 1264 | } |
1195 | 1265 | ||
1196 | void evergreen_pcie_gart_fini(struct radeon_device *rdev) | 1266 | static void evergreen_pcie_gart_fini(struct radeon_device *rdev) |
1197 | { | 1267 | { |
1198 | evergreen_pcie_gart_disable(rdev); | 1268 | evergreen_pcie_gart_disable(rdev); |
1199 | radeon_gart_table_vram_free(rdev); | 1269 | radeon_gart_table_vram_free(rdev); |
@@ -1201,7 +1271,7 @@ void evergreen_pcie_gart_fini(struct radeon_device *rdev) | |||
1201 | } | 1271 | } |
1202 | 1272 | ||
1203 | 1273 | ||
1204 | void evergreen_agp_enable(struct radeon_device *rdev) | 1274 | static void evergreen_agp_enable(struct radeon_device *rdev) |
1205 | { | 1275 | { |
1206 | u32 tmp; | 1276 | u32 tmp; |
1207 | 1277 | ||
@@ -1229,116 +1299,103 @@ void evergreen_agp_enable(struct radeon_device *rdev) | |||
1229 | 1299 | ||
1230 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1300 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
1231 | { | 1301 | { |
1302 | u32 crtc_enabled, tmp, frame_count, blackout; | ||
1303 | int i, j; | ||
1304 | |||
1232 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 1305 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
1233 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 1306 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
1234 | 1307 | ||
1235 | /* Stop all video */ | 1308 | /* disable VGA render */ |
1236 | WREG32(VGA_RENDER_CONTROL, 0); | 1309 | WREG32(VGA_RENDER_CONTROL, 0); |
1237 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | 1310 | /* blank the display controllers */ |
1238 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | 1311 | for (i = 0; i < rdev->num_crtc; i++) { |
1239 | if (rdev->num_crtc >= 4) { | 1312 | crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN; |
1240 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | 1313 | if (crtc_enabled) { |
1241 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | 1314 | save->crtc_enabled[i] = true; |
1242 | } | 1315 | if (ASIC_IS_DCE6(rdev)) { |
1243 | if (rdev->num_crtc >= 6) { | 1316 | tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); |
1244 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | 1317 | if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) { |
1245 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | 1318 | radeon_wait_for_vblank(rdev, i); |
1246 | } | 1319 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; |
1247 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1320 | WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); |
1248 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1321 | } |
1249 | if (rdev->num_crtc >= 4) { | 1322 | } else { |
1250 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 1323 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); |
1251 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 1324 | if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) { |
1252 | } | 1325 | radeon_wait_for_vblank(rdev, i); |
1253 | if (rdev->num_crtc >= 6) { | 1326 | tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; |
1254 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 1327 | WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); |
1255 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 1328 | } |
1256 | } | 1329 | } |
1257 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1330 | /* wait for the next frame */ |
1258 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1331 | frame_count = radeon_get_vblank_counter(rdev, i); |
1259 | if (rdev->num_crtc >= 4) { | 1332 | for (j = 0; j < rdev->usec_timeout; j++) { |
1260 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 1333 | if (radeon_get_vblank_counter(rdev, i) != frame_count) |
1261 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 1334 | break; |
1262 | } | 1335 | udelay(1); |
1263 | if (rdev->num_crtc >= 6) { | 1336 | } |
1264 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 1337 | } |
1265 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
1266 | } | 1338 | } |
1267 | 1339 | ||
1268 | WREG32(D1VGA_CONTROL, 0); | 1340 | radeon_mc_wait_for_idle(rdev); |
1269 | WREG32(D2VGA_CONTROL, 0); | 1341 | |
1270 | if (rdev->num_crtc >= 4) { | 1342 | blackout = RREG32(MC_SHARED_BLACKOUT_CNTL); |
1271 | WREG32(EVERGREEN_D3VGA_CONTROL, 0); | 1343 | if ((blackout & BLACKOUT_MODE_MASK) != 1) { |
1272 | WREG32(EVERGREEN_D4VGA_CONTROL, 0); | 1344 | /* Block CPU access */ |
1273 | } | 1345 | WREG32(BIF_FB_EN, 0); |
1274 | if (rdev->num_crtc >= 6) { | 1346 | /* blackout the MC */ |
1275 | WREG32(EVERGREEN_D5VGA_CONTROL, 0); | 1347 | blackout &= ~BLACKOUT_MODE_MASK; |
1276 | WREG32(EVERGREEN_D6VGA_CONTROL, 0); | 1348 | WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1); |
1277 | } | 1349 | } |
1278 | } | 1350 | } |
1279 | 1351 | ||
1280 | void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1352 | void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) |
1281 | { | 1353 | { |
1282 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, | 1354 | u32 tmp, frame_count; |
1283 | upper_32_bits(rdev->mc.vram_start)); | 1355 | int i, j; |
1284 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
1285 | upper_32_bits(rdev->mc.vram_start)); | ||
1286 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
1287 | (u32)rdev->mc.vram_start); | ||
1288 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
1289 | (u32)rdev->mc.vram_start); | ||
1290 | |||
1291 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
1292 | upper_32_bits(rdev->mc.vram_start)); | ||
1293 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
1294 | upper_32_bits(rdev->mc.vram_start)); | ||
1295 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
1296 | (u32)rdev->mc.vram_start); | ||
1297 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
1298 | (u32)rdev->mc.vram_start); | ||
1299 | |||
1300 | if (rdev->num_crtc >= 4) { | ||
1301 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
1302 | upper_32_bits(rdev->mc.vram_start)); | ||
1303 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
1304 | upper_32_bits(rdev->mc.vram_start)); | ||
1305 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
1306 | (u32)rdev->mc.vram_start); | ||
1307 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
1308 | (u32)rdev->mc.vram_start); | ||
1309 | |||
1310 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
1311 | upper_32_bits(rdev->mc.vram_start)); | ||
1312 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
1313 | upper_32_bits(rdev->mc.vram_start)); | ||
1314 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
1315 | (u32)rdev->mc.vram_start); | ||
1316 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
1317 | (u32)rdev->mc.vram_start); | ||
1318 | } | ||
1319 | if (rdev->num_crtc >= 6) { | ||
1320 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
1321 | upper_32_bits(rdev->mc.vram_start)); | ||
1322 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
1323 | upper_32_bits(rdev->mc.vram_start)); | ||
1324 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
1325 | (u32)rdev->mc.vram_start); | ||
1326 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
1327 | (u32)rdev->mc.vram_start); | ||
1328 | 1356 | ||
1329 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1357 | /* update crtc base addresses */ |
1358 | for (i = 0; i < rdev->num_crtc; i++) { | ||
1359 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], | ||
1330 | upper_32_bits(rdev->mc.vram_start)); | 1360 | upper_32_bits(rdev->mc.vram_start)); |
1331 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1361 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], |
1332 | upper_32_bits(rdev->mc.vram_start)); | 1362 | upper_32_bits(rdev->mc.vram_start)); |
1333 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1363 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], |
1334 | (u32)rdev->mc.vram_start); | 1364 | (u32)rdev->mc.vram_start); |
1335 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, | 1365 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], |
1336 | (u32)rdev->mc.vram_start); | 1366 | (u32)rdev->mc.vram_start); |
1337 | } | 1367 | } |
1338 | |||
1339 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); | 1368 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); |
1340 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); | 1369 | WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); |
1341 | /* Unlock host access */ | 1370 | |
1371 | /* unblackout the MC */ | ||
1372 | tmp = RREG32(MC_SHARED_BLACKOUT_CNTL); | ||
1373 | tmp &= ~BLACKOUT_MODE_MASK; | ||
1374 | WREG32(MC_SHARED_BLACKOUT_CNTL, tmp); | ||
1375 | /* allow CPU access */ | ||
1376 | WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); | ||
1377 | |||
1378 | for (i = 0; i < rdev->num_crtc; i++) { | ||
1379 | if (save->crtc_enabled) { | ||
1380 | if (ASIC_IS_DCE6(rdev)) { | ||
1381 | tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); | ||
1382 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; | ||
1383 | WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); | ||
1384 | } else { | ||
1385 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); | ||
1386 | tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; | ||
1387 | WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); | ||
1388 | } | ||
1389 | /* wait for the next frame */ | ||
1390 | frame_count = radeon_get_vblank_counter(rdev, i); | ||
1391 | for (j = 0; j < rdev->usec_timeout; j++) { | ||
1392 | if (radeon_get_vblank_counter(rdev, i) != frame_count) | ||
1393 | break; | ||
1394 | udelay(1); | ||
1395 | } | ||
1396 | } | ||
1397 | } | ||
1398 | /* Unlock vga access */ | ||
1342 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); | 1399 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); |
1343 | mdelay(1); | 1400 | mdelay(1); |
1344 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | 1401 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); |
@@ -1557,7 +1614,7 @@ static int evergreen_cp_start(struct radeon_device *rdev) | |||
1557 | return 0; | 1614 | return 0; |
1558 | } | 1615 | } |
1559 | 1616 | ||
1560 | int evergreen_cp_resume(struct radeon_device *rdev) | 1617 | static int evergreen_cp_resume(struct radeon_device *rdev) |
1561 | { | 1618 | { |
1562 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 1619 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
1563 | u32 tmp; | 1620 | u32 tmp; |
@@ -2333,22 +2390,10 @@ int evergreen_asic_reset(struct radeon_device *rdev) | |||
2333 | 2390 | ||
2334 | u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc) | 2391 | u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc) |
2335 | { | 2392 | { |
2336 | switch (crtc) { | 2393 | if (crtc >= rdev->num_crtc) |
2337 | case 0: | ||
2338 | return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
2339 | case 1: | ||
2340 | return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
2341 | case 2: | ||
2342 | return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
2343 | case 3: | ||
2344 | return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
2345 | case 4: | ||
2346 | return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
2347 | case 5: | ||
2348 | return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
2349 | default: | ||
2350 | return 0; | 2394 | return 0; |
2351 | } | 2395 | else |
2396 | return RREG32(CRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]); | ||
2352 | } | 2397 | } |
2353 | 2398 | ||
2354 | void evergreen_disable_interrupt_state(struct radeon_device *rdev) | 2399 | void evergreen_disable_interrupt_state(struct radeon_device *rdev) |
@@ -2541,10 +2586,6 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2541 | DRM_DEBUG("evergreen_irq_set: hdmi 5\n"); | 2586 | DRM_DEBUG("evergreen_irq_set: hdmi 5\n"); |
2542 | afmt6 |= AFMT_AZ_FORMAT_WTRIG_MASK; | 2587 | afmt6 |= AFMT_AZ_FORMAT_WTRIG_MASK; |
2543 | } | 2588 | } |
2544 | if (rdev->irq.gui_idle) { | ||
2545 | DRM_DEBUG("gui idle\n"); | ||
2546 | grbm_int_cntl |= GUI_IDLE_INT_ENABLE; | ||
2547 | } | ||
2548 | 2589 | ||
2549 | if (rdev->family >= CHIP_CAYMAN) { | 2590 | if (rdev->family >= CHIP_CAYMAN) { |
2550 | cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl); | 2591 | cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl); |
@@ -2726,7 +2767,7 @@ static void evergreen_irq_ack(struct radeon_device *rdev) | |||
2726 | } | 2767 | } |
2727 | } | 2768 | } |
2728 | 2769 | ||
2729 | void evergreen_irq_disable(struct radeon_device *rdev) | 2770 | static void evergreen_irq_disable(struct radeon_device *rdev) |
2730 | { | 2771 | { |
2731 | r600_disable_interrupts(rdev); | 2772 | r600_disable_interrupts(rdev); |
2732 | /* Wait and acknowledge irq */ | 2773 | /* Wait and acknowledge irq */ |
@@ -3079,7 +3120,6 @@ restart_ih: | |||
3079 | break; | 3120 | break; |
3080 | case 233: /* GUI IDLE */ | 3121 | case 233: /* GUI IDLE */ |
3081 | DRM_DEBUG("IH: GUI idle\n"); | 3122 | DRM_DEBUG("IH: GUI idle\n"); |
3082 | wake_up(&rdev->irq.idle_queue); | ||
3083 | break; | 3123 | break; |
3084 | default: | 3124 | default: |
3085 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | 3125 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index e44a62a07fe3..2ceab2b52d69 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -846,6 +846,16 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, | |||
846 | return -EINVAL; | 846 | return -EINVAL; |
847 | } | 847 | } |
848 | 848 | ||
849 | if (!mipmap) { | ||
850 | if (llevel) { | ||
851 | dev_warn(p->dev, "%s:%i got NULL MIP_ADDRESS relocation\n", | ||
852 | __func__, __LINE__); | ||
853 | return -EINVAL; | ||
854 | } else { | ||
855 | return 0; /* everything's ok */ | ||
856 | } | ||
857 | } | ||
858 | |||
849 | /* check mipmap size */ | 859 | /* check mipmap size */ |
850 | for (i = 1; i <= llevel; i++) { | 860 | for (i = 1; i <= llevel; i++) { |
851 | unsigned w, h, d; | 861 | unsigned w, h, d; |
@@ -995,7 +1005,7 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) | |||
995 | * Assume that chunk_ib_index is properly set. Will return -EINVAL | 1005 | * Assume that chunk_ib_index is properly set. Will return -EINVAL |
996 | * if packet is bigger than remaining ib size. or if packets is unknown. | 1006 | * if packet is bigger than remaining ib size. or if packets is unknown. |
997 | **/ | 1007 | **/ |
998 | int evergreen_cs_packet_parse(struct radeon_cs_parser *p, | 1008 | static int evergreen_cs_packet_parse(struct radeon_cs_parser *p, |
999 | struct radeon_cs_packet *pkt, | 1009 | struct radeon_cs_packet *pkt, |
1000 | unsigned idx) | 1010 | unsigned idx) |
1001 | { | 1011 | { |
@@ -1081,6 +1091,27 @@ static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, | |||
1081 | } | 1091 | } |
1082 | 1092 | ||
1083 | /** | 1093 | /** |
1094 | * evergreen_cs_packet_next_is_pkt3_nop() - test if the next packet is NOP | ||
1095 | * @p: structure holding the parser context. | ||
1096 | * | ||
1097 | * Check if the next packet is a relocation packet3. | ||
1098 | **/ | ||
1099 | static bool evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) | ||
1100 | { | ||
1101 | struct radeon_cs_packet p3reloc; | ||
1102 | int r; | ||
1103 | |||
1104 | r = evergreen_cs_packet_parse(p, &p3reloc, p->idx); | ||
1105 | if (r) { | ||
1106 | return false; | ||
1107 | } | ||
1108 | if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { | ||
1109 | return false; | ||
1110 | } | ||
1111 | return true; | ||
1112 | } | ||
1113 | |||
1114 | /** | ||
1084 | * evergreen_cs_packet_next_vline() - parse userspace VLINE packet | 1115 | * evergreen_cs_packet_next_vline() - parse userspace VLINE packet |
1085 | * @parser: parser structure holding parsing context. | 1116 | * @parser: parser structure holding parsing context. |
1086 | * | 1117 | * |
@@ -2330,7 +2361,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2330 | for (i = 0; i < (pkt->count / 8); i++) { | 2361 | for (i = 0; i < (pkt->count / 8); i++) { |
2331 | struct radeon_bo *texture, *mipmap; | 2362 | struct radeon_bo *texture, *mipmap; |
2332 | u32 toffset, moffset; | 2363 | u32 toffset, moffset; |
2333 | u32 size, offset; | 2364 | u32 size, offset, mip_address, tex_dim; |
2334 | 2365 | ||
2335 | switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { | 2366 | switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { |
2336 | case SQ_TEX_VTX_VALID_TEXTURE: | 2367 | case SQ_TEX_VTX_VALID_TEXTURE: |
@@ -2359,14 +2390,28 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2359 | } | 2390 | } |
2360 | texture = reloc->robj; | 2391 | texture = reloc->robj; |
2361 | toffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 2392 | toffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
2393 | |||
2362 | /* tex mip base */ | 2394 | /* tex mip base */ |
2363 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2395 | tex_dim = ib[idx+1+(i*8)+0] & 0x7; |
2364 | if (r) { | 2396 | mip_address = ib[idx+1+(i*8)+3]; |
2365 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); | 2397 | |
2366 | return -EINVAL; | 2398 | if ((tex_dim == SQ_TEX_DIM_2D_MSAA || tex_dim == SQ_TEX_DIM_2D_ARRAY_MSAA) && |
2399 | !mip_address && | ||
2400 | !evergreen_cs_packet_next_is_pkt3_nop(p)) { | ||
2401 | /* MIP_ADDRESS should point to FMASK for an MSAA texture. | ||
2402 | * It should be 0 if FMASK is disabled. */ | ||
2403 | moffset = 0; | ||
2404 | mipmap = NULL; | ||
2405 | } else { | ||
2406 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2407 | if (r) { | ||
2408 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); | ||
2409 | return -EINVAL; | ||
2410 | } | ||
2411 | moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
2412 | mipmap = reloc->robj; | ||
2367 | } | 2413 | } |
2368 | moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 2414 | |
2369 | mipmap = reloc->robj; | ||
2370 | r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8)); | 2415 | r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8)); |
2371 | if (r) | 2416 | if (r) |
2372 | return r; | 2417 | return r; |
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 8beac1065025..034f4c22e5db 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
@@ -218,6 +218,8 @@ | |||
218 | #define EVERGREEN_CRTC_CONTROL 0x6e70 | 218 | #define EVERGREEN_CRTC_CONTROL 0x6e70 |
219 | # define EVERGREEN_CRTC_MASTER_EN (1 << 0) | 219 | # define EVERGREEN_CRTC_MASTER_EN (1 << 0) |
220 | # define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) | 220 | # define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) |
221 | #define EVERGREEN_CRTC_BLANK_CONTROL 0x6e74 | ||
222 | # define EVERGREEN_CRTC_BLANK_DATA_EN (1 << 8) | ||
221 | #define EVERGREEN_CRTC_STATUS 0x6e8c | 223 | #define EVERGREEN_CRTC_STATUS 0x6e8c |
222 | # define EVERGREEN_CRTC_V_BLANK (1 << 0) | 224 | # define EVERGREEN_CRTC_V_BLANK (1 << 0) |
223 | #define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 | 225 | #define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 79347855d9bf..df542f1a5dfb 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -87,6 +87,10 @@ | |||
87 | 87 | ||
88 | #define CONFIG_MEMSIZE 0x5428 | 88 | #define CONFIG_MEMSIZE 0x5428 |
89 | 89 | ||
90 | #define BIF_FB_EN 0x5490 | ||
91 | #define FB_READ_EN (1 << 0) | ||
92 | #define FB_WRITE_EN (1 << 1) | ||
93 | |||
90 | #define CP_COHER_BASE 0x85F8 | 94 | #define CP_COHER_BASE 0x85F8 |
91 | #define CP_STALLED_STAT1 0x8674 | 95 | #define CP_STALLED_STAT1 0x8674 |
92 | #define CP_STALLED_STAT2 0x8678 | 96 | #define CP_STALLED_STAT2 0x8678 |
@@ -430,6 +434,9 @@ | |||
430 | #define NOOFCHAN_MASK 0x00003000 | 434 | #define NOOFCHAN_MASK 0x00003000 |
431 | #define MC_SHARED_CHREMAP 0x2008 | 435 | #define MC_SHARED_CHREMAP 0x2008 |
432 | 436 | ||
437 | #define MC_SHARED_BLACKOUT_CNTL 0x20ac | ||
438 | #define BLACKOUT_MODE_MASK 0x00000007 | ||
439 | |||
433 | #define MC_ARB_RAMCFG 0x2760 | 440 | #define MC_ARB_RAMCFG 0x2760 |
434 | #define NOOFBANK_SHIFT 0 | 441 | #define NOOFBANK_SHIFT 0 |
435 | #define NOOFBANK_MASK 0x00000003 | 442 | #define NOOFBANK_MASK 0x00000003 |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 853800e8582f..9a46f7d4e61f 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -726,7 +726,7 @@ void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
726 | WREG32(VM_INVALIDATE_REQUEST, 1); | 726 | WREG32(VM_INVALIDATE_REQUEST, 1); |
727 | } | 727 | } |
728 | 728 | ||
729 | int cayman_pcie_gart_enable(struct radeon_device *rdev) | 729 | static int cayman_pcie_gart_enable(struct radeon_device *rdev) |
730 | { | 730 | { |
731 | int i, r; | 731 | int i, r; |
732 | 732 | ||
@@ -782,7 +782,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
782 | (u32)(rdev->dummy_page.addr >> 12)); | 782 | (u32)(rdev->dummy_page.addr >> 12)); |
783 | WREG32(VM_CONTEXT1_CNTL2, 0); | 783 | WREG32(VM_CONTEXT1_CNTL2, 0); |
784 | WREG32(VM_CONTEXT1_CNTL, 0); | 784 | WREG32(VM_CONTEXT1_CNTL, 0); |
785 | WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | | 785 | WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) | |
786 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); | 786 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); |
787 | 787 | ||
788 | cayman_pcie_gart_tlb_flush(rdev); | 788 | cayman_pcie_gart_tlb_flush(rdev); |
@@ -793,7 +793,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
793 | return 0; | 793 | return 0; |
794 | } | 794 | } |
795 | 795 | ||
796 | void cayman_pcie_gart_disable(struct radeon_device *rdev) | 796 | static void cayman_pcie_gart_disable(struct radeon_device *rdev) |
797 | { | 797 | { |
798 | /* Disable all tables */ | 798 | /* Disable all tables */ |
799 | WREG32(VM_CONTEXT0_CNTL, 0); | 799 | WREG32(VM_CONTEXT0_CNTL, 0); |
@@ -813,7 +813,7 @@ void cayman_pcie_gart_disable(struct radeon_device *rdev) | |||
813 | radeon_gart_table_vram_unpin(rdev); | 813 | radeon_gart_table_vram_unpin(rdev); |
814 | } | 814 | } |
815 | 815 | ||
816 | void cayman_pcie_gart_fini(struct radeon_device *rdev) | 816 | static void cayman_pcie_gart_fini(struct radeon_device *rdev) |
817 | { | 817 | { |
818 | cayman_pcie_gart_disable(rdev); | 818 | cayman_pcie_gart_disable(rdev); |
819 | radeon_gart_table_vram_free(rdev); | 819 | radeon_gart_table_vram_free(rdev); |
@@ -879,12 +879,13 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
879 | #endif | 879 | #endif |
880 | (ib->gpu_addr & 0xFFFFFFFC)); | 880 | (ib->gpu_addr & 0xFFFFFFFC)); |
881 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); | 881 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); |
882 | radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24)); | 882 | radeon_ring_write(ring, ib->length_dw | |
883 | (ib->vm ? (ib->vm->id << 24) : 0)); | ||
883 | 884 | ||
884 | /* flush read cache over gart for this vmid */ | 885 | /* flush read cache over gart for this vmid */ |
885 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 886 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
886 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); | 887 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); |
887 | radeon_ring_write(ring, ib->vm_id); | 888 | radeon_ring_write(ring, ib->vm ? ib->vm->id : 0); |
888 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 889 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
889 | radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); | 890 | radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); |
890 | radeon_ring_write(ring, 0xFFFFFFFF); | 891 | radeon_ring_write(ring, 0xFFFFFFFF); |
@@ -1004,7 +1005,7 @@ static void cayman_cp_fini(struct radeon_device *rdev) | |||
1004 | radeon_scratch_free(rdev, ring->rptr_save_reg); | 1005 | radeon_scratch_free(rdev, ring->rptr_save_reg); |
1005 | } | 1006 | } |
1006 | 1007 | ||
1007 | int cayman_cp_resume(struct radeon_device *rdev) | 1008 | static int cayman_cp_resume(struct radeon_device *rdev) |
1008 | { | 1009 | { |
1009 | static const int ridx[] = { | 1010 | static const int ridx[] = { |
1010 | RADEON_RING_TYPE_GFX_INDEX, | 1011 | RADEON_RING_TYPE_GFX_INDEX, |
@@ -1496,53 +1497,16 @@ void cayman_vm_fini(struct radeon_device *rdev) | |||
1496 | { | 1497 | { |
1497 | } | 1498 | } |
1498 | 1499 | ||
1499 | int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id) | 1500 | #define R600_ENTRY_VALID (1 << 0) |
1500 | { | ||
1501 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (id << 2), 0); | ||
1502 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (id << 2), vm->last_pfn); | ||
1503 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (id << 2), vm->pt_gpu_addr >> 12); | ||
1504 | /* flush hdp cache */ | ||
1505 | WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
1506 | /* bits 0-7 are the VM contexts0-7 */ | ||
1507 | WREG32(VM_INVALIDATE_REQUEST, 1 << id); | ||
1508 | return 0; | ||
1509 | } | ||
1510 | |||
1511 | void cayman_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) | ||
1512 | { | ||
1513 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (vm->id << 2), 0); | ||
1514 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (vm->id << 2), 0); | ||
1515 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0); | ||
1516 | /* flush hdp cache */ | ||
1517 | WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
1518 | /* bits 0-7 are the VM contexts0-7 */ | ||
1519 | WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); | ||
1520 | } | ||
1521 | |||
1522 | void cayman_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm) | ||
1523 | { | ||
1524 | if (vm->id == -1) | ||
1525 | return; | ||
1526 | |||
1527 | /* flush hdp cache */ | ||
1528 | WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
1529 | /* bits 0-7 are the VM contexts0-7 */ | ||
1530 | WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); | ||
1531 | } | ||
1532 | |||
1533 | #define R600_PTE_VALID (1 << 0) | ||
1534 | #define R600_PTE_SYSTEM (1 << 1) | 1501 | #define R600_PTE_SYSTEM (1 << 1) |
1535 | #define R600_PTE_SNOOPED (1 << 2) | 1502 | #define R600_PTE_SNOOPED (1 << 2) |
1536 | #define R600_PTE_READABLE (1 << 5) | 1503 | #define R600_PTE_READABLE (1 << 5) |
1537 | #define R600_PTE_WRITEABLE (1 << 6) | 1504 | #define R600_PTE_WRITEABLE (1 << 6) |
1538 | 1505 | ||
1539 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, | 1506 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags) |
1540 | struct radeon_vm *vm, | ||
1541 | uint32_t flags) | ||
1542 | { | 1507 | { |
1543 | uint32_t r600_flags = 0; | 1508 | uint32_t r600_flags = 0; |
1544 | 1509 | r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0; | |
1545 | r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_PTE_VALID : 0; | ||
1546 | r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; | 1510 | r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; |
1547 | r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; | 1511 | r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; |
1548 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 1512 | if (flags & RADEON_VM_PAGE_SYSTEM) { |
@@ -1552,12 +1516,76 @@ uint32_t cayman_vm_page_flags(struct radeon_device *rdev, | |||
1552 | return r600_flags; | 1516 | return r600_flags; |
1553 | } | 1517 | } |
1554 | 1518 | ||
1555 | void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, | 1519 | /** |
1556 | unsigned pfn, uint64_t addr, uint32_t flags) | 1520 | * cayman_vm_set_page - update the page tables using the CP |
1521 | * | ||
1522 | * @rdev: radeon_device pointer | ||
1523 | * @pe: addr of the page entry | ||
1524 | * @addr: dst addr to write into pe | ||
1525 | * @count: number of page entries to update | ||
1526 | * @incr: increase next addr by incr bytes | ||
1527 | * @flags: access flags | ||
1528 | * | ||
1529 | * Update the page tables using the CP (cayman-si). | ||
1530 | */ | ||
1531 | void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, | ||
1532 | uint64_t addr, unsigned count, | ||
1533 | uint32_t incr, uint32_t flags) | ||
1534 | { | ||
1535 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; | ||
1536 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | ||
1537 | int i; | ||
1538 | |||
1539 | radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, 1 + count * 2)); | ||
1540 | radeon_ring_write(ring, pe); | ||
1541 | radeon_ring_write(ring, upper_32_bits(pe) & 0xff); | ||
1542 | for (i = 0; i < count; ++i) { | ||
1543 | uint64_t value = 0; | ||
1544 | if (flags & RADEON_VM_PAGE_SYSTEM) { | ||
1545 | value = radeon_vm_map_gart(rdev, addr); | ||
1546 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
1547 | addr += incr; | ||
1548 | |||
1549 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
1550 | value = addr; | ||
1551 | addr += incr; | ||
1552 | } | ||
1553 | |||
1554 | value |= r600_flags; | ||
1555 | radeon_ring_write(ring, value); | ||
1556 | radeon_ring_write(ring, upper_32_bits(value)); | ||
1557 | } | ||
1558 | } | ||
1559 | |||
1560 | /** | ||
1561 | * cayman_vm_flush - vm flush using the CP | ||
1562 | * | ||
1563 | * @rdev: radeon_device pointer | ||
1564 | * | ||
1565 | * Update the page table base and flush the VM TLB | ||
1566 | * using the CP (cayman-si). | ||
1567 | */ | ||
1568 | void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | ||
1557 | { | 1569 | { |
1558 | void __iomem *ptr = (void *)vm->pt; | 1570 | struct radeon_ring *ring = &rdev->ring[ridx]; |
1571 | |||
1572 | if (vm == NULL) | ||
1573 | return; | ||
1574 | |||
1575 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (vm->id << 2), 0)); | ||
1576 | radeon_ring_write(ring, 0); | ||
1577 | |||
1578 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (vm->id << 2), 0)); | ||
1579 | radeon_ring_write(ring, vm->last_pfn); | ||
1559 | 1580 | ||
1560 | addr = addr & 0xFFFFFFFFFFFFF000ULL; | 1581 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0)); |
1561 | addr |= flags; | 1582 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); |
1562 | writeq(addr, ptr + (pfn * 8)); | 1583 | |
1584 | /* flush hdp cache */ | ||
1585 | radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0)); | ||
1586 | radeon_ring_write(ring, 0x1); | ||
1587 | |||
1588 | /* bits 0-7 are the VM contexts0-7 */ | ||
1589 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); | ||
1590 | radeon_ring_write(ring, 1 << vm->id); | ||
1563 | } | 1591 | } |
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 870db340d377..2423d1b5d385 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h | |||
@@ -585,6 +585,7 @@ | |||
585 | #define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73 | 585 | #define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73 |
586 | #define PACKET3_SET_RESOURCE_INDIRECT 0x74 | 586 | #define PACKET3_SET_RESOURCE_INDIRECT 0x74 |
587 | #define PACKET3_SET_APPEND_CNT 0x75 | 587 | #define PACKET3_SET_APPEND_CNT 0x75 |
588 | #define PACKET3_ME_WRITE 0x7A | ||
588 | 589 | ||
589 | #endif | 590 | #endif |
590 | 591 | ||
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 8d7e33a0b243..b41237bf884b 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -80,10 +80,12 @@ MODULE_FIRMWARE(FIRMWARE_R520); | |||
80 | */ | 80 | */ |
81 | void r100_wait_for_vblank(struct radeon_device *rdev, int crtc) | 81 | void r100_wait_for_vblank(struct radeon_device *rdev, int crtc) |
82 | { | 82 | { |
83 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; | ||
84 | int i; | 83 | int i; |
85 | 84 | ||
86 | if (radeon_crtc->crtc_id == 0) { | 85 | if (crtc >= rdev->num_crtc) |
86 | return; | ||
87 | |||
88 | if (crtc == 0) { | ||
87 | if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) { | 89 | if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) { |
88 | for (i = 0; i < rdev->usec_timeout; i++) { | 90 | for (i = 0; i < rdev->usec_timeout; i++) { |
89 | if (!(RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)) | 91 | if (!(RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)) |
@@ -698,9 +700,6 @@ int r100_irq_set(struct radeon_device *rdev) | |||
698 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { | 700 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
699 | tmp |= RADEON_SW_INT_ENABLE; | 701 | tmp |= RADEON_SW_INT_ENABLE; |
700 | } | 702 | } |
701 | if (rdev->irq.gui_idle) { | ||
702 | tmp |= RADEON_GUI_IDLE_MASK; | ||
703 | } | ||
704 | if (rdev->irq.crtc_vblank_int[0] || | 703 | if (rdev->irq.crtc_vblank_int[0] || |
705 | atomic_read(&rdev->irq.pflip[0])) { | 704 | atomic_read(&rdev->irq.pflip[0])) { |
706 | tmp |= RADEON_CRTC_VBLANK_MASK; | 705 | tmp |= RADEON_CRTC_VBLANK_MASK; |
@@ -737,12 +736,6 @@ static uint32_t r100_irq_ack(struct radeon_device *rdev) | |||
737 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | | 736 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | |
738 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; | 737 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; |
739 | 738 | ||
740 | /* the interrupt works, but the status bit is permanently asserted */ | ||
741 | if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { | ||
742 | if (!rdev->irq.gui_idle_acked) | ||
743 | irq_mask |= RADEON_GUI_IDLE_STAT; | ||
744 | } | ||
745 | |||
746 | if (irqs) { | 739 | if (irqs) { |
747 | WREG32(RADEON_GEN_INT_STATUS, irqs); | 740 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
748 | } | 741 | } |
@@ -754,9 +747,6 @@ int r100_irq_process(struct radeon_device *rdev) | |||
754 | uint32_t status, msi_rearm; | 747 | uint32_t status, msi_rearm; |
755 | bool queue_hotplug = false; | 748 | bool queue_hotplug = false; |
756 | 749 | ||
757 | /* reset gui idle ack. the status bit is broken */ | ||
758 | rdev->irq.gui_idle_acked = false; | ||
759 | |||
760 | status = r100_irq_ack(rdev); | 750 | status = r100_irq_ack(rdev); |
761 | if (!status) { | 751 | if (!status) { |
762 | return IRQ_NONE; | 752 | return IRQ_NONE; |
@@ -769,11 +759,6 @@ int r100_irq_process(struct radeon_device *rdev) | |||
769 | if (status & RADEON_SW_INT_TEST) { | 759 | if (status & RADEON_SW_INT_TEST) { |
770 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | 760 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |
771 | } | 761 | } |
772 | /* gui idle interrupt */ | ||
773 | if (status & RADEON_GUI_IDLE_STAT) { | ||
774 | rdev->irq.gui_idle_acked = true; | ||
775 | wake_up(&rdev->irq.idle_queue); | ||
776 | } | ||
777 | /* Vertical blank interrupts */ | 762 | /* Vertical blank interrupts */ |
778 | if (status & RADEON_CRTC_VBLANK_STAT) { | 763 | if (status & RADEON_CRTC_VBLANK_STAT) { |
779 | if (rdev->irq.crtc_vblank_int[0]) { | 764 | if (rdev->irq.crtc_vblank_int[0]) { |
@@ -803,8 +788,6 @@ int r100_irq_process(struct radeon_device *rdev) | |||
803 | } | 788 | } |
804 | status = r100_irq_ack(rdev); | 789 | status = r100_irq_ack(rdev); |
805 | } | 790 | } |
806 | /* reset gui idle ack. the status bit is broken */ | ||
807 | rdev->irq.gui_idle_acked = false; | ||
808 | if (queue_hotplug) | 791 | if (queue_hotplug) |
809 | schedule_work(&rdev->hotplug_work); | 792 | schedule_work(&rdev->hotplug_work); |
810 | if (rdev->msi_enabled) { | 793 | if (rdev->msi_enabled) { |
@@ -2530,7 +2513,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track | |||
2530 | /* | 2513 | /* |
2531 | * Global GPU functions | 2514 | * Global GPU functions |
2532 | */ | 2515 | */ |
2533 | void r100_errata(struct radeon_device *rdev) | 2516 | static void r100_errata(struct radeon_device *rdev) |
2534 | { | 2517 | { |
2535 | rdev->pll_errata = 0; | 2518 | rdev->pll_errata = 0; |
2536 | 2519 | ||
@@ -2545,51 +2528,7 @@ void r100_errata(struct radeon_device *rdev) | |||
2545 | } | 2528 | } |
2546 | } | 2529 | } |
2547 | 2530 | ||
2548 | /* Wait for vertical sync on primary CRTC */ | 2531 | static int r100_rbbm_fifo_wait_for_entry(struct radeon_device *rdev, unsigned n) |
2549 | void r100_gpu_wait_for_vsync(struct radeon_device *rdev) | ||
2550 | { | ||
2551 | uint32_t crtc_gen_cntl, tmp; | ||
2552 | int i; | ||
2553 | |||
2554 | crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL); | ||
2555 | if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) || | ||
2556 | !(crtc_gen_cntl & RADEON_CRTC_EN)) { | ||
2557 | return; | ||
2558 | } | ||
2559 | /* Clear the CRTC_VBLANK_SAVE bit */ | ||
2560 | WREG32(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR); | ||
2561 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
2562 | tmp = RREG32(RADEON_CRTC_STATUS); | ||
2563 | if (tmp & RADEON_CRTC_VBLANK_SAVE) { | ||
2564 | return; | ||
2565 | } | ||
2566 | DRM_UDELAY(1); | ||
2567 | } | ||
2568 | } | ||
2569 | |||
2570 | /* Wait for vertical sync on secondary CRTC */ | ||
2571 | void r100_gpu_wait_for_vsync2(struct radeon_device *rdev) | ||
2572 | { | ||
2573 | uint32_t crtc2_gen_cntl, tmp; | ||
2574 | int i; | ||
2575 | |||
2576 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
2577 | if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) || | ||
2578 | !(crtc2_gen_cntl & RADEON_CRTC2_EN)) | ||
2579 | return; | ||
2580 | |||
2581 | /* Clear the CRTC_VBLANK_SAVE bit */ | ||
2582 | WREG32(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR); | ||
2583 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
2584 | tmp = RREG32(RADEON_CRTC2_STATUS); | ||
2585 | if (tmp & RADEON_CRTC2_VBLANK_SAVE) { | ||
2586 | return; | ||
2587 | } | ||
2588 | DRM_UDELAY(1); | ||
2589 | } | ||
2590 | } | ||
2591 | |||
2592 | int r100_rbbm_fifo_wait_for_entry(struct radeon_device *rdev, unsigned n) | ||
2593 | { | 2532 | { |
2594 | unsigned i; | 2533 | unsigned i; |
2595 | uint32_t tmp; | 2534 | uint32_t tmp; |
@@ -2950,7 +2889,7 @@ void r100_vga_set_state(struct radeon_device *rdev, bool state) | |||
2950 | WREG32(RADEON_CONFIG_CNTL, temp); | 2889 | WREG32(RADEON_CONFIG_CNTL, temp); |
2951 | } | 2890 | } |
2952 | 2891 | ||
2953 | void r100_mc_init(struct radeon_device *rdev) | 2892 | static void r100_mc_init(struct radeon_device *rdev) |
2954 | { | 2893 | { |
2955 | u64 base; | 2894 | u64 base; |
2956 | 2895 | ||
@@ -3022,7 +2961,7 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
3022 | r100_pll_errata_after_data(rdev); | 2961 | r100_pll_errata_after_data(rdev); |
3023 | } | 2962 | } |
3024 | 2963 | ||
3025 | void r100_set_safe_registers(struct radeon_device *rdev) | 2964 | static void r100_set_safe_registers(struct radeon_device *rdev) |
3026 | { | 2965 | { |
3027 | if (ASIC_IS_RN50(rdev)) { | 2966 | if (ASIC_IS_RN50(rdev)) { |
3028 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; | 2967 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; |
@@ -3817,9 +3756,10 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
3817 | return r; | 3756 | return r; |
3818 | } | 3757 | } |
3819 | WREG32(scratch, 0xCAFEDEAD); | 3758 | WREG32(scratch, 0xCAFEDEAD); |
3820 | r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &ib, 256); | 3759 | r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &ib, NULL, 256); |
3821 | if (r) { | 3760 | if (r) { |
3822 | return r; | 3761 | DRM_ERROR("radeon: failed to get ib (%d).\n", r); |
3762 | goto free_scratch; | ||
3823 | } | 3763 | } |
3824 | ib.ptr[0] = PACKET0(scratch, 0); | 3764 | ib.ptr[0] = PACKET0(scratch, 0); |
3825 | ib.ptr[1] = 0xDEADBEEF; | 3765 | ib.ptr[1] = 0xDEADBEEF; |
@@ -3832,13 +3772,13 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
3832 | ib.length_dw = 8; | 3772 | ib.length_dw = 8; |
3833 | r = radeon_ib_schedule(rdev, &ib, NULL); | 3773 | r = radeon_ib_schedule(rdev, &ib, NULL); |
3834 | if (r) { | 3774 | if (r) { |
3835 | radeon_scratch_free(rdev, scratch); | 3775 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
3836 | radeon_ib_free(rdev, &ib); | 3776 | goto free_ib; |
3837 | return r; | ||
3838 | } | 3777 | } |
3839 | r = radeon_fence_wait(ib.fence, false); | 3778 | r = radeon_fence_wait(ib.fence, false); |
3840 | if (r) { | 3779 | if (r) { |
3841 | return r; | 3780 | DRM_ERROR("radeon: fence wait failed (%d).\n", r); |
3781 | goto free_ib; | ||
3842 | } | 3782 | } |
3843 | for (i = 0; i < rdev->usec_timeout; i++) { | 3783 | for (i = 0; i < rdev->usec_timeout; i++) { |
3844 | tmp = RREG32(scratch); | 3784 | tmp = RREG32(scratch); |
@@ -3854,8 +3794,10 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
3854 | scratch, tmp); | 3794 | scratch, tmp); |
3855 | r = -EINVAL; | 3795 | r = -EINVAL; |
3856 | } | 3796 | } |
3857 | radeon_scratch_free(rdev, scratch); | 3797 | free_ib: |
3858 | radeon_ib_free(rdev, &ib); | 3798 | radeon_ib_free(rdev, &ib); |
3799 | free_scratch: | ||
3800 | radeon_scratch_free(rdev, scratch); | ||
3859 | return r; | 3801 | return r; |
3860 | } | 3802 | } |
3861 | 3803 | ||
@@ -3964,7 +3906,7 @@ static void r100_mc_program(struct radeon_device *rdev) | |||
3964 | r100_mc_resume(rdev, &save); | 3906 | r100_mc_resume(rdev, &save); |
3965 | } | 3907 | } |
3966 | 3908 | ||
3967 | void r100_clock_startup(struct radeon_device *rdev) | 3909 | static void r100_clock_startup(struct radeon_device *rdev) |
3968 | { | 3910 | { |
3969 | u32 tmp; | 3911 | u32 tmp; |
3970 | 3912 | ||
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 646a1927dda7..4949bfc14b58 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -296,7 +296,7 @@ void r300_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) | |||
296 | radeon_ring_unlock_commit(rdev, ring); | 296 | radeon_ring_unlock_commit(rdev, ring); |
297 | } | 297 | } |
298 | 298 | ||
299 | void r300_errata(struct radeon_device *rdev) | 299 | static void r300_errata(struct radeon_device *rdev) |
300 | { | 300 | { |
301 | rdev->pll_errata = 0; | 301 | rdev->pll_errata = 0; |
302 | 302 | ||
@@ -322,7 +322,7 @@ int r300_mc_wait_for_idle(struct radeon_device *rdev) | |||
322 | return -1; | 322 | return -1; |
323 | } | 323 | } |
324 | 324 | ||
325 | void r300_gpu_init(struct radeon_device *rdev) | 325 | static void r300_gpu_init(struct radeon_device *rdev) |
326 | { | 326 | { |
327 | uint32_t gb_tile_config, tmp; | 327 | uint32_t gb_tile_config, tmp; |
328 | 328 | ||
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 079d3c52c08a..28b4f871aaf4 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -119,7 +119,7 @@ static void r520_vram_get_type(struct radeon_device *rdev) | |||
119 | rdev->mc.vram_width *= 2; | 119 | rdev->mc.vram_width *= 2; |
120 | } | 120 | } |
121 | 121 | ||
122 | void r520_mc_init(struct radeon_device *rdev) | 122 | static void r520_mc_init(struct radeon_device *rdev) |
123 | { | 123 | { |
124 | 124 | ||
125 | r520_vram_get_type(rdev); | 125 | r520_vram_get_type(rdev); |
@@ -131,7 +131,7 @@ void r520_mc_init(struct radeon_device *rdev) | |||
131 | radeon_update_bandwidth_info(rdev); | 131 | radeon_update_bandwidth_info(rdev); |
132 | } | 132 | } |
133 | 133 | ||
134 | void r520_mc_program(struct radeon_device *rdev) | 134 | static void r520_mc_program(struct radeon_device *rdev) |
135 | { | 135 | { |
136 | struct rv515_mc_save save; | 136 | struct rv515_mc_save save; |
137 | 137 | ||
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index d79c639ae739..39b743fff791 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -98,7 +98,7 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev); | |||
98 | 98 | ||
99 | /* r600,rv610,rv630,rv620,rv635,rv670 */ | 99 | /* r600,rv610,rv630,rv620,rv635,rv670 */ |
100 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | 100 | int r600_mc_wait_for_idle(struct radeon_device *rdev); |
101 | void r600_gpu_init(struct radeon_device *rdev); | 101 | static void r600_gpu_init(struct radeon_device *rdev); |
102 | void r600_fini(struct radeon_device *rdev); | 102 | void r600_fini(struct radeon_device *rdev); |
103 | void r600_irq_disable(struct radeon_device *rdev); | 103 | void r600_irq_disable(struct radeon_device *rdev); |
104 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); | 104 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); |
@@ -881,7 +881,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev) | |||
881 | return radeon_gart_table_vram_alloc(rdev); | 881 | return radeon_gart_table_vram_alloc(rdev); |
882 | } | 882 | } |
883 | 883 | ||
884 | int r600_pcie_gart_enable(struct radeon_device *rdev) | 884 | static int r600_pcie_gart_enable(struct radeon_device *rdev) |
885 | { | 885 | { |
886 | u32 tmp; | 886 | u32 tmp; |
887 | int r, i; | 887 | int r, i; |
@@ -938,7 +938,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) | |||
938 | return 0; | 938 | return 0; |
939 | } | 939 | } |
940 | 940 | ||
941 | void r600_pcie_gart_disable(struct radeon_device *rdev) | 941 | static void r600_pcie_gart_disable(struct radeon_device *rdev) |
942 | { | 942 | { |
943 | u32 tmp; | 943 | u32 tmp; |
944 | int i; | 944 | int i; |
@@ -971,14 +971,14 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) | |||
971 | radeon_gart_table_vram_unpin(rdev); | 971 | radeon_gart_table_vram_unpin(rdev); |
972 | } | 972 | } |
973 | 973 | ||
974 | void r600_pcie_gart_fini(struct radeon_device *rdev) | 974 | static void r600_pcie_gart_fini(struct radeon_device *rdev) |
975 | { | 975 | { |
976 | radeon_gart_fini(rdev); | 976 | radeon_gart_fini(rdev); |
977 | r600_pcie_gart_disable(rdev); | 977 | r600_pcie_gart_disable(rdev); |
978 | radeon_gart_table_vram_free(rdev); | 978 | radeon_gart_table_vram_free(rdev); |
979 | } | 979 | } |
980 | 980 | ||
981 | void r600_agp_enable(struct radeon_device *rdev) | 981 | static void r600_agp_enable(struct radeon_device *rdev) |
982 | { | 982 | { |
983 | u32 tmp; | 983 | u32 tmp; |
984 | int i; | 984 | int i; |
@@ -1158,7 +1158,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc | |||
1158 | } | 1158 | } |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | int r600_mc_init(struct radeon_device *rdev) | 1161 | static int r600_mc_init(struct radeon_device *rdev) |
1162 | { | 1162 | { |
1163 | u32 tmp; | 1163 | u32 tmp; |
1164 | int chansize, numchan; | 1164 | int chansize, numchan; |
@@ -1258,7 +1258,7 @@ void r600_vram_scratch_fini(struct radeon_device *rdev) | |||
1258 | * reset, it's up to the caller to determine if the GPU needs one. We | 1258 | * reset, it's up to the caller to determine if the GPU needs one. We |
1259 | * might add an helper function to check that. | 1259 | * might add an helper function to check that. |
1260 | */ | 1260 | */ |
1261 | int r600_gpu_soft_reset(struct radeon_device *rdev) | 1261 | static int r600_gpu_soft_reset(struct radeon_device *rdev) |
1262 | { | 1262 | { |
1263 | struct rv515_mc_save save; | 1263 | struct rv515_mc_save save; |
1264 | u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | | 1264 | u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | |
@@ -1433,7 +1433,7 @@ int r600_count_pipe_bits(uint32_t val) | |||
1433 | return ret; | 1433 | return ret; |
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | void r600_gpu_init(struct radeon_device *rdev) | 1436 | static void r600_gpu_init(struct radeon_device *rdev) |
1437 | { | 1437 | { |
1438 | u32 tiling_config; | 1438 | u32 tiling_config; |
1439 | u32 ramcfg; | 1439 | u32 ramcfg; |
@@ -2347,7 +2347,7 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg) | |||
2347 | /* FIXME: implement */ | 2347 | /* FIXME: implement */ |
2348 | } | 2348 | } |
2349 | 2349 | ||
2350 | int r600_startup(struct radeon_device *rdev) | 2350 | static int r600_startup(struct radeon_device *rdev) |
2351 | { | 2351 | { |
2352 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 2352 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
2353 | int r; | 2353 | int r; |
@@ -2635,10 +2635,10 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2635 | return r; | 2635 | return r; |
2636 | } | 2636 | } |
2637 | WREG32(scratch, 0xCAFEDEAD); | 2637 | WREG32(scratch, 0xCAFEDEAD); |
2638 | r = radeon_ib_get(rdev, ring->idx, &ib, 256); | 2638 | r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256); |
2639 | if (r) { | 2639 | if (r) { |
2640 | DRM_ERROR("radeon: failed to get ib (%d).\n", r); | 2640 | DRM_ERROR("radeon: failed to get ib (%d).\n", r); |
2641 | return r; | 2641 | goto free_scratch; |
2642 | } | 2642 | } |
2643 | ib.ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); | 2643 | ib.ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); |
2644 | ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | 2644 | ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); |
@@ -2646,15 +2646,13 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2646 | ib.length_dw = 3; | 2646 | ib.length_dw = 3; |
2647 | r = radeon_ib_schedule(rdev, &ib, NULL); | 2647 | r = radeon_ib_schedule(rdev, &ib, NULL); |
2648 | if (r) { | 2648 | if (r) { |
2649 | radeon_scratch_free(rdev, scratch); | ||
2650 | radeon_ib_free(rdev, &ib); | ||
2651 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); | 2649 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
2652 | return r; | 2650 | goto free_ib; |
2653 | } | 2651 | } |
2654 | r = radeon_fence_wait(ib.fence, false); | 2652 | r = radeon_fence_wait(ib.fence, false); |
2655 | if (r) { | 2653 | if (r) { |
2656 | DRM_ERROR("radeon: fence wait failed (%d).\n", r); | 2654 | DRM_ERROR("radeon: fence wait failed (%d).\n", r); |
2657 | return r; | 2655 | goto free_ib; |
2658 | } | 2656 | } |
2659 | for (i = 0; i < rdev->usec_timeout; i++) { | 2657 | for (i = 0; i < rdev->usec_timeout; i++) { |
2660 | tmp = RREG32(scratch); | 2658 | tmp = RREG32(scratch); |
@@ -2669,8 +2667,10 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2669 | scratch, tmp); | 2667 | scratch, tmp); |
2670 | r = -EINVAL; | 2668 | r = -EINVAL; |
2671 | } | 2669 | } |
2672 | radeon_scratch_free(rdev, scratch); | 2670 | free_ib: |
2673 | radeon_ib_free(rdev, &ib); | 2671 | radeon_ib_free(rdev, &ib); |
2672 | free_scratch: | ||
2673 | radeon_scratch_free(rdev, scratch); | ||
2674 | return r; | 2674 | return r; |
2675 | } | 2675 | } |
2676 | 2676 | ||
@@ -3088,10 +3088,6 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3088 | DRM_DEBUG("r600_irq_set: hdmi 0\n"); | 3088 | DRM_DEBUG("r600_irq_set: hdmi 0\n"); |
3089 | hdmi1 |= HDMI0_AZ_FORMAT_WTRIG_MASK; | 3089 | hdmi1 |= HDMI0_AZ_FORMAT_WTRIG_MASK; |
3090 | } | 3090 | } |
3091 | if (rdev->irq.gui_idle) { | ||
3092 | DRM_DEBUG("gui idle\n"); | ||
3093 | grbm_int_cntl |= GUI_IDLE_INT_ENABLE; | ||
3094 | } | ||
3095 | 3091 | ||
3096 | WREG32(CP_INT_CNTL, cp_int_cntl); | 3092 | WREG32(CP_INT_CNTL, cp_int_cntl); |
3097 | WREG32(DxMODE_INT_MASK, mode_int); | 3093 | WREG32(DxMODE_INT_MASK, mode_int); |
@@ -3475,7 +3471,6 @@ restart_ih: | |||
3475 | break; | 3471 | break; |
3476 | case 233: /* GUI IDLE */ | 3472 | case 233: /* GUI IDLE */ |
3477 | DRM_DEBUG("IH: GUI idle\n"); | 3473 | DRM_DEBUG("IH: GUI idle\n"); |
3478 | wake_up(&rdev->irq.idle_queue); | ||
3479 | break; | 3474 | break; |
3480 | default: | 3475 | default: |
3481 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | 3476 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c index 3c031a48205d..661fec2a2cc1 100644 --- a/drivers/gpu/drm/radeon/r600_blit.c +++ b/drivers/gpu/drm/radeon/r600_blit.c | |||
@@ -489,31 +489,36 @@ set_default_state(drm_radeon_private_t *dev_priv) | |||
489 | ADVANCE_RING(); | 489 | ADVANCE_RING(); |
490 | } | 490 | } |
491 | 491 | ||
492 | static uint32_t i2f(uint32_t input) | 492 | /* 23 bits of float fractional data */ |
493 | #define I2F_FRAC_BITS 23 | ||
494 | #define I2F_MASK ((1 << I2F_FRAC_BITS) - 1) | ||
495 | |||
496 | /* | ||
497 | * Converts unsigned integer into 32-bit IEEE floating point representation. | ||
498 | * Will be exact from 0 to 2^24. Above that, we round towards zero | ||
499 | * as the fractional bits will not fit in a float. (It would be better to | ||
500 | * round towards even as the fpu does, but that is slower.) | ||
501 | */ | ||
502 | __pure uint32_t int2float(uint32_t x) | ||
493 | { | 503 | { |
494 | u32 result, i, exponent, fraction; | 504 | uint32_t msb, exponent, fraction; |
495 | 505 | ||
496 | if ((input & 0x3fff) == 0) | 506 | /* Zero is special */ |
497 | result = 0; /* 0 is a special case */ | 507 | if (!x) return 0; |
498 | else { | 508 | |
499 | exponent = 140; /* exponent biased by 127; */ | 509 | /* Get location of the most significant bit */ |
500 | fraction = (input & 0x3fff) << 10; /* cheat and only | 510 | msb = __fls(x); |
501 | handle numbers below 2^^15 */ | ||
502 | for (i = 0; i < 14; i++) { | ||
503 | if (fraction & 0x800000) | ||
504 | break; | ||
505 | else { | ||
506 | fraction = fraction << 1; /* keep | ||
507 | shifting left until top bit = 1 */ | ||
508 | exponent = exponent - 1; | ||
509 | } | ||
510 | } | ||
511 | result = exponent << 23 | (fraction & 0x7fffff); /* mask | ||
512 | off top bit; assumed 1 */ | ||
513 | } | ||
514 | return result; | ||
515 | } | ||
516 | 511 | ||
512 | /* | ||
513 | * Use a rotate instead of a shift because that works both leftwards | ||
514 | * and rightwards due to the mod(32) behaviour. This means we don't | ||
515 | * need to check to see if we are above 2^24 or not. | ||
516 | */ | ||
517 | fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK; | ||
518 | exponent = (127 + msb) << I2F_FRAC_BITS; | ||
519 | |||
520 | return fraction + exponent; | ||
521 | } | ||
517 | 522 | ||
518 | static int r600_nomm_get_vb(struct drm_device *dev) | 523 | static int r600_nomm_get_vb(struct drm_device *dev) |
519 | { | 524 | { |
@@ -632,20 +637,20 @@ r600_blit_copy(struct drm_device *dev, | |||
632 | vb = r600_nomm_get_vb_ptr(dev); | 637 | vb = r600_nomm_get_vb_ptr(dev); |
633 | } | 638 | } |
634 | 639 | ||
635 | vb[0] = i2f(dst_x); | 640 | vb[0] = int2float(dst_x); |
636 | vb[1] = 0; | 641 | vb[1] = 0; |
637 | vb[2] = i2f(src_x); | 642 | vb[2] = int2float(src_x); |
638 | vb[3] = 0; | 643 | vb[3] = 0; |
639 | 644 | ||
640 | vb[4] = i2f(dst_x); | 645 | vb[4] = int2float(dst_x); |
641 | vb[5] = i2f(h); | 646 | vb[5] = int2float(h); |
642 | vb[6] = i2f(src_x); | 647 | vb[6] = int2float(src_x); |
643 | vb[7] = i2f(h); | 648 | vb[7] = int2float(h); |
644 | 649 | ||
645 | vb[8] = i2f(dst_x + cur_size); | 650 | vb[8] = int2float(dst_x + cur_size); |
646 | vb[9] = i2f(h); | 651 | vb[9] = int2float(h); |
647 | vb[10] = i2f(src_x + cur_size); | 652 | vb[10] = int2float(src_x + cur_size); |
648 | vb[11] = i2f(h); | 653 | vb[11] = int2float(h); |
649 | 654 | ||
650 | /* src */ | 655 | /* src */ |
651 | set_tex_resource(dev_priv, FMT_8, | 656 | set_tex_resource(dev_priv, FMT_8, |
@@ -721,20 +726,20 @@ r600_blit_copy(struct drm_device *dev, | |||
721 | vb = r600_nomm_get_vb_ptr(dev); | 726 | vb = r600_nomm_get_vb_ptr(dev); |
722 | } | 727 | } |
723 | 728 | ||
724 | vb[0] = i2f(dst_x / 4); | 729 | vb[0] = int2float(dst_x / 4); |
725 | vb[1] = 0; | 730 | vb[1] = 0; |
726 | vb[2] = i2f(src_x / 4); | 731 | vb[2] = int2float(src_x / 4); |
727 | vb[3] = 0; | 732 | vb[3] = 0; |
728 | 733 | ||
729 | vb[4] = i2f(dst_x / 4); | 734 | vb[4] = int2float(dst_x / 4); |
730 | vb[5] = i2f(h); | 735 | vb[5] = int2float(h); |
731 | vb[6] = i2f(src_x / 4); | 736 | vb[6] = int2float(src_x / 4); |
732 | vb[7] = i2f(h); | 737 | vb[7] = int2float(h); |
733 | 738 | ||
734 | vb[8] = i2f((dst_x + cur_size) / 4); | 739 | vb[8] = int2float((dst_x + cur_size) / 4); |
735 | vb[9] = i2f(h); | 740 | vb[9] = int2float(h); |
736 | vb[10] = i2f((src_x + cur_size) / 4); | 741 | vb[10] = int2float((src_x + cur_size) / 4); |
737 | vb[11] = i2f(h); | 742 | vb[11] = int2float(h); |
738 | 743 | ||
739 | /* src */ | 744 | /* src */ |
740 | set_tex_resource(dev_priv, FMT_8_8_8_8, | 745 | set_tex_resource(dev_priv, FMT_8_8_8_8, |
@@ -804,20 +809,20 @@ r600_blit_swap(struct drm_device *dev, | |||
804 | dx2 = dx + w; | 809 | dx2 = dx + w; |
805 | dy2 = dy + h; | 810 | dy2 = dy + h; |
806 | 811 | ||
807 | vb[0] = i2f(dx); | 812 | vb[0] = int2float(dx); |
808 | vb[1] = i2f(dy); | 813 | vb[1] = int2float(dy); |
809 | vb[2] = i2f(sx); | 814 | vb[2] = int2float(sx); |
810 | vb[3] = i2f(sy); | 815 | vb[3] = int2float(sy); |
811 | 816 | ||
812 | vb[4] = i2f(dx); | 817 | vb[4] = int2float(dx); |
813 | vb[5] = i2f(dy2); | 818 | vb[5] = int2float(dy2); |
814 | vb[6] = i2f(sx); | 819 | vb[6] = int2float(sx); |
815 | vb[7] = i2f(sy2); | 820 | vb[7] = int2float(sy2); |
816 | 821 | ||
817 | vb[8] = i2f(dx2); | 822 | vb[8] = int2float(dx2); |
818 | vb[9] = i2f(dy2); | 823 | vb[9] = int2float(dy2); |
819 | vb[10] = i2f(sx2); | 824 | vb[10] = int2float(sx2); |
820 | vb[11] = i2f(sy2); | 825 | vb[11] = int2float(sy2); |
821 | 826 | ||
822 | switch(cpp) { | 827 | switch(cpp) { |
823 | case 4: | 828 | case 4: |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 2bef8549ddfe..1c7ed3a5d045 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -455,46 +455,6 @@ set_default_state(struct radeon_device *rdev) | |||
455 | radeon_ring_write(ring, sq_stack_resource_mgmt_2); | 455 | radeon_ring_write(ring, sq_stack_resource_mgmt_2); |
456 | } | 456 | } |
457 | 457 | ||
458 | #define I2F_MAX_BITS 15 | ||
459 | #define I2F_MAX_INPUT ((1 << I2F_MAX_BITS) - 1) | ||
460 | #define I2F_SHIFT (24 - I2F_MAX_BITS) | ||
461 | |||
462 | /* | ||
463 | * Converts unsigned integer into 32-bit IEEE floating point representation. | ||
464 | * Conversion is not universal and only works for the range from 0 | ||
465 | * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between | ||
466 | * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary, | ||
467 | * I2F_MAX_BITS can be increased, but that will add to the loop iterations | ||
468 | * and slow us down. Conversion is done by shifting the input and counting | ||
469 | * down until the first 1 reaches bit position 23. The resulting counter | ||
470 | * and the shifted input are, respectively, the exponent and the fraction. | ||
471 | * The sign is always zero. | ||
472 | */ | ||
473 | static uint32_t i2f(uint32_t input) | ||
474 | { | ||
475 | u32 result, i, exponent, fraction; | ||
476 | |||
477 | WARN_ON_ONCE(input > I2F_MAX_INPUT); | ||
478 | |||
479 | if ((input & I2F_MAX_INPUT) == 0) | ||
480 | result = 0; | ||
481 | else { | ||
482 | exponent = 126 + I2F_MAX_BITS; | ||
483 | fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT; | ||
484 | |||
485 | for (i = 0; i < I2F_MAX_BITS; i++) { | ||
486 | if (fraction & 0x800000) | ||
487 | break; | ||
488 | else { | ||
489 | fraction = fraction << 1; | ||
490 | exponent = exponent - 1; | ||
491 | } | ||
492 | } | ||
493 | result = exponent << 23 | (fraction & 0x7fffff); | ||
494 | } | ||
495 | return result; | ||
496 | } | ||
497 | |||
498 | int r600_blit_init(struct radeon_device *rdev) | 458 | int r600_blit_init(struct radeon_device *rdev) |
499 | { | 459 | { |
500 | u32 obj_size; | 460 | u32 obj_size; |
@@ -766,14 +726,14 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
766 | vb_cpu_addr[3] = 0; | 726 | vb_cpu_addr[3] = 0; |
767 | 727 | ||
768 | vb_cpu_addr[4] = 0; | 728 | vb_cpu_addr[4] = 0; |
769 | vb_cpu_addr[5] = i2f(h); | 729 | vb_cpu_addr[5] = int2float(h); |
770 | vb_cpu_addr[6] = 0; | 730 | vb_cpu_addr[6] = 0; |
771 | vb_cpu_addr[7] = i2f(h); | 731 | vb_cpu_addr[7] = int2float(h); |
772 | 732 | ||
773 | vb_cpu_addr[8] = i2f(w); | 733 | vb_cpu_addr[8] = int2float(w); |
774 | vb_cpu_addr[9] = i2f(h); | 734 | vb_cpu_addr[9] = int2float(h); |
775 | vb_cpu_addr[10] = i2f(w); | 735 | vb_cpu_addr[10] = int2float(w); |
776 | vb_cpu_addr[11] = i2f(h); | 736 | vb_cpu_addr[11] = int2float(h); |
777 | 737 | ||
778 | rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8, | 738 | rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8, |
779 | w, h, w, src_gpu_addr, size_in_bytes); | 739 | w, h, w, src_gpu_addr, size_in_bytes); |
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.h b/drivers/gpu/drm/radeon/r600_blit_shaders.h index f437d36dd98c..2f3ce7a75976 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.h +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.h | |||
@@ -35,4 +35,5 @@ extern const u32 r6xx_default_state[]; | |||
35 | extern const u32 r6xx_ps_size, r6xx_vs_size; | 35 | extern const u32 r6xx_ps_size, r6xx_vs_size; |
36 | extern const u32 r6xx_default_size, r7xx_default_size; | 36 | extern const u32 r6xx_default_size, r7xx_default_size; |
37 | 37 | ||
38 | __pure uint32_t int2float(uint32_t x); | ||
38 | #endif | 39 | #endif |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index f37676d7f217..853f05ced1b1 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -847,7 +847,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
847 | * Assume that chunk_ib_index is properly set. Will return -EINVAL | 847 | * Assume that chunk_ib_index is properly set. Will return -EINVAL |
848 | * if packet is bigger than remaining ib size. or if packets is unknown. | 848 | * if packet is bigger than remaining ib size. or if packets is unknown. |
849 | **/ | 849 | **/ |
850 | int r600_cs_packet_parse(struct radeon_cs_parser *p, | 850 | static int r600_cs_packet_parse(struct radeon_cs_parser *p, |
851 | struct radeon_cs_packet *pkt, | 851 | struct radeon_cs_packet *pkt, |
852 | unsigned idx) | 852 | unsigned idx) |
853 | { | 853 | { |
@@ -2180,7 +2180,8 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
2180 | } | 2180 | } |
2181 | break; | 2181 | break; |
2182 | case PACKET3_STRMOUT_BASE_UPDATE: | 2182 | case PACKET3_STRMOUT_BASE_UPDATE: |
2183 | if (p->family < CHIP_RV770) { | 2183 | /* RS780 and RS880 also need this */ |
2184 | if (p->family < CHIP_RS780) { | ||
2184 | DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n"); | 2185 | DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n"); |
2185 | return -EINVAL; | 2186 | return -EINVAL; |
2186 | } | 2187 | } |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index e3558c3ef24a..857a7d7862fb 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -53,7 +53,7 @@ enum r600_hdmi_iec_status_bits { | |||
53 | AUDIO_STATUS_LEVEL = 0x80 | 53 | AUDIO_STATUS_LEVEL = 0x80 |
54 | }; | 54 | }; |
55 | 55 | ||
56 | struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { | 56 | static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { |
57 | /* 32kHz 44.1kHz 48kHz */ | 57 | /* 32kHz 44.1kHz 48kHz */ |
58 | /* Clock N CTS N CTS N CTS */ | 58 | /* Clock N CTS N CTS N CTS */ |
59 | { 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */ | 59 | { 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 59a15315ae9f..b04c06444d8b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -123,6 +123,7 @@ extern int radeon_lockup_timeout; | |||
123 | #define CAYMAN_RING_TYPE_CP2_INDEX 2 | 123 | #define CAYMAN_RING_TYPE_CP2_INDEX 2 |
124 | 124 | ||
125 | /* hardcode those limit for now */ | 125 | /* hardcode those limit for now */ |
126 | #define RADEON_VA_IB_OFFSET (1 << 20) | ||
126 | #define RADEON_VA_RESERVED_SIZE (8 << 20) | 127 | #define RADEON_VA_RESERVED_SIZE (8 << 20) |
127 | #define RADEON_IB_VM_MAX_SIZE (64 << 10) | 128 | #define RADEON_IB_VM_MAX_SIZE (64 << 10) |
128 | 129 | ||
@@ -253,6 +254,22 @@ static inline struct radeon_fence *radeon_fence_later(struct radeon_fence *a, | |||
253 | } | 254 | } |
254 | } | 255 | } |
255 | 256 | ||
257 | static inline bool radeon_fence_is_earlier(struct radeon_fence *a, | ||
258 | struct radeon_fence *b) | ||
259 | { | ||
260 | if (!a) { | ||
261 | return false; | ||
262 | } | ||
263 | |||
264 | if (!b) { | ||
265 | return true; | ||
266 | } | ||
267 | |||
268 | BUG_ON(a->ring != b->ring); | ||
269 | |||
270 | return a->seq < b->seq; | ||
271 | } | ||
272 | |||
256 | /* | 273 | /* |
257 | * Tiling registers | 274 | * Tiling registers |
258 | */ | 275 | */ |
@@ -275,18 +292,20 @@ struct radeon_mman { | |||
275 | 292 | ||
276 | /* bo virtual address in a specific vm */ | 293 | /* bo virtual address in a specific vm */ |
277 | struct radeon_bo_va { | 294 | struct radeon_bo_va { |
278 | /* bo list is protected by bo being reserved */ | 295 | /* protected by bo being reserved */ |
279 | struct list_head bo_list; | 296 | struct list_head bo_list; |
280 | /* vm list is protected by vm mutex */ | ||
281 | struct list_head vm_list; | ||
282 | /* constant after initialization */ | ||
283 | struct radeon_vm *vm; | ||
284 | struct radeon_bo *bo; | ||
285 | uint64_t soffset; | 297 | uint64_t soffset; |
286 | uint64_t eoffset; | 298 | uint64_t eoffset; |
287 | uint32_t flags; | 299 | uint32_t flags; |
288 | struct radeon_fence *fence; | ||
289 | bool valid; | 300 | bool valid; |
301 | unsigned ref_count; | ||
302 | |||
303 | /* protected by vm mutex */ | ||
304 | struct list_head vm_list; | ||
305 | |||
306 | /* constant after initialization */ | ||
307 | struct radeon_vm *vm; | ||
308 | struct radeon_bo *bo; | ||
290 | }; | 309 | }; |
291 | 310 | ||
292 | struct radeon_bo { | 311 | struct radeon_bo { |
@@ -566,9 +585,6 @@ struct radeon_irq { | |||
566 | atomic_t pflip[RADEON_MAX_CRTCS]; | 585 | atomic_t pflip[RADEON_MAX_CRTCS]; |
567 | wait_queue_head_t vblank_queue; | 586 | wait_queue_head_t vblank_queue; |
568 | bool hpd[RADEON_MAX_HPD_PINS]; | 587 | bool hpd[RADEON_MAX_HPD_PINS]; |
569 | bool gui_idle; | ||
570 | bool gui_idle_acked; | ||
571 | wait_queue_head_t idle_queue; | ||
572 | bool afmt[RADEON_MAX_AFMT_BLOCKS]; | 588 | bool afmt[RADEON_MAX_AFMT_BLOCKS]; |
573 | union radeon_irq_stat_regs stat_regs; | 589 | union radeon_irq_stat_regs stat_regs; |
574 | }; | 590 | }; |
@@ -583,7 +599,6 @@ void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block); | |||
583 | void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block); | 599 | void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block); |
584 | void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask); | 600 | void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask); |
585 | void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask); | 601 | void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask); |
586 | int radeon_irq_kms_wait_gui_idle(struct radeon_device *rdev); | ||
587 | 602 | ||
588 | /* | 603 | /* |
589 | * CP & rings. | 604 | * CP & rings. |
@@ -596,7 +611,7 @@ struct radeon_ib { | |||
596 | uint32_t *ptr; | 611 | uint32_t *ptr; |
597 | int ring; | 612 | int ring; |
598 | struct radeon_fence *fence; | 613 | struct radeon_fence *fence; |
599 | unsigned vm_id; | 614 | struct radeon_vm *vm; |
600 | bool is_const_ib; | 615 | bool is_const_ib; |
601 | struct radeon_fence *sync_to[RADEON_NUM_RINGS]; | 616 | struct radeon_fence *sync_to[RADEON_NUM_RINGS]; |
602 | struct radeon_semaphore *semaphore; | 617 | struct radeon_semaphore *semaphore; |
@@ -632,41 +647,38 @@ struct radeon_ring { | |||
632 | /* | 647 | /* |
633 | * VM | 648 | * VM |
634 | */ | 649 | */ |
650 | |||
651 | /* maximum number of VMIDs */ | ||
652 | #define RADEON_NUM_VM 16 | ||
653 | |||
654 | /* defines number of bits in page table versus page directory, | ||
655 | * a page is 4KB so we have 12 bits offset, 9 bits in the page | ||
656 | * table and the remaining 19 bits are in the page directory */ | ||
657 | #define RADEON_VM_BLOCK_SIZE 9 | ||
658 | |||
659 | /* number of entries in page table */ | ||
660 | #define RADEON_VM_PTE_COUNT (1 << RADEON_VM_BLOCK_SIZE) | ||
661 | |||
635 | struct radeon_vm { | 662 | struct radeon_vm { |
636 | struct list_head list; | 663 | struct list_head list; |
637 | struct list_head va; | 664 | struct list_head va; |
638 | int id; | 665 | unsigned id; |
639 | unsigned last_pfn; | 666 | unsigned last_pfn; |
640 | u64 pt_gpu_addr; | 667 | u64 pd_gpu_addr; |
641 | u64 *pt; | ||
642 | struct radeon_sa_bo *sa_bo; | 668 | struct radeon_sa_bo *sa_bo; |
643 | struct mutex mutex; | 669 | struct mutex mutex; |
644 | /* last fence for cs using this vm */ | 670 | /* last fence for cs using this vm */ |
645 | struct radeon_fence *fence; | 671 | struct radeon_fence *fence; |
646 | }; | 672 | /* last flush or NULL if we still need to flush */ |
647 | 673 | struct radeon_fence *last_flush; | |
648 | struct radeon_vm_funcs { | ||
649 | int (*init)(struct radeon_device *rdev); | ||
650 | void (*fini)(struct radeon_device *rdev); | ||
651 | /* cs mutex must be lock for schedule_ib */ | ||
652 | int (*bind)(struct radeon_device *rdev, struct radeon_vm *vm, int id); | ||
653 | void (*unbind)(struct radeon_device *rdev, struct radeon_vm *vm); | ||
654 | void (*tlb_flush)(struct radeon_device *rdev, struct radeon_vm *vm); | ||
655 | uint32_t (*page_flags)(struct radeon_device *rdev, | ||
656 | struct radeon_vm *vm, | ||
657 | uint32_t flags); | ||
658 | void (*set_page)(struct radeon_device *rdev, struct radeon_vm *vm, | ||
659 | unsigned pfn, uint64_t addr, uint32_t flags); | ||
660 | }; | 674 | }; |
661 | 675 | ||
662 | struct radeon_vm_manager { | 676 | struct radeon_vm_manager { |
663 | struct mutex lock; | 677 | struct mutex lock; |
664 | struct list_head lru_vm; | 678 | struct list_head lru_vm; |
665 | uint32_t use_bitmap; | 679 | struct radeon_fence *active[RADEON_NUM_VM]; |
666 | struct radeon_sa_manager sa_manager; | 680 | struct radeon_sa_manager sa_manager; |
667 | uint32_t max_pfn; | 681 | uint32_t max_pfn; |
668 | /* fields constant after init */ | ||
669 | const struct radeon_vm_funcs *funcs; | ||
670 | /* number of VMIDs */ | 682 | /* number of VMIDs */ |
671 | unsigned nvm; | 683 | unsigned nvm; |
672 | /* vram base address for page table entry */ | 684 | /* vram base address for page table entry */ |
@@ -738,7 +750,8 @@ struct si_rlc { | |||
738 | }; | 750 | }; |
739 | 751 | ||
740 | int radeon_ib_get(struct radeon_device *rdev, int ring, | 752 | int radeon_ib_get(struct radeon_device *rdev, int ring, |
741 | struct radeon_ib *ib, unsigned size); | 753 | struct radeon_ib *ib, struct radeon_vm *vm, |
754 | unsigned size); | ||
742 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib); | 755 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib); |
743 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | 756 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, |
744 | struct radeon_ib *const_ib); | 757 | struct radeon_ib *const_ib); |
@@ -1131,6 +1144,15 @@ struct radeon_asic { | |||
1131 | void (*tlb_flush)(struct radeon_device *rdev); | 1144 | void (*tlb_flush)(struct radeon_device *rdev); |
1132 | int (*set_page)(struct radeon_device *rdev, int i, uint64_t addr); | 1145 | int (*set_page)(struct radeon_device *rdev, int i, uint64_t addr); |
1133 | } gart; | 1146 | } gart; |
1147 | struct { | ||
1148 | int (*init)(struct radeon_device *rdev); | ||
1149 | void (*fini)(struct radeon_device *rdev); | ||
1150 | |||
1151 | u32 pt_ring_index; | ||
1152 | void (*set_page)(struct radeon_device *rdev, uint64_t pe, | ||
1153 | uint64_t addr, unsigned count, | ||
1154 | uint32_t incr, uint32_t flags); | ||
1155 | } vm; | ||
1134 | /* ring specific callbacks */ | 1156 | /* ring specific callbacks */ |
1135 | struct { | 1157 | struct { |
1136 | void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); | 1158 | void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); |
@@ -1143,6 +1165,7 @@ struct radeon_asic { | |||
1143 | int (*ring_test)(struct radeon_device *rdev, struct radeon_ring *cp); | 1165 | int (*ring_test)(struct radeon_device *rdev, struct radeon_ring *cp); |
1144 | int (*ib_test)(struct radeon_device *rdev, struct radeon_ring *cp); | 1166 | int (*ib_test)(struct radeon_device *rdev, struct radeon_ring *cp); |
1145 | bool (*is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp); | 1167 | bool (*is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp); |
1168 | void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | ||
1146 | } ring[RADEON_NUM_RINGS]; | 1169 | } ring[RADEON_NUM_RINGS]; |
1147 | /* irqs */ | 1170 | /* irqs */ |
1148 | struct { | 1171 | struct { |
@@ -1157,6 +1180,10 @@ struct radeon_asic { | |||
1157 | u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); | 1180 | u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); |
1158 | /* wait for vblank */ | 1181 | /* wait for vblank */ |
1159 | void (*wait_for_vblank)(struct radeon_device *rdev, int crtc); | 1182 | void (*wait_for_vblank)(struct radeon_device *rdev, int crtc); |
1183 | /* set backlight level */ | ||
1184 | void (*set_backlight_level)(struct radeon_encoder *radeon_encoder, u8 level); | ||
1185 | /* get backlight level */ | ||
1186 | u8 (*get_backlight_level)(struct radeon_encoder *radeon_encoder); | ||
1160 | } display; | 1187 | } display; |
1161 | /* copy functions for bo handling */ | 1188 | /* copy functions for bo handling */ |
1162 | struct { | 1189 | struct { |
@@ -1428,6 +1455,56 @@ struct r600_vram_scratch { | |||
1428 | u64 gpu_addr; | 1455 | u64 gpu_addr; |
1429 | }; | 1456 | }; |
1430 | 1457 | ||
1458 | /* | ||
1459 | * ACPI | ||
1460 | */ | ||
1461 | struct radeon_atif_notification_cfg { | ||
1462 | bool enabled; | ||
1463 | int command_code; | ||
1464 | }; | ||
1465 | |||
1466 | struct radeon_atif_notifications { | ||
1467 | bool display_switch; | ||
1468 | bool expansion_mode_change; | ||
1469 | bool thermal_state; | ||
1470 | bool forced_power_state; | ||
1471 | bool system_power_state; | ||
1472 | bool display_conf_change; | ||
1473 | bool px_gfx_switch; | ||
1474 | bool brightness_change; | ||
1475 | bool dgpu_display_event; | ||
1476 | }; | ||
1477 | |||
1478 | struct radeon_atif_functions { | ||
1479 | bool system_params; | ||
1480 | bool sbios_requests; | ||
1481 | bool select_active_disp; | ||
1482 | bool lid_state; | ||
1483 | bool get_tv_standard; | ||
1484 | bool set_tv_standard; | ||
1485 | bool get_panel_expansion_mode; | ||
1486 | bool set_panel_expansion_mode; | ||
1487 | bool temperature_change; | ||
1488 | bool graphics_device_types; | ||
1489 | }; | ||
1490 | |||
1491 | struct radeon_atif { | ||
1492 | struct radeon_atif_notifications notifications; | ||
1493 | struct radeon_atif_functions functions; | ||
1494 | struct radeon_atif_notification_cfg notification_cfg; | ||
1495 | struct radeon_encoder *encoder_for_bl; | ||
1496 | }; | ||
1497 | |||
1498 | struct radeon_atcs_functions { | ||
1499 | bool get_ext_state; | ||
1500 | bool pcie_perf_req; | ||
1501 | bool pcie_dev_rdy; | ||
1502 | bool pcie_bus_width; | ||
1503 | }; | ||
1504 | |||
1505 | struct radeon_atcs { | ||
1506 | struct radeon_atcs_functions functions; | ||
1507 | }; | ||
1431 | 1508 | ||
1432 | /* | 1509 | /* |
1433 | * Core structure, functions and helpers. | 1510 | * Core structure, functions and helpers. |
@@ -1520,6 +1597,9 @@ struct radeon_device { | |||
1520 | /* virtual memory */ | 1597 | /* virtual memory */ |
1521 | struct radeon_vm_manager vm_manager; | 1598 | struct radeon_vm_manager vm_manager; |
1522 | struct mutex gpu_clock_mutex; | 1599 | struct mutex gpu_clock_mutex; |
1600 | /* ACPI interface */ | ||
1601 | struct radeon_atif atif; | ||
1602 | struct radeon_atcs atcs; | ||
1523 | }; | 1603 | }; |
1524 | 1604 | ||
1525 | int radeon_device_init(struct radeon_device *rdev, | 1605 | int radeon_device_init(struct radeon_device *rdev, |
@@ -1683,15 +1763,21 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); | |||
1683 | #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) | 1763 | #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) |
1684 | #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) | 1764 | #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) |
1685 | #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p)) | 1765 | #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p)) |
1766 | #define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev)) | ||
1767 | #define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev)) | ||
1768 | #define radeon_asic_vm_set_page(rdev, pe, addr, count, incr, flags) ((rdev)->asic->vm.set_page((rdev), (pe), (addr), (count), (incr), (flags))) | ||
1686 | #define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)].ring_start((rdev), (cp)) | 1769 | #define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)].ring_start((rdev), (cp)) |
1687 | #define radeon_ring_test(rdev, r, cp) (rdev)->asic->ring[(r)].ring_test((rdev), (cp)) | 1770 | #define radeon_ring_test(rdev, r, cp) (rdev)->asic->ring[(r)].ring_test((rdev), (cp)) |
1688 | #define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), (cp)) | 1771 | #define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), (cp)) |
1689 | #define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)].ib_execute((rdev), (ib)) | 1772 | #define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)].ib_execute((rdev), (ib)) |
1690 | #define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib)) | 1773 | #define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib)) |
1691 | #define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)].is_lockup((rdev), (cp)) | 1774 | #define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)].is_lockup((rdev), (cp)) |
1775 | #define radeon_ring_vm_flush(rdev, r, vm) (rdev)->asic->ring[(r)].vm_flush((rdev), (r), (vm)) | ||
1692 | #define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev)) | 1776 | #define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev)) |
1693 | #define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev)) | 1777 | #define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev)) |
1694 | #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->display.get_vblank_counter((rdev), (crtc)) | 1778 | #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->display.get_vblank_counter((rdev), (crtc)) |
1779 | #define radeon_set_backlight_level(rdev, e, l) (rdev)->asic->display.set_backlight_level((e), (l)) | ||
1780 | #define radeon_get_backlight_level(rdev, e) (rdev)->asic->display.get_backlight_level((e)) | ||
1695 | #define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)].emit_fence((rdev), (fence)) | 1781 | #define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)].emit_fence((rdev), (fence)) |
1696 | #define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)].emit_semaphore((rdev), (cp), (semaphore), (emit_wait)) | 1782 | #define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)].emit_semaphore((rdev), (cp), (semaphore), (emit_wait)) |
1697 | #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (f)) | 1783 | #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (f)) |
@@ -1759,22 +1845,30 @@ int radeon_vm_manager_init(struct radeon_device *rdev); | |||
1759 | void radeon_vm_manager_fini(struct radeon_device *rdev); | 1845 | void radeon_vm_manager_fini(struct radeon_device *rdev); |
1760 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); | 1846 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); |
1761 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); | 1847 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); |
1762 | int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); | 1848 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm); |
1763 | void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); | 1849 | struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, |
1850 | struct radeon_vm *vm, int ring); | ||
1851 | void radeon_vm_fence(struct radeon_device *rdev, | ||
1852 | struct radeon_vm *vm, | ||
1853 | struct radeon_fence *fence); | ||
1854 | uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr); | ||
1764 | int radeon_vm_bo_update_pte(struct radeon_device *rdev, | 1855 | int radeon_vm_bo_update_pte(struct radeon_device *rdev, |
1765 | struct radeon_vm *vm, | 1856 | struct radeon_vm *vm, |
1766 | struct radeon_bo *bo, | 1857 | struct radeon_bo *bo, |
1767 | struct ttm_mem_reg *mem); | 1858 | struct ttm_mem_reg *mem); |
1768 | void radeon_vm_bo_invalidate(struct radeon_device *rdev, | 1859 | void radeon_vm_bo_invalidate(struct radeon_device *rdev, |
1769 | struct radeon_bo *bo); | 1860 | struct radeon_bo *bo); |
1770 | int radeon_vm_bo_add(struct radeon_device *rdev, | 1861 | struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm, |
1771 | struct radeon_vm *vm, | 1862 | struct radeon_bo *bo); |
1772 | struct radeon_bo *bo, | 1863 | struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, |
1773 | uint64_t offset, | 1864 | struct radeon_vm *vm, |
1774 | uint32_t flags); | 1865 | struct radeon_bo *bo); |
1866 | int radeon_vm_bo_set_addr(struct radeon_device *rdev, | ||
1867 | struct radeon_bo_va *bo_va, | ||
1868 | uint64_t offset, | ||
1869 | uint32_t flags); | ||
1775 | int radeon_vm_bo_rmv(struct radeon_device *rdev, | 1870 | int radeon_vm_bo_rmv(struct radeon_device *rdev, |
1776 | struct radeon_vm *vm, | 1871 | struct radeon_bo_va *bo_va); |
1777 | struct radeon_bo *bo); | ||
1778 | 1872 | ||
1779 | /* audio */ | 1873 | /* audio */ |
1780 | void r600_audio_update_hdmi(struct work_struct *work); | 1874 | void r600_audio_update_hdmi(struct work_struct *work); |
@@ -1832,12 +1926,14 @@ extern void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_displ | |||
1832 | extern int ni_init_microcode(struct radeon_device *rdev); | 1926 | extern int ni_init_microcode(struct radeon_device *rdev); |
1833 | extern int ni_mc_load_microcode(struct radeon_device *rdev); | 1927 | extern int ni_mc_load_microcode(struct radeon_device *rdev); |
1834 | 1928 | ||
1835 | /* radeon_acpi.c */ | 1929 | /* radeon_acpi.c */ |
1836 | #if defined(CONFIG_ACPI) | 1930 | #if defined(CONFIG_ACPI) |
1837 | extern int radeon_acpi_init(struct radeon_device *rdev); | 1931 | extern int radeon_acpi_init(struct radeon_device *rdev); |
1838 | #else | 1932 | extern void radeon_acpi_fini(struct radeon_device *rdev); |
1839 | static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } | 1933 | #else |
1840 | #endif | 1934 | static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } |
1935 | static inline void radeon_acpi_fini(struct radeon_device *rdev) { } | ||
1936 | #endif | ||
1841 | 1937 | ||
1842 | #include "radeon_object.h" | 1938 | #include "radeon_object.h" |
1843 | 1939 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index 3516a6081dcf..c3976eb341bf 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c | |||
@@ -1,35 +1,120 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
1 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
2 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
3 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/power_supply.h> | ||
4 | #include <acpi/acpi_drivers.h> | 28 | #include <acpi/acpi_drivers.h> |
5 | #include <acpi/acpi_bus.h> | 29 | #include <acpi/acpi_bus.h> |
30 | #include <acpi/video.h> | ||
6 | 31 | ||
7 | #include "drmP.h" | 32 | #include "drmP.h" |
8 | #include "drm.h" | 33 | #include "drm.h" |
9 | #include "drm_sarea.h" | 34 | #include "drm_sarea.h" |
10 | #include "drm_crtc_helper.h" | 35 | #include "drm_crtc_helper.h" |
11 | #include "radeon.h" | 36 | #include "radeon.h" |
37 | #include "radeon_acpi.h" | ||
38 | #include "atom.h" | ||
12 | 39 | ||
13 | #include <linux/vga_switcheroo.h> | 40 | #include <linux/vga_switcheroo.h> |
14 | 41 | ||
42 | #define ACPI_AC_CLASS "ac_adapter" | ||
43 | |||
44 | extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev); | ||
45 | |||
46 | struct atif_verify_interface { | ||
47 | u16 size; /* structure size in bytes (includes size field) */ | ||
48 | u16 version; /* version */ | ||
49 | u32 notification_mask; /* supported notifications mask */ | ||
50 | u32 function_bits; /* supported functions bit vector */ | ||
51 | } __packed; | ||
52 | |||
53 | struct atif_system_params { | ||
54 | u16 size; /* structure size in bytes (includes size field) */ | ||
55 | u32 valid_mask; /* valid flags mask */ | ||
56 | u32 flags; /* flags */ | ||
57 | u8 command_code; /* notify command code */ | ||
58 | } __packed; | ||
59 | |||
60 | struct atif_sbios_requests { | ||
61 | u16 size; /* structure size in bytes (includes size field) */ | ||
62 | u32 pending; /* pending sbios requests */ | ||
63 | u8 panel_exp_mode; /* panel expansion mode */ | ||
64 | u8 thermal_gfx; /* thermal state: target gfx controller */ | ||
65 | u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */ | ||
66 | u8 forced_power_gfx; /* forced power state: target gfx controller */ | ||
67 | u8 forced_power_state; /* forced power state: state id */ | ||
68 | u8 system_power_src; /* system power source */ | ||
69 | u8 backlight_level; /* panel backlight level (0-255) */ | ||
70 | } __packed; | ||
71 | |||
72 | #define ATIF_NOTIFY_MASK 0x3 | ||
73 | #define ATIF_NOTIFY_NONE 0 | ||
74 | #define ATIF_NOTIFY_81 1 | ||
75 | #define ATIF_NOTIFY_N 2 | ||
76 | |||
77 | struct atcs_verify_interface { | ||
78 | u16 size; /* structure size in bytes (includes size field) */ | ||
79 | u16 version; /* version */ | ||
80 | u32 function_bits; /* supported functions bit vector */ | ||
81 | } __packed; | ||
82 | |||
15 | /* Call the ATIF method | 83 | /* Call the ATIF method |
84 | */ | ||
85 | /** | ||
86 | * radeon_atif_call - call an ATIF method | ||
16 | * | 87 | * |
17 | * Note: currently we discard the output | 88 | * @handle: acpi handle |
89 | * @function: the ATIF function to execute | ||
90 | * @params: ATIF function params | ||
91 | * | ||
92 | * Executes the requested ATIF function (all asics). | ||
93 | * Returns a pointer to the acpi output buffer. | ||
18 | */ | 94 | */ |
19 | static int radeon_atif_call(acpi_handle handle) | 95 | static union acpi_object *radeon_atif_call(acpi_handle handle, int function, |
96 | struct acpi_buffer *params) | ||
20 | { | 97 | { |
21 | acpi_status status; | 98 | acpi_status status; |
22 | union acpi_object atif_arg_elements[2]; | 99 | union acpi_object atif_arg_elements[2]; |
23 | struct acpi_object_list atif_arg; | 100 | struct acpi_object_list atif_arg; |
24 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; | 101 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
25 | 102 | ||
26 | atif_arg.count = 2; | 103 | atif_arg.count = 2; |
27 | atif_arg.pointer = &atif_arg_elements[0]; | 104 | atif_arg.pointer = &atif_arg_elements[0]; |
28 | 105 | ||
29 | atif_arg_elements[0].type = ACPI_TYPE_INTEGER; | 106 | atif_arg_elements[0].type = ACPI_TYPE_INTEGER; |
30 | atif_arg_elements[0].integer.value = 0; | 107 | atif_arg_elements[0].integer.value = function; |
31 | atif_arg_elements[1].type = ACPI_TYPE_INTEGER; | 108 | |
32 | atif_arg_elements[1].integer.value = 0; | 109 | if (params) { |
110 | atif_arg_elements[1].type = ACPI_TYPE_BUFFER; | ||
111 | atif_arg_elements[1].buffer.length = params->length; | ||
112 | atif_arg_elements[1].buffer.pointer = params->pointer; | ||
113 | } else { | ||
114 | /* We need a second fake parameter */ | ||
115 | atif_arg_elements[1].type = ACPI_TYPE_INTEGER; | ||
116 | atif_arg_elements[1].integer.value = 0; | ||
117 | } | ||
33 | 118 | ||
34 | status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); | 119 | status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); |
35 | 120 | ||
@@ -38,17 +123,434 @@ static int radeon_atif_call(acpi_handle handle) | |||
38 | DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", | 123 | DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", |
39 | acpi_format_exception(status)); | 124 | acpi_format_exception(status)); |
40 | kfree(buffer.pointer); | 125 | kfree(buffer.pointer); |
41 | return 1; | 126 | return NULL; |
42 | } | 127 | } |
43 | 128 | ||
44 | kfree(buffer.pointer); | 129 | return buffer.pointer; |
45 | return 0; | 130 | } |
131 | |||
132 | /** | ||
133 | * radeon_atif_parse_notification - parse supported notifications | ||
134 | * | ||
135 | * @n: supported notifications struct | ||
136 | * @mask: supported notifications mask from ATIF | ||
137 | * | ||
138 | * Use the supported notifications mask from ATIF function | ||
139 | * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications | ||
140 | * are supported (all asics). | ||
141 | */ | ||
142 | static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask) | ||
143 | { | ||
144 | n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED; | ||
145 | n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED; | ||
146 | n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED; | ||
147 | n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED; | ||
148 | n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED; | ||
149 | n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED; | ||
150 | n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED; | ||
151 | n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED; | ||
152 | n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED; | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * radeon_atif_parse_functions - parse supported functions | ||
157 | * | ||
158 | * @f: supported functions struct | ||
159 | * @mask: supported functions mask from ATIF | ||
160 | * | ||
161 | * Use the supported functions mask from ATIF function | ||
162 | * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions | ||
163 | * are supported (all asics). | ||
164 | */ | ||
165 | static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask) | ||
166 | { | ||
167 | f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED; | ||
168 | f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED; | ||
169 | f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED; | ||
170 | f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED; | ||
171 | f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED; | ||
172 | f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED; | ||
173 | f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED; | ||
174 | f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED; | ||
175 | f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED; | ||
176 | f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED; | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * radeon_atif_verify_interface - verify ATIF | ||
181 | * | ||
182 | * @handle: acpi handle | ||
183 | * @atif: radeon atif struct | ||
184 | * | ||
185 | * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function | ||
186 | * to initialize ATIF and determine what features are supported | ||
187 | * (all asics). | ||
188 | * returns 0 on success, error on failure. | ||
189 | */ | ||
190 | static int radeon_atif_verify_interface(acpi_handle handle, | ||
191 | struct radeon_atif *atif) | ||
192 | { | ||
193 | union acpi_object *info; | ||
194 | struct atif_verify_interface output; | ||
195 | size_t size; | ||
196 | int err = 0; | ||
197 | |||
198 | info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); | ||
199 | if (!info) | ||
200 | return -EIO; | ||
201 | |||
202 | memset(&output, 0, sizeof(output)); | ||
203 | |||
204 | size = *(u16 *) info->buffer.pointer; | ||
205 | if (size < 12) { | ||
206 | DRM_INFO("ATIF buffer is too small: %lu\n", size); | ||
207 | err = -EINVAL; | ||
208 | goto out; | ||
209 | } | ||
210 | size = min(sizeof(output), size); | ||
211 | |||
212 | memcpy(&output, info->buffer.pointer, size); | ||
213 | |||
214 | /* TODO: check version? */ | ||
215 | DRM_DEBUG_DRIVER("ATIF version %u\n", output.version); | ||
216 | |||
217 | radeon_atif_parse_notification(&atif->notifications, output.notification_mask); | ||
218 | radeon_atif_parse_functions(&atif->functions, output.function_bits); | ||
219 | |||
220 | out: | ||
221 | kfree(info); | ||
222 | return err; | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * radeon_atif_get_notification_params - determine notify configuration | ||
227 | * | ||
228 | * @handle: acpi handle | ||
229 | * @n: atif notification configuration struct | ||
230 | * | ||
231 | * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function | ||
232 | * to determine if a notifier is used and if so which one | ||
233 | * (all asics). This is either Notify(VGA, 0x81) or Notify(VGA, n) | ||
234 | * where n is specified in the result if a notifier is used. | ||
235 | * Returns 0 on success, error on failure. | ||
236 | */ | ||
237 | static int radeon_atif_get_notification_params(acpi_handle handle, | ||
238 | struct radeon_atif_notification_cfg *n) | ||
239 | { | ||
240 | union acpi_object *info; | ||
241 | struct atif_system_params params; | ||
242 | size_t size; | ||
243 | int err = 0; | ||
244 | |||
245 | info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); | ||
246 | if (!info) { | ||
247 | err = -EIO; | ||
248 | goto out; | ||
249 | } | ||
250 | |||
251 | size = *(u16 *) info->buffer.pointer; | ||
252 | if (size < 10) { | ||
253 | err = -EINVAL; | ||
254 | goto out; | ||
255 | } | ||
256 | |||
257 | memset(¶ms, 0, sizeof(params)); | ||
258 | size = min(sizeof(params), size); | ||
259 | memcpy(¶ms, info->buffer.pointer, size); | ||
260 | |||
261 | DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n", | ||
262 | params.flags, params.valid_mask); | ||
263 | params.flags = params.flags & params.valid_mask; | ||
264 | |||
265 | if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) { | ||
266 | n->enabled = false; | ||
267 | n->command_code = 0; | ||
268 | } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) { | ||
269 | n->enabled = true; | ||
270 | n->command_code = 0x81; | ||
271 | } else { | ||
272 | if (size < 11) { | ||
273 | err = -EINVAL; | ||
274 | goto out; | ||
275 | } | ||
276 | n->enabled = true; | ||
277 | n->command_code = params.command_code; | ||
278 | } | ||
279 | |||
280 | out: | ||
281 | DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n", | ||
282 | (n->enabled ? "enabled" : "disabled"), | ||
283 | n->command_code); | ||
284 | kfree(info); | ||
285 | return err; | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * radeon_atif_get_sbios_requests - get requested sbios event | ||
290 | * | ||
291 | * @handle: acpi handle | ||
292 | * @req: atif sbios request struct | ||
293 | * | ||
294 | * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function | ||
295 | * to determine what requests the sbios is making to the driver | ||
296 | * (all asics). | ||
297 | * Returns 0 on success, error on failure. | ||
298 | */ | ||
299 | static int radeon_atif_get_sbios_requests(acpi_handle handle, | ||
300 | struct atif_sbios_requests *req) | ||
301 | { | ||
302 | union acpi_object *info; | ||
303 | size_t size; | ||
304 | int count = 0; | ||
305 | |||
306 | info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); | ||
307 | if (!info) | ||
308 | return -EIO; | ||
309 | |||
310 | size = *(u16 *)info->buffer.pointer; | ||
311 | if (size < 0xd) { | ||
312 | count = -EINVAL; | ||
313 | goto out; | ||
314 | } | ||
315 | memset(req, 0, sizeof(*req)); | ||
316 | |||
317 | size = min(sizeof(*req), size); | ||
318 | memcpy(req, info->buffer.pointer, size); | ||
319 | DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending); | ||
320 | |||
321 | count = hweight32(req->pending); | ||
322 | |||
323 | out: | ||
324 | kfree(info); | ||
325 | return count; | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * radeon_atif_handler - handle ATIF notify requests | ||
330 | * | ||
331 | * @rdev: radeon_device pointer | ||
332 | * @event: atif sbios request struct | ||
333 | * | ||
334 | * Checks the acpi event and if it matches an atif event, | ||
335 | * handles it. | ||
336 | * Returns NOTIFY code | ||
337 | */ | ||
338 | int radeon_atif_handler(struct radeon_device *rdev, | ||
339 | struct acpi_bus_event *event) | ||
340 | { | ||
341 | struct radeon_atif *atif = &rdev->atif; | ||
342 | struct atif_sbios_requests req; | ||
343 | acpi_handle handle; | ||
344 | int count; | ||
345 | |||
346 | DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", | ||
347 | event->device_class, event->type); | ||
348 | |||
349 | if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) | ||
350 | return NOTIFY_DONE; | ||
351 | |||
352 | if (!atif->notification_cfg.enabled || | ||
353 | event->type != atif->notification_cfg.command_code) | ||
354 | /* Not our event */ | ||
355 | return NOTIFY_DONE; | ||
356 | |||
357 | /* Check pending SBIOS requests */ | ||
358 | handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); | ||
359 | count = radeon_atif_get_sbios_requests(handle, &req); | ||
360 | |||
361 | if (count <= 0) | ||
362 | return NOTIFY_DONE; | ||
363 | |||
364 | DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count); | ||
365 | |||
366 | if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) { | ||
367 | struct radeon_encoder *enc = atif->encoder_for_bl; | ||
368 | |||
369 | if (enc) { | ||
370 | DRM_DEBUG_DRIVER("Changing brightness to %d\n", | ||
371 | req.backlight_level); | ||
372 | |||
373 | radeon_set_backlight_level(rdev, enc, req.backlight_level); | ||
374 | |||
375 | if (rdev->is_atom_bios) { | ||
376 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; | ||
377 | backlight_force_update(dig->bl_dev, | ||
378 | BACKLIGHT_UPDATE_HOTKEY); | ||
379 | } else { | ||
380 | struct radeon_encoder_lvds *dig = enc->enc_priv; | ||
381 | backlight_force_update(dig->bl_dev, | ||
382 | BACKLIGHT_UPDATE_HOTKEY); | ||
383 | } | ||
384 | } | ||
385 | } | ||
386 | /* TODO: check other events */ | ||
387 | |||
388 | /* We've handled the event, stop the notifier chain. The ACPI interface | ||
389 | * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to | ||
390 | * userspace if the event was generated only to signal a SBIOS | ||
391 | * request. | ||
392 | */ | ||
393 | return NOTIFY_BAD; | ||
394 | } | ||
395 | |||
396 | /* Call the ATCS method | ||
397 | */ | ||
398 | /** | ||
399 | * radeon_atcs_call - call an ATCS method | ||
400 | * | ||
401 | * @handle: acpi handle | ||
402 | * @function: the ATCS function to execute | ||
403 | * @params: ATCS function params | ||
404 | * | ||
405 | * Executes the requested ATCS function (all asics). | ||
406 | * Returns a pointer to the acpi output buffer. | ||
407 | */ | ||
408 | static union acpi_object *radeon_atcs_call(acpi_handle handle, int function, | ||
409 | struct acpi_buffer *params) | ||
410 | { | ||
411 | acpi_status status; | ||
412 | union acpi_object atcs_arg_elements[2]; | ||
413 | struct acpi_object_list atcs_arg; | ||
414 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
415 | |||
416 | atcs_arg.count = 2; | ||
417 | atcs_arg.pointer = &atcs_arg_elements[0]; | ||
418 | |||
419 | atcs_arg_elements[0].type = ACPI_TYPE_INTEGER; | ||
420 | atcs_arg_elements[0].integer.value = function; | ||
421 | |||
422 | if (params) { | ||
423 | atcs_arg_elements[1].type = ACPI_TYPE_BUFFER; | ||
424 | atcs_arg_elements[1].buffer.length = params->length; | ||
425 | atcs_arg_elements[1].buffer.pointer = params->pointer; | ||
426 | } else { | ||
427 | /* We need a second fake parameter */ | ||
428 | atcs_arg_elements[1].type = ACPI_TYPE_INTEGER; | ||
429 | atcs_arg_elements[1].integer.value = 0; | ||
430 | } | ||
431 | |||
432 | status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer); | ||
433 | |||
434 | /* Fail only if calling the method fails and ATIF is supported */ | ||
435 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
436 | DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n", | ||
437 | acpi_format_exception(status)); | ||
438 | kfree(buffer.pointer); | ||
439 | return NULL; | ||
440 | } | ||
441 | |||
442 | return buffer.pointer; | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * radeon_atcs_parse_functions - parse supported functions | ||
447 | * | ||
448 | * @f: supported functions struct | ||
449 | * @mask: supported functions mask from ATCS | ||
450 | * | ||
451 | * Use the supported functions mask from ATCS function | ||
452 | * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions | ||
453 | * are supported (all asics). | ||
454 | */ | ||
455 | static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask) | ||
456 | { | ||
457 | f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED; | ||
458 | f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED; | ||
459 | f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED; | ||
460 | f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED; | ||
461 | } | ||
462 | |||
463 | /** | ||
464 | * radeon_atcs_verify_interface - verify ATCS | ||
465 | * | ||
466 | * @handle: acpi handle | ||
467 | * @atcs: radeon atcs struct | ||
468 | * | ||
469 | * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function | ||
470 | * to initialize ATCS and determine what features are supported | ||
471 | * (all asics). | ||
472 | * returns 0 on success, error on failure. | ||
473 | */ | ||
474 | static int radeon_atcs_verify_interface(acpi_handle handle, | ||
475 | struct radeon_atcs *atcs) | ||
476 | { | ||
477 | union acpi_object *info; | ||
478 | struct atcs_verify_interface output; | ||
479 | size_t size; | ||
480 | int err = 0; | ||
481 | |||
482 | info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL); | ||
483 | if (!info) | ||
484 | return -EIO; | ||
485 | |||
486 | memset(&output, 0, sizeof(output)); | ||
487 | |||
488 | size = *(u16 *) info->buffer.pointer; | ||
489 | if (size < 8) { | ||
490 | DRM_INFO("ATCS buffer is too small: %lu\n", size); | ||
491 | err = -EINVAL; | ||
492 | goto out; | ||
493 | } | ||
494 | size = min(sizeof(output), size); | ||
495 | |||
496 | memcpy(&output, info->buffer.pointer, size); | ||
497 | |||
498 | /* TODO: check version? */ | ||
499 | DRM_DEBUG_DRIVER("ATCS version %u\n", output.version); | ||
500 | |||
501 | radeon_atcs_parse_functions(&atcs->functions, output.function_bits); | ||
502 | |||
503 | out: | ||
504 | kfree(info); | ||
505 | return err; | ||
506 | } | ||
507 | |||
508 | /** | ||
509 | * radeon_acpi_event - handle notify events | ||
510 | * | ||
511 | * @nb: notifier block | ||
512 | * @val: val | ||
513 | * @data: acpi event | ||
514 | * | ||
515 | * Calls relevant radeon functions in response to various | ||
516 | * acpi events. | ||
517 | * Returns NOTIFY code | ||
518 | */ | ||
519 | static int radeon_acpi_event(struct notifier_block *nb, | ||
520 | unsigned long val, | ||
521 | void *data) | ||
522 | { | ||
523 | struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb); | ||
524 | struct acpi_bus_event *entry = (struct acpi_bus_event *)data; | ||
525 | |||
526 | if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { | ||
527 | if (power_supply_is_system_supplied() > 0) | ||
528 | DRM_DEBUG_DRIVER("pm: AC\n"); | ||
529 | else | ||
530 | DRM_DEBUG_DRIVER("pm: DC\n"); | ||
531 | |||
532 | radeon_pm_acpi_event_handler(rdev); | ||
533 | } | ||
534 | |||
535 | /* Check for pending SBIOS requests */ | ||
536 | return radeon_atif_handler(rdev, entry); | ||
46 | } | 537 | } |
47 | 538 | ||
48 | /* Call all ACPI methods here */ | 539 | /* Call all ACPI methods here */ |
540 | /** | ||
541 | * radeon_acpi_init - init driver acpi support | ||
542 | * | ||
543 | * @rdev: radeon_device pointer | ||
544 | * | ||
545 | * Verifies the AMD ACPI interfaces and registers with the acpi | ||
546 | * notifier chain (all asics). | ||
547 | * Returns 0 on success, error on failure. | ||
548 | */ | ||
49 | int radeon_acpi_init(struct radeon_device *rdev) | 549 | int radeon_acpi_init(struct radeon_device *rdev) |
50 | { | 550 | { |
51 | acpi_handle handle; | 551 | acpi_handle handle; |
552 | struct radeon_atif *atif = &rdev->atif; | ||
553 | struct radeon_atcs *atcs = &rdev->atcs; | ||
52 | int ret; | 554 | int ret; |
53 | 555 | ||
54 | /* Get the device handle */ | 556 | /* Get the device handle */ |
@@ -58,11 +560,90 @@ int radeon_acpi_init(struct radeon_device *rdev) | |||
58 | if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle) | 560 | if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle) |
59 | return 0; | 561 | return 0; |
60 | 562 | ||
563 | /* Call the ATCS method */ | ||
564 | ret = radeon_atcs_verify_interface(handle, atcs); | ||
565 | if (ret) { | ||
566 | DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret); | ||
567 | } | ||
568 | |||
61 | /* Call the ATIF method */ | 569 | /* Call the ATIF method */ |
62 | ret = radeon_atif_call(handle); | 570 | ret = radeon_atif_verify_interface(handle, atif); |
63 | if (ret) | 571 | if (ret) { |
64 | return ret; | 572 | DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); |
573 | goto out; | ||
574 | } | ||
575 | |||
576 | if (atif->notifications.brightness_change) { | ||
577 | struct drm_encoder *tmp; | ||
578 | struct radeon_encoder *target = NULL; | ||
579 | |||
580 | /* Find the encoder controlling the brightness */ | ||
581 | list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list, | ||
582 | head) { | ||
583 | struct radeon_encoder *enc = to_radeon_encoder(tmp); | ||
584 | |||
585 | if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) && | ||
586 | enc->enc_priv) { | ||
587 | if (rdev->is_atom_bios) { | ||
588 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; | ||
589 | if (dig->bl_dev) { | ||
590 | target = enc; | ||
591 | break; | ||
592 | } | ||
593 | } else { | ||
594 | struct radeon_encoder_lvds *dig = enc->enc_priv; | ||
595 | if (dig->bl_dev) { | ||
596 | target = enc; | ||
597 | break; | ||
598 | } | ||
599 | } | ||
600 | } | ||
601 | } | ||
602 | |||
603 | atif->encoder_for_bl = target; | ||
604 | if (!target) { | ||
605 | /* Brightness change notification is enabled, but we | ||
606 | * didn't find a backlight controller, this should | ||
607 | * never happen. | ||
608 | */ | ||
609 | DRM_ERROR("Cannot find a backlight controller\n"); | ||
610 | } | ||
611 | } | ||
65 | 612 | ||
66 | return 0; | 613 | if (atif->functions.sbios_requests && !atif->functions.system_params) { |
614 | /* XXX check this workraround, if sbios request function is | ||
615 | * present we have to see how it's configured in the system | ||
616 | * params | ||
617 | */ | ||
618 | atif->functions.system_params = true; | ||
619 | } | ||
620 | |||
621 | if (atif->functions.system_params) { | ||
622 | ret = radeon_atif_get_notification_params(handle, | ||
623 | &atif->notification_cfg); | ||
624 | if (ret) { | ||
625 | DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", | ||
626 | ret); | ||
627 | /* Disable notification */ | ||
628 | atif->notification_cfg.enabled = false; | ||
629 | } | ||
630 | } | ||
631 | |||
632 | out: | ||
633 | rdev->acpi_nb.notifier_call = radeon_acpi_event; | ||
634 | register_acpi_notifier(&rdev->acpi_nb); | ||
635 | |||
636 | return ret; | ||
67 | } | 637 | } |
68 | 638 | ||
639 | /** | ||
640 | * radeon_acpi_fini - tear down driver acpi support | ||
641 | * | ||
642 | * @rdev: radeon_device pointer | ||
643 | * | ||
644 | * Unregisters with the acpi notifier chain (all asics). | ||
645 | */ | ||
646 | void radeon_acpi_fini(struct radeon_device *rdev) | ||
647 | { | ||
648 | unregister_acpi_notifier(&rdev->acpi_nb); | ||
649 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.h b/drivers/gpu/drm/radeon/radeon_acpi.h new file mode 100644 index 000000000000..be4af76f213d --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_acpi.h | |||
@@ -0,0 +1,445 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef RADEON_ACPI_H | ||
25 | #define RADEON_ACPI_H | ||
26 | |||
27 | struct radeon_device; | ||
28 | struct acpi_bus_event; | ||
29 | |||
30 | int radeon_atif_handler(struct radeon_device *rdev, | ||
31 | struct acpi_bus_event *event); | ||
32 | |||
33 | /* AMD hw uses four ACPI control methods: | ||
34 | * 1. ATIF | ||
35 | * ARG0: (ACPI_INTEGER) function code | ||
36 | * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes | ||
37 | * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes | ||
38 | * ATIF provides an entry point for the gfx driver to interact with the sbios. | ||
39 | * The AMD ACPI notification mechanism uses Notify (VGA, 0x81) or a custom | ||
40 | * notification. Which notification is used as indicated by the ATIF Control | ||
41 | * Method GET_SYSTEM_PARAMETERS. When the driver receives Notify (VGA, 0x81) or | ||
42 | * a custom notification it invokes ATIF Control Method GET_SYSTEM_BIOS_REQUESTS | ||
43 | * to identify pending System BIOS requests and associated parameters. For | ||
44 | * example, if one of the pending requests is DISPLAY_SWITCH_REQUEST, the driver | ||
45 | * will perform display device detection and invoke ATIF Control Method | ||
46 | * SELECT_ACTIVE_DISPLAYS. | ||
47 | * | ||
48 | * 2. ATPX | ||
49 | * ARG0: (ACPI_INTEGER) function code | ||
50 | * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes | ||
51 | * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes | ||
52 | * ATPX methods are used on PowerXpress systems to handle mux switching and | ||
53 | * discrete GPU power control. | ||
54 | * | ||
55 | * 3. ATRM | ||
56 | * ARG0: (ACPI_INTEGER) offset of vbios rom data | ||
57 | * ARG1: (ACPI_BUFFER) size of the buffer to fill (up to 4K). | ||
58 | * OUTPUT: (ACPI_BUFFER) output buffer | ||
59 | * ATRM provides an interfacess to access the discrete GPU vbios image on | ||
60 | * PowerXpress systems with multiple GPUs. | ||
61 | * | ||
62 | * 4. ATCS | ||
63 | * ARG0: (ACPI_INTEGER) function code | ||
64 | * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes | ||
65 | * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes | ||
66 | * ATCS provides an interface to AMD chipset specific functionality. | ||
67 | * | ||
68 | */ | ||
69 | /* ATIF */ | ||
70 | #define ATIF_FUNCTION_VERIFY_INTERFACE 0x0 | ||
71 | /* ARG0: ATIF_FUNCTION_VERIFY_INTERFACE | ||
72 | * ARG1: none | ||
73 | * OUTPUT: | ||
74 | * WORD - structure size in bytes (includes size field) | ||
75 | * WORD - version | ||
76 | * DWORD - supported notifications mask | ||
77 | * DWORD - supported functions bit vector | ||
78 | */ | ||
79 | /* Notifications mask */ | ||
80 | # define ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED (1 << 0) | ||
81 | # define ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED (1 << 1) | ||
82 | # define ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED (1 << 2) | ||
83 | # define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED (1 << 3) | ||
84 | # define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED (1 << 4) | ||
85 | # define ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED (1 << 5) | ||
86 | # define ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED (1 << 6) | ||
87 | # define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED (1 << 7) | ||
88 | # define ATIF_DGPU_DISPLAY_EVENT_SUPPORTED (1 << 8) | ||
89 | /* supported functions vector */ | ||
90 | # define ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED (1 << 0) | ||
91 | # define ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED (1 << 1) | ||
92 | # define ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED (1 << 2) | ||
93 | # define ATIF_GET_LID_STATE_SUPPORTED (1 << 3) | ||
94 | # define ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED (1 << 4) | ||
95 | # define ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED (1 << 5) | ||
96 | # define ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED (1 << 6) | ||
97 | # define ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED (1 << 7) | ||
98 | # define ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED (1 << 12) | ||
99 | # define ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED (1 << 14) | ||
100 | #define ATIF_FUNCTION_GET_SYSTEM_PARAMETERS 0x1 | ||
101 | /* ARG0: ATIF_FUNCTION_GET_SYSTEM_PARAMETERS | ||
102 | * ARG1: none | ||
103 | * OUTPUT: | ||
104 | * WORD - structure size in bytes (includes size field) | ||
105 | * DWORD - valid flags mask | ||
106 | * DWORD - flags | ||
107 | * | ||
108 | * OR | ||
109 | * | ||
110 | * WORD - structure size in bytes (includes size field) | ||
111 | * DWORD - valid flags mask | ||
112 | * DWORD - flags | ||
113 | * BYTE - notify command code | ||
114 | * | ||
115 | * flags | ||
116 | * bits 1:0: | ||
117 | * 0 - Notify(VGA, 0x81) is not used for notification | ||
118 | * 1 - Notify(VGA, 0x81) is used for notification | ||
119 | * 2 - Notify(VGA, n) is used for notification where | ||
120 | * n (0xd0-0xd9) is specified in notify command code. | ||
121 | * bit 2: | ||
122 | * 1 - lid changes not reported though int10 | ||
123 | */ | ||
124 | #define ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS 0x2 | ||
125 | /* ARG0: ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS | ||
126 | * ARG1: none | ||
127 | * OUTPUT: | ||
128 | * WORD - structure size in bytes (includes size field) | ||
129 | * DWORD - pending sbios requests | ||
130 | * BYTE - panel expansion mode | ||
131 | * BYTE - thermal state: target gfx controller | ||
132 | * BYTE - thermal state: state id (0: exit state, non-0: state) | ||
133 | * BYTE - forced power state: target gfx controller | ||
134 | * BYTE - forced power state: state id | ||
135 | * BYTE - system power source | ||
136 | * BYTE - panel backlight level (0-255) | ||
137 | */ | ||
138 | /* pending sbios requests */ | ||
139 | # define ATIF_DISPLAY_SWITCH_REQUEST (1 << 0) | ||
140 | # define ATIF_EXPANSION_MODE_CHANGE_REQUEST (1 << 1) | ||
141 | # define ATIF_THERMAL_STATE_CHANGE_REQUEST (1 << 2) | ||
142 | # define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST (1 << 3) | ||
143 | # define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST (1 << 4) | ||
144 | # define ATIF_DISPLAY_CONF_CHANGE_REQUEST (1 << 5) | ||
145 | # define ATIF_PX_GFX_SWITCH_REQUEST (1 << 6) | ||
146 | # define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST (1 << 7) | ||
147 | # define ATIF_DGPU_DISPLAY_EVENT (1 << 8) | ||
148 | /* panel expansion mode */ | ||
149 | # define ATIF_PANEL_EXPANSION_DISABLE 0 | ||
150 | # define ATIF_PANEL_EXPANSION_FULL 1 | ||
151 | # define ATIF_PANEL_EXPANSION_ASPECT 2 | ||
152 | /* target gfx controller */ | ||
153 | # define ATIF_TARGET_GFX_SINGLE 0 | ||
154 | # define ATIF_TARGET_GFX_PX_IGPU 1 | ||
155 | # define ATIF_TARGET_GFX_PX_DGPU 2 | ||
156 | /* system power source */ | ||
157 | # define ATIF_POWER_SOURCE_AC 1 | ||
158 | # define ATIF_POWER_SOURCE_DC 2 | ||
159 | # define ATIF_POWER_SOURCE_RESTRICTED_AC_1 3 | ||
160 | # define ATIF_POWER_SOURCE_RESTRICTED_AC_2 4 | ||
161 | #define ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS 0x3 | ||
162 | /* ARG0: ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS | ||
163 | * ARG1: | ||
164 | * WORD - structure size in bytes (includes size field) | ||
165 | * WORD - selected displays | ||
166 | * WORD - connected displays | ||
167 | * OUTPUT: | ||
168 | * WORD - structure size in bytes (includes size field) | ||
169 | * WORD - selected displays | ||
170 | */ | ||
171 | # define ATIF_LCD1 (1 << 0) | ||
172 | # define ATIF_CRT1 (1 << 1) | ||
173 | # define ATIF_TV (1 << 2) | ||
174 | # define ATIF_DFP1 (1 << 3) | ||
175 | # define ATIF_CRT2 (1 << 4) | ||
176 | # define ATIF_LCD2 (1 << 5) | ||
177 | # define ATIF_DFP2 (1 << 7) | ||
178 | # define ATIF_CV (1 << 8) | ||
179 | # define ATIF_DFP3 (1 << 9) | ||
180 | # define ATIF_DFP4 (1 << 10) | ||
181 | # define ATIF_DFP5 (1 << 11) | ||
182 | # define ATIF_DFP6 (1 << 12) | ||
183 | #define ATIF_FUNCTION_GET_LID_STATE 0x4 | ||
184 | /* ARG0: ATIF_FUNCTION_GET_LID_STATE | ||
185 | * ARG1: none | ||
186 | * OUTPUT: | ||
187 | * WORD - structure size in bytes (includes size field) | ||
188 | * BYTE - lid state (0: open, 1: closed) | ||
189 | * | ||
190 | * GET_LID_STATE only works at boot and resume, for general lid | ||
191 | * status, use the kernel provided status | ||
192 | */ | ||
193 | #define ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS 0x5 | ||
194 | /* ARG0: ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS | ||
195 | * ARG1: none | ||
196 | * OUTPUT: | ||
197 | * WORD - structure size in bytes (includes size field) | ||
198 | * BYTE - 0 | ||
199 | * BYTE - TV standard | ||
200 | */ | ||
201 | # define ATIF_TV_STD_NTSC 0 | ||
202 | # define ATIF_TV_STD_PAL 1 | ||
203 | # define ATIF_TV_STD_PALM 2 | ||
204 | # define ATIF_TV_STD_PAL60 3 | ||
205 | # define ATIF_TV_STD_NTSCJ 4 | ||
206 | # define ATIF_TV_STD_PALCN 5 | ||
207 | # define ATIF_TV_STD_PALN 6 | ||
208 | # define ATIF_TV_STD_SCART_RGB 9 | ||
209 | #define ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS 0x6 | ||
210 | /* ARG0: ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS | ||
211 | * ARG1: | ||
212 | * WORD - structure size in bytes (includes size field) | ||
213 | * BYTE - 0 | ||
214 | * BYTE - TV standard | ||
215 | * OUTPUT: none | ||
216 | */ | ||
217 | #define ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS 0x7 | ||
218 | /* ARG0: ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS | ||
219 | * ARG1: none | ||
220 | * OUTPUT: | ||
221 | * WORD - structure size in bytes (includes size field) | ||
222 | * BYTE - panel expansion mode | ||
223 | */ | ||
224 | #define ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS 0x8 | ||
225 | /* ARG0: ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS | ||
226 | * ARG1: | ||
227 | * WORD - structure size in bytes (includes size field) | ||
228 | * BYTE - panel expansion mode | ||
229 | * OUTPUT: none | ||
230 | */ | ||
231 | #define ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION 0xD | ||
232 | /* ARG0: ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION | ||
233 | * ARG1: | ||
234 | * WORD - structure size in bytes (includes size field) | ||
235 | * WORD - gfx controller id | ||
236 | * BYTE - current temperature (degress Celsius) | ||
237 | * OUTPUT: none | ||
238 | */ | ||
239 | #define ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES 0xF | ||
240 | /* ARG0: ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES | ||
241 | * ARG1: none | ||
242 | * OUTPUT: | ||
243 | * WORD - number of gfx devices | ||
244 | * WORD - device structure size in bytes (excludes device size field) | ||
245 | * DWORD - flags \ | ||
246 | * WORD - bus number } repeated structure | ||
247 | * WORD - device number / | ||
248 | */ | ||
249 | /* flags */ | ||
250 | # define ATIF_PX_REMOVABLE_GRAPHICS_DEVICE (1 << 0) | ||
251 | # define ATIF_XGP_PORT (1 << 1) | ||
252 | # define ATIF_VGA_ENABLED_GRAPHICS_DEVICE (1 << 2) | ||
253 | # define ATIF_XGP_PORT_IN_DOCK (1 << 3) | ||
254 | |||
255 | /* ATPX */ | ||
256 | #define ATPX_FUNCTION_VERIFY_INTERFACE 0x0 | ||
257 | /* ARG0: ATPX_FUNCTION_VERIFY_INTERFACE | ||
258 | * ARG1: none | ||
259 | * OUTPUT: | ||
260 | * WORD - structure size in bytes (includes size field) | ||
261 | * WORD - version | ||
262 | * DWORD - supported functions bit vector | ||
263 | */ | ||
264 | /* supported functions vector */ | ||
265 | # define ATPX_GET_PX_PARAMETERS_SUPPORTED (1 << 0) | ||
266 | # define ATPX_POWER_CONTROL_SUPPORTED (1 << 1) | ||
267 | # define ATPX_DISPLAY_MUX_CONTROL_SUPPORTED (1 << 2) | ||
268 | # define ATPX_I2C_MUX_CONTROL_SUPPORTED (1 << 3) | ||
269 | # define ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED (1 << 4) | ||
270 | # define ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED (1 << 5) | ||
271 | # define ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED (1 << 7) | ||
272 | # define ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED (1 << 8) | ||
273 | #define ATPX_FUNCTION_GET_PX_PARAMETERS 0x1 | ||
274 | /* ARG0: ATPX_FUNCTION_GET_PX_PARAMETERS | ||
275 | * ARG1: none | ||
276 | * OUTPUT: | ||
277 | * WORD - structure size in bytes (includes size field) | ||
278 | * DWORD - valid flags mask | ||
279 | * DWORD - flags | ||
280 | */ | ||
281 | /* flags */ | ||
282 | # define ATPX_LVDS_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 0) | ||
283 | # define ATPX_CRT1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 1) | ||
284 | # define ATPX_DVI1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 2) | ||
285 | # define ATPX_CRT1_RGB_SIGNAL_MUXED (1 << 3) | ||
286 | # define ATPX_TV_SIGNAL_MUXED (1 << 4) | ||
287 | # define ATPX_DFP_SIGNAL_MUXED (1 << 5) | ||
288 | # define ATPX_SEPARATE_MUX_FOR_I2C (1 << 6) | ||
289 | # define ATPX_DYNAMIC_PX_SUPPORTED (1 << 7) | ||
290 | # define ATPX_ACF_NOT_SUPPORTED (1 << 8) | ||
291 | # define ATPX_FIXED_NOT_SUPPORTED (1 << 9) | ||
292 | # define ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED (1 << 10) | ||
293 | # define ATPX_DGPU_REQ_POWER_FOR_DISPLAYS (1 << 11) | ||
294 | #define ATPX_FUNCTION_POWER_CONTROL 0x2 | ||
295 | /* ARG0: ATPX_FUNCTION_POWER_CONTROL | ||
296 | * ARG1: | ||
297 | * WORD - structure size in bytes (includes size field) | ||
298 | * BYTE - dGPU power state (0: power off, 1: power on) | ||
299 | * OUTPUT: none | ||
300 | */ | ||
301 | #define ATPX_FUNCTION_DISPLAY_MUX_CONTROL 0x3 | ||
302 | /* ARG0: ATPX_FUNCTION_DISPLAY_MUX_CONTROL | ||
303 | * ARG1: | ||
304 | * WORD - structure size in bytes (includes size field) | ||
305 | * WORD - display mux control (0: iGPU, 1: dGPU) | ||
306 | * OUTPUT: none | ||
307 | */ | ||
308 | # define ATPX_INTEGRATED_GPU 0 | ||
309 | # define ATPX_DISCRETE_GPU 1 | ||
310 | #define ATPX_FUNCTION_I2C_MUX_CONTROL 0x4 | ||
311 | /* ARG0: ATPX_FUNCTION_I2C_MUX_CONTROL | ||
312 | * ARG1: | ||
313 | * WORD - structure size in bytes (includes size field) | ||
314 | * WORD - i2c/aux/hpd mux control (0: iGPU, 1: dGPU) | ||
315 | * OUTPUT: none | ||
316 | */ | ||
317 | #define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION 0x5 | ||
318 | /* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION | ||
319 | * ARG1: | ||
320 | * WORD - structure size in bytes (includes size field) | ||
321 | * WORD - target gpu (0: iGPU, 1: dGPU) | ||
322 | * OUTPUT: none | ||
323 | */ | ||
324 | #define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION 0x6 | ||
325 | /* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION | ||
326 | * ARG1: | ||
327 | * WORD - structure size in bytes (includes size field) | ||
328 | * WORD - target gpu (0: iGPU, 1: dGPU) | ||
329 | * OUTPUT: none | ||
330 | */ | ||
331 | #define ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING 0x8 | ||
332 | /* ARG0: ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING | ||
333 | * ARG1: none | ||
334 | * OUTPUT: | ||
335 | * WORD - number of display connectors | ||
336 | * WORD - connector structure size in bytes (excludes connector size field) | ||
337 | * BYTE - flags \ | ||
338 | * BYTE - ATIF display vector bit position } repeated | ||
339 | * BYTE - adapter id (0: iGPU, 1-n: dGPU ordered by pcie bus number) } structure | ||
340 | * WORD - connector ACPI id / | ||
341 | */ | ||
342 | /* flags */ | ||
343 | # define ATPX_DISPLAY_OUTPUT_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 0) | ||
344 | # define ATPX_DISPLAY_HPD_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 1) | ||
345 | # define ATPX_DISPLAY_I2C_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 2) | ||
346 | #define ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS 0x9 | ||
347 | /* ARG0: ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS | ||
348 | * ARG1: none | ||
349 | * OUTPUT: | ||
350 | * WORD - number of HPD/DDC ports | ||
351 | * WORD - port structure size in bytes (excludes port size field) | ||
352 | * BYTE - ATIF display vector bit position \ | ||
353 | * BYTE - hpd id } reapeated structure | ||
354 | * BYTE - ddc id / | ||
355 | * | ||
356 | * available on A+A systems only | ||
357 | */ | ||
358 | /* hpd id */ | ||
359 | # define ATPX_HPD_NONE 0 | ||
360 | # define ATPX_HPD1 1 | ||
361 | # define ATPX_HPD2 2 | ||
362 | # define ATPX_HPD3 3 | ||
363 | # define ATPX_HPD4 4 | ||
364 | # define ATPX_HPD5 5 | ||
365 | # define ATPX_HPD6 6 | ||
366 | /* ddc id */ | ||
367 | # define ATPX_DDC_NONE 0 | ||
368 | # define ATPX_DDC1 1 | ||
369 | # define ATPX_DDC2 2 | ||
370 | # define ATPX_DDC3 3 | ||
371 | # define ATPX_DDC4 4 | ||
372 | # define ATPX_DDC5 5 | ||
373 | # define ATPX_DDC6 6 | ||
374 | # define ATPX_DDC7 7 | ||
375 | # define ATPX_DDC8 8 | ||
376 | |||
377 | /* ATCS */ | ||
378 | #define ATCS_FUNCTION_VERIFY_INTERFACE 0x0 | ||
379 | /* ARG0: ATCS_FUNCTION_VERIFY_INTERFACE | ||
380 | * ARG1: none | ||
381 | * OUTPUT: | ||
382 | * WORD - structure size in bytes (includes size field) | ||
383 | * WORD - version | ||
384 | * DWORD - supported functions bit vector | ||
385 | */ | ||
386 | /* supported functions vector */ | ||
387 | # define ATCS_GET_EXTERNAL_STATE_SUPPORTED (1 << 0) | ||
388 | # define ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED (1 << 1) | ||
389 | # define ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED (1 << 2) | ||
390 | # define ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED (1 << 3) | ||
391 | #define ATCS_FUNCTION_GET_EXTERNAL_STATE 0x1 | ||
392 | /* ARG0: ATCS_FUNCTION_GET_EXTERNAL_STATE | ||
393 | * ARG1: none | ||
394 | * OUTPUT: | ||
395 | * WORD - structure size in bytes (includes size field) | ||
396 | * DWORD - valid flags mask | ||
397 | * DWORD - flags (0: undocked, 1: docked) | ||
398 | */ | ||
399 | /* flags */ | ||
400 | # define ATCS_DOCKED (1 << 0) | ||
401 | #define ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST 0x2 | ||
402 | /* ARG0: ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST | ||
403 | * ARG1: | ||
404 | * WORD - structure size in bytes (includes size field) | ||
405 | * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) | ||
406 | * WORD - valid flags mask | ||
407 | * WORD - flags | ||
408 | * BYTE - request type | ||
409 | * BYTE - performance request | ||
410 | * OUTPUT: | ||
411 | * WORD - structure size in bytes (includes size field) | ||
412 | * BYTE - return value | ||
413 | */ | ||
414 | /* flags */ | ||
415 | # define ATCS_ADVERTISE_CAPS (1 << 0) | ||
416 | # define ATCS_WAIT_FOR_COMPLETION (1 << 1) | ||
417 | /* request type */ | ||
418 | # define ATCS_PCIE_LINK_SPEED 1 | ||
419 | /* performance request */ | ||
420 | # define ATCS_REMOVE 0 | ||
421 | # define ATCS_FORCE_LOW_POWER 1 | ||
422 | # define ATCS_PERF_LEVEL_1 2 /* PCIE Gen 1 */ | ||
423 | # define ATCS_PERF_LEVEL_2 3 /* PCIE Gen 2 */ | ||
424 | # define ATCS_PERF_LEVEL_3 4 /* PCIE Gen 3 */ | ||
425 | /* return value */ | ||
426 | # define ATCS_REQUEST_REFUSED 1 | ||
427 | # define ATCS_REQUEST_COMPLETE 2 | ||
428 | # define ATCS_REQUEST_IN_PROGRESS 3 | ||
429 | #define ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION 0x3 | ||
430 | /* ARG0: ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION | ||
431 | * ARG1: none | ||
432 | * OUTPUT: none | ||
433 | */ | ||
434 | #define ATCS_FUNCTION_SET_PCIE_BUS_WIDTH 0x4 | ||
435 | /* ARG0: ATCS_FUNCTION_SET_PCIE_BUS_WIDTH | ||
436 | * ARG1: | ||
437 | * WORD - structure size in bytes (includes size field) | ||
438 | * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) | ||
439 | * BYTE - number of active lanes | ||
440 | * OUTPUT: | ||
441 | * WORD - structure size in bytes (includes size field) | ||
442 | * BYTE - number of active lanes | ||
443 | */ | ||
444 | |||
445 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 973417c4b014..654520b95ab7 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -198,6 +198,8 @@ static struct radeon_asic r100_asic = { | |||
198 | .bandwidth_update = &r100_bandwidth_update, | 198 | .bandwidth_update = &r100_bandwidth_update, |
199 | .get_vblank_counter = &r100_get_vblank_counter, | 199 | .get_vblank_counter = &r100_get_vblank_counter, |
200 | .wait_for_vblank = &r100_wait_for_vblank, | 200 | .wait_for_vblank = &r100_wait_for_vblank, |
201 | .set_backlight_level = &radeon_legacy_set_backlight_level, | ||
202 | .get_backlight_level = &radeon_legacy_get_backlight_level, | ||
201 | }, | 203 | }, |
202 | .copy = { | 204 | .copy = { |
203 | .blit = &r100_copy_blit, | 205 | .blit = &r100_copy_blit, |
@@ -272,6 +274,8 @@ static struct radeon_asic r200_asic = { | |||
272 | .bandwidth_update = &r100_bandwidth_update, | 274 | .bandwidth_update = &r100_bandwidth_update, |
273 | .get_vblank_counter = &r100_get_vblank_counter, | 275 | .get_vblank_counter = &r100_get_vblank_counter, |
274 | .wait_for_vblank = &r100_wait_for_vblank, | 276 | .wait_for_vblank = &r100_wait_for_vblank, |
277 | .set_backlight_level = &radeon_legacy_set_backlight_level, | ||
278 | .get_backlight_level = &radeon_legacy_get_backlight_level, | ||
275 | }, | 279 | }, |
276 | .copy = { | 280 | .copy = { |
277 | .blit = &r100_copy_blit, | 281 | .blit = &r100_copy_blit, |
@@ -346,6 +350,8 @@ static struct radeon_asic r300_asic = { | |||
346 | .bandwidth_update = &r100_bandwidth_update, | 350 | .bandwidth_update = &r100_bandwidth_update, |
347 | .get_vblank_counter = &r100_get_vblank_counter, | 351 | .get_vblank_counter = &r100_get_vblank_counter, |
348 | .wait_for_vblank = &r100_wait_for_vblank, | 352 | .wait_for_vblank = &r100_wait_for_vblank, |
353 | .set_backlight_level = &radeon_legacy_set_backlight_level, | ||
354 | .get_backlight_level = &radeon_legacy_get_backlight_level, | ||
349 | }, | 355 | }, |
350 | .copy = { | 356 | .copy = { |
351 | .blit = &r100_copy_blit, | 357 | .blit = &r100_copy_blit, |
@@ -420,6 +426,8 @@ static struct radeon_asic r300_asic_pcie = { | |||
420 | .bandwidth_update = &r100_bandwidth_update, | 426 | .bandwidth_update = &r100_bandwidth_update, |
421 | .get_vblank_counter = &r100_get_vblank_counter, | 427 | .get_vblank_counter = &r100_get_vblank_counter, |
422 | .wait_for_vblank = &r100_wait_for_vblank, | 428 | .wait_for_vblank = &r100_wait_for_vblank, |
429 | .set_backlight_level = &radeon_legacy_set_backlight_level, | ||
430 | .get_backlight_level = &radeon_legacy_get_backlight_level, | ||
423 | }, | 431 | }, |
424 | .copy = { | 432 | .copy = { |
425 | .blit = &r100_copy_blit, | 433 | .blit = &r100_copy_blit, |
@@ -494,6 +502,8 @@ static struct radeon_asic r420_asic = { | |||
494 | .bandwidth_update = &r100_bandwidth_update, | 502 | .bandwidth_update = &r100_bandwidth_update, |
495 | .get_vblank_counter = &r100_get_vblank_counter, | 503 | .get_vblank_counter = &r100_get_vblank_counter, |
496 | .wait_for_vblank = &r100_wait_for_vblank, | 504 | .wait_for_vblank = &r100_wait_for_vblank, |
505 | .set_backlight_level = &atombios_set_backlight_level, | ||
506 | .get_backlight_level = &atombios_get_backlight_level, | ||
497 | }, | 507 | }, |
498 | .copy = { | 508 | .copy = { |
499 | .blit = &r100_copy_blit, | 509 | .blit = &r100_copy_blit, |
@@ -568,6 +578,8 @@ static struct radeon_asic rs400_asic = { | |||
568 | .bandwidth_update = &r100_bandwidth_update, | 578 | .bandwidth_update = &r100_bandwidth_update, |
569 | .get_vblank_counter = &r100_get_vblank_counter, | 579 | .get_vblank_counter = &r100_get_vblank_counter, |
570 | .wait_for_vblank = &r100_wait_for_vblank, | 580 | .wait_for_vblank = &r100_wait_for_vblank, |
581 | .set_backlight_level = &radeon_legacy_set_backlight_level, | ||
582 | .get_backlight_level = &radeon_legacy_get_backlight_level, | ||
571 | }, | 583 | }, |
572 | .copy = { | 584 | .copy = { |
573 | .blit = &r100_copy_blit, | 585 | .blit = &r100_copy_blit, |
@@ -642,6 +654,8 @@ static struct radeon_asic rs600_asic = { | |||
642 | .bandwidth_update = &rs600_bandwidth_update, | 654 | .bandwidth_update = &rs600_bandwidth_update, |
643 | .get_vblank_counter = &rs600_get_vblank_counter, | 655 | .get_vblank_counter = &rs600_get_vblank_counter, |
644 | .wait_for_vblank = &avivo_wait_for_vblank, | 656 | .wait_for_vblank = &avivo_wait_for_vblank, |
657 | .set_backlight_level = &atombios_set_backlight_level, | ||
658 | .get_backlight_level = &atombios_get_backlight_level, | ||
645 | }, | 659 | }, |
646 | .copy = { | 660 | .copy = { |
647 | .blit = &r100_copy_blit, | 661 | .blit = &r100_copy_blit, |
@@ -716,6 +730,8 @@ static struct radeon_asic rs690_asic = { | |||
716 | .get_vblank_counter = &rs600_get_vblank_counter, | 730 | .get_vblank_counter = &rs600_get_vblank_counter, |
717 | .bandwidth_update = &rs690_bandwidth_update, | 731 | .bandwidth_update = &rs690_bandwidth_update, |
718 | .wait_for_vblank = &avivo_wait_for_vblank, | 732 | .wait_for_vblank = &avivo_wait_for_vblank, |
733 | .set_backlight_level = &atombios_set_backlight_level, | ||
734 | .get_backlight_level = &atombios_get_backlight_level, | ||
719 | }, | 735 | }, |
720 | .copy = { | 736 | .copy = { |
721 | .blit = &r100_copy_blit, | 737 | .blit = &r100_copy_blit, |
@@ -790,6 +806,8 @@ static struct radeon_asic rv515_asic = { | |||
790 | .get_vblank_counter = &rs600_get_vblank_counter, | 806 | .get_vblank_counter = &rs600_get_vblank_counter, |
791 | .bandwidth_update = &rv515_bandwidth_update, | 807 | .bandwidth_update = &rv515_bandwidth_update, |
792 | .wait_for_vblank = &avivo_wait_for_vblank, | 808 | .wait_for_vblank = &avivo_wait_for_vblank, |
809 | .set_backlight_level = &atombios_set_backlight_level, | ||
810 | .get_backlight_level = &atombios_get_backlight_level, | ||
793 | }, | 811 | }, |
794 | .copy = { | 812 | .copy = { |
795 | .blit = &r100_copy_blit, | 813 | .blit = &r100_copy_blit, |
@@ -864,6 +882,8 @@ static struct radeon_asic r520_asic = { | |||
864 | .bandwidth_update = &rv515_bandwidth_update, | 882 | .bandwidth_update = &rv515_bandwidth_update, |
865 | .get_vblank_counter = &rs600_get_vblank_counter, | 883 | .get_vblank_counter = &rs600_get_vblank_counter, |
866 | .wait_for_vblank = &avivo_wait_for_vblank, | 884 | .wait_for_vblank = &avivo_wait_for_vblank, |
885 | .set_backlight_level = &atombios_set_backlight_level, | ||
886 | .get_backlight_level = &atombios_get_backlight_level, | ||
867 | }, | 887 | }, |
868 | .copy = { | 888 | .copy = { |
869 | .blit = &r100_copy_blit, | 889 | .blit = &r100_copy_blit, |
@@ -937,6 +957,8 @@ static struct radeon_asic r600_asic = { | |||
937 | .bandwidth_update = &rv515_bandwidth_update, | 957 | .bandwidth_update = &rv515_bandwidth_update, |
938 | .get_vblank_counter = &rs600_get_vblank_counter, | 958 | .get_vblank_counter = &rs600_get_vblank_counter, |
939 | .wait_for_vblank = &avivo_wait_for_vblank, | 959 | .wait_for_vblank = &avivo_wait_for_vblank, |
960 | .set_backlight_level = &atombios_set_backlight_level, | ||
961 | .get_backlight_level = &atombios_get_backlight_level, | ||
940 | }, | 962 | }, |
941 | .copy = { | 963 | .copy = { |
942 | .blit = &r600_copy_blit, | 964 | .blit = &r600_copy_blit, |
@@ -1010,6 +1032,8 @@ static struct radeon_asic rs780_asic = { | |||
1010 | .bandwidth_update = &rs690_bandwidth_update, | 1032 | .bandwidth_update = &rs690_bandwidth_update, |
1011 | .get_vblank_counter = &rs600_get_vblank_counter, | 1033 | .get_vblank_counter = &rs600_get_vblank_counter, |
1012 | .wait_for_vblank = &avivo_wait_for_vblank, | 1034 | .wait_for_vblank = &avivo_wait_for_vblank, |
1035 | .set_backlight_level = &atombios_set_backlight_level, | ||
1036 | .get_backlight_level = &atombios_get_backlight_level, | ||
1013 | }, | 1037 | }, |
1014 | .copy = { | 1038 | .copy = { |
1015 | .blit = &r600_copy_blit, | 1039 | .blit = &r600_copy_blit, |
@@ -1083,6 +1107,8 @@ static struct radeon_asic rv770_asic = { | |||
1083 | .bandwidth_update = &rv515_bandwidth_update, | 1107 | .bandwidth_update = &rv515_bandwidth_update, |
1084 | .get_vblank_counter = &rs600_get_vblank_counter, | 1108 | .get_vblank_counter = &rs600_get_vblank_counter, |
1085 | .wait_for_vblank = &avivo_wait_for_vblank, | 1109 | .wait_for_vblank = &avivo_wait_for_vblank, |
1110 | .set_backlight_level = &atombios_set_backlight_level, | ||
1111 | .get_backlight_level = &atombios_get_backlight_level, | ||
1086 | }, | 1112 | }, |
1087 | .copy = { | 1113 | .copy = { |
1088 | .blit = &r600_copy_blit, | 1114 | .blit = &r600_copy_blit, |
@@ -1156,6 +1182,8 @@ static struct radeon_asic evergreen_asic = { | |||
1156 | .bandwidth_update = &evergreen_bandwidth_update, | 1182 | .bandwidth_update = &evergreen_bandwidth_update, |
1157 | .get_vblank_counter = &evergreen_get_vblank_counter, | 1183 | .get_vblank_counter = &evergreen_get_vblank_counter, |
1158 | .wait_for_vblank = &dce4_wait_for_vblank, | 1184 | .wait_for_vblank = &dce4_wait_for_vblank, |
1185 | .set_backlight_level = &atombios_set_backlight_level, | ||
1186 | .get_backlight_level = &atombios_get_backlight_level, | ||
1159 | }, | 1187 | }, |
1160 | .copy = { | 1188 | .copy = { |
1161 | .blit = &r600_copy_blit, | 1189 | .blit = &r600_copy_blit, |
@@ -1229,6 +1257,8 @@ static struct radeon_asic sumo_asic = { | |||
1229 | .bandwidth_update = &evergreen_bandwidth_update, | 1257 | .bandwidth_update = &evergreen_bandwidth_update, |
1230 | .get_vblank_counter = &evergreen_get_vblank_counter, | 1258 | .get_vblank_counter = &evergreen_get_vblank_counter, |
1231 | .wait_for_vblank = &dce4_wait_for_vblank, | 1259 | .wait_for_vblank = &dce4_wait_for_vblank, |
1260 | .set_backlight_level = &atombios_set_backlight_level, | ||
1261 | .get_backlight_level = &atombios_get_backlight_level, | ||
1232 | }, | 1262 | }, |
1233 | .copy = { | 1263 | .copy = { |
1234 | .blit = &r600_copy_blit, | 1264 | .blit = &r600_copy_blit, |
@@ -1302,6 +1332,8 @@ static struct radeon_asic btc_asic = { | |||
1302 | .bandwidth_update = &evergreen_bandwidth_update, | 1332 | .bandwidth_update = &evergreen_bandwidth_update, |
1303 | .get_vblank_counter = &evergreen_get_vblank_counter, | 1333 | .get_vblank_counter = &evergreen_get_vblank_counter, |
1304 | .wait_for_vblank = &dce4_wait_for_vblank, | 1334 | .wait_for_vblank = &dce4_wait_for_vblank, |
1335 | .set_backlight_level = &atombios_set_backlight_level, | ||
1336 | .get_backlight_level = &atombios_get_backlight_level, | ||
1305 | }, | 1337 | }, |
1306 | .copy = { | 1338 | .copy = { |
1307 | .blit = &r600_copy_blit, | 1339 | .blit = &r600_copy_blit, |
@@ -1325,7 +1357,7 @@ static struct radeon_asic btc_asic = { | |||
1325 | .misc = &evergreen_pm_misc, | 1357 | .misc = &evergreen_pm_misc, |
1326 | .prepare = &evergreen_pm_prepare, | 1358 | .prepare = &evergreen_pm_prepare, |
1327 | .finish = &evergreen_pm_finish, | 1359 | .finish = &evergreen_pm_finish, |
1328 | .init_profile = &r600_pm_init_profile, | 1360 | .init_profile = &btc_pm_init_profile, |
1329 | .get_dynpm_state = &r600_pm_get_dynpm_state, | 1361 | .get_dynpm_state = &r600_pm_get_dynpm_state, |
1330 | .get_engine_clock = &radeon_atom_get_engine_clock, | 1362 | .get_engine_clock = &radeon_atom_get_engine_clock, |
1331 | .set_engine_clock = &radeon_atom_set_engine_clock, | 1363 | .set_engine_clock = &radeon_atom_set_engine_clock, |
@@ -1342,16 +1374,6 @@ static struct radeon_asic btc_asic = { | |||
1342 | }, | 1374 | }, |
1343 | }; | 1375 | }; |
1344 | 1376 | ||
1345 | static const struct radeon_vm_funcs cayman_vm_funcs = { | ||
1346 | .init = &cayman_vm_init, | ||
1347 | .fini = &cayman_vm_fini, | ||
1348 | .bind = &cayman_vm_bind, | ||
1349 | .unbind = &cayman_vm_unbind, | ||
1350 | .tlb_flush = &cayman_vm_tlb_flush, | ||
1351 | .page_flags = &cayman_vm_page_flags, | ||
1352 | .set_page = &cayman_vm_set_page, | ||
1353 | }; | ||
1354 | |||
1355 | static struct radeon_asic cayman_asic = { | 1377 | static struct radeon_asic cayman_asic = { |
1356 | .init = &cayman_init, | 1378 | .init = &cayman_init, |
1357 | .fini = &cayman_fini, | 1379 | .fini = &cayman_fini, |
@@ -1366,6 +1388,12 @@ static struct radeon_asic cayman_asic = { | |||
1366 | .tlb_flush = &cayman_pcie_gart_tlb_flush, | 1388 | .tlb_flush = &cayman_pcie_gart_tlb_flush, |
1367 | .set_page = &rs600_gart_set_page, | 1389 | .set_page = &rs600_gart_set_page, |
1368 | }, | 1390 | }, |
1391 | .vm = { | ||
1392 | .init = &cayman_vm_init, | ||
1393 | .fini = &cayman_vm_fini, | ||
1394 | .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX, | ||
1395 | .set_page = &cayman_vm_set_page, | ||
1396 | }, | ||
1369 | .ring = { | 1397 | .ring = { |
1370 | [RADEON_RING_TYPE_GFX_INDEX] = { | 1398 | [RADEON_RING_TYPE_GFX_INDEX] = { |
1371 | .ib_execute = &cayman_ring_ib_execute, | 1399 | .ib_execute = &cayman_ring_ib_execute, |
@@ -1376,6 +1404,7 @@ static struct radeon_asic cayman_asic = { | |||
1376 | .ring_test = &r600_ring_test, | 1404 | .ring_test = &r600_ring_test, |
1377 | .ib_test = &r600_ib_test, | 1405 | .ib_test = &r600_ib_test, |
1378 | .is_lockup = &evergreen_gpu_is_lockup, | 1406 | .is_lockup = &evergreen_gpu_is_lockup, |
1407 | .vm_flush = &cayman_vm_flush, | ||
1379 | }, | 1408 | }, |
1380 | [CAYMAN_RING_TYPE_CP1_INDEX] = { | 1409 | [CAYMAN_RING_TYPE_CP1_INDEX] = { |
1381 | .ib_execute = &cayman_ring_ib_execute, | 1410 | .ib_execute = &cayman_ring_ib_execute, |
@@ -1386,6 +1415,7 @@ static struct radeon_asic cayman_asic = { | |||
1386 | .ring_test = &r600_ring_test, | 1415 | .ring_test = &r600_ring_test, |
1387 | .ib_test = &r600_ib_test, | 1416 | .ib_test = &r600_ib_test, |
1388 | .is_lockup = &evergreen_gpu_is_lockup, | 1417 | .is_lockup = &evergreen_gpu_is_lockup, |
1418 | .vm_flush = &cayman_vm_flush, | ||
1389 | }, | 1419 | }, |
1390 | [CAYMAN_RING_TYPE_CP2_INDEX] = { | 1420 | [CAYMAN_RING_TYPE_CP2_INDEX] = { |
1391 | .ib_execute = &cayman_ring_ib_execute, | 1421 | .ib_execute = &cayman_ring_ib_execute, |
@@ -1396,6 +1426,7 @@ static struct radeon_asic cayman_asic = { | |||
1396 | .ring_test = &r600_ring_test, | 1426 | .ring_test = &r600_ring_test, |
1397 | .ib_test = &r600_ib_test, | 1427 | .ib_test = &r600_ib_test, |
1398 | .is_lockup = &evergreen_gpu_is_lockup, | 1428 | .is_lockup = &evergreen_gpu_is_lockup, |
1429 | .vm_flush = &cayman_vm_flush, | ||
1399 | } | 1430 | } |
1400 | }, | 1431 | }, |
1401 | .irq = { | 1432 | .irq = { |
@@ -1406,6 +1437,8 @@ static struct radeon_asic cayman_asic = { | |||
1406 | .bandwidth_update = &evergreen_bandwidth_update, | 1437 | .bandwidth_update = &evergreen_bandwidth_update, |
1407 | .get_vblank_counter = &evergreen_get_vblank_counter, | 1438 | .get_vblank_counter = &evergreen_get_vblank_counter, |
1408 | .wait_for_vblank = &dce4_wait_for_vblank, | 1439 | .wait_for_vblank = &dce4_wait_for_vblank, |
1440 | .set_backlight_level = &atombios_set_backlight_level, | ||
1441 | .get_backlight_level = &atombios_get_backlight_level, | ||
1409 | }, | 1442 | }, |
1410 | .copy = { | 1443 | .copy = { |
1411 | .blit = &r600_copy_blit, | 1444 | .blit = &r600_copy_blit, |
@@ -1429,7 +1462,7 @@ static struct radeon_asic cayman_asic = { | |||
1429 | .misc = &evergreen_pm_misc, | 1462 | .misc = &evergreen_pm_misc, |
1430 | .prepare = &evergreen_pm_prepare, | 1463 | .prepare = &evergreen_pm_prepare, |
1431 | .finish = &evergreen_pm_finish, | 1464 | .finish = &evergreen_pm_finish, |
1432 | .init_profile = &r600_pm_init_profile, | 1465 | .init_profile = &btc_pm_init_profile, |
1433 | .get_dynpm_state = &r600_pm_get_dynpm_state, | 1466 | .get_dynpm_state = &r600_pm_get_dynpm_state, |
1434 | .get_engine_clock = &radeon_atom_get_engine_clock, | 1467 | .get_engine_clock = &radeon_atom_get_engine_clock, |
1435 | .set_engine_clock = &radeon_atom_set_engine_clock, | 1468 | .set_engine_clock = &radeon_atom_set_engine_clock, |
@@ -1460,6 +1493,12 @@ static struct radeon_asic trinity_asic = { | |||
1460 | .tlb_flush = &cayman_pcie_gart_tlb_flush, | 1493 | .tlb_flush = &cayman_pcie_gart_tlb_flush, |
1461 | .set_page = &rs600_gart_set_page, | 1494 | .set_page = &rs600_gart_set_page, |
1462 | }, | 1495 | }, |
1496 | .vm = { | ||
1497 | .init = &cayman_vm_init, | ||
1498 | .fini = &cayman_vm_fini, | ||
1499 | .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX, | ||
1500 | .set_page = &cayman_vm_set_page, | ||
1501 | }, | ||
1463 | .ring = { | 1502 | .ring = { |
1464 | [RADEON_RING_TYPE_GFX_INDEX] = { | 1503 | [RADEON_RING_TYPE_GFX_INDEX] = { |
1465 | .ib_execute = &cayman_ring_ib_execute, | 1504 | .ib_execute = &cayman_ring_ib_execute, |
@@ -1470,6 +1509,7 @@ static struct radeon_asic trinity_asic = { | |||
1470 | .ring_test = &r600_ring_test, | 1509 | .ring_test = &r600_ring_test, |
1471 | .ib_test = &r600_ib_test, | 1510 | .ib_test = &r600_ib_test, |
1472 | .is_lockup = &evergreen_gpu_is_lockup, | 1511 | .is_lockup = &evergreen_gpu_is_lockup, |
1512 | .vm_flush = &cayman_vm_flush, | ||
1473 | }, | 1513 | }, |
1474 | [CAYMAN_RING_TYPE_CP1_INDEX] = { | 1514 | [CAYMAN_RING_TYPE_CP1_INDEX] = { |
1475 | .ib_execute = &cayman_ring_ib_execute, | 1515 | .ib_execute = &cayman_ring_ib_execute, |
@@ -1480,6 +1520,7 @@ static struct radeon_asic trinity_asic = { | |||
1480 | .ring_test = &r600_ring_test, | 1520 | .ring_test = &r600_ring_test, |
1481 | .ib_test = &r600_ib_test, | 1521 | .ib_test = &r600_ib_test, |
1482 | .is_lockup = &evergreen_gpu_is_lockup, | 1522 | .is_lockup = &evergreen_gpu_is_lockup, |
1523 | .vm_flush = &cayman_vm_flush, | ||
1483 | }, | 1524 | }, |
1484 | [CAYMAN_RING_TYPE_CP2_INDEX] = { | 1525 | [CAYMAN_RING_TYPE_CP2_INDEX] = { |
1485 | .ib_execute = &cayman_ring_ib_execute, | 1526 | .ib_execute = &cayman_ring_ib_execute, |
@@ -1490,6 +1531,7 @@ static struct radeon_asic trinity_asic = { | |||
1490 | .ring_test = &r600_ring_test, | 1531 | .ring_test = &r600_ring_test, |
1491 | .ib_test = &r600_ib_test, | 1532 | .ib_test = &r600_ib_test, |
1492 | .is_lockup = &evergreen_gpu_is_lockup, | 1533 | .is_lockup = &evergreen_gpu_is_lockup, |
1534 | .vm_flush = &cayman_vm_flush, | ||
1493 | } | 1535 | } |
1494 | }, | 1536 | }, |
1495 | .irq = { | 1537 | .irq = { |
@@ -1500,6 +1542,8 @@ static struct radeon_asic trinity_asic = { | |||
1500 | .bandwidth_update = &dce6_bandwidth_update, | 1542 | .bandwidth_update = &dce6_bandwidth_update, |
1501 | .get_vblank_counter = &evergreen_get_vblank_counter, | 1543 | .get_vblank_counter = &evergreen_get_vblank_counter, |
1502 | .wait_for_vblank = &dce4_wait_for_vblank, | 1544 | .wait_for_vblank = &dce4_wait_for_vblank, |
1545 | .set_backlight_level = &atombios_set_backlight_level, | ||
1546 | .get_backlight_level = &atombios_get_backlight_level, | ||
1503 | }, | 1547 | }, |
1504 | .copy = { | 1548 | .copy = { |
1505 | .blit = &r600_copy_blit, | 1549 | .blit = &r600_copy_blit, |
@@ -1540,16 +1584,6 @@ static struct radeon_asic trinity_asic = { | |||
1540 | }, | 1584 | }, |
1541 | }; | 1585 | }; |
1542 | 1586 | ||
1543 | static const struct radeon_vm_funcs si_vm_funcs = { | ||
1544 | .init = &si_vm_init, | ||
1545 | .fini = &si_vm_fini, | ||
1546 | .bind = &si_vm_bind, | ||
1547 | .unbind = &si_vm_unbind, | ||
1548 | .tlb_flush = &si_vm_tlb_flush, | ||
1549 | .page_flags = &cayman_vm_page_flags, | ||
1550 | .set_page = &cayman_vm_set_page, | ||
1551 | }; | ||
1552 | |||
1553 | static struct radeon_asic si_asic = { | 1587 | static struct radeon_asic si_asic = { |
1554 | .init = &si_init, | 1588 | .init = &si_init, |
1555 | .fini = &si_fini, | 1589 | .fini = &si_fini, |
@@ -1564,6 +1598,12 @@ static struct radeon_asic si_asic = { | |||
1564 | .tlb_flush = &si_pcie_gart_tlb_flush, | 1598 | .tlb_flush = &si_pcie_gart_tlb_flush, |
1565 | .set_page = &rs600_gart_set_page, | 1599 | .set_page = &rs600_gart_set_page, |
1566 | }, | 1600 | }, |
1601 | .vm = { | ||
1602 | .init = &si_vm_init, | ||
1603 | .fini = &si_vm_fini, | ||
1604 | .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX, | ||
1605 | .set_page = &si_vm_set_page, | ||
1606 | }, | ||
1567 | .ring = { | 1607 | .ring = { |
1568 | [RADEON_RING_TYPE_GFX_INDEX] = { | 1608 | [RADEON_RING_TYPE_GFX_INDEX] = { |
1569 | .ib_execute = &si_ring_ib_execute, | 1609 | .ib_execute = &si_ring_ib_execute, |
@@ -1574,6 +1614,7 @@ static struct radeon_asic si_asic = { | |||
1574 | .ring_test = &r600_ring_test, | 1614 | .ring_test = &r600_ring_test, |
1575 | .ib_test = &r600_ib_test, | 1615 | .ib_test = &r600_ib_test, |
1576 | .is_lockup = &si_gpu_is_lockup, | 1616 | .is_lockup = &si_gpu_is_lockup, |
1617 | .vm_flush = &si_vm_flush, | ||
1577 | }, | 1618 | }, |
1578 | [CAYMAN_RING_TYPE_CP1_INDEX] = { | 1619 | [CAYMAN_RING_TYPE_CP1_INDEX] = { |
1579 | .ib_execute = &si_ring_ib_execute, | 1620 | .ib_execute = &si_ring_ib_execute, |
@@ -1584,6 +1625,7 @@ static struct radeon_asic si_asic = { | |||
1584 | .ring_test = &r600_ring_test, | 1625 | .ring_test = &r600_ring_test, |
1585 | .ib_test = &r600_ib_test, | 1626 | .ib_test = &r600_ib_test, |
1586 | .is_lockup = &si_gpu_is_lockup, | 1627 | .is_lockup = &si_gpu_is_lockup, |
1628 | .vm_flush = &si_vm_flush, | ||
1587 | }, | 1629 | }, |
1588 | [CAYMAN_RING_TYPE_CP2_INDEX] = { | 1630 | [CAYMAN_RING_TYPE_CP2_INDEX] = { |
1589 | .ib_execute = &si_ring_ib_execute, | 1631 | .ib_execute = &si_ring_ib_execute, |
@@ -1594,6 +1636,7 @@ static struct radeon_asic si_asic = { | |||
1594 | .ring_test = &r600_ring_test, | 1636 | .ring_test = &r600_ring_test, |
1595 | .ib_test = &r600_ib_test, | 1637 | .ib_test = &r600_ib_test, |
1596 | .is_lockup = &si_gpu_is_lockup, | 1638 | .is_lockup = &si_gpu_is_lockup, |
1639 | .vm_flush = &si_vm_flush, | ||
1597 | } | 1640 | } |
1598 | }, | 1641 | }, |
1599 | .irq = { | 1642 | .irq = { |
@@ -1604,6 +1647,8 @@ static struct radeon_asic si_asic = { | |||
1604 | .bandwidth_update = &dce6_bandwidth_update, | 1647 | .bandwidth_update = &dce6_bandwidth_update, |
1605 | .get_vblank_counter = &evergreen_get_vblank_counter, | 1648 | .get_vblank_counter = &evergreen_get_vblank_counter, |
1606 | .wait_for_vblank = &dce4_wait_for_vblank, | 1649 | .wait_for_vblank = &dce4_wait_for_vblank, |
1650 | .set_backlight_level = &atombios_set_backlight_level, | ||
1651 | .get_backlight_level = &atombios_get_backlight_level, | ||
1607 | }, | 1652 | }, |
1608 | .copy = { | 1653 | .copy = { |
1609 | .blit = NULL, | 1654 | .blit = NULL, |
@@ -1697,6 +1742,7 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
1697 | rdev->asic->pm.set_engine_clock = &radeon_legacy_set_engine_clock; | 1742 | rdev->asic->pm.set_engine_clock = &radeon_legacy_set_engine_clock; |
1698 | rdev->asic->pm.get_memory_clock = &radeon_legacy_get_memory_clock; | 1743 | rdev->asic->pm.get_memory_clock = &radeon_legacy_get_memory_clock; |
1699 | rdev->asic->pm.set_memory_clock = NULL; | 1744 | rdev->asic->pm.set_memory_clock = NULL; |
1745 | rdev->asic->display.set_backlight_level = &radeon_legacy_set_backlight_level; | ||
1700 | } | 1746 | } |
1701 | break; | 1747 | break; |
1702 | case CHIP_RS400: | 1748 | case CHIP_RS400: |
@@ -1769,13 +1815,11 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
1769 | rdev->asic = &cayman_asic; | 1815 | rdev->asic = &cayman_asic; |
1770 | /* set num crtcs */ | 1816 | /* set num crtcs */ |
1771 | rdev->num_crtc = 6; | 1817 | rdev->num_crtc = 6; |
1772 | rdev->vm_manager.funcs = &cayman_vm_funcs; | ||
1773 | break; | 1818 | break; |
1774 | case CHIP_ARUBA: | 1819 | case CHIP_ARUBA: |
1775 | rdev->asic = &trinity_asic; | 1820 | rdev->asic = &trinity_asic; |
1776 | /* set num crtcs */ | 1821 | /* set num crtcs */ |
1777 | rdev->num_crtc = 4; | 1822 | rdev->num_crtc = 4; |
1778 | rdev->vm_manager.funcs = &cayman_vm_funcs; | ||
1779 | break; | 1823 | break; |
1780 | case CHIP_TAHITI: | 1824 | case CHIP_TAHITI: |
1781 | case CHIP_PITCAIRN: | 1825 | case CHIP_PITCAIRN: |
@@ -1783,7 +1827,6 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
1783 | rdev->asic = &si_asic; | 1827 | rdev->asic = &si_asic; |
1784 | /* set num crtcs */ | 1828 | /* set num crtcs */ |
1785 | rdev->num_crtc = 6; | 1829 | rdev->num_crtc = 6; |
1786 | rdev->vm_manager.funcs = &si_vm_funcs; | ||
1787 | break; | 1830 | break; |
1788 | default: | 1831 | default: |
1789 | /* FIXME: not supported yet */ | 1832 | /* FIXME: not supported yet */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 18c38d14c8cd..5e3a0e5c6be1 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -42,6 +42,12 @@ uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev); | |||
42 | void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock); | 42 | void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock); |
43 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); | 43 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); |
44 | 44 | ||
45 | void atombios_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level); | ||
46 | u8 atombios_get_backlight_level(struct radeon_encoder *radeon_encoder); | ||
47 | void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level); | ||
48 | u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder); | ||
49 | |||
50 | |||
45 | /* | 51 | /* |
46 | * r100,rv100,rs100,rv200,rs200 | 52 | * r100,rv100,rs100,rv200,rs200 |
47 | */ | 53 | */ |
@@ -389,6 +395,7 @@ void r700_cp_fini(struct radeon_device *rdev); | |||
389 | struct evergreen_mc_save { | 395 | struct evergreen_mc_save { |
390 | u32 vga_render_control; | 396 | u32 vga_render_control; |
391 | u32 vga_hdp_control; | 397 | u32 vga_hdp_control; |
398 | bool crtc_enabled[RADEON_MAX_CRTCS]; | ||
392 | }; | 399 | }; |
393 | 400 | ||
394 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); | 401 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); |
@@ -413,6 +420,7 @@ extern void evergreen_pm_misc(struct radeon_device *rdev); | |||
413 | extern void evergreen_pm_prepare(struct radeon_device *rdev); | 420 | extern void evergreen_pm_prepare(struct radeon_device *rdev); |
414 | extern void evergreen_pm_finish(struct radeon_device *rdev); | 421 | extern void evergreen_pm_finish(struct radeon_device *rdev); |
415 | extern void sumo_pm_init_profile(struct radeon_device *rdev); | 422 | extern void sumo_pm_init_profile(struct radeon_device *rdev); |
423 | extern void btc_pm_init_profile(struct radeon_device *rdev); | ||
416 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); | 424 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); |
417 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | 425 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); |
418 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); | 426 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); |
@@ -435,14 +443,11 @@ int cayman_asic_reset(struct radeon_device *rdev); | |||
435 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | 443 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); |
436 | int cayman_vm_init(struct radeon_device *rdev); | 444 | int cayman_vm_init(struct radeon_device *rdev); |
437 | void cayman_vm_fini(struct radeon_device *rdev); | 445 | void cayman_vm_fini(struct radeon_device *rdev); |
438 | int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); | 446 | void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
439 | void cayman_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); | 447 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); |
440 | void cayman_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); | 448 | void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, |
441 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, | 449 | uint64_t addr, unsigned count, |
442 | struct radeon_vm *vm, | 450 | uint32_t incr, uint32_t flags); |
443 | uint32_t flags); | ||
444 | void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, | ||
445 | unsigned pfn, uint64_t addr, uint32_t flags); | ||
446 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 451 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
447 | 452 | ||
448 | /* DCE6 - SI */ | 453 | /* DCE6 - SI */ |
@@ -465,9 +470,10 @@ int si_irq_set(struct radeon_device *rdev); | |||
465 | int si_irq_process(struct radeon_device *rdev); | 470 | int si_irq_process(struct radeon_device *rdev); |
466 | int si_vm_init(struct radeon_device *rdev); | 471 | int si_vm_init(struct radeon_device *rdev); |
467 | void si_vm_fini(struct radeon_device *rdev); | 472 | void si_vm_fini(struct radeon_device *rdev); |
468 | int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); | 473 | void si_vm_set_page(struct radeon_device *rdev, uint64_t pe, |
469 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); | 474 | uint64_t addr, unsigned count, |
470 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); | 475 | uint32_t incr, uint32_t flags); |
476 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | ||
471 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 477 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
472 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); | 478 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); |
473 | 479 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index d67d4f3eb6f4..01b90b4f5e22 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -1254,6 +1254,10 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
1254 | if (rdev->clock.max_pixel_clock == 0) | 1254 | if (rdev->clock.max_pixel_clock == 0) |
1255 | rdev->clock.max_pixel_clock = 40000; | 1255 | rdev->clock.max_pixel_clock = 40000; |
1256 | 1256 | ||
1257 | /* not technically a clock, but... */ | ||
1258 | rdev->mode_info.firmware_flags = | ||
1259 | le16_to_cpu(firmware_info->info.usFirmwareCapability.susAccess); | ||
1260 | |||
1257 | return true; | 1261 | return true; |
1258 | } | 1262 | } |
1259 | 1263 | ||
@@ -2005,7 +2009,8 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | |||
2005 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | 2009 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
2006 | 2010 | ||
2007 | /* add the i2c bus for thermal/fan chip */ | 2011 | /* add the i2c bus for thermal/fan chip */ |
2008 | if (power_info->info.ucOverdriveThermalController > 0) { | 2012 | if ((power_info->info.ucOverdriveThermalController > 0) && |
2013 | (power_info->info.ucOverdriveThermalController < ARRAY_SIZE(thermal_controller_names))) { | ||
2009 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", | 2014 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", |
2010 | thermal_controller_names[power_info->info.ucOverdriveThermalController], | 2015 | thermal_controller_names[power_info->info.ucOverdriveThermalController], |
2011 | power_info->info.ucOverdriveControllerAddress >> 1); | 2016 | power_info->info.ucOverdriveControllerAddress >> 1); |
@@ -2209,7 +2214,7 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r | |||
2209 | (controller->ucType == | 2214 | (controller->ucType == |
2210 | ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) { | 2215 | ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) { |
2211 | DRM_INFO("Special thermal controller config\n"); | 2216 | DRM_INFO("Special thermal controller config\n"); |
2212 | } else { | 2217 | } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) { |
2213 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", | 2218 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", |
2214 | pp_lib_thermal_controller_names[controller->ucType], | 2219 | pp_lib_thermal_controller_names[controller->ucType], |
2215 | controller->ucI2cAddress >> 1, | 2220 | controller->ucI2cAddress >> 1, |
@@ -2224,6 +2229,12 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r | |||
2224 | strlcpy(info.type, name, sizeof(info.type)); | 2229 | strlcpy(info.type, name, sizeof(info.type)); |
2225 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | 2230 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); |
2226 | } | 2231 | } |
2232 | } else { | ||
2233 | DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n", | ||
2234 | controller->ucType, | ||
2235 | controller->ucI2cAddress >> 1, | ||
2236 | (controller->ucFanParameters & | ||
2237 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2227 | } | 2238 | } |
2228 | } | 2239 | } |
2229 | } | 2240 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 2a2cf0b88a28..582e99449c12 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -12,30 +12,62 @@ | |||
12 | #include <acpi/acpi_bus.h> | 12 | #include <acpi/acpi_bus.h> |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | 14 | ||
15 | #define ATPX_VERSION 0 | 15 | #include "radeon_acpi.h" |
16 | #define ATPX_GPU_PWR 2 | 16 | |
17 | #define ATPX_MUX_SELECT 3 | 17 | struct radeon_atpx_functions { |
18 | #define ATPX_I2C_MUX_SELECT 4 | 18 | bool px_params; |
19 | #define ATPX_SWITCH_START 5 | 19 | bool power_cntl; |
20 | #define ATPX_SWITCH_END 6 | 20 | bool disp_mux_cntl; |
21 | 21 | bool i2c_mux_cntl; | |
22 | #define ATPX_INTEGRATED 0 | 22 | bool switch_start; |
23 | #define ATPX_DISCRETE 1 | 23 | bool switch_end; |
24 | bool disp_connectors_mapping; | ||
25 | bool disp_detetion_ports; | ||
26 | }; | ||
24 | 27 | ||
25 | #define ATPX_MUX_IGD 0 | 28 | struct radeon_atpx { |
26 | #define ATPX_MUX_DISCRETE 1 | 29 | acpi_handle handle; |
30 | struct radeon_atpx_functions functions; | ||
31 | }; | ||
27 | 32 | ||
28 | static struct radeon_atpx_priv { | 33 | static struct radeon_atpx_priv { |
29 | bool atpx_detected; | 34 | bool atpx_detected; |
30 | /* handle for device - and atpx */ | 35 | /* handle for device - and atpx */ |
31 | acpi_handle dhandle; | 36 | acpi_handle dhandle; |
32 | acpi_handle atpx_handle; | 37 | struct radeon_atpx atpx; |
33 | } radeon_atpx_priv; | 38 | } radeon_atpx_priv; |
34 | 39 | ||
35 | static int radeon_atpx_get_version(acpi_handle handle) | 40 | struct atpx_verify_interface { |
41 | u16 size; /* structure size in bytes (includes size field) */ | ||
42 | u16 version; /* version */ | ||
43 | u32 function_bits; /* supported functions bit vector */ | ||
44 | } __packed; | ||
45 | |||
46 | struct atpx_power_control { | ||
47 | u16 size; | ||
48 | u8 dgpu_state; | ||
49 | } __packed; | ||
50 | |||
51 | struct atpx_mux { | ||
52 | u16 size; | ||
53 | u16 mux; | ||
54 | } __packed; | ||
55 | |||
56 | /** | ||
57 | * radeon_atpx_call - call an ATPX method | ||
58 | * | ||
59 | * @handle: acpi handle | ||
60 | * @function: the ATPX function to execute | ||
61 | * @params: ATPX function params | ||
62 | * | ||
63 | * Executes the requested ATPX function (all asics). | ||
64 | * Returns a pointer to the acpi output buffer. | ||
65 | */ | ||
66 | static union acpi_object *radeon_atpx_call(acpi_handle handle, int function, | ||
67 | struct acpi_buffer *params) | ||
36 | { | 68 | { |
37 | acpi_status status; | 69 | acpi_status status; |
38 | union acpi_object atpx_arg_elements[2], *obj; | 70 | union acpi_object atpx_arg_elements[2]; |
39 | struct acpi_object_list atpx_arg; | 71 | struct acpi_object_list atpx_arg; |
40 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 72 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
41 | 73 | ||
@@ -43,99 +75,292 @@ static int radeon_atpx_get_version(acpi_handle handle) | |||
43 | atpx_arg.pointer = &atpx_arg_elements[0]; | 75 | atpx_arg.pointer = &atpx_arg_elements[0]; |
44 | 76 | ||
45 | atpx_arg_elements[0].type = ACPI_TYPE_INTEGER; | 77 | atpx_arg_elements[0].type = ACPI_TYPE_INTEGER; |
46 | atpx_arg_elements[0].integer.value = ATPX_VERSION; | 78 | atpx_arg_elements[0].integer.value = function; |
79 | |||
80 | if (params) { | ||
81 | atpx_arg_elements[1].type = ACPI_TYPE_BUFFER; | ||
82 | atpx_arg_elements[1].buffer.length = params->length; | ||
83 | atpx_arg_elements[1].buffer.pointer = params->pointer; | ||
84 | } else { | ||
85 | /* We need a second fake parameter */ | ||
86 | atpx_arg_elements[1].type = ACPI_TYPE_INTEGER; | ||
87 | atpx_arg_elements[1].integer.value = 0; | ||
88 | } | ||
47 | 89 | ||
48 | atpx_arg_elements[1].type = ACPI_TYPE_INTEGER; | 90 | status = acpi_evaluate_object(handle, "ATPX", &atpx_arg, &buffer); |
49 | atpx_arg_elements[1].integer.value = ATPX_VERSION; | ||
50 | 91 | ||
51 | status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer); | 92 | /* Fail only if calling the method fails and ATPX is supported */ |
52 | if (ACPI_FAILURE(status)) { | 93 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
53 | printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status)); | 94 | printk("failed to evaluate ATPX got %s\n", |
54 | return -ENOSYS; | 95 | acpi_format_exception(status)); |
96 | kfree(buffer.pointer); | ||
97 | return NULL; | ||
55 | } | 98 | } |
56 | obj = (union acpi_object *)buffer.pointer; | 99 | |
57 | if (obj && (obj->type == ACPI_TYPE_BUFFER)) | 100 | return buffer.pointer; |
58 | printk(KERN_INFO "radeon atpx: version is %d\n", *((u8 *)(obj->buffer.pointer) + 2)); | ||
59 | kfree(buffer.pointer); | ||
60 | return 0; | ||
61 | } | 101 | } |
62 | 102 | ||
63 | static int radeon_atpx_execute(acpi_handle handle, int cmd_id, u16 value) | 103 | /** |
104 | * radeon_atpx_parse_functions - parse supported functions | ||
105 | * | ||
106 | * @f: supported functions struct | ||
107 | * @mask: supported functions mask from ATPX | ||
108 | * | ||
109 | * Use the supported functions mask from ATPX function | ||
110 | * ATPX_FUNCTION_VERIFY_INTERFACE to determine what functions | ||
111 | * are supported (all asics). | ||
112 | */ | ||
113 | static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mask) | ||
64 | { | 114 | { |
65 | acpi_status status; | 115 | f->px_params = mask & ATPX_GET_PX_PARAMETERS_SUPPORTED; |
66 | union acpi_object atpx_arg_elements[2]; | 116 | f->power_cntl = mask & ATPX_POWER_CONTROL_SUPPORTED; |
67 | struct acpi_object_list atpx_arg; | 117 | f->disp_mux_cntl = mask & ATPX_DISPLAY_MUX_CONTROL_SUPPORTED; |
68 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 118 | f->i2c_mux_cntl = mask & ATPX_I2C_MUX_CONTROL_SUPPORTED; |
69 | uint8_t buf[4] = {0}; | 119 | f->switch_start = mask & ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED; |
70 | 120 | f->switch_end = mask & ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED; | |
71 | if (!handle) | 121 | f->disp_connectors_mapping = mask & ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED; |
72 | return -EINVAL; | 122 | f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED; |
73 | 123 | } | |
74 | atpx_arg.count = 2; | ||
75 | atpx_arg.pointer = &atpx_arg_elements[0]; | ||
76 | 124 | ||
77 | atpx_arg_elements[0].type = ACPI_TYPE_INTEGER; | 125 | /** |
78 | atpx_arg_elements[0].integer.value = cmd_id; | 126 | * radeon_atpx_verify_interface - verify ATPX |
127 | * | ||
128 | * @handle: acpi handle | ||
129 | * @atpx: radeon atpx struct | ||
130 | * | ||
131 | * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function | ||
132 | * to initialize ATPX and determine what features are supported | ||
133 | * (all asics). | ||
134 | * returns 0 on success, error on failure. | ||
135 | */ | ||
136 | static int radeon_atpx_verify_interface(struct radeon_atpx *atpx) | ||
137 | { | ||
138 | union acpi_object *info; | ||
139 | struct atpx_verify_interface output; | ||
140 | size_t size; | ||
141 | int err = 0; | ||
142 | |||
143 | info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_VERIFY_INTERFACE, NULL); | ||
144 | if (!info) | ||
145 | return -EIO; | ||
146 | |||
147 | memset(&output, 0, sizeof(output)); | ||
148 | |||
149 | size = *(u16 *) info->buffer.pointer; | ||
150 | if (size < 8) { | ||
151 | printk("ATPX buffer is too small: %lu\n", size); | ||
152 | err = -EINVAL; | ||
153 | goto out; | ||
154 | } | ||
155 | size = min(sizeof(output), size); | ||
79 | 156 | ||
80 | buf[2] = value & 0xff; | 157 | memcpy(&output, info->buffer.pointer, size); |
81 | buf[3] = (value >> 8) & 0xff; | ||
82 | 158 | ||
83 | atpx_arg_elements[1].type = ACPI_TYPE_BUFFER; | 159 | /* TODO: check version? */ |
84 | atpx_arg_elements[1].buffer.length = 4; | 160 | printk("ATPX version %u\n", output.version); |
85 | atpx_arg_elements[1].buffer.pointer = buf; | ||
86 | 161 | ||
87 | status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer); | 162 | radeon_atpx_parse_functions(&atpx->functions, output.function_bits); |
88 | if (ACPI_FAILURE(status)) { | ||
89 | printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status)); | ||
90 | return -ENOSYS; | ||
91 | } | ||
92 | kfree(buffer.pointer); | ||
93 | 163 | ||
94 | return 0; | 164 | out: |
165 | kfree(info); | ||
166 | return err; | ||
95 | } | 167 | } |
96 | 168 | ||
97 | static int radeon_atpx_set_discrete_state(acpi_handle handle, int state) | 169 | /** |
170 | * radeon_atpx_set_discrete_state - power up/down discrete GPU | ||
171 | * | ||
172 | * @atpx: atpx info struct | ||
173 | * @state: discrete GPU state (0 = power down, 1 = power up) | ||
174 | * | ||
175 | * Execute the ATPX_FUNCTION_POWER_CONTROL ATPX function to | ||
176 | * power down/up the discrete GPU (all asics). | ||
177 | * Returns 0 on success, error on failure. | ||
178 | */ | ||
179 | static int radeon_atpx_set_discrete_state(struct radeon_atpx *atpx, u8 state) | ||
98 | { | 180 | { |
99 | return radeon_atpx_execute(handle, ATPX_GPU_PWR, state); | 181 | struct acpi_buffer params; |
182 | union acpi_object *info; | ||
183 | struct atpx_power_control input; | ||
184 | |||
185 | if (atpx->functions.power_cntl) { | ||
186 | input.size = 3; | ||
187 | input.dgpu_state = state; | ||
188 | params.length = input.size; | ||
189 | params.pointer = &input; | ||
190 | info = radeon_atpx_call(atpx->handle, | ||
191 | ATPX_FUNCTION_POWER_CONTROL, | ||
192 | ¶ms); | ||
193 | if (!info) | ||
194 | return -EIO; | ||
195 | kfree(info); | ||
196 | } | ||
197 | return 0; | ||
100 | } | 198 | } |
101 | 199 | ||
102 | static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id) | 200 | /** |
201 | * radeon_atpx_switch_disp_mux - switch display mux | ||
202 | * | ||
203 | * @atpx: atpx info struct | ||
204 | * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU) | ||
205 | * | ||
206 | * Execute the ATPX_FUNCTION_DISPLAY_MUX_CONTROL ATPX function to | ||
207 | * switch the display mux between the discrete GPU and integrated GPU | ||
208 | * (all asics). | ||
209 | * Returns 0 on success, error on failure. | ||
210 | */ | ||
211 | static int radeon_atpx_switch_disp_mux(struct radeon_atpx *atpx, u16 mux_id) | ||
103 | { | 212 | { |
104 | return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id); | 213 | struct acpi_buffer params; |
214 | union acpi_object *info; | ||
215 | struct atpx_mux input; | ||
216 | |||
217 | if (atpx->functions.disp_mux_cntl) { | ||
218 | input.size = 4; | ||
219 | input.mux = mux_id; | ||
220 | params.length = input.size; | ||
221 | params.pointer = &input; | ||
222 | info = radeon_atpx_call(atpx->handle, | ||
223 | ATPX_FUNCTION_DISPLAY_MUX_CONTROL, | ||
224 | ¶ms); | ||
225 | if (!info) | ||
226 | return -EIO; | ||
227 | kfree(info); | ||
228 | } | ||
229 | return 0; | ||
105 | } | 230 | } |
106 | 231 | ||
107 | static int radeon_atpx_switch_i2c_mux(acpi_handle handle, int mux_id) | 232 | /** |
233 | * radeon_atpx_switch_i2c_mux - switch i2c/hpd mux | ||
234 | * | ||
235 | * @atpx: atpx info struct | ||
236 | * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU) | ||
237 | * | ||
238 | * Execute the ATPX_FUNCTION_I2C_MUX_CONTROL ATPX function to | ||
239 | * switch the i2c/hpd mux between the discrete GPU and integrated GPU | ||
240 | * (all asics). | ||
241 | * Returns 0 on success, error on failure. | ||
242 | */ | ||
243 | static int radeon_atpx_switch_i2c_mux(struct radeon_atpx *atpx, u16 mux_id) | ||
108 | { | 244 | { |
109 | return radeon_atpx_execute(handle, ATPX_I2C_MUX_SELECT, mux_id); | 245 | struct acpi_buffer params; |
246 | union acpi_object *info; | ||
247 | struct atpx_mux input; | ||
248 | |||
249 | if (atpx->functions.i2c_mux_cntl) { | ||
250 | input.size = 4; | ||
251 | input.mux = mux_id; | ||
252 | params.length = input.size; | ||
253 | params.pointer = &input; | ||
254 | info = radeon_atpx_call(atpx->handle, | ||
255 | ATPX_FUNCTION_I2C_MUX_CONTROL, | ||
256 | ¶ms); | ||
257 | if (!info) | ||
258 | return -EIO; | ||
259 | kfree(info); | ||
260 | } | ||
261 | return 0; | ||
110 | } | 262 | } |
111 | 263 | ||
112 | static int radeon_atpx_switch_start(acpi_handle handle, int gpu_id) | 264 | /** |
265 | * radeon_atpx_switch_start - notify the sbios of a GPU switch | ||
266 | * | ||
267 | * @atpx: atpx info struct | ||
268 | * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU) | ||
269 | * | ||
270 | * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION ATPX | ||
271 | * function to notify the sbios that a switch between the discrete GPU and | ||
272 | * integrated GPU has begun (all asics). | ||
273 | * Returns 0 on success, error on failure. | ||
274 | */ | ||
275 | static int radeon_atpx_switch_start(struct radeon_atpx *atpx, u16 mux_id) | ||
113 | { | 276 | { |
114 | return radeon_atpx_execute(handle, ATPX_SWITCH_START, gpu_id); | 277 | struct acpi_buffer params; |
278 | union acpi_object *info; | ||
279 | struct atpx_mux input; | ||
280 | |||
281 | if (atpx->functions.switch_start) { | ||
282 | input.size = 4; | ||
283 | input.mux = mux_id; | ||
284 | params.length = input.size; | ||
285 | params.pointer = &input; | ||
286 | info = radeon_atpx_call(atpx->handle, | ||
287 | ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION, | ||
288 | ¶ms); | ||
289 | if (!info) | ||
290 | return -EIO; | ||
291 | kfree(info); | ||
292 | } | ||
293 | return 0; | ||
115 | } | 294 | } |
116 | 295 | ||
117 | static int radeon_atpx_switch_end(acpi_handle handle, int gpu_id) | 296 | /** |
297 | * radeon_atpx_switch_end - notify the sbios of a GPU switch | ||
298 | * | ||
299 | * @atpx: atpx info struct | ||
300 | * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU) | ||
301 | * | ||
302 | * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION ATPX | ||
303 | * function to notify the sbios that a switch between the discrete GPU and | ||
304 | * integrated GPU has ended (all asics). | ||
305 | * Returns 0 on success, error on failure. | ||
306 | */ | ||
307 | static int radeon_atpx_switch_end(struct radeon_atpx *atpx, u16 mux_id) | ||
118 | { | 308 | { |
119 | return radeon_atpx_execute(handle, ATPX_SWITCH_END, gpu_id); | 309 | struct acpi_buffer params; |
310 | union acpi_object *info; | ||
311 | struct atpx_mux input; | ||
312 | |||
313 | if (atpx->functions.switch_end) { | ||
314 | input.size = 4; | ||
315 | input.mux = mux_id; | ||
316 | params.length = input.size; | ||
317 | params.pointer = &input; | ||
318 | info = radeon_atpx_call(atpx->handle, | ||
319 | ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION, | ||
320 | ¶ms); | ||
321 | if (!info) | ||
322 | return -EIO; | ||
323 | kfree(info); | ||
324 | } | ||
325 | return 0; | ||
120 | } | 326 | } |
121 | 327 | ||
328 | /** | ||
329 | * radeon_atpx_switchto - switch to the requested GPU | ||
330 | * | ||
331 | * @id: GPU to switch to | ||
332 | * | ||
333 | * Execute the necessary ATPX functions to switch between the discrete GPU and | ||
334 | * integrated GPU (all asics). | ||
335 | * Returns 0 on success, error on failure. | ||
336 | */ | ||
122 | static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) | 337 | static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) |
123 | { | 338 | { |
124 | int gpu_id; | 339 | u16 gpu_id; |
125 | 340 | ||
126 | if (id == VGA_SWITCHEROO_IGD) | 341 | if (id == VGA_SWITCHEROO_IGD) |
127 | gpu_id = ATPX_INTEGRATED; | 342 | gpu_id = ATPX_INTEGRATED_GPU; |
128 | else | 343 | else |
129 | gpu_id = ATPX_DISCRETE; | 344 | gpu_id = ATPX_DISCRETE_GPU; |
130 | 345 | ||
131 | radeon_atpx_switch_start(radeon_atpx_priv.atpx_handle, gpu_id); | 346 | radeon_atpx_switch_start(&radeon_atpx_priv.atpx, gpu_id); |
132 | radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, gpu_id); | 347 | radeon_atpx_switch_disp_mux(&radeon_atpx_priv.atpx, gpu_id); |
133 | radeon_atpx_switch_i2c_mux(radeon_atpx_priv.atpx_handle, gpu_id); | 348 | radeon_atpx_switch_i2c_mux(&radeon_atpx_priv.atpx, gpu_id); |
134 | radeon_atpx_switch_end(radeon_atpx_priv.atpx_handle, gpu_id); | 349 | radeon_atpx_switch_end(&radeon_atpx_priv.atpx, gpu_id); |
135 | 350 | ||
136 | return 0; | 351 | return 0; |
137 | } | 352 | } |
138 | 353 | ||
354 | /** | ||
355 | * radeon_atpx_switchto - switch to the requested GPU | ||
356 | * | ||
357 | * @id: GPU to switch to | ||
358 | * @state: requested power state (0 = off, 1 = on) | ||
359 | * | ||
360 | * Execute the necessary ATPX function to power down/up the discrete GPU | ||
361 | * (all asics). | ||
362 | * Returns 0 on success, error on failure. | ||
363 | */ | ||
139 | static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, | 364 | static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, |
140 | enum vga_switcheroo_state state) | 365 | enum vga_switcheroo_state state) |
141 | { | 366 | { |
@@ -143,10 +368,18 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, | |||
143 | if (id == VGA_SWITCHEROO_IGD) | 368 | if (id == VGA_SWITCHEROO_IGD) |
144 | return 0; | 369 | return 0; |
145 | 370 | ||
146 | radeon_atpx_set_discrete_state(radeon_atpx_priv.atpx_handle, state); | 371 | radeon_atpx_set_discrete_state(&radeon_atpx_priv.atpx, state); |
147 | return 0; | 372 | return 0; |
148 | } | 373 | } |
149 | 374 | ||
375 | /** | ||
376 | * radeon_atpx_pci_probe_handle - look up the ATRM and ATPX handles | ||
377 | * | ||
378 | * @pdev: pci device | ||
379 | * | ||
380 | * Look up the ATPX and ATRM handles (all asics). | ||
381 | * Returns true if the handles are found, false if not. | ||
382 | */ | ||
150 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | 383 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) |
151 | { | 384 | { |
152 | acpi_handle dhandle, atpx_handle; | 385 | acpi_handle dhandle, atpx_handle; |
@@ -161,18 +394,30 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | |||
161 | return false; | 394 | return false; |
162 | 395 | ||
163 | radeon_atpx_priv.dhandle = dhandle; | 396 | radeon_atpx_priv.dhandle = dhandle; |
164 | radeon_atpx_priv.atpx_handle = atpx_handle; | 397 | radeon_atpx_priv.atpx.handle = atpx_handle; |
165 | return true; | 398 | return true; |
166 | } | 399 | } |
167 | 400 | ||
401 | /** | ||
402 | * radeon_atpx_init - verify the ATPX interface | ||
403 | * | ||
404 | * Verify the ATPX interface (all asics). | ||
405 | * Returns 0 on success, error on failure. | ||
406 | */ | ||
168 | static int radeon_atpx_init(void) | 407 | static int radeon_atpx_init(void) |
169 | { | 408 | { |
170 | /* set up the ATPX handle */ | 409 | /* set up the ATPX handle */ |
171 | 410 | return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx); | |
172 | radeon_atpx_get_version(radeon_atpx_priv.atpx_handle); | ||
173 | return 0; | ||
174 | } | 411 | } |
175 | 412 | ||
413 | /** | ||
414 | * radeon_atpx_get_client_id - get the client id | ||
415 | * | ||
416 | * @pdev: pci device | ||
417 | * | ||
418 | * look up whether we are the integrated or discrete GPU (all asics). | ||
419 | * Returns the client id. | ||
420 | */ | ||
176 | static int radeon_atpx_get_client_id(struct pci_dev *pdev) | 421 | static int radeon_atpx_get_client_id(struct pci_dev *pdev) |
177 | { | 422 | { |
178 | if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) | 423 | if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) |
@@ -188,6 +433,12 @@ static struct vga_switcheroo_handler radeon_atpx_handler = { | |||
188 | .get_client_id = radeon_atpx_get_client_id, | 433 | .get_client_id = radeon_atpx_get_client_id, |
189 | }; | 434 | }; |
190 | 435 | ||
436 | /** | ||
437 | * radeon_atpx_detect - detect whether we have PX | ||
438 | * | ||
439 | * Check if we have a PX system (all asics). | ||
440 | * Returns true if we have a PX system, false if not. | ||
441 | */ | ||
191 | static bool radeon_atpx_detect(void) | 442 | static bool radeon_atpx_detect(void) |
192 | { | 443 | { |
193 | char acpi_method_name[255] = { 0 }; | 444 | char acpi_method_name[255] = { 0 }; |
@@ -203,7 +454,7 @@ static bool radeon_atpx_detect(void) | |||
203 | } | 454 | } |
204 | 455 | ||
205 | if (has_atpx && vga_count == 2) { | 456 | if (has_atpx && vga_count == 2) { |
206 | acpi_get_name(radeon_atpx_priv.atpx_handle, ACPI_FULL_PATHNAME, &buffer); | 457 | acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer); |
207 | printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", | 458 | printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", |
208 | acpi_method_name); | 459 | acpi_method_name); |
209 | radeon_atpx_priv.atpx_detected = true; | 460 | radeon_atpx_priv.atpx_detected = true; |
@@ -212,6 +463,11 @@ static bool radeon_atpx_detect(void) | |||
212 | return false; | 463 | return false; |
213 | } | 464 | } |
214 | 465 | ||
466 | /** | ||
467 | * radeon_register_atpx_handler - register with vga_switcheroo | ||
468 | * | ||
469 | * Register the PX callbacks with vga_switcheroo (all asics). | ||
470 | */ | ||
215 | void radeon_register_atpx_handler(void) | 471 | void radeon_register_atpx_handler(void) |
216 | { | 472 | { |
217 | bool r; | 473 | bool r; |
@@ -224,6 +480,11 @@ void radeon_register_atpx_handler(void) | |||
224 | vga_switcheroo_register_handler(&radeon_atpx_handler); | 480 | vga_switcheroo_register_handler(&radeon_atpx_handler); |
225 | } | 481 | } |
226 | 482 | ||
483 | /** | ||
484 | * radeon_unregister_atpx_handler - unregister with vga_switcheroo | ||
485 | * | ||
486 | * Unregister the PX callbacks with vga_switcheroo (all asics). | ||
487 | */ | ||
227 | void radeon_unregister_atpx_handler(void) | 488 | void radeon_unregister_atpx_handler(void) |
228 | { | 489 | { |
229 | vga_switcheroo_unregister_handler(); | 490 | vga_switcheroo_unregister_handler(); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index f75247d42ffd..8a73f0758903 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -3319,15 +3319,6 @@ static void combios_write_ram_size(struct drm_device *dev) | |||
3319 | WREG32(RADEON_CONFIG_MEMSIZE, mem_size); | 3319 | WREG32(RADEON_CONFIG_MEMSIZE, mem_size); |
3320 | } | 3320 | } |
3321 | 3321 | ||
3322 | void radeon_combios_dyn_clk_setup(struct drm_device *dev, int enable) | ||
3323 | { | ||
3324 | uint16_t dyn_clk_info = | ||
3325 | combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); | ||
3326 | |||
3327 | if (dyn_clk_info) | ||
3328 | combios_parse_pll_table(dev, dyn_clk_info); | ||
3329 | } | ||
3330 | |||
3331 | void radeon_combios_asic_init(struct drm_device *dev) | 3322 | void radeon_combios_asic_init(struct drm_device *dev) |
3332 | { | 3323 | { |
3333 | struct radeon_device *rdev = dev->dev_private; | 3324 | struct radeon_device *rdev = dev->dev_private; |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 895e628b60f8..69a142fc3d1d 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -40,10 +40,6 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
40 | struct drm_encoder *encoder, | 40 | struct drm_encoder *encoder, |
41 | bool connected); | 41 | bool connected); |
42 | 42 | ||
43 | extern void | ||
44 | radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | ||
45 | struct drm_connector *drm_connector); | ||
46 | |||
47 | void radeon_connector_hotplug(struct drm_connector *connector) | 43 | void radeon_connector_hotplug(struct drm_connector *connector) |
48 | { | 44 | { |
49 | struct drm_device *dev = connector->dev; | 45 | struct drm_device *dev = connector->dev; |
@@ -198,7 +194,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c | |||
198 | } | 194 | } |
199 | } | 195 | } |
200 | 196 | ||
201 | struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type) | 197 | static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type) |
202 | { | 198 | { |
203 | struct drm_mode_object *obj; | 199 | struct drm_mode_object *obj; |
204 | struct drm_encoder *encoder; | 200 | struct drm_encoder *encoder; |
@@ -219,7 +215,7 @@ struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int enc | |||
219 | return NULL; | 215 | return NULL; |
220 | } | 216 | } |
221 | 217 | ||
222 | struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) | 218 | static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) |
223 | { | 219 | { |
224 | int enc_id = connector->encoder_ids[0]; | 220 | int enc_id = connector->encoder_ids[0]; |
225 | struct drm_mode_object *obj; | 221 | struct drm_mode_object *obj; |
@@ -370,7 +366,7 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn | |||
370 | } | 366 | } |
371 | } | 367 | } |
372 | 368 | ||
373 | int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, | 369 | static int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, |
374 | uint64_t val) | 370 | uint64_t val) |
375 | { | 371 | { |
376 | struct drm_device *dev = connector->dev; | 372 | struct drm_device *dev = connector->dev; |
@@ -691,13 +687,13 @@ static int radeon_lvds_set_property(struct drm_connector *connector, | |||
691 | } | 687 | } |
692 | 688 | ||
693 | 689 | ||
694 | struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = { | 690 | static const struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = { |
695 | .get_modes = radeon_lvds_get_modes, | 691 | .get_modes = radeon_lvds_get_modes, |
696 | .mode_valid = radeon_lvds_mode_valid, | 692 | .mode_valid = radeon_lvds_mode_valid, |
697 | .best_encoder = radeon_best_single_encoder, | 693 | .best_encoder = radeon_best_single_encoder, |
698 | }; | 694 | }; |
699 | 695 | ||
700 | struct drm_connector_funcs radeon_lvds_connector_funcs = { | 696 | static const struct drm_connector_funcs radeon_lvds_connector_funcs = { |
701 | .dpms = drm_helper_connector_dpms, | 697 | .dpms = drm_helper_connector_dpms, |
702 | .detect = radeon_lvds_detect, | 698 | .detect = radeon_lvds_detect, |
703 | .fill_modes = drm_helper_probe_single_connector_modes, | 699 | .fill_modes = drm_helper_probe_single_connector_modes, |
@@ -809,13 +805,13 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
809 | return ret; | 805 | return ret; |
810 | } | 806 | } |
811 | 807 | ||
812 | struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = { | 808 | static const struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = { |
813 | .get_modes = radeon_vga_get_modes, | 809 | .get_modes = radeon_vga_get_modes, |
814 | .mode_valid = radeon_vga_mode_valid, | 810 | .mode_valid = radeon_vga_mode_valid, |
815 | .best_encoder = radeon_best_single_encoder, | 811 | .best_encoder = radeon_best_single_encoder, |
816 | }; | 812 | }; |
817 | 813 | ||
818 | struct drm_connector_funcs radeon_vga_connector_funcs = { | 814 | static const struct drm_connector_funcs radeon_vga_connector_funcs = { |
819 | .dpms = drm_helper_connector_dpms, | 815 | .dpms = drm_helper_connector_dpms, |
820 | .detect = radeon_vga_detect, | 816 | .detect = radeon_vga_detect, |
821 | .fill_modes = drm_helper_probe_single_connector_modes, | 817 | .fill_modes = drm_helper_probe_single_connector_modes, |
@@ -879,13 +875,13 @@ radeon_tv_detect(struct drm_connector *connector, bool force) | |||
879 | return ret; | 875 | return ret; |
880 | } | 876 | } |
881 | 877 | ||
882 | struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = { | 878 | static const struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = { |
883 | .get_modes = radeon_tv_get_modes, | 879 | .get_modes = radeon_tv_get_modes, |
884 | .mode_valid = radeon_tv_mode_valid, | 880 | .mode_valid = radeon_tv_mode_valid, |
885 | .best_encoder = radeon_best_single_encoder, | 881 | .best_encoder = radeon_best_single_encoder, |
886 | }; | 882 | }; |
887 | 883 | ||
888 | struct drm_connector_funcs radeon_tv_connector_funcs = { | 884 | static const struct drm_connector_funcs radeon_tv_connector_funcs = { |
889 | .dpms = drm_helper_connector_dpms, | 885 | .dpms = drm_helper_connector_dpms, |
890 | .detect = radeon_tv_detect, | 886 | .detect = radeon_tv_detect, |
891 | .fill_modes = drm_helper_probe_single_connector_modes, | 887 | .fill_modes = drm_helper_probe_single_connector_modes, |
@@ -1089,7 +1085,7 @@ out: | |||
1089 | } | 1085 | } |
1090 | 1086 | ||
1091 | /* okay need to be smart in here about which encoder to pick */ | 1087 | /* okay need to be smart in here about which encoder to pick */ |
1092 | struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) | 1088 | static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) |
1093 | { | 1089 | { |
1094 | int enc_id = connector->encoder_ids[0]; | 1090 | int enc_id = connector->encoder_ids[0]; |
1095 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 1091 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -1179,13 +1175,13 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, | |||
1179 | return MODE_OK; | 1175 | return MODE_OK; |
1180 | } | 1176 | } |
1181 | 1177 | ||
1182 | struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { | 1178 | static const struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { |
1183 | .get_modes = radeon_dvi_get_modes, | 1179 | .get_modes = radeon_dvi_get_modes, |
1184 | .mode_valid = radeon_dvi_mode_valid, | 1180 | .mode_valid = radeon_dvi_mode_valid, |
1185 | .best_encoder = radeon_dvi_encoder, | 1181 | .best_encoder = radeon_dvi_encoder, |
1186 | }; | 1182 | }; |
1187 | 1183 | ||
1188 | struct drm_connector_funcs radeon_dvi_connector_funcs = { | 1184 | static const struct drm_connector_funcs radeon_dvi_connector_funcs = { |
1189 | .dpms = drm_helper_connector_dpms, | 1185 | .dpms = drm_helper_connector_dpms, |
1190 | .detect = radeon_dvi_detect, | 1186 | .detect = radeon_dvi_detect, |
1191 | .fill_modes = drm_helper_probe_single_connector_modes, | 1187 | .fill_modes = drm_helper_probe_single_connector_modes, |
@@ -1462,13 +1458,13 @@ static int radeon_dp_mode_valid(struct drm_connector *connector, | |||
1462 | } | 1458 | } |
1463 | } | 1459 | } |
1464 | 1460 | ||
1465 | struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { | 1461 | static const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { |
1466 | .get_modes = radeon_dp_get_modes, | 1462 | .get_modes = radeon_dp_get_modes, |
1467 | .mode_valid = radeon_dp_mode_valid, | 1463 | .mode_valid = radeon_dp_mode_valid, |
1468 | .best_encoder = radeon_dvi_encoder, | 1464 | .best_encoder = radeon_dvi_encoder, |
1469 | }; | 1465 | }; |
1470 | 1466 | ||
1471 | struct drm_connector_funcs radeon_dp_connector_funcs = { | 1467 | static const struct drm_connector_funcs radeon_dp_connector_funcs = { |
1472 | .dpms = drm_helper_connector_dpms, | 1468 | .dpms = drm_helper_connector_dpms, |
1473 | .detect = radeon_dp_detect, | 1469 | .detect = radeon_dp_detect, |
1474 | .fill_modes = drm_helper_probe_single_connector_modes, | 1470 | .fill_modes = drm_helper_probe_single_connector_modes, |
@@ -2008,15 +2004,4 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
2008 | connector->polled = DRM_CONNECTOR_POLL_HPD; | 2004 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
2009 | connector->display_info.subpixel_order = subpixel_order; | 2005 | connector->display_info.subpixel_order = subpixel_order; |
2010 | drm_sysfs_connector_add(connector); | 2006 | drm_sysfs_connector_add(connector); |
2011 | if (connector_type == DRM_MODE_CONNECTOR_LVDS) { | ||
2012 | struct drm_encoder *drm_encoder; | ||
2013 | |||
2014 | list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) { | ||
2015 | struct radeon_encoder *radeon_encoder; | ||
2016 | |||
2017 | radeon_encoder = to_radeon_encoder(drm_encoder); | ||
2018 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_LVDS) | ||
2019 | radeon_legacy_backlight_init(radeon_encoder, connector); | ||
2020 | } | ||
2021 | } | ||
2022 | } | 2007 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index b4a0db24f4dd..d59eb59cdb81 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -32,7 +32,7 @@ | |||
32 | void r100_cs_dump_packet(struct radeon_cs_parser *p, | 32 | void r100_cs_dump_packet(struct radeon_cs_parser *p, |
33 | struct radeon_cs_packet *pkt); | 33 | struct radeon_cs_packet *pkt); |
34 | 34 | ||
35 | int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | 35 | static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) |
36 | { | 36 | { |
37 | struct drm_device *ddev = p->rdev->ddev; | 37 | struct drm_device *ddev = p->rdev->ddev; |
38 | struct radeon_cs_chunk *chunk; | 38 | struct radeon_cs_chunk *chunk; |
@@ -115,19 +115,27 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority | |||
115 | return 0; | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | static void radeon_cs_sync_to(struct radeon_cs_parser *p, | ||
119 | struct radeon_fence *fence) | ||
120 | { | ||
121 | struct radeon_fence *other; | ||
122 | |||
123 | if (!fence) | ||
124 | return; | ||
125 | |||
126 | other = p->ib.sync_to[fence->ring]; | ||
127 | p->ib.sync_to[fence->ring] = radeon_fence_later(fence, other); | ||
128 | } | ||
129 | |||
118 | static void radeon_cs_sync_rings(struct radeon_cs_parser *p) | 130 | static void radeon_cs_sync_rings(struct radeon_cs_parser *p) |
119 | { | 131 | { |
120 | int i; | 132 | int i; |
121 | 133 | ||
122 | for (i = 0; i < p->nrelocs; i++) { | 134 | for (i = 0; i < p->nrelocs; i++) { |
123 | struct radeon_fence *a, *b; | 135 | if (!p->relocs[i].robj) |
124 | |||
125 | if (!p->relocs[i].robj || !p->relocs[i].robj->tbo.sync_obj) | ||
126 | continue; | 136 | continue; |
127 | 137 | ||
128 | a = p->relocs[i].robj->tbo.sync_obj; | 138 | radeon_cs_sync_to(p, p->relocs[i].robj->tbo.sync_obj); |
129 | b = p->ib.sync_to[a->ring]; | ||
130 | p->ib.sync_to[a->ring] = radeon_fence_later(a, b); | ||
131 | } | 139 | } |
132 | } | 140 | } |
133 | 141 | ||
@@ -278,30 +286,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
278 | return 0; | 286 | return 0; |
279 | } | 287 | } |
280 | 288 | ||
281 | static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser, | ||
282 | struct radeon_fence *fence) | ||
283 | { | ||
284 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; | ||
285 | struct radeon_vm *vm = &fpriv->vm; | ||
286 | struct radeon_bo_list *lobj; | ||
287 | |||
288 | if (parser->chunk_ib_idx == -1) { | ||
289 | return; | ||
290 | } | ||
291 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) { | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | list_for_each_entry(lobj, &parser->validated, tv.head) { | ||
296 | struct radeon_bo_va *bo_va; | ||
297 | struct radeon_bo *rbo = lobj->bo; | ||
298 | |||
299 | bo_va = radeon_bo_va(rbo, vm); | ||
300 | radeon_fence_unref(&bo_va->fence); | ||
301 | bo_va->fence = radeon_fence_ref(fence); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | /** | 289 | /** |
306 | * cs_parser_fini() - clean parser states | 290 | * cs_parser_fini() - clean parser states |
307 | * @parser: parser structure holding parsing context. | 291 | * @parser: parser structure holding parsing context. |
@@ -315,8 +299,6 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
315 | unsigned i; | 299 | unsigned i; |
316 | 300 | ||
317 | if (!error) { | 301 | if (!error) { |
318 | /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */ | ||
319 | radeon_bo_vm_fence_va(parser, parser->ib.fence); | ||
320 | ttm_eu_fence_buffer_objects(&parser->validated, | 302 | ttm_eu_fence_buffer_objects(&parser->validated, |
321 | parser->ib.fence); | 303 | parser->ib.fence); |
322 | } else { | 304 | } else { |
@@ -363,7 +345,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, | |||
363 | * uncached). | 345 | * uncached). |
364 | */ | 346 | */ |
365 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, | 347 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, |
366 | ib_chunk->length_dw * 4); | 348 | NULL, ib_chunk->length_dw * 4); |
367 | if (r) { | 349 | if (r) { |
368 | DRM_ERROR("Failed to get ib !\n"); | 350 | DRM_ERROR("Failed to get ib !\n"); |
369 | return r; | 351 | return r; |
@@ -380,7 +362,6 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, | |||
380 | return r; | 362 | return r; |
381 | } | 363 | } |
382 | radeon_cs_sync_rings(parser); | 364 | radeon_cs_sync_rings(parser); |
383 | parser->ib.vm_id = 0; | ||
384 | r = radeon_ib_schedule(rdev, &parser->ib, NULL); | 365 | r = radeon_ib_schedule(rdev, &parser->ib, NULL); |
385 | if (r) { | 366 | if (r) { |
386 | DRM_ERROR("Failed to schedule IB !\n"); | 367 | DRM_ERROR("Failed to schedule IB !\n"); |
@@ -391,10 +372,15 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, | |||
391 | static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, | 372 | static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, |
392 | struct radeon_vm *vm) | 373 | struct radeon_vm *vm) |
393 | { | 374 | { |
375 | struct radeon_device *rdev = parser->rdev; | ||
394 | struct radeon_bo_list *lobj; | 376 | struct radeon_bo_list *lobj; |
395 | struct radeon_bo *bo; | 377 | struct radeon_bo *bo; |
396 | int r; | 378 | int r; |
397 | 379 | ||
380 | r = radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, &rdev->ring_tmp_bo.bo->tbo.mem); | ||
381 | if (r) { | ||
382 | return r; | ||
383 | } | ||
398 | list_for_each_entry(lobj, &parser->validated, tv.head) { | 384 | list_for_each_entry(lobj, &parser->validated, tv.head) { |
399 | bo = lobj->bo; | 385 | bo = lobj->bo; |
400 | r = radeon_vm_bo_update_pte(parser->rdev, vm, bo, &bo->tbo.mem); | 386 | r = radeon_vm_bo_update_pte(parser->rdev, vm, bo, &bo->tbo.mem); |
@@ -426,7 +412,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
426 | return -EINVAL; | 412 | return -EINVAL; |
427 | } | 413 | } |
428 | r = radeon_ib_get(rdev, parser->ring, &parser->const_ib, | 414 | r = radeon_ib_get(rdev, parser->ring, &parser->const_ib, |
429 | ib_chunk->length_dw * 4); | 415 | vm, ib_chunk->length_dw * 4); |
430 | if (r) { | 416 | if (r) { |
431 | DRM_ERROR("Failed to get const ib !\n"); | 417 | DRM_ERROR("Failed to get const ib !\n"); |
432 | return r; | 418 | return r; |
@@ -450,7 +436,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
450 | return -EINVAL; | 436 | return -EINVAL; |
451 | } | 437 | } |
452 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, | 438 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, |
453 | ib_chunk->length_dw * 4); | 439 | vm, ib_chunk->length_dw * 4); |
454 | if (r) { | 440 | if (r) { |
455 | DRM_ERROR("Failed to get ib !\n"); | 441 | DRM_ERROR("Failed to get ib !\n"); |
456 | return r; | 442 | return r; |
@@ -468,7 +454,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
468 | 454 | ||
469 | mutex_lock(&rdev->vm_manager.lock); | 455 | mutex_lock(&rdev->vm_manager.lock); |
470 | mutex_lock(&vm->mutex); | 456 | mutex_lock(&vm->mutex); |
471 | r = radeon_vm_bind(rdev, vm); | 457 | r = radeon_vm_alloc_pt(rdev, vm); |
472 | if (r) { | 458 | if (r) { |
473 | goto out; | 459 | goto out; |
474 | } | 460 | } |
@@ -477,32 +463,21 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
477 | goto out; | 463 | goto out; |
478 | } | 464 | } |
479 | radeon_cs_sync_rings(parser); | 465 | radeon_cs_sync_rings(parser); |
480 | 466 | radeon_cs_sync_to(parser, vm->fence); | |
481 | parser->ib.vm_id = vm->id; | 467 | radeon_cs_sync_to(parser, radeon_vm_grab_id(rdev, vm, parser->ring)); |
482 | /* ib pool is bind at 0 in virtual address space, | ||
483 | * so gpu_addr is the offset inside the pool bo | ||
484 | */ | ||
485 | parser->ib.gpu_addr = parser->ib.sa_bo->soffset; | ||
486 | 468 | ||
487 | if ((rdev->family >= CHIP_TAHITI) && | 469 | if ((rdev->family >= CHIP_TAHITI) && |
488 | (parser->chunk_const_ib_idx != -1)) { | 470 | (parser->chunk_const_ib_idx != -1)) { |
489 | parser->const_ib.vm_id = vm->id; | ||
490 | /* ib pool is bind at 0 in virtual address space, | ||
491 | * so gpu_addr is the offset inside the pool bo | ||
492 | */ | ||
493 | parser->const_ib.gpu_addr = parser->const_ib.sa_bo->soffset; | ||
494 | r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib); | 471 | r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib); |
495 | } else { | 472 | } else { |
496 | r = radeon_ib_schedule(rdev, &parser->ib, NULL); | 473 | r = radeon_ib_schedule(rdev, &parser->ib, NULL); |
497 | } | 474 | } |
498 | 475 | ||
499 | out: | ||
500 | if (!r) { | 476 | if (!r) { |
501 | if (vm->fence) { | 477 | radeon_vm_fence(rdev, vm, parser->ib.fence); |
502 | radeon_fence_unref(&vm->fence); | ||
503 | } | ||
504 | vm->fence = radeon_fence_ref(parser->ib.fence); | ||
505 | } | 478 | } |
479 | |||
480 | out: | ||
506 | mutex_unlock(&vm->mutex); | 481 | mutex_unlock(&vm->mutex); |
507 | mutex_unlock(&rdev->vm_manager.lock); | 482 | mutex_unlock(&rdev->vm_manager.lock); |
508 | return r; | 483 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 7a3daebd732d..64a42647f08a 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -842,7 +842,7 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) | |||
842 | * Validates certain module parameters and updates | 842 | * Validates certain module parameters and updates |
843 | * the associated values used by the driver (all asics). | 843 | * the associated values used by the driver (all asics). |
844 | */ | 844 | */ |
845 | void radeon_check_arguments(struct radeon_device *rdev) | 845 | static void radeon_check_arguments(struct radeon_device *rdev) |
846 | { | 846 | { |
847 | /* vramlimit must be a power of two */ | 847 | /* vramlimit must be a power of two */ |
848 | switch (radeon_vram_limit) { | 848 | switch (radeon_vram_limit) { |
@@ -1013,13 +1013,11 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1013 | init_rwsem(&rdev->pm.mclk_lock); | 1013 | init_rwsem(&rdev->pm.mclk_lock); |
1014 | init_rwsem(&rdev->exclusive_lock); | 1014 | init_rwsem(&rdev->exclusive_lock); |
1015 | init_waitqueue_head(&rdev->irq.vblank_queue); | 1015 | init_waitqueue_head(&rdev->irq.vblank_queue); |
1016 | init_waitqueue_head(&rdev->irq.idle_queue); | ||
1017 | r = radeon_gem_init(rdev); | 1016 | r = radeon_gem_init(rdev); |
1018 | if (r) | 1017 | if (r) |
1019 | return r; | 1018 | return r; |
1020 | /* initialize vm here */ | 1019 | /* initialize vm here */ |
1021 | mutex_init(&rdev->vm_manager.lock); | 1020 | mutex_init(&rdev->vm_manager.lock); |
1022 | rdev->vm_manager.use_bitmap = 1; | ||
1023 | rdev->vm_manager.max_pfn = 1 << 20; | 1021 | rdev->vm_manager.max_pfn = 1 << 20; |
1024 | INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); | 1022 | INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); |
1025 | 1023 | ||
@@ -1284,6 +1282,13 @@ int radeon_resume_kms(struct drm_device *dev) | |||
1284 | if (rdev->is_atom_bios) { | 1282 | if (rdev->is_atom_bios) { |
1285 | radeon_atom_encoder_init(rdev); | 1283 | radeon_atom_encoder_init(rdev); |
1286 | radeon_atom_disp_eng_pll_init(rdev); | 1284 | radeon_atom_disp_eng_pll_init(rdev); |
1285 | /* turn on the BL */ | ||
1286 | if (rdev->mode_info.bl_encoder) { | ||
1287 | u8 bl_level = radeon_get_backlight_level(rdev, | ||
1288 | rdev->mode_info.bl_encoder); | ||
1289 | radeon_set_backlight_level(rdev, rdev->mode_info.bl_encoder, | ||
1290 | bl_level); | ||
1291 | } | ||
1287 | } | 1292 | } |
1288 | /* reset hpd state */ | 1293 | /* reset hpd state */ |
1289 | radeon_hpd_init(rdev); | 1294 | radeon_hpd_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 8c593ea82c41..27ece75b4789 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -64,9 +64,11 @@ | |||
64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query | 64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query |
65 | * 2.21.0 - r600-r700: FMASK and CMASK | 65 | * 2.21.0 - r600-r700: FMASK and CMASK |
66 | * 2.22.0 - r600 only: RESOLVE_BOX allowed | 66 | * 2.22.0 - r600 only: RESOLVE_BOX allowed |
67 | * 2.23.0 - allow STRMOUT_BASE_UPDATE on RS780 and RS880 | ||
68 | * 2.24.0 - eg only: allow MIP_ADDRESS=0 for MSAA textures | ||
67 | */ | 69 | */ |
68 | #define KMS_DRIVER_MAJOR 2 | 70 | #define KMS_DRIVER_MAJOR 2 |
69 | #define KMS_DRIVER_MINOR 22 | 71 | #define KMS_DRIVER_MINOR 24 |
70 | #define KMS_DRIVER_PATCHLEVEL 0 | 72 | #define KMS_DRIVER_PATCHLEVEL 0 |
71 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 73 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
72 | int radeon_driver_unload_kms(struct drm_device *dev); | 74 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 74670696277d..e66c807df9e6 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -29,6 +29,14 @@ | |||
29 | #include "radeon.h" | 29 | #include "radeon.h" |
30 | #include "atom.h" | 30 | #include "atom.h" |
31 | 31 | ||
32 | extern void | ||
33 | radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | ||
34 | struct drm_connector *drm_connector); | ||
35 | extern void | ||
36 | radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, | ||
37 | struct drm_connector *drm_connector); | ||
38 | |||
39 | |||
32 | static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) | 40 | static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) |
33 | { | 41 | { |
34 | struct drm_device *dev = encoder->dev; | 42 | struct drm_device *dev = encoder->dev; |
@@ -153,6 +161,7 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8 | |||
153 | void | 161 | void |
154 | radeon_link_encoder_connector(struct drm_device *dev) | 162 | radeon_link_encoder_connector(struct drm_device *dev) |
155 | { | 163 | { |
164 | struct radeon_device *rdev = dev->dev_private; | ||
156 | struct drm_connector *connector; | 165 | struct drm_connector *connector; |
157 | struct radeon_connector *radeon_connector; | 166 | struct radeon_connector *radeon_connector; |
158 | struct drm_encoder *encoder; | 167 | struct drm_encoder *encoder; |
@@ -163,8 +172,16 @@ radeon_link_encoder_connector(struct drm_device *dev) | |||
163 | radeon_connector = to_radeon_connector(connector); | 172 | radeon_connector = to_radeon_connector(connector); |
164 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 173 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
165 | radeon_encoder = to_radeon_encoder(encoder); | 174 | radeon_encoder = to_radeon_encoder(encoder); |
166 | if (radeon_encoder->devices & radeon_connector->devices) | 175 | if (radeon_encoder->devices & radeon_connector->devices) { |
167 | drm_mode_connector_attach_encoder(connector, encoder); | 176 | drm_mode_connector_attach_encoder(connector, encoder); |
177 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
178 | if (rdev->is_atom_bios) | ||
179 | radeon_atom_backlight_init(radeon_encoder, connector); | ||
180 | else | ||
181 | radeon_legacy_backlight_init(radeon_encoder, connector); | ||
182 | rdev->mode_info.bl_encoder = radeon_encoder; | ||
183 | } | ||
184 | } | ||
168 | } | 185 | } |
169 | } | 186 | } |
170 | } | 187 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 5906914a78bc..6ada72c6d7a1 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -316,22 +316,6 @@ static int radeon_fb_find_or_create_single(struct drm_fb_helper *helper, | |||
316 | return new_fb; | 316 | return new_fb; |
317 | } | 317 | } |
318 | 318 | ||
319 | static char *mode_option; | ||
320 | int radeon_parse_options(char *options) | ||
321 | { | ||
322 | char *this_opt; | ||
323 | |||
324 | if (!options || !*options) | ||
325 | return 0; | ||
326 | |||
327 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
328 | if (!*this_opt) | ||
329 | continue; | ||
330 | mode_option = this_opt; | ||
331 | } | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | void radeon_fb_output_poll_changed(struct radeon_device *rdev) | 319 | void radeon_fb_output_poll_changed(struct radeon_device *rdev) |
336 | { | 320 | { |
337 | drm_fb_helper_hotplug_event(&rdev->mode_info.rfbdev->helper); | 321 | drm_fb_helper_hotplug_event(&rdev->mode_info.rfbdev->helper); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 2a59375dbe52..1eb3db52a36e 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -399,7 +399,7 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) | |||
399 | return 0; | 399 | return 0; |
400 | } | 400 | } |
401 | 401 | ||
402 | bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq) | 402 | static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq) |
403 | { | 403 | { |
404 | unsigned i; | 404 | unsigned i; |
405 | 405 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index bb3b7fe05ccd..753b7ca3c807 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -423,6 +423,18 @@ void radeon_gart_fini(struct radeon_device *rdev) | |||
423 | */ | 423 | */ |
424 | 424 | ||
425 | /** | 425 | /** |
426 | * radeon_vm_directory_size - returns the size of the page directory in bytes | ||
427 | * | ||
428 | * @rdev: radeon_device pointer | ||
429 | * | ||
430 | * Calculate the size of the page directory in bytes (cayman+). | ||
431 | */ | ||
432 | static unsigned radeon_vm_directory_size(struct radeon_device *rdev) | ||
433 | { | ||
434 | return (rdev->vm_manager.max_pfn >> RADEON_VM_BLOCK_SIZE) * 8; | ||
435 | } | ||
436 | |||
437 | /** | ||
426 | * radeon_vm_manager_init - init the vm manager | 438 | * radeon_vm_manager_init - init the vm manager |
427 | * | 439 | * |
428 | * @rdev: radeon_device pointer | 440 | * @rdev: radeon_device pointer |
@@ -435,12 +447,15 @@ int radeon_vm_manager_init(struct radeon_device *rdev) | |||
435 | struct radeon_vm *vm; | 447 | struct radeon_vm *vm; |
436 | struct radeon_bo_va *bo_va; | 448 | struct radeon_bo_va *bo_va; |
437 | int r; | 449 | int r; |
450 | unsigned size; | ||
438 | 451 | ||
439 | if (!rdev->vm_manager.enabled) { | 452 | if (!rdev->vm_manager.enabled) { |
440 | /* mark first vm as always in use, it's the system one */ | ||
441 | /* allocate enough for 2 full VM pts */ | 453 | /* allocate enough for 2 full VM pts */ |
454 | size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev)); | ||
455 | size += RADEON_GPU_PAGE_ALIGN(rdev->vm_manager.max_pfn * 8); | ||
456 | size *= 2; | ||
442 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, | 457 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, |
443 | rdev->vm_manager.max_pfn * 8 * 2, | 458 | size, |
444 | RADEON_GEM_DOMAIN_VRAM); | 459 | RADEON_GEM_DOMAIN_VRAM); |
445 | if (r) { | 460 | if (r) { |
446 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", | 461 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", |
@@ -448,10 +463,10 @@ int radeon_vm_manager_init(struct radeon_device *rdev) | |||
448 | return r; | 463 | return r; |
449 | } | 464 | } |
450 | 465 | ||
451 | r = rdev->vm_manager.funcs->init(rdev); | 466 | r = radeon_asic_vm_init(rdev); |
452 | if (r) | 467 | if (r) |
453 | return r; | 468 | return r; |
454 | 469 | ||
455 | rdev->vm_manager.enabled = true; | 470 | rdev->vm_manager.enabled = true; |
456 | 471 | ||
457 | r = radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager); | 472 | r = radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager); |
@@ -461,73 +476,36 @@ int radeon_vm_manager_init(struct radeon_device *rdev) | |||
461 | 476 | ||
462 | /* restore page table */ | 477 | /* restore page table */ |
463 | list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) { | 478 | list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) { |
464 | if (vm->id == -1) | 479 | if (vm->sa_bo == NULL) |
465 | continue; | 480 | continue; |
466 | 481 | ||
467 | list_for_each_entry(bo_va, &vm->va, vm_list) { | 482 | list_for_each_entry(bo_va, &vm->va, vm_list) { |
468 | struct ttm_mem_reg *mem = NULL; | ||
469 | if (bo_va->valid) | ||
470 | mem = &bo_va->bo->tbo.mem; | ||
471 | |||
472 | bo_va->valid = false; | 483 | bo_va->valid = false; |
473 | r = radeon_vm_bo_update_pte(rdev, vm, bo_va->bo, mem); | ||
474 | if (r) { | ||
475 | DRM_ERROR("Failed to update pte for vm %d!\n", vm->id); | ||
476 | } | ||
477 | } | ||
478 | |||
479 | r = rdev->vm_manager.funcs->bind(rdev, vm, vm->id); | ||
480 | if (r) { | ||
481 | DRM_ERROR("Failed to bind vm %d!\n", vm->id); | ||
482 | } | 484 | } |
483 | } | 485 | } |
484 | return 0; | 486 | return 0; |
485 | } | 487 | } |
486 | 488 | ||
487 | /* global mutex must be lock */ | ||
488 | /** | 489 | /** |
489 | * radeon_vm_unbind_locked - unbind a specific vm | 490 | * radeon_vm_free_pt - free the page table for a specific vm |
490 | * | 491 | * |
491 | * @rdev: radeon_device pointer | 492 | * @rdev: radeon_device pointer |
492 | * @vm: vm to unbind | 493 | * @vm: vm to unbind |
493 | * | 494 | * |
494 | * Unbind the requested vm (cayman+). | 495 | * Free the page table of a specific vm (cayman+). |
495 | * Wait for use of the VM to finish, then unbind the page table, | 496 | * |
496 | * and free the page table memory. | 497 | * Global and local mutex must be lock! |
497 | */ | 498 | */ |
498 | static void radeon_vm_unbind_locked(struct radeon_device *rdev, | 499 | static void radeon_vm_free_pt(struct radeon_device *rdev, |
499 | struct radeon_vm *vm) | 500 | struct radeon_vm *vm) |
500 | { | 501 | { |
501 | struct radeon_bo_va *bo_va; | 502 | struct radeon_bo_va *bo_va; |
502 | 503 | ||
503 | if (vm->id == -1) { | 504 | if (!vm->sa_bo) |
504 | return; | 505 | return; |
505 | } | ||
506 | 506 | ||
507 | /* wait for vm use to end */ | ||
508 | while (vm->fence) { | ||
509 | int r; | ||
510 | r = radeon_fence_wait(vm->fence, false); | ||
511 | if (r) | ||
512 | DRM_ERROR("error while waiting for fence: %d\n", r); | ||
513 | if (r == -EDEADLK) { | ||
514 | mutex_unlock(&rdev->vm_manager.lock); | ||
515 | r = radeon_gpu_reset(rdev); | ||
516 | mutex_lock(&rdev->vm_manager.lock); | ||
517 | if (!r) | ||
518 | continue; | ||
519 | } | ||
520 | break; | ||
521 | } | ||
522 | radeon_fence_unref(&vm->fence); | ||
523 | |||
524 | /* hw unbind */ | ||
525 | rdev->vm_manager.funcs->unbind(rdev, vm); | ||
526 | rdev->vm_manager.use_bitmap &= ~(1 << vm->id); | ||
527 | list_del_init(&vm->list); | 507 | list_del_init(&vm->list); |
528 | vm->id = -1; | 508 | radeon_sa_bo_free(rdev, &vm->sa_bo, vm->fence); |
529 | radeon_sa_bo_free(rdev, &vm->sa_bo, NULL); | ||
530 | vm->pt = NULL; | ||
531 | 509 | ||
532 | list_for_each_entry(bo_va, &vm->va, vm_list) { | 510 | list_for_each_entry(bo_va, &vm->va, vm_list) { |
533 | bo_va->valid = false; | 511 | bo_va->valid = false; |
@@ -544,16 +522,22 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev, | |||
544 | void radeon_vm_manager_fini(struct radeon_device *rdev) | 522 | void radeon_vm_manager_fini(struct radeon_device *rdev) |
545 | { | 523 | { |
546 | struct radeon_vm *vm, *tmp; | 524 | struct radeon_vm *vm, *tmp; |
525 | int i; | ||
547 | 526 | ||
548 | if (!rdev->vm_manager.enabled) | 527 | if (!rdev->vm_manager.enabled) |
549 | return; | 528 | return; |
550 | 529 | ||
551 | mutex_lock(&rdev->vm_manager.lock); | 530 | mutex_lock(&rdev->vm_manager.lock); |
552 | /* unbind all active vm */ | 531 | /* free all allocated page tables */ |
553 | list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { | 532 | list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { |
554 | radeon_vm_unbind_locked(rdev, vm); | 533 | mutex_lock(&vm->mutex); |
534 | radeon_vm_free_pt(rdev, vm); | ||
535 | mutex_unlock(&vm->mutex); | ||
555 | } | 536 | } |
556 | rdev->vm_manager.funcs->fini(rdev); | 537 | for (i = 0; i < RADEON_NUM_VM; ++i) { |
538 | radeon_fence_unref(&rdev->vm_manager.active[i]); | ||
539 | } | ||
540 | radeon_asic_vm_fini(rdev); | ||
557 | mutex_unlock(&rdev->vm_manager.lock); | 541 | mutex_unlock(&rdev->vm_manager.lock); |
558 | 542 | ||
559 | radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); | 543 | radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); |
@@ -561,46 +545,34 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) | |||
561 | rdev->vm_manager.enabled = false; | 545 | rdev->vm_manager.enabled = false; |
562 | } | 546 | } |
563 | 547 | ||
564 | /* global mutex must be locked */ | ||
565 | /** | 548 | /** |
566 | * radeon_vm_unbind - locked version of unbind | 549 | * radeon_vm_alloc_pt - allocates a page table for a VM |
567 | * | ||
568 | * @rdev: radeon_device pointer | ||
569 | * @vm: vm to unbind | ||
570 | * | ||
571 | * Locked version that wraps radeon_vm_unbind_locked (cayman+). | ||
572 | */ | ||
573 | void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) | ||
574 | { | ||
575 | mutex_lock(&vm->mutex); | ||
576 | radeon_vm_unbind_locked(rdev, vm); | ||
577 | mutex_unlock(&vm->mutex); | ||
578 | } | ||
579 | |||
580 | /* global and local mutex must be locked */ | ||
581 | /** | ||
582 | * radeon_vm_bind - bind a page table to a VMID | ||
583 | * | 550 | * |
584 | * @rdev: radeon_device pointer | 551 | * @rdev: radeon_device pointer |
585 | * @vm: vm to bind | 552 | * @vm: vm to bind |
586 | * | 553 | * |
587 | * Bind the requested vm (cayman+). | 554 | * Allocate a page table for the requested vm (cayman+). |
588 | * Suballocate memory for the page table, allocate a VMID | 555 | * Also starts to populate the page table. |
589 | * and bind the page table to it, and finally start to populate | ||
590 | * the page table. | ||
591 | * Returns 0 for success, error for failure. | 556 | * Returns 0 for success, error for failure. |
557 | * | ||
558 | * Global and local mutex must be locked! | ||
592 | */ | 559 | */ |
593 | int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) | 560 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm) |
594 | { | 561 | { |
595 | struct radeon_vm *vm_evict; | 562 | struct radeon_vm *vm_evict; |
596 | unsigned i; | 563 | int r; |
597 | int id = -1, r; | 564 | u64 *pd_addr; |
565 | int tables_size; | ||
598 | 566 | ||
599 | if (vm == NULL) { | 567 | if (vm == NULL) { |
600 | return -EINVAL; | 568 | return -EINVAL; |
601 | } | 569 | } |
602 | 570 | ||
603 | if (vm->id != -1) { | 571 | /* allocate enough to cover the current VM size */ |
572 | tables_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev)); | ||
573 | tables_size += RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8); | ||
574 | |||
575 | if (vm->sa_bo != NULL) { | ||
604 | /* update lru */ | 576 | /* update lru */ |
605 | list_del_init(&vm->list); | 577 | list_del_init(&vm->list); |
606 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); | 578 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); |
@@ -609,98 +581,215 @@ int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) | |||
609 | 581 | ||
610 | retry: | 582 | retry: |
611 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo, | 583 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo, |
612 | RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8), | 584 | tables_size, RADEON_GPU_PAGE_SIZE, false); |
613 | RADEON_GPU_PAGE_SIZE, false); | 585 | if (r == -ENOMEM) { |
614 | if (r) { | ||
615 | if (list_empty(&rdev->vm_manager.lru_vm)) { | 586 | if (list_empty(&rdev->vm_manager.lru_vm)) { |
616 | return r; | 587 | return r; |
617 | } | 588 | } |
618 | vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list); | 589 | vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list); |
619 | radeon_vm_unbind(rdev, vm_evict); | 590 | mutex_lock(&vm_evict->mutex); |
591 | radeon_vm_free_pt(rdev, vm_evict); | ||
592 | mutex_unlock(&vm_evict->mutex); | ||
620 | goto retry; | 593 | goto retry; |
594 | |||
595 | } else if (r) { | ||
596 | return r; | ||
621 | } | 597 | } |
622 | vm->pt = radeon_sa_bo_cpu_addr(vm->sa_bo); | ||
623 | vm->pt_gpu_addr = radeon_sa_bo_gpu_addr(vm->sa_bo); | ||
624 | memset(vm->pt, 0, RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8)); | ||
625 | 598 | ||
626 | retry_id: | 599 | pd_addr = radeon_sa_bo_cpu_addr(vm->sa_bo); |
627 | /* search for free vm */ | 600 | vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->sa_bo); |
628 | for (i = 0; i < rdev->vm_manager.nvm; i++) { | 601 | memset(pd_addr, 0, tables_size); |
629 | if (!(rdev->vm_manager.use_bitmap & (1 << i))) { | 602 | |
630 | id = i; | 603 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); |
631 | break; | 604 | return radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, |
605 | &rdev->ring_tmp_bo.bo->tbo.mem); | ||
606 | } | ||
607 | |||
608 | /** | ||
609 | * radeon_vm_grab_id - allocate the next free VMID | ||
610 | * | ||
611 | * @rdev: radeon_device pointer | ||
612 | * @vm: vm to allocate id for | ||
613 | * @ring: ring we want to submit job to | ||
614 | * | ||
615 | * Allocate an id for the vm (cayman+). | ||
616 | * Returns the fence we need to sync to (if any). | ||
617 | * | ||
618 | * Global and local mutex must be locked! | ||
619 | */ | ||
620 | struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | ||
621 | struct radeon_vm *vm, int ring) | ||
622 | { | ||
623 | struct radeon_fence *best[RADEON_NUM_RINGS] = {}; | ||
624 | unsigned choices[2] = {}; | ||
625 | unsigned i; | ||
626 | |||
627 | /* check if the id is still valid */ | ||
628 | if (vm->fence && vm->fence == rdev->vm_manager.active[vm->id]) | ||
629 | return NULL; | ||
630 | |||
631 | /* we definately need to flush */ | ||
632 | radeon_fence_unref(&vm->last_flush); | ||
633 | |||
634 | /* skip over VMID 0, since it is the system VM */ | ||
635 | for (i = 1; i < rdev->vm_manager.nvm; ++i) { | ||
636 | struct radeon_fence *fence = rdev->vm_manager.active[i]; | ||
637 | |||
638 | if (fence == NULL) { | ||
639 | /* found a free one */ | ||
640 | vm->id = i; | ||
641 | return NULL; | ||
642 | } | ||
643 | |||
644 | if (radeon_fence_is_earlier(fence, best[fence->ring])) { | ||
645 | best[fence->ring] = fence; | ||
646 | choices[fence->ring == ring ? 0 : 1] = i; | ||
632 | } | 647 | } |
633 | } | 648 | } |
634 | /* evict vm if necessary */ | 649 | |
635 | if (id == -1) { | 650 | for (i = 0; i < 2; ++i) { |
636 | vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list); | 651 | if (choices[i]) { |
637 | radeon_vm_unbind(rdev, vm_evict); | 652 | vm->id = choices[i]; |
638 | goto retry_id; | 653 | return rdev->vm_manager.active[choices[i]]; |
654 | } | ||
639 | } | 655 | } |
640 | 656 | ||
641 | /* do hw bind */ | 657 | /* should never happen */ |
642 | r = rdev->vm_manager.funcs->bind(rdev, vm, id); | 658 | BUG(); |
643 | if (r) { | 659 | return NULL; |
644 | radeon_sa_bo_free(rdev, &vm->sa_bo, NULL); | 660 | } |
645 | return r; | 661 | |
662 | /** | ||
663 | * radeon_vm_fence - remember fence for vm | ||
664 | * | ||
665 | * @rdev: radeon_device pointer | ||
666 | * @vm: vm we want to fence | ||
667 | * @fence: fence to remember | ||
668 | * | ||
669 | * Fence the vm (cayman+). | ||
670 | * Set the fence used to protect page table and id. | ||
671 | * | ||
672 | * Global and local mutex must be locked! | ||
673 | */ | ||
674 | void radeon_vm_fence(struct radeon_device *rdev, | ||
675 | struct radeon_vm *vm, | ||
676 | struct radeon_fence *fence) | ||
677 | { | ||
678 | radeon_fence_unref(&rdev->vm_manager.active[vm->id]); | ||
679 | rdev->vm_manager.active[vm->id] = radeon_fence_ref(fence); | ||
680 | |||
681 | radeon_fence_unref(&vm->fence); | ||
682 | vm->fence = radeon_fence_ref(fence); | ||
683 | } | ||
684 | |||
685 | /** | ||
686 | * radeon_vm_bo_find - find the bo_va for a specific vm & bo | ||
687 | * | ||
688 | * @vm: requested vm | ||
689 | * @bo: requested buffer object | ||
690 | * | ||
691 | * Find @bo inside the requested vm (cayman+). | ||
692 | * Search inside the @bos vm list for the requested vm | ||
693 | * Returns the found bo_va or NULL if none is found | ||
694 | * | ||
695 | * Object has to be reserved! | ||
696 | */ | ||
697 | struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm, | ||
698 | struct radeon_bo *bo) | ||
699 | { | ||
700 | struct radeon_bo_va *bo_va; | ||
701 | |||
702 | list_for_each_entry(bo_va, &bo->va, bo_list) { | ||
703 | if (bo_va->vm == vm) { | ||
704 | return bo_va; | ||
705 | } | ||
646 | } | 706 | } |
647 | rdev->vm_manager.use_bitmap |= 1 << id; | 707 | return NULL; |
648 | vm->id = id; | ||
649 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); | ||
650 | return radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, | ||
651 | &rdev->ring_tmp_bo.bo->tbo.mem); | ||
652 | } | 708 | } |
653 | 709 | ||
654 | /* object have to be reserved */ | ||
655 | /** | 710 | /** |
656 | * radeon_vm_bo_add - add a bo to a specific vm | 711 | * radeon_vm_bo_add - add a bo to a specific vm |
657 | * | 712 | * |
658 | * @rdev: radeon_device pointer | 713 | * @rdev: radeon_device pointer |
659 | * @vm: requested vm | 714 | * @vm: requested vm |
660 | * @bo: radeon buffer object | 715 | * @bo: radeon buffer object |
661 | * @offset: requested offset of the buffer in the VM address space | ||
662 | * @flags: attributes of pages (read/write/valid/etc.) | ||
663 | * | 716 | * |
664 | * Add @bo into the requested vm (cayman+). | 717 | * Add @bo into the requested vm (cayman+). |
665 | * Add @bo to the list of bos associated with the vm and validate | 718 | * Add @bo to the list of bos associated with the vm |
666 | * the offset requested within the vm address space. | 719 | * Returns newly added bo_va or NULL for failure |
667 | * Returns 0 for success, error for failure. | 720 | * |
721 | * Object has to be reserved! | ||
668 | */ | 722 | */ |
669 | int radeon_vm_bo_add(struct radeon_device *rdev, | 723 | struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, |
670 | struct radeon_vm *vm, | 724 | struct radeon_vm *vm, |
671 | struct radeon_bo *bo, | 725 | struct radeon_bo *bo) |
672 | uint64_t offset, | ||
673 | uint32_t flags) | ||
674 | { | 726 | { |
675 | struct radeon_bo_va *bo_va, *tmp; | 727 | struct radeon_bo_va *bo_va; |
676 | struct list_head *head; | ||
677 | uint64_t size = radeon_bo_size(bo), last_offset = 0; | ||
678 | unsigned last_pfn; | ||
679 | 728 | ||
680 | bo_va = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); | 729 | bo_va = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); |
681 | if (bo_va == NULL) { | 730 | if (bo_va == NULL) { |
682 | return -ENOMEM; | 731 | return NULL; |
683 | } | 732 | } |
684 | bo_va->vm = vm; | 733 | bo_va->vm = vm; |
685 | bo_va->bo = bo; | 734 | bo_va->bo = bo; |
686 | bo_va->soffset = offset; | 735 | bo_va->soffset = 0; |
687 | bo_va->eoffset = offset + size; | 736 | bo_va->eoffset = 0; |
688 | bo_va->flags = flags; | 737 | bo_va->flags = 0; |
689 | bo_va->valid = false; | 738 | bo_va->valid = false; |
739 | bo_va->ref_count = 1; | ||
690 | INIT_LIST_HEAD(&bo_va->bo_list); | 740 | INIT_LIST_HEAD(&bo_va->bo_list); |
691 | INIT_LIST_HEAD(&bo_va->vm_list); | 741 | INIT_LIST_HEAD(&bo_va->vm_list); |
692 | /* make sure object fit at this offset */ | ||
693 | if (bo_va->soffset >= bo_va->eoffset) { | ||
694 | kfree(bo_va); | ||
695 | return -EINVAL; | ||
696 | } | ||
697 | 742 | ||
698 | last_pfn = bo_va->eoffset / RADEON_GPU_PAGE_SIZE; | 743 | mutex_lock(&vm->mutex); |
699 | if (last_pfn > rdev->vm_manager.max_pfn) { | 744 | list_add(&bo_va->vm_list, &vm->va); |
700 | kfree(bo_va); | 745 | list_add_tail(&bo_va->bo_list, &bo->va); |
701 | dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n", | 746 | mutex_unlock(&vm->mutex); |
702 | last_pfn, rdev->vm_manager.max_pfn); | 747 | |
703 | return -EINVAL; | 748 | return bo_va; |
749 | } | ||
750 | |||
751 | /** | ||
752 | * radeon_vm_bo_set_addr - set bos virtual address inside a vm | ||
753 | * | ||
754 | * @rdev: radeon_device pointer | ||
755 | * @bo_va: bo_va to store the address | ||
756 | * @soffset: requested offset of the buffer in the VM address space | ||
757 | * @flags: attributes of pages (read/write/valid/etc.) | ||
758 | * | ||
759 | * Set offset of @bo_va (cayman+). | ||
760 | * Validate and set the offset requested within the vm address space. | ||
761 | * Returns 0 for success, error for failure. | ||
762 | * | ||
763 | * Object has to be reserved! | ||
764 | */ | ||
765 | int radeon_vm_bo_set_addr(struct radeon_device *rdev, | ||
766 | struct radeon_bo_va *bo_va, | ||
767 | uint64_t soffset, | ||
768 | uint32_t flags) | ||
769 | { | ||
770 | uint64_t size = radeon_bo_size(bo_va->bo); | ||
771 | uint64_t eoffset, last_offset = 0; | ||
772 | struct radeon_vm *vm = bo_va->vm; | ||
773 | struct radeon_bo_va *tmp; | ||
774 | struct list_head *head; | ||
775 | unsigned last_pfn; | ||
776 | |||
777 | if (soffset) { | ||
778 | /* make sure object fit at this offset */ | ||
779 | eoffset = soffset + size; | ||
780 | if (soffset >= eoffset) { | ||
781 | return -EINVAL; | ||
782 | } | ||
783 | |||
784 | last_pfn = eoffset / RADEON_GPU_PAGE_SIZE; | ||
785 | if (last_pfn > rdev->vm_manager.max_pfn) { | ||
786 | dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n", | ||
787 | last_pfn, rdev->vm_manager.max_pfn); | ||
788 | return -EINVAL; | ||
789 | } | ||
790 | |||
791 | } else { | ||
792 | eoffset = last_pfn = 0; | ||
704 | } | 793 | } |
705 | 794 | ||
706 | mutex_lock(&vm->mutex); | 795 | mutex_lock(&vm->mutex); |
@@ -713,7 +802,7 @@ int radeon_vm_bo_add(struct radeon_device *rdev, | |||
713 | if (last_pfn > vm->last_pfn) { | 802 | if (last_pfn > vm->last_pfn) { |
714 | /* grow va space 32M by 32M */ | 803 | /* grow va space 32M by 32M */ |
715 | unsigned align = ((32 << 20) >> 12) - 1; | 804 | unsigned align = ((32 << 20) >> 12) - 1; |
716 | radeon_vm_unbind_locked(rdev, vm); | 805 | radeon_vm_free_pt(rdev, vm); |
717 | vm->last_pfn = (last_pfn + align) & ~align; | 806 | vm->last_pfn = (last_pfn + align) & ~align; |
718 | } | 807 | } |
719 | mutex_unlock(&rdev->vm_manager.lock); | 808 | mutex_unlock(&rdev->vm_manager.lock); |
@@ -721,68 +810,60 @@ int radeon_vm_bo_add(struct radeon_device *rdev, | |||
721 | head = &vm->va; | 810 | head = &vm->va; |
722 | last_offset = 0; | 811 | last_offset = 0; |
723 | list_for_each_entry(tmp, &vm->va, vm_list) { | 812 | list_for_each_entry(tmp, &vm->va, vm_list) { |
724 | if (bo_va->soffset >= last_offset && bo_va->eoffset < tmp->soffset) { | 813 | if (bo_va == tmp) { |
814 | /* skip over currently modified bo */ | ||
815 | continue; | ||
816 | } | ||
817 | |||
818 | if (soffset >= last_offset && eoffset <= tmp->soffset) { | ||
725 | /* bo can be added before this one */ | 819 | /* bo can be added before this one */ |
726 | break; | 820 | break; |
727 | } | 821 | } |
728 | if (bo_va->soffset >= tmp->soffset && bo_va->soffset < tmp->eoffset) { | 822 | if (eoffset > tmp->soffset && soffset < tmp->eoffset) { |
729 | /* bo and tmp overlap, invalid offset */ | 823 | /* bo and tmp overlap, invalid offset */ |
730 | dev_err(rdev->dev, "bo %p va 0x%08X conflict with (bo %p 0x%08X 0x%08X)\n", | 824 | dev_err(rdev->dev, "bo %p va 0x%08X conflict with (bo %p 0x%08X 0x%08X)\n", |
731 | bo, (unsigned)bo_va->soffset, tmp->bo, | 825 | bo_va->bo, (unsigned)bo_va->soffset, tmp->bo, |
732 | (unsigned)tmp->soffset, (unsigned)tmp->eoffset); | 826 | (unsigned)tmp->soffset, (unsigned)tmp->eoffset); |
733 | kfree(bo_va); | ||
734 | mutex_unlock(&vm->mutex); | 827 | mutex_unlock(&vm->mutex); |
735 | return -EINVAL; | 828 | return -EINVAL; |
736 | } | 829 | } |
737 | last_offset = tmp->eoffset; | 830 | last_offset = tmp->eoffset; |
738 | head = &tmp->vm_list; | 831 | head = &tmp->vm_list; |
739 | } | 832 | } |
740 | list_add(&bo_va->vm_list, head); | 833 | |
741 | list_add_tail(&bo_va->bo_list, &bo->va); | 834 | bo_va->soffset = soffset; |
835 | bo_va->eoffset = eoffset; | ||
836 | bo_va->flags = flags; | ||
837 | bo_va->valid = false; | ||
838 | list_move(&bo_va->vm_list, head); | ||
839 | |||
742 | mutex_unlock(&vm->mutex); | 840 | mutex_unlock(&vm->mutex); |
743 | return 0; | 841 | return 0; |
744 | } | 842 | } |
745 | 843 | ||
746 | /** | 844 | /** |
747 | * radeon_vm_get_addr - get the physical address of the page | 845 | * radeon_vm_map_gart - get the physical address of a gart page |
748 | * | 846 | * |
749 | * @rdev: radeon_device pointer | 847 | * @rdev: radeon_device pointer |
750 | * @mem: ttm mem | 848 | * @addr: the unmapped addr |
751 | * @pfn: pfn | ||
752 | * | 849 | * |
753 | * Look up the physical address of the page that the pte resolves | 850 | * Look up the physical address of the page that the pte resolves |
754 | * to (cayman+). | 851 | * to (cayman+). |
755 | * Returns the physical address of the page. | 852 | * Returns the physical address of the page. |
756 | */ | 853 | */ |
757 | static u64 radeon_vm_get_addr(struct radeon_device *rdev, | 854 | uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr) |
758 | struct ttm_mem_reg *mem, | ||
759 | unsigned pfn) | ||
760 | { | 855 | { |
761 | u64 addr = 0; | 856 | uint64_t result; |
762 | 857 | ||
763 | switch (mem->mem_type) { | 858 | /* page table offset */ |
764 | case TTM_PL_VRAM: | 859 | result = rdev->gart.pages_addr[addr >> PAGE_SHIFT]; |
765 | addr = (mem->start << PAGE_SHIFT); | 860 | |
766 | addr += pfn * RADEON_GPU_PAGE_SIZE; | 861 | /* in case cpu page size != gpu page size*/ |
767 | addr += rdev->vm_manager.vram_base_offset; | 862 | result |= addr & (~PAGE_MASK); |
768 | break; | 863 | |
769 | case TTM_PL_TT: | 864 | return result; |
770 | /* offset inside page table */ | ||
771 | addr = mem->start << PAGE_SHIFT; | ||
772 | addr += pfn * RADEON_GPU_PAGE_SIZE; | ||
773 | addr = addr >> PAGE_SHIFT; | ||
774 | /* page table offset */ | ||
775 | addr = rdev->gart.pages_addr[addr]; | ||
776 | /* in case cpu page size != gpu page size*/ | ||
777 | addr += (pfn * RADEON_GPU_PAGE_SIZE) & (~PAGE_MASK); | ||
778 | break; | ||
779 | default: | ||
780 | break; | ||
781 | } | ||
782 | return addr; | ||
783 | } | 865 | } |
784 | 866 | ||
785 | /* object have to be reserved & global and local mutex must be locked */ | ||
786 | /** | 867 | /** |
787 | * radeon_vm_bo_update_pte - map a bo into the vm page table | 868 | * radeon_vm_bo_update_pte - map a bo into the vm page table |
788 | * | 869 | * |
@@ -793,103 +874,160 @@ static u64 radeon_vm_get_addr(struct radeon_device *rdev, | |||
793 | * | 874 | * |
794 | * Fill in the page table entries for @bo (cayman+). | 875 | * Fill in the page table entries for @bo (cayman+). |
795 | * Returns 0 for success, -EINVAL for failure. | 876 | * Returns 0 for success, -EINVAL for failure. |
877 | * | ||
878 | * Object have to be reserved & global and local mutex must be locked! | ||
796 | */ | 879 | */ |
797 | int radeon_vm_bo_update_pte(struct radeon_device *rdev, | 880 | int radeon_vm_bo_update_pte(struct radeon_device *rdev, |
798 | struct radeon_vm *vm, | 881 | struct radeon_vm *vm, |
799 | struct radeon_bo *bo, | 882 | struct radeon_bo *bo, |
800 | struct ttm_mem_reg *mem) | 883 | struct ttm_mem_reg *mem) |
801 | { | 884 | { |
885 | unsigned ridx = rdev->asic->vm.pt_ring_index; | ||
886 | struct radeon_ring *ring = &rdev->ring[ridx]; | ||
887 | struct radeon_semaphore *sem = NULL; | ||
802 | struct radeon_bo_va *bo_va; | 888 | struct radeon_bo_va *bo_va; |
803 | unsigned ngpu_pages, i; | 889 | unsigned nptes, npdes, ndw; |
804 | uint64_t addr = 0, pfn; | 890 | uint64_t pe, addr; |
805 | uint32_t flags; | 891 | uint64_t pfn; |
892 | int r; | ||
806 | 893 | ||
807 | /* nothing to do if vm isn't bound */ | 894 | /* nothing to do if vm isn't bound */ |
808 | if (vm->id == -1) | 895 | if (vm->sa_bo == NULL) |
809 | return 0; | 896 | return 0; |
810 | 897 | ||
811 | bo_va = radeon_bo_va(bo, vm); | 898 | bo_va = radeon_vm_bo_find(vm, bo); |
812 | if (bo_va == NULL) { | 899 | if (bo_va == NULL) { |
813 | dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm); | 900 | dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm); |
814 | return -EINVAL; | 901 | return -EINVAL; |
815 | } | 902 | } |
816 | 903 | ||
817 | if (bo_va->valid && mem) | 904 | if (!bo_va->soffset) { |
905 | dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n", | ||
906 | bo, vm); | ||
907 | return -EINVAL; | ||
908 | } | ||
909 | |||
910 | if ((bo_va->valid && mem) || (!bo_va->valid && mem == NULL)) | ||
818 | return 0; | 911 | return 0; |
819 | 912 | ||
820 | ngpu_pages = radeon_bo_ngpu_pages(bo); | ||
821 | bo_va->flags &= ~RADEON_VM_PAGE_VALID; | 913 | bo_va->flags &= ~RADEON_VM_PAGE_VALID; |
822 | bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; | 914 | bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; |
823 | if (mem) { | 915 | if (mem) { |
916 | addr = mem->start << PAGE_SHIFT; | ||
824 | if (mem->mem_type != TTM_PL_SYSTEM) { | 917 | if (mem->mem_type != TTM_PL_SYSTEM) { |
825 | bo_va->flags |= RADEON_VM_PAGE_VALID; | 918 | bo_va->flags |= RADEON_VM_PAGE_VALID; |
826 | bo_va->valid = true; | 919 | bo_va->valid = true; |
827 | } | 920 | } |
828 | if (mem->mem_type == TTM_PL_TT) { | 921 | if (mem->mem_type == TTM_PL_TT) { |
829 | bo_va->flags |= RADEON_VM_PAGE_SYSTEM; | 922 | bo_va->flags |= RADEON_VM_PAGE_SYSTEM; |
923 | } else { | ||
924 | addr += rdev->vm_manager.vram_base_offset; | ||
830 | } | 925 | } |
926 | } else { | ||
927 | addr = 0; | ||
928 | bo_va->valid = false; | ||
831 | } | 929 | } |
832 | pfn = bo_va->soffset / RADEON_GPU_PAGE_SIZE; | 930 | |
833 | flags = rdev->vm_manager.funcs->page_flags(rdev, bo_va->vm, bo_va->flags); | 931 | if (vm->fence && radeon_fence_signaled(vm->fence)) { |
834 | for (i = 0, addr = 0; i < ngpu_pages; i++) { | 932 | radeon_fence_unref(&vm->fence); |
835 | if (mem && bo_va->valid) { | 933 | } |
836 | addr = radeon_vm_get_addr(rdev, mem, i); | 934 | |
935 | if (vm->fence && vm->fence->ring != ridx) { | ||
936 | r = radeon_semaphore_create(rdev, &sem); | ||
937 | if (r) { | ||
938 | return r; | ||
837 | } | 939 | } |
838 | rdev->vm_manager.funcs->set_page(rdev, bo_va->vm, i + pfn, addr, flags); | ||
839 | } | 940 | } |
840 | rdev->vm_manager.funcs->tlb_flush(rdev, bo_va->vm); | 941 | |
942 | /* estimate number of dw needed */ | ||
943 | /* reserve space for 32-bit padding */ | ||
944 | ndw = 32; | ||
945 | |||
946 | nptes = radeon_bo_ngpu_pages(bo); | ||
947 | |||
948 | pfn = (bo_va->soffset / RADEON_GPU_PAGE_SIZE); | ||
949 | |||
950 | /* handle cases where a bo spans several pdes */ | ||
951 | npdes = (ALIGN(pfn + nptes, RADEON_VM_PTE_COUNT) - | ||
952 | (pfn & ~(RADEON_VM_PTE_COUNT - 1))) >> RADEON_VM_BLOCK_SIZE; | ||
953 | |||
954 | /* reserve space for one header for every 2k dwords */ | ||
955 | ndw += (nptes >> 11) * 3; | ||
956 | /* reserve space for pte addresses */ | ||
957 | ndw += nptes * 2; | ||
958 | |||
959 | /* reserve space for one header for every 2k dwords */ | ||
960 | ndw += (npdes >> 11) * 3; | ||
961 | /* reserve space for pde addresses */ | ||
962 | ndw += npdes * 2; | ||
963 | |||
964 | r = radeon_ring_lock(rdev, ring, ndw); | ||
965 | if (r) { | ||
966 | return r; | ||
967 | } | ||
968 | |||
969 | if (sem && radeon_fence_need_sync(vm->fence, ridx)) { | ||
970 | radeon_semaphore_sync_rings(rdev, sem, vm->fence->ring, ridx); | ||
971 | radeon_fence_note_sync(vm->fence, ridx); | ||
972 | } | ||
973 | |||
974 | /* update page table entries */ | ||
975 | pe = vm->pd_gpu_addr; | ||
976 | pe += radeon_vm_directory_size(rdev); | ||
977 | pe += (bo_va->soffset / RADEON_GPU_PAGE_SIZE) * 8; | ||
978 | |||
979 | radeon_asic_vm_set_page(rdev, pe, addr, nptes, | ||
980 | RADEON_GPU_PAGE_SIZE, bo_va->flags); | ||
981 | |||
982 | /* update page directory entries */ | ||
983 | addr = pe; | ||
984 | |||
985 | pe = vm->pd_gpu_addr; | ||
986 | pe += ((bo_va->soffset / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE) * 8; | ||
987 | |||
988 | radeon_asic_vm_set_page(rdev, pe, addr, npdes, | ||
989 | RADEON_VM_PTE_COUNT * 8, RADEON_VM_PAGE_VALID); | ||
990 | |||
991 | radeon_fence_unref(&vm->fence); | ||
992 | r = radeon_fence_emit(rdev, &vm->fence, ridx); | ||
993 | if (r) { | ||
994 | radeon_ring_unlock_undo(rdev, ring); | ||
995 | return r; | ||
996 | } | ||
997 | radeon_ring_unlock_commit(rdev, ring); | ||
998 | radeon_semaphore_free(rdev, &sem, vm->fence); | ||
999 | radeon_fence_unref(&vm->last_flush); | ||
841 | return 0; | 1000 | return 0; |
842 | } | 1001 | } |
843 | 1002 | ||
844 | /* object have to be reserved */ | ||
845 | /** | 1003 | /** |
846 | * radeon_vm_bo_rmv - remove a bo to a specific vm | 1004 | * radeon_vm_bo_rmv - remove a bo to a specific vm |
847 | * | 1005 | * |
848 | * @rdev: radeon_device pointer | 1006 | * @rdev: radeon_device pointer |
849 | * @vm: requested vm | 1007 | * @bo_va: requested bo_va |
850 | * @bo: radeon buffer object | ||
851 | * | 1008 | * |
852 | * Remove @bo from the requested vm (cayman+). | 1009 | * Remove @bo_va->bo from the requested vm (cayman+). |
853 | * Remove @bo from the list of bos associated with the vm and | 1010 | * Remove @bo_va->bo from the list of bos associated with the bo_va->vm and |
854 | * remove the ptes for @bo in the page table. | 1011 | * remove the ptes for @bo_va in the page table. |
855 | * Returns 0 for success. | 1012 | * Returns 0 for success. |
1013 | * | ||
1014 | * Object have to be reserved! | ||
856 | */ | 1015 | */ |
857 | int radeon_vm_bo_rmv(struct radeon_device *rdev, | 1016 | int radeon_vm_bo_rmv(struct radeon_device *rdev, |
858 | struct radeon_vm *vm, | 1017 | struct radeon_bo_va *bo_va) |
859 | struct radeon_bo *bo) | ||
860 | { | 1018 | { |
861 | struct radeon_bo_va *bo_va; | ||
862 | int r; | 1019 | int r; |
863 | 1020 | ||
864 | bo_va = radeon_bo_va(bo, vm); | ||
865 | if (bo_va == NULL) | ||
866 | return 0; | ||
867 | |||
868 | /* wait for va use to end */ | ||
869 | while (bo_va->fence) { | ||
870 | r = radeon_fence_wait(bo_va->fence, false); | ||
871 | if (r) { | ||
872 | DRM_ERROR("error while waiting for fence: %d\n", r); | ||
873 | } | ||
874 | if (r == -EDEADLK) { | ||
875 | r = radeon_gpu_reset(rdev); | ||
876 | if (!r) | ||
877 | continue; | ||
878 | } | ||
879 | break; | ||
880 | } | ||
881 | radeon_fence_unref(&bo_va->fence); | ||
882 | |||
883 | mutex_lock(&rdev->vm_manager.lock); | 1021 | mutex_lock(&rdev->vm_manager.lock); |
884 | mutex_lock(&vm->mutex); | 1022 | mutex_lock(&bo_va->vm->mutex); |
885 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 1023 | r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL); |
886 | mutex_unlock(&rdev->vm_manager.lock); | 1024 | mutex_unlock(&rdev->vm_manager.lock); |
887 | list_del(&bo_va->vm_list); | 1025 | list_del(&bo_va->vm_list); |
888 | mutex_unlock(&vm->mutex); | 1026 | mutex_unlock(&bo_va->vm->mutex); |
889 | list_del(&bo_va->bo_list); | 1027 | list_del(&bo_va->bo_list); |
890 | 1028 | ||
891 | kfree(bo_va); | 1029 | kfree(bo_va); |
892 | return 0; | 1030 | return r; |
893 | } | 1031 | } |
894 | 1032 | ||
895 | /** | 1033 | /** |
@@ -925,27 +1063,23 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev, | |||
925 | */ | 1063 | */ |
926 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | 1064 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) |
927 | { | 1065 | { |
1066 | struct radeon_bo_va *bo_va; | ||
928 | int r; | 1067 | int r; |
929 | 1068 | ||
930 | vm->id = -1; | 1069 | vm->id = 0; |
931 | vm->fence = NULL; | 1070 | vm->fence = NULL; |
1071 | vm->last_pfn = 0; | ||
932 | mutex_init(&vm->mutex); | 1072 | mutex_init(&vm->mutex); |
933 | INIT_LIST_HEAD(&vm->list); | 1073 | INIT_LIST_HEAD(&vm->list); |
934 | INIT_LIST_HEAD(&vm->va); | 1074 | INIT_LIST_HEAD(&vm->va); |
935 | /* SI requires equal sized PTs for all VMs, so always set | 1075 | |
936 | * last_pfn to max_pfn. cayman allows variable sized | ||
937 | * pts so we can grow then as needed. Once we switch | ||
938 | * to two level pts we can unify this again. | ||
939 | */ | ||
940 | if (rdev->family >= CHIP_TAHITI) | ||
941 | vm->last_pfn = rdev->vm_manager.max_pfn; | ||
942 | else | ||
943 | vm->last_pfn = 0; | ||
944 | /* map the ib pool buffer at 0 in virtual address space, set | 1076 | /* map the ib pool buffer at 0 in virtual address space, set |
945 | * read only | 1077 | * read only |
946 | */ | 1078 | */ |
947 | r = radeon_vm_bo_add(rdev, vm, rdev->ring_tmp_bo.bo, 0, | 1079 | bo_va = radeon_vm_bo_add(rdev, vm, rdev->ring_tmp_bo.bo); |
948 | RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED); | 1080 | r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, |
1081 | RADEON_VM_PAGE_READABLE | | ||
1082 | RADEON_VM_PAGE_SNOOPED); | ||
949 | return r; | 1083 | return r; |
950 | } | 1084 | } |
951 | 1085 | ||
@@ -965,7 +1099,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
965 | 1099 | ||
966 | mutex_lock(&rdev->vm_manager.lock); | 1100 | mutex_lock(&rdev->vm_manager.lock); |
967 | mutex_lock(&vm->mutex); | 1101 | mutex_lock(&vm->mutex); |
968 | radeon_vm_unbind_locked(rdev, vm); | 1102 | radeon_vm_free_pt(rdev, vm); |
969 | mutex_unlock(&rdev->vm_manager.lock); | 1103 | mutex_unlock(&rdev->vm_manager.lock); |
970 | 1104 | ||
971 | /* remove all bo at this point non are busy any more because unbind | 1105 | /* remove all bo at this point non are busy any more because unbind |
@@ -973,10 +1107,9 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
973 | */ | 1107 | */ |
974 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | 1108 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); |
975 | if (!r) { | 1109 | if (!r) { |
976 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); | 1110 | bo_va = radeon_vm_bo_find(vm, rdev->ring_tmp_bo.bo); |
977 | list_del_init(&bo_va->bo_list); | 1111 | list_del_init(&bo_va->bo_list); |
978 | list_del_init(&bo_va->vm_list); | 1112 | list_del_init(&bo_va->vm_list); |
979 | radeon_fence_unref(&bo_va->fence); | ||
980 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | 1113 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); |
981 | kfree(bo_va); | 1114 | kfree(bo_va); |
982 | } | 1115 | } |
@@ -988,10 +1121,11 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
988 | r = radeon_bo_reserve(bo_va->bo, false); | 1121 | r = radeon_bo_reserve(bo_va->bo, false); |
989 | if (!r) { | 1122 | if (!r) { |
990 | list_del_init(&bo_va->bo_list); | 1123 | list_del_init(&bo_va->bo_list); |
991 | radeon_fence_unref(&bo_va->fence); | ||
992 | radeon_bo_unreserve(bo_va->bo); | 1124 | radeon_bo_unreserve(bo_va->bo); |
993 | kfree(bo_va); | 1125 | kfree(bo_va); |
994 | } | 1126 | } |
995 | } | 1127 | } |
1128 | radeon_fence_unref(&vm->fence); | ||
1129 | radeon_fence_unref(&vm->last_flush); | ||
996 | mutex_unlock(&vm->mutex); | 1130 | mutex_unlock(&vm->mutex); |
997 | } | 1131 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 1b57b0058ad6..6579befa5101 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -124,6 +124,30 @@ void radeon_gem_fini(struct radeon_device *rdev) | |||
124 | */ | 124 | */ |
125 | int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) | 125 | int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) |
126 | { | 126 | { |
127 | struct radeon_bo *rbo = gem_to_radeon_bo(obj); | ||
128 | struct radeon_device *rdev = rbo->rdev; | ||
129 | struct radeon_fpriv *fpriv = file_priv->driver_priv; | ||
130 | struct radeon_vm *vm = &fpriv->vm; | ||
131 | struct radeon_bo_va *bo_va; | ||
132 | int r; | ||
133 | |||
134 | if (rdev->family < CHIP_CAYMAN) { | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | r = radeon_bo_reserve(rbo, false); | ||
139 | if (r) { | ||
140 | return r; | ||
141 | } | ||
142 | |||
143 | bo_va = radeon_vm_bo_find(vm, rbo); | ||
144 | if (!bo_va) { | ||
145 | bo_va = radeon_vm_bo_add(rdev, vm, rbo); | ||
146 | } else { | ||
147 | ++bo_va->ref_count; | ||
148 | } | ||
149 | radeon_bo_unreserve(rbo); | ||
150 | |||
127 | return 0; | 151 | return 0; |
128 | } | 152 | } |
129 | 153 | ||
@@ -134,16 +158,25 @@ void radeon_gem_object_close(struct drm_gem_object *obj, | |||
134 | struct radeon_device *rdev = rbo->rdev; | 158 | struct radeon_device *rdev = rbo->rdev; |
135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; | 159 | struct radeon_fpriv *fpriv = file_priv->driver_priv; |
136 | struct radeon_vm *vm = &fpriv->vm; | 160 | struct radeon_vm *vm = &fpriv->vm; |
161 | struct radeon_bo_va *bo_va; | ||
162 | int r; | ||
137 | 163 | ||
138 | if (rdev->family < CHIP_CAYMAN) { | 164 | if (rdev->family < CHIP_CAYMAN) { |
139 | return; | 165 | return; |
140 | } | 166 | } |
141 | 167 | ||
142 | if (radeon_bo_reserve(rbo, false)) { | 168 | r = radeon_bo_reserve(rbo, true); |
143 | dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n"); | 169 | if (r) { |
170 | dev_err(rdev->dev, "leaking bo va because " | ||
171 | "we fail to reserve bo (%d)\n", r); | ||
144 | return; | 172 | return; |
145 | } | 173 | } |
146 | radeon_vm_bo_rmv(rdev, vm, rbo); | 174 | bo_va = radeon_vm_bo_find(vm, rbo); |
175 | if (bo_va) { | ||
176 | if (--bo_va->ref_count == 0) { | ||
177 | radeon_vm_bo_rmv(rdev, bo_va); | ||
178 | } | ||
179 | } | ||
147 | radeon_bo_unreserve(rbo); | 180 | radeon_bo_unreserve(rbo); |
148 | } | 181 | } |
149 | 182 | ||
@@ -459,19 +492,24 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, | |||
459 | drm_gem_object_unreference_unlocked(gobj); | 492 | drm_gem_object_unreference_unlocked(gobj); |
460 | return r; | 493 | return r; |
461 | } | 494 | } |
495 | bo_va = radeon_vm_bo_find(&fpriv->vm, rbo); | ||
496 | if (!bo_va) { | ||
497 | args->operation = RADEON_VA_RESULT_ERROR; | ||
498 | drm_gem_object_unreference_unlocked(gobj); | ||
499 | return -ENOENT; | ||
500 | } | ||
501 | |||
462 | switch (args->operation) { | 502 | switch (args->operation) { |
463 | case RADEON_VA_MAP: | 503 | case RADEON_VA_MAP: |
464 | bo_va = radeon_bo_va(rbo, &fpriv->vm); | 504 | if (bo_va->soffset) { |
465 | if (bo_va) { | ||
466 | args->operation = RADEON_VA_RESULT_VA_EXIST; | 505 | args->operation = RADEON_VA_RESULT_VA_EXIST; |
467 | args->offset = bo_va->soffset; | 506 | args->offset = bo_va->soffset; |
468 | goto out; | 507 | goto out; |
469 | } | 508 | } |
470 | r = radeon_vm_bo_add(rdev, &fpriv->vm, rbo, | 509 | r = radeon_vm_bo_set_addr(rdev, bo_va, args->offset, args->flags); |
471 | args->offset, args->flags); | ||
472 | break; | 510 | break; |
473 | case RADEON_VA_UNMAP: | 511 | case RADEON_VA_UNMAP: |
474 | r = radeon_vm_bo_rmv(rdev, &fpriv->vm, rbo); | 512 | r = radeon_vm_bo_set_addr(rdev, bo_va, 0, 0); |
475 | break; | 513 | break; |
476 | default: | 514 | default: |
477 | break; | 515 | break; |
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c index 48b7cea31e08..c4bb2269be10 100644 --- a/drivers/gpu/drm/radeon/radeon_ioc32.c +++ b/drivers/gpu/drm/radeon/radeon_ioc32.c | |||
@@ -369,7 +369,7 @@ static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd, | |||
369 | #define compat_radeon_cp_setparam NULL | 369 | #define compat_radeon_cp_setparam NULL |
370 | #endif /* X86_64 || IA64 */ | 370 | #endif /* X86_64 || IA64 */ |
371 | 371 | ||
372 | drm_ioctl_compat_t *radeon_compat_ioctls[] = { | 372 | static drm_ioctl_compat_t *radeon_compat_ioctls[] = { |
373 | [DRM_RADEON_CP_INIT] = compat_radeon_cp_init, | 373 | [DRM_RADEON_CP_INIT] = compat_radeon_cp_init, |
374 | [DRM_RADEON_CLEAR] = compat_radeon_cp_clear, | 374 | [DRM_RADEON_CLEAR] = compat_radeon_cp_clear, |
375 | [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple, | 375 | [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple, |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index afaa1727abd2..b06fa5936100 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -99,7 +99,6 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | |||
99 | /* Disable *all* interrupts */ | 99 | /* Disable *all* interrupts */ |
100 | for (i = 0; i < RADEON_NUM_RINGS; i++) | 100 | for (i = 0; i < RADEON_NUM_RINGS; i++) |
101 | atomic_set(&rdev->irq.ring_int[i], 0); | 101 | atomic_set(&rdev->irq.ring_int[i], 0); |
102 | rdev->irq.gui_idle = false; | ||
103 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) | 102 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
104 | rdev->irq.hpd[i] = false; | 103 | rdev->irq.hpd[i] = false; |
105 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | 104 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { |
@@ -147,7 +146,6 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) | |||
147 | /* Disable *all* interrupts */ | 146 | /* Disable *all* interrupts */ |
148 | for (i = 0; i < RADEON_NUM_RINGS; i++) | 147 | for (i = 0; i < RADEON_NUM_RINGS; i++) |
149 | atomic_set(&rdev->irq.ring_int[i], 0); | 148 | atomic_set(&rdev->irq.ring_int[i], 0); |
150 | rdev->irq.gui_idle = false; | ||
151 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) | 149 | for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
152 | rdev->irq.hpd[i] = false; | 150 | rdev->irq.hpd[i] = false; |
153 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | 151 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { |
@@ -204,6 +202,16 @@ static bool radeon_msi_ok(struct radeon_device *rdev) | |||
204 | (rdev->pdev->subsystem_device == 0x01fd)) | 202 | (rdev->pdev->subsystem_device == 0x01fd)) |
205 | return true; | 203 | return true; |
206 | 204 | ||
205 | /* Gateway RS690 only seems to work with MSIs. */ | ||
206 | if ((rdev->pdev->device == 0x791f) && | ||
207 | (rdev->pdev->subsystem_vendor == 0x107b) && | ||
208 | (rdev->pdev->subsystem_device == 0x0185)) | ||
209 | return true; | ||
210 | |||
211 | /* try and enable MSIs by default on all RS690s */ | ||
212 | if (rdev->family == CHIP_RS690) | ||
213 | return true; | ||
214 | |||
207 | /* RV515 seems to have MSI issues where it loses | 215 | /* RV515 seems to have MSI issues where it loses |
208 | * MSI rearms occasionally. This leads to lockups and freezes. | 216 | * MSI rearms occasionally. This leads to lockups and freezes. |
209 | * disable it by default. | 217 | * disable it by default. |
@@ -457,34 +465,3 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask) | |||
457 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | 465 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
458 | } | 466 | } |
459 | 467 | ||
460 | /** | ||
461 | * radeon_irq_kms_wait_gui_idle - waits for drawing engine to be idle | ||
462 | * | ||
463 | * @rdev: radeon device pointer | ||
464 | * | ||
465 | * Enabled the GUI idle interrupt and waits for it to fire (r6xx+). | ||
466 | * This is currently used to make sure the 3D engine is idle for power | ||
467 | * management, but should be replaces with proper fence waits. | ||
468 | * GUI idle interrupts don't work very well on pre-r6xx hw and it also | ||
469 | * does not take into account other aspects of the chip that may be busy. | ||
470 | * DO NOT USE GOING FORWARD. | ||
471 | */ | ||
472 | int radeon_irq_kms_wait_gui_idle(struct radeon_device *rdev) | ||
473 | { | ||
474 | unsigned long irqflags; | ||
475 | int r; | ||
476 | |||
477 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
478 | rdev->irq.gui_idle = true; | ||
479 | radeon_irq_set(rdev); | ||
480 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
481 | |||
482 | r = wait_event_timeout(rdev->irq.idle_queue, radeon_gui_idle(rdev), | ||
483 | msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); | ||
484 | |||
485 | spin_lock_irqsave(&rdev->irq.lock, irqflags); | ||
486 | rdev->irq.gui_idle = false; | ||
487 | radeon_irq_set(rdev); | ||
488 | spin_unlock_irqrestore(&rdev->irq.lock, irqflags); | ||
489 | return r; | ||
490 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 414b4acf6947..cb8e94d1a2b2 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -51,6 +51,7 @@ int radeon_driver_unload_kms(struct drm_device *dev) | |||
51 | 51 | ||
52 | if (rdev == NULL) | 52 | if (rdev == NULL) |
53 | return 0; | 53 | return 0; |
54 | radeon_acpi_fini(rdev); | ||
54 | radeon_modeset_fini(rdev); | 55 | radeon_modeset_fini(rdev); |
55 | radeon_device_fini(rdev); | 56 | radeon_device_fini(rdev); |
56 | kfree(rdev); | 57 | kfree(rdev); |
@@ -103,11 +104,6 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
103 | goto out; | 104 | goto out; |
104 | } | 105 | } |
105 | 106 | ||
106 | /* Call ACPI methods */ | ||
107 | acpi_status = radeon_acpi_init(rdev); | ||
108 | if (acpi_status) | ||
109 | dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n"); | ||
110 | |||
111 | /* Again modeset_init should fail only on fatal error | 107 | /* Again modeset_init should fail only on fatal error |
112 | * otherwise it should provide enough functionalities | 108 | * otherwise it should provide enough functionalities |
113 | * for shadowfb to run | 109 | * for shadowfb to run |
@@ -115,6 +111,17 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
115 | r = radeon_modeset_init(rdev); | 111 | r = radeon_modeset_init(rdev); |
116 | if (r) | 112 | if (r) |
117 | dev_err(&dev->pdev->dev, "Fatal error during modeset init\n"); | 113 | dev_err(&dev->pdev->dev, "Fatal error during modeset init\n"); |
114 | |||
115 | /* Call ACPI methods: require modeset init | ||
116 | * but failure is not fatal | ||
117 | */ | ||
118 | if (!r) { | ||
119 | acpi_status = radeon_acpi_init(rdev); | ||
120 | if (acpi_status) | ||
121 | dev_dbg(&dev->pdev->dev, | ||
122 | "Error during ACPI methods call\n"); | ||
123 | } | ||
124 | |||
118 | out: | 125 | out: |
119 | if (r) | 126 | if (r) |
120 | radeon_driver_unload_kms(dev); | 127 | radeon_driver_unload_kms(dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 94b4a1c12893..5677a424b585 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -206,11 +206,6 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
206 | WREG32(RADEON_FP_CRTC_V_TOTAL_DISP, fp_crtc_v_total_disp); | 206 | WREG32(RADEON_FP_CRTC_V_TOTAL_DISP, fp_crtc_v_total_disp); |
207 | } | 207 | } |
208 | 208 | ||
209 | void radeon_restore_common_regs(struct drm_device *dev) | ||
210 | { | ||
211 | /* don't need this yet */ | ||
212 | } | ||
213 | |||
214 | static void radeon_pll_wait_for_read_update_complete(struct drm_device *dev) | 209 | static void radeon_pll_wait_for_read_update_complete(struct drm_device *dev) |
215 | { | 210 | { |
216 | struct radeon_device *rdev = dev->dev_private; | 211 | struct radeon_device *rdev = dev->dev_private; |
@@ -295,7 +290,7 @@ static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div, | |||
295 | return 1; | 290 | return 1; |
296 | } | 291 | } |
297 | 292 | ||
298 | void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | 293 | static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) |
299 | { | 294 | { |
300 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 295 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
301 | struct drm_device *dev = crtc->dev; | 296 | struct drm_device *dev = crtc->dev; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 670e9910f869..8ad9c5f16014 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -271,13 +271,6 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { | |||
271 | 271 | ||
272 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | 272 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) |
273 | 273 | ||
274 | #define MAX_RADEON_LEVEL 0xFF | ||
275 | |||
276 | struct radeon_backlight_privdata { | ||
277 | struct radeon_encoder *encoder; | ||
278 | uint8_t negative; | ||
279 | }; | ||
280 | |||
281 | static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) | 274 | static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) |
282 | { | 275 | { |
283 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | 276 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); |
@@ -286,21 +279,33 @@ static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) | |||
286 | /* Convert brightness to hardware level */ | 279 | /* Convert brightness to hardware level */ |
287 | if (bd->props.brightness < 0) | 280 | if (bd->props.brightness < 0) |
288 | level = 0; | 281 | level = 0; |
289 | else if (bd->props.brightness > MAX_RADEON_LEVEL) | 282 | else if (bd->props.brightness > RADEON_MAX_BL_LEVEL) |
290 | level = MAX_RADEON_LEVEL; | 283 | level = RADEON_MAX_BL_LEVEL; |
291 | else | 284 | else |
292 | level = bd->props.brightness; | 285 | level = bd->props.brightness; |
293 | 286 | ||
294 | if (pdata->negative) | 287 | if (pdata->negative) |
295 | level = MAX_RADEON_LEVEL - level; | 288 | level = RADEON_MAX_BL_LEVEL - level; |
296 | 289 | ||
297 | return level; | 290 | return level; |
298 | } | 291 | } |
299 | 292 | ||
300 | static int radeon_legacy_backlight_update_status(struct backlight_device *bd) | 293 | u8 |
294 | radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder) | ||
295 | { | ||
296 | struct drm_device *dev = radeon_encoder->base.dev; | ||
297 | struct radeon_device *rdev = dev->dev_private; | ||
298 | u8 backlight_level; | ||
299 | |||
300 | backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >> | ||
301 | RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; | ||
302 | |||
303 | return backlight_level; | ||
304 | } | ||
305 | |||
306 | void | ||
307 | radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level) | ||
301 | { | 308 | { |
302 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | ||
303 | struct radeon_encoder *radeon_encoder = pdata->encoder; | ||
304 | struct drm_device *dev = radeon_encoder->base.dev; | 309 | struct drm_device *dev = radeon_encoder->base.dev; |
305 | struct radeon_device *rdev = dev->dev_private; | 310 | struct radeon_device *rdev = dev->dev_private; |
306 | int dpms_mode = DRM_MODE_DPMS_ON; | 311 | int dpms_mode = DRM_MODE_DPMS_ON; |
@@ -308,19 +313,31 @@ static int radeon_legacy_backlight_update_status(struct backlight_device *bd) | |||
308 | if (radeon_encoder->enc_priv) { | 313 | if (radeon_encoder->enc_priv) { |
309 | if (rdev->is_atom_bios) { | 314 | if (rdev->is_atom_bios) { |
310 | struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; | 315 | struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; |
311 | dpms_mode = lvds->dpms_mode; | 316 | if (lvds->backlight_level > 0) |
312 | lvds->backlight_level = radeon_legacy_lvds_level(bd); | 317 | dpms_mode = lvds->dpms_mode; |
318 | else | ||
319 | dpms_mode = DRM_MODE_DPMS_OFF; | ||
320 | lvds->backlight_level = level; | ||
313 | } else { | 321 | } else { |
314 | struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; | 322 | struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; |
315 | dpms_mode = lvds->dpms_mode; | 323 | if (lvds->backlight_level > 0) |
316 | lvds->backlight_level = radeon_legacy_lvds_level(bd); | 324 | dpms_mode = lvds->dpms_mode; |
325 | else | ||
326 | dpms_mode = DRM_MODE_DPMS_OFF; | ||
327 | lvds->backlight_level = level; | ||
317 | } | 328 | } |
318 | } | 329 | } |
319 | 330 | ||
320 | if (bd->props.brightness > 0) | 331 | radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode); |
321 | radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode); | 332 | } |
322 | else | 333 | |
323 | radeon_legacy_lvds_update(&radeon_encoder->base, DRM_MODE_DPMS_OFF); | 334 | static int radeon_legacy_backlight_update_status(struct backlight_device *bd) |
335 | { | ||
336 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | ||
337 | struct radeon_encoder *radeon_encoder = pdata->encoder; | ||
338 | |||
339 | radeon_legacy_set_backlight_level(radeon_encoder, | ||
340 | radeon_legacy_lvds_level(bd)); | ||
324 | 341 | ||
325 | return 0; | 342 | return 0; |
326 | } | 343 | } |
@@ -336,7 +353,7 @@ static int radeon_legacy_backlight_get_brightness(struct backlight_device *bd) | |||
336 | backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >> | 353 | backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >> |
337 | RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; | 354 | RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; |
338 | 355 | ||
339 | return pdata->negative ? MAX_RADEON_LEVEL - backlight_level : backlight_level; | 356 | return pdata->negative ? RADEON_MAX_BL_LEVEL - backlight_level : backlight_level; |
340 | } | 357 | } |
341 | 358 | ||
342 | static const struct backlight_ops radeon_backlight_ops = { | 359 | static const struct backlight_ops radeon_backlight_ops = { |
@@ -370,7 +387,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | |||
370 | } | 387 | } |
371 | 388 | ||
372 | memset(&props, 0, sizeof(props)); | 389 | memset(&props, 0, sizeof(props)); |
373 | props.max_brightness = MAX_RADEON_LEVEL; | 390 | props.max_brightness = RADEON_MAX_BL_LEVEL; |
374 | props.type = BACKLIGHT_RAW; | 391 | props.type = BACKLIGHT_RAW; |
375 | bd = backlight_device_register("radeon_bl", &drm_connector->kdev, | 392 | bd = backlight_device_register("radeon_bl", &drm_connector->kdev, |
376 | pdata, &radeon_backlight_ops, &props); | 393 | pdata, &radeon_backlight_ops, &props); |
@@ -449,7 +466,7 @@ static void radeon_legacy_backlight_exit(struct radeon_encoder *radeon_encoder) | |||
449 | } | 466 | } |
450 | 467 | ||
451 | if (bd) { | 468 | if (bd) { |
452 | struct radeon_legacy_backlight_privdata *pdata; | 469 | struct radeon_backlight_privdata *pdata; |
453 | 470 | ||
454 | pdata = bl_get_data(bd); | 471 | pdata = bl_get_data(bd); |
455 | backlight_device_unregister(bd); | 472 | backlight_device_unregister(bd); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index d56978949f34..527761801590 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -252,8 +252,23 @@ struct radeon_mode_info { | |||
252 | 252 | ||
253 | /* pointer to fbdev info structure */ | 253 | /* pointer to fbdev info structure */ |
254 | struct radeon_fbdev *rfbdev; | 254 | struct radeon_fbdev *rfbdev; |
255 | /* firmware flags */ | ||
256 | u16 firmware_flags; | ||
257 | /* pointer to backlight encoder */ | ||
258 | struct radeon_encoder *bl_encoder; | ||
255 | }; | 259 | }; |
256 | 260 | ||
261 | #define RADEON_MAX_BL_LEVEL 0xFF | ||
262 | |||
263 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | ||
264 | |||
265 | struct radeon_backlight_privdata { | ||
266 | struct radeon_encoder *encoder; | ||
267 | uint8_t negative; | ||
268 | }; | ||
269 | |||
270 | #endif | ||
271 | |||
257 | #define MAX_H_CODE_TIMING_LEN 32 | 272 | #define MAX_H_CODE_TIMING_LEN 32 |
258 | #define MAX_V_CODE_TIMING_LEN 32 | 273 | #define MAX_V_CODE_TIMING_LEN 32 |
259 | 274 | ||
@@ -269,6 +284,18 @@ struct radeon_tv_regs { | |||
269 | uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN]; | 284 | uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN]; |
270 | }; | 285 | }; |
271 | 286 | ||
287 | struct radeon_atom_ss { | ||
288 | uint16_t percentage; | ||
289 | uint8_t type; | ||
290 | uint16_t step; | ||
291 | uint8_t delay; | ||
292 | uint8_t range; | ||
293 | uint8_t refdiv; | ||
294 | /* asic_ss */ | ||
295 | uint16_t rate; | ||
296 | uint16_t amount; | ||
297 | }; | ||
298 | |||
272 | struct radeon_crtc { | 299 | struct radeon_crtc { |
273 | struct drm_crtc base; | 300 | struct drm_crtc base; |
274 | int crtc_id; | 301 | int crtc_id; |
@@ -293,6 +320,16 @@ struct radeon_crtc { | |||
293 | /* page flipping */ | 320 | /* page flipping */ |
294 | struct radeon_unpin_work *unpin_work; | 321 | struct radeon_unpin_work *unpin_work; |
295 | int deferred_flip_completion; | 322 | int deferred_flip_completion; |
323 | /* pll sharing */ | ||
324 | struct radeon_atom_ss ss; | ||
325 | bool ss_enabled; | ||
326 | u32 adjusted_clock; | ||
327 | int bpc; | ||
328 | u32 pll_reference_div; | ||
329 | u32 pll_post_div; | ||
330 | u32 pll_flags; | ||
331 | struct drm_encoder *encoder; | ||
332 | struct drm_connector *connector; | ||
296 | }; | 333 | }; |
297 | 334 | ||
298 | struct radeon_encoder_primary_dac { | 335 | struct radeon_encoder_primary_dac { |
@@ -346,18 +383,6 @@ struct radeon_encoder_ext_tmds { | |||
346 | }; | 383 | }; |
347 | 384 | ||
348 | /* spread spectrum */ | 385 | /* spread spectrum */ |
349 | struct radeon_atom_ss { | ||
350 | uint16_t percentage; | ||
351 | uint8_t type; | ||
352 | uint16_t step; | ||
353 | uint8_t delay; | ||
354 | uint8_t range; | ||
355 | uint8_t refdiv; | ||
356 | /* asic_ss */ | ||
357 | uint16_t rate; | ||
358 | uint16_t amount; | ||
359 | }; | ||
360 | |||
361 | struct radeon_encoder_atom_dig { | 386 | struct radeon_encoder_atom_dig { |
362 | bool linkb; | 387 | bool linkb; |
363 | /* atom dig */ | 388 | /* atom dig */ |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 9024e7222839..a236795dc69a 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -52,7 +52,7 @@ void radeon_bo_clear_va(struct radeon_bo *bo) | |||
52 | 52 | ||
53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { | 53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { |
54 | /* remove from all vm address space */ | 54 | /* remove from all vm address space */ |
55 | radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo); | 55 | radeon_vm_bo_rmv(bo->rdev, bo_va); |
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
@@ -627,18 +627,17 @@ int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, bool no_wait) | |||
627 | /** | 627 | /** |
628 | * radeon_bo_reserve - reserve bo | 628 | * radeon_bo_reserve - reserve bo |
629 | * @bo: bo structure | 629 | * @bo: bo structure |
630 | * @no_wait: don't sleep while trying to reserve (return -EBUSY) | 630 | * @no_intr: don't return -ERESTARTSYS on pending signal |
631 | * | 631 | * |
632 | * Returns: | 632 | * Returns: |
633 | * -EBUSY: buffer is busy and @no_wait is true | ||
634 | * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by | 633 | * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by |
635 | * a signal. Release all buffer reservations and return to user-space. | 634 | * a signal. Release all buffer reservations and return to user-space. |
636 | */ | 635 | */ |
637 | int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait) | 636 | int radeon_bo_reserve(struct radeon_bo *bo, bool no_intr) |
638 | { | 637 | { |
639 | int r; | 638 | int r; |
640 | 639 | ||
641 | r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); | 640 | r = ttm_bo_reserve(&bo->tbo, !no_intr, false, false, 0); |
642 | if (unlikely(r != 0)) { | 641 | if (unlikely(r != 0)) { |
643 | if (r != -ERESTARTSYS) | 642 | if (r != -ERESTARTSYS) |
644 | dev_err(bo->rdev->dev, "%p reserve failed\n", bo); | 643 | dev_err(bo->rdev->dev, "%p reserve failed\n", bo); |
@@ -646,16 +645,3 @@ int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait) | |||
646 | } | 645 | } |
647 | return 0; | 646 | return 0; |
648 | } | 647 | } |
649 | |||
650 | /* object have to be reserved */ | ||
651 | struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo, struct radeon_vm *vm) | ||
652 | { | ||
653 | struct radeon_bo_va *bo_va; | ||
654 | |||
655 | list_for_each_entry(bo_va, &rbo->va, bo_list) { | ||
656 | if (bo_va->vm == vm) { | ||
657 | return bo_va; | ||
658 | } | ||
659 | } | ||
660 | return NULL; | ||
661 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 17fb99f177cf..93cd491fff2e 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -52,7 +52,7 @@ static inline unsigned radeon_mem_type_to_domain(u32 mem_type) | |||
52 | return 0; | 52 | return 0; |
53 | } | 53 | } |
54 | 54 | ||
55 | int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait); | 55 | int radeon_bo_reserve(struct radeon_bo *bo, bool no_intr); |
56 | 56 | ||
57 | static inline void radeon_bo_unreserve(struct radeon_bo *bo) | 57 | static inline void radeon_bo_unreserve(struct radeon_bo *bo) |
58 | { | 58 | { |
@@ -141,8 +141,6 @@ extern void radeon_bo_move_notify(struct ttm_buffer_object *bo, | |||
141 | struct ttm_mem_reg *mem); | 141 | struct ttm_mem_reg *mem); |
142 | extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); | 142 | extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); |
143 | extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); | 143 | extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); |
144 | extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo, | ||
145 | struct radeon_vm *vm); | ||
146 | 144 | ||
147 | /* | 145 | /* |
148 | * sub allocation | 146 | * sub allocation |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 7ae606600107..bc2e7050a9d8 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -24,9 +24,6 @@ | |||
24 | #include "radeon.h" | 24 | #include "radeon.h" |
25 | #include "avivod.h" | 25 | #include "avivod.h" |
26 | #include "atom.h" | 26 | #include "atom.h" |
27 | #ifdef CONFIG_ACPI | ||
28 | #include <linux/acpi.h> | ||
29 | #endif | ||
30 | #include <linux/power_supply.h> | 27 | #include <linux/power_supply.h> |
31 | #include <linux/hwmon.h> | 28 | #include <linux/hwmon.h> |
32 | #include <linux/hwmon-sysfs.h> | 29 | #include <linux/hwmon-sysfs.h> |
@@ -36,7 +33,7 @@ | |||
36 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 | 33 | #define RADEON_WAIT_VBLANK_TIMEOUT 200 |
37 | 34 | ||
38 | static const char *radeon_pm_state_type_name[5] = { | 35 | static const char *radeon_pm_state_type_name[5] = { |
39 | "Default", | 36 | "", |
40 | "Powersave", | 37 | "Powersave", |
41 | "Battery", | 38 | "Battery", |
42 | "Balanced", | 39 | "Balanced", |
@@ -50,8 +47,6 @@ static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish | |||
50 | static void radeon_pm_update_profile(struct radeon_device *rdev); | 47 | static void radeon_pm_update_profile(struct radeon_device *rdev); |
51 | static void radeon_pm_set_clocks(struct radeon_device *rdev); | 48 | static void radeon_pm_set_clocks(struct radeon_device *rdev); |
52 | 49 | ||
53 | #define ACPI_AC_CLASS "ac_adapter" | ||
54 | |||
55 | int radeon_pm_get_type_index(struct radeon_device *rdev, | 50 | int radeon_pm_get_type_index(struct radeon_device *rdev, |
56 | enum radeon_pm_state_type ps_type, | 51 | enum radeon_pm_state_type ps_type, |
57 | int instance) | 52 | int instance) |
@@ -70,33 +65,17 @@ int radeon_pm_get_type_index(struct radeon_device *rdev, | |||
70 | return rdev->pm.default_power_state_index; | 65 | return rdev->pm.default_power_state_index; |
71 | } | 66 | } |
72 | 67 | ||
73 | #ifdef CONFIG_ACPI | 68 | void radeon_pm_acpi_event_handler(struct radeon_device *rdev) |
74 | static int radeon_acpi_event(struct notifier_block *nb, | ||
75 | unsigned long val, | ||
76 | void *data) | ||
77 | { | 69 | { |
78 | struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb); | 70 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { |
79 | struct acpi_bus_event *entry = (struct acpi_bus_event *)data; | 71 | if (rdev->pm.profile == PM_PROFILE_AUTO) { |
80 | 72 | mutex_lock(&rdev->pm.mutex); | |
81 | if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { | 73 | radeon_pm_update_profile(rdev); |
82 | if (power_supply_is_system_supplied() > 0) | 74 | radeon_pm_set_clocks(rdev); |
83 | DRM_DEBUG_DRIVER("pm: AC\n"); | 75 | mutex_unlock(&rdev->pm.mutex); |
84 | else | ||
85 | DRM_DEBUG_DRIVER("pm: DC\n"); | ||
86 | |||
87 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { | ||
88 | if (rdev->pm.profile == PM_PROFILE_AUTO) { | ||
89 | mutex_lock(&rdev->pm.mutex); | ||
90 | radeon_pm_update_profile(rdev); | ||
91 | radeon_pm_set_clocks(rdev); | ||
92 | mutex_unlock(&rdev->pm.mutex); | ||
93 | } | ||
94 | } | 76 | } |
95 | } | 77 | } |
96 | |||
97 | return NOTIFY_OK; | ||
98 | } | 78 | } |
99 | #endif | ||
100 | 79 | ||
101 | static void radeon_pm_update_profile(struct radeon_device *rdev) | 80 | static void radeon_pm_update_profile(struct radeon_device *rdev) |
102 | { | 81 | { |
@@ -188,8 +167,21 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
188 | if (sclk > rdev->pm.default_sclk) | 167 | if (sclk > rdev->pm.default_sclk) |
189 | sclk = rdev->pm.default_sclk; | 168 | sclk = rdev->pm.default_sclk; |
190 | 169 | ||
191 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 170 | /* starting with BTC, there is one state that is used for both |
192 | clock_info[rdev->pm.requested_clock_mode_index].mclk; | 171 | * MH and SH. Difference is that we always use the high clock index for |
172 | * mclk. | ||
173 | */ | ||
174 | if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && | ||
175 | (rdev->family >= CHIP_BARTS) && | ||
176 | rdev->pm.active_crtc_count && | ||
177 | ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) || | ||
178 | (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX))) | ||
179 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | ||
180 | clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].mclk; | ||
181 | else | ||
182 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | ||
183 | clock_info[rdev->pm.requested_clock_mode_index].mclk; | ||
184 | |||
193 | if (mclk > rdev->pm.default_mclk) | 185 | if (mclk > rdev->pm.default_mclk) |
194 | mclk = rdev->pm.default_mclk; | 186 | mclk = rdev->pm.default_mclk; |
195 | 187 | ||
@@ -253,18 +245,13 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
253 | down_write(&rdev->pm.mclk_lock); | 245 | down_write(&rdev->pm.mclk_lock); |
254 | mutex_lock(&rdev->ring_lock); | 246 | mutex_lock(&rdev->ring_lock); |
255 | 247 | ||
256 | /* gui idle int has issues on older chips it seems */ | 248 | /* wait for the rings to drain */ |
257 | if (rdev->family >= CHIP_R600) { | 249 | for (i = 0; i < RADEON_NUM_RINGS; i++) { |
258 | if (rdev->irq.installed) { | 250 | struct radeon_ring *ring = &rdev->ring[i]; |
259 | /* wait for GPU to become idle */ | 251 | if (ring->ready) |
260 | radeon_irq_kms_wait_gui_idle(rdev); | 252 | radeon_fence_wait_empty_locked(rdev, i); |
261 | } | ||
262 | } else { | ||
263 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | ||
264 | if (ring->ready) { | ||
265 | radeon_fence_wait_empty_locked(rdev, RADEON_RING_TYPE_GFX_INDEX); | ||
266 | } | ||
267 | } | 253 | } |
254 | |||
268 | radeon_unmap_vram_bos(rdev); | 255 | radeon_unmap_vram_bos(rdev); |
269 | 256 | ||
270 | if (rdev->irq.installed) { | 257 | if (rdev->irq.installed) { |
@@ -320,17 +307,15 @@ static void radeon_pm_print_states(struct radeon_device *rdev) | |||
320 | for (j = 0; j < power_state->num_clock_modes; j++) { | 307 | for (j = 0; j < power_state->num_clock_modes; j++) { |
321 | clock_info = &(power_state->clock_info[j]); | 308 | clock_info = &(power_state->clock_info[j]); |
322 | if (rdev->flags & RADEON_IS_IGP) | 309 | if (rdev->flags & RADEON_IS_IGP) |
323 | DRM_DEBUG_DRIVER("\t\t%d e: %d%s\n", | 310 | DRM_DEBUG_DRIVER("\t\t%d e: %d\n", |
324 | j, | 311 | j, |
325 | clock_info->sclk * 10, | 312 | clock_info->sclk * 10); |
326 | clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : ""); | ||
327 | else | 313 | else |
328 | DRM_DEBUG_DRIVER("\t\t%d e: %d\tm: %d\tv: %d%s\n", | 314 | DRM_DEBUG_DRIVER("\t\t%d e: %d\tm: %d\tv: %d\n", |
329 | j, | 315 | j, |
330 | clock_info->sclk * 10, | 316 | clock_info->sclk * 10, |
331 | clock_info->mclk * 10, | 317 | clock_info->mclk * 10, |
332 | clock_info->voltage.voltage, | 318 | clock_info->voltage.voltage); |
333 | clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : ""); | ||
334 | } | 319 | } |
335 | } | 320 | } |
336 | } | 321 | } |
@@ -547,7 +532,9 @@ void radeon_pm_suspend(struct radeon_device *rdev) | |||
547 | void radeon_pm_resume(struct radeon_device *rdev) | 532 | void radeon_pm_resume(struct radeon_device *rdev) |
548 | { | 533 | { |
549 | /* set up the default clocks if the MC ucode is loaded */ | 534 | /* set up the default clocks if the MC ucode is loaded */ |
550 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { | 535 | if ((rdev->family >= CHIP_BARTS) && |
536 | (rdev->family <= CHIP_CAYMAN) && | ||
537 | rdev->mc_fw) { | ||
551 | if (rdev->pm.default_vddc) | 538 | if (rdev->pm.default_vddc) |
552 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, | 539 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, |
553 | SET_VOLTAGE_TYPE_ASIC_VDDC); | 540 | SET_VOLTAGE_TYPE_ASIC_VDDC); |
@@ -602,7 +589,9 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
602 | radeon_pm_print_states(rdev); | 589 | radeon_pm_print_states(rdev); |
603 | radeon_pm_init_profile(rdev); | 590 | radeon_pm_init_profile(rdev); |
604 | /* set up the default clocks if the MC ucode is loaded */ | 591 | /* set up the default clocks if the MC ucode is loaded */ |
605 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { | 592 | if ((rdev->family >= CHIP_BARTS) && |
593 | (rdev->family <= CHIP_CAYMAN) && | ||
594 | rdev->mc_fw) { | ||
606 | if (rdev->pm.default_vddc) | 595 | if (rdev->pm.default_vddc) |
607 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, | 596 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, |
608 | SET_VOLTAGE_TYPE_ASIC_VDDC); | 597 | SET_VOLTAGE_TYPE_ASIC_VDDC); |
@@ -632,10 +621,6 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
632 | if (ret) | 621 | if (ret) |
633 | DRM_ERROR("failed to create device file for power method\n"); | 622 | DRM_ERROR("failed to create device file for power method\n"); |
634 | 623 | ||
635 | #ifdef CONFIG_ACPI | ||
636 | rdev->acpi_nb.notifier_call = radeon_acpi_event; | ||
637 | register_acpi_notifier(&rdev->acpi_nb); | ||
638 | #endif | ||
639 | if (radeon_debugfs_pm_init(rdev)) { | 624 | if (radeon_debugfs_pm_init(rdev)) { |
640 | DRM_ERROR("Failed to register debugfs file for PM!\n"); | 625 | DRM_ERROR("Failed to register debugfs file for PM!\n"); |
641 | } | 626 | } |
@@ -666,9 +651,6 @@ void radeon_pm_fini(struct radeon_device *rdev) | |||
666 | 651 | ||
667 | device_remove_file(rdev->dev, &dev_attr_power_profile); | 652 | device_remove_file(rdev->dev, &dev_attr_power_profile); |
668 | device_remove_file(rdev->dev, &dev_attr_power_method); | 653 | device_remove_file(rdev->dev, &dev_attr_power_method); |
669 | #ifdef CONFIG_ACPI | ||
670 | unregister_acpi_notifier(&rdev->acpi_nb); | ||
671 | #endif | ||
672 | } | 654 | } |
673 | 655 | ||
674 | if (rdev->pm.power_state) | 656 | if (rdev->pm.power_state) |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 43c431a2686d..028508859a3b 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -43,7 +43,7 @@ | |||
43 | * produce command buffers which are send to the kernel and | 43 | * produce command buffers which are send to the kernel and |
44 | * put in IBs for execution by the requested ring. | 44 | * put in IBs for execution by the requested ring. |
45 | */ | 45 | */ |
46 | int radeon_debugfs_sa_init(struct radeon_device *rdev); | 46 | static int radeon_debugfs_sa_init(struct radeon_device *rdev); |
47 | 47 | ||
48 | /** | 48 | /** |
49 | * radeon_ib_get - request an IB (Indirect Buffer) | 49 | * radeon_ib_get - request an IB (Indirect Buffer) |
@@ -58,7 +58,8 @@ int radeon_debugfs_sa_init(struct radeon_device *rdev); | |||
58 | * Returns 0 on success, error on failure. | 58 | * Returns 0 on success, error on failure. |
59 | */ | 59 | */ |
60 | int radeon_ib_get(struct radeon_device *rdev, int ring, | 60 | int radeon_ib_get(struct radeon_device *rdev, int ring, |
61 | struct radeon_ib *ib, unsigned size) | 61 | struct radeon_ib *ib, struct radeon_vm *vm, |
62 | unsigned size) | ||
62 | { | 63 | { |
63 | int i, r; | 64 | int i, r; |
64 | 65 | ||
@@ -76,8 +77,15 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, | |||
76 | ib->ring = ring; | 77 | ib->ring = ring; |
77 | ib->fence = NULL; | 78 | ib->fence = NULL; |
78 | ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo); | 79 | ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo); |
79 | ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo); | 80 | ib->vm = vm; |
80 | ib->vm_id = 0; | 81 | if (vm) { |
82 | /* ib pool is bound at RADEON_VA_IB_OFFSET in virtual address | ||
83 | * space and soffset is the offset inside the pool bo | ||
84 | */ | ||
85 | ib->gpu_addr = ib->sa_bo->soffset + RADEON_VA_IB_OFFSET; | ||
86 | } else { | ||
87 | ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo); | ||
88 | } | ||
81 | ib->is_const_ib = false; | 89 | ib->is_const_ib = false; |
82 | for (i = 0; i < RADEON_NUM_RINGS; ++i) | 90 | for (i = 0; i < RADEON_NUM_RINGS; ++i) |
83 | ib->sync_to[i] = NULL; | 91 | ib->sync_to[i] = NULL; |
@@ -152,6 +160,10 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | |||
152 | if (!need_sync) { | 160 | if (!need_sync) { |
153 | radeon_semaphore_free(rdev, &ib->semaphore, NULL); | 161 | radeon_semaphore_free(rdev, &ib->semaphore, NULL); |
154 | } | 162 | } |
163 | /* if we can't remember our last VM flush then flush now! */ | ||
164 | if (ib->vm && !ib->vm->last_flush) { | ||
165 | radeon_ring_vm_flush(rdev, ib->ring, ib->vm); | ||
166 | } | ||
155 | if (const_ib) { | 167 | if (const_ib) { |
156 | radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); | 168 | radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); |
157 | radeon_semaphore_free(rdev, &const_ib->semaphore, NULL); | 169 | radeon_semaphore_free(rdev, &const_ib->semaphore, NULL); |
@@ -166,6 +178,10 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | |||
166 | if (const_ib) { | 178 | if (const_ib) { |
167 | const_ib->fence = radeon_fence_ref(ib->fence); | 179 | const_ib->fence = radeon_fence_ref(ib->fence); |
168 | } | 180 | } |
181 | /* we just flushed the VM, remember that */ | ||
182 | if (ib->vm && !ib->vm->last_flush) { | ||
183 | ib->vm->last_flush = radeon_fence_ref(ib->fence); | ||
184 | } | ||
169 | radeon_ring_unlock_commit(rdev, ring); | 185 | radeon_ring_unlock_commit(rdev, ring); |
170 | return 0; | 186 | return 0; |
171 | } | 187 | } |
@@ -275,7 +291,7 @@ int radeon_ib_ring_tests(struct radeon_device *rdev) | |||
275 | * wptr. The GPU then starts fetching commands and executes | 291 | * wptr. The GPU then starts fetching commands and executes |
276 | * them until the pointers are equal again. | 292 | * them until the pointers are equal again. |
277 | */ | 293 | */ |
278 | int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring); | 294 | static int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring); |
279 | 295 | ||
280 | /** | 296 | /** |
281 | * radeon_ring_write - write a value to the ring | 297 | * radeon_ring_write - write a value to the ring |
@@ -803,7 +819,7 @@ static struct drm_info_list radeon_debugfs_sa_list[] = { | |||
803 | 819 | ||
804 | #endif | 820 | #endif |
805 | 821 | ||
806 | int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring) | 822 | static int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring) |
807 | { | 823 | { |
808 | #if defined(CONFIG_DEBUG_FS) | 824 | #if defined(CONFIG_DEBUG_FS) |
809 | unsigned i; | 825 | unsigned i; |
@@ -823,7 +839,7 @@ int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *rin | |||
823 | return 0; | 839 | return 0; |
824 | } | 840 | } |
825 | 841 | ||
826 | int radeon_debugfs_sa_init(struct radeon_device *rdev) | 842 | static int radeon_debugfs_sa_init(struct radeon_device *rdev) |
827 | { | 843 | { |
828 | #if defined(CONFIG_DEBUG_FS) | 844 | #if defined(CONFIG_DEBUG_FS) |
829 | return radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1); | 845 | return radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1); |
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c index 4e771240fdd0..105fde69d045 100644 --- a/drivers/gpu/drm/radeon/radeon_sa.c +++ b/drivers/gpu/drm/radeon/radeon_sa.c | |||
@@ -316,7 +316,7 @@ int radeon_sa_bo_new(struct radeon_device *rdev, | |||
316 | { | 316 | { |
317 | struct radeon_fence *fences[RADEON_NUM_RINGS]; | 317 | struct radeon_fence *fences[RADEON_NUM_RINGS]; |
318 | unsigned tries[RADEON_NUM_RINGS]; | 318 | unsigned tries[RADEON_NUM_RINGS]; |
319 | int i, r = -ENOMEM; | 319 | int i, r; |
320 | 320 | ||
321 | BUG_ON(align > RADEON_GPU_PAGE_SIZE); | 321 | BUG_ON(align > RADEON_GPU_PAGE_SIZE); |
322 | BUG_ON(size > sa_manager->size); | 322 | BUG_ON(size > sa_manager->size); |
@@ -331,7 +331,7 @@ int radeon_sa_bo_new(struct radeon_device *rdev, | |||
331 | INIT_LIST_HEAD(&(*sa_bo)->flist); | 331 | INIT_LIST_HEAD(&(*sa_bo)->flist); |
332 | 332 | ||
333 | spin_lock(&sa_manager->wq.lock); | 333 | spin_lock(&sa_manager->wq.lock); |
334 | while(1) { | 334 | do { |
335 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 335 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
336 | fences[i] = NULL; | 336 | fences[i] = NULL; |
337 | tries[i] = 0; | 337 | tries[i] = 0; |
@@ -349,26 +349,22 @@ int radeon_sa_bo_new(struct radeon_device *rdev, | |||
349 | /* see if we can skip over some allocations */ | 349 | /* see if we can skip over some allocations */ |
350 | } while (radeon_sa_bo_next_hole(sa_manager, fences, tries)); | 350 | } while (radeon_sa_bo_next_hole(sa_manager, fences, tries)); |
351 | 351 | ||
352 | if (!block) { | ||
353 | break; | ||
354 | } | ||
355 | |||
356 | spin_unlock(&sa_manager->wq.lock); | 352 | spin_unlock(&sa_manager->wq.lock); |
357 | r = radeon_fence_wait_any(rdev, fences, false); | 353 | r = radeon_fence_wait_any(rdev, fences, false); |
358 | spin_lock(&sa_manager->wq.lock); | 354 | spin_lock(&sa_manager->wq.lock); |
359 | /* if we have nothing to wait for block */ | 355 | /* if we have nothing to wait for block */ |
360 | if (r == -ENOENT) { | 356 | if (r == -ENOENT && block) { |
361 | r = wait_event_interruptible_locked( | 357 | r = wait_event_interruptible_locked( |
362 | sa_manager->wq, | 358 | sa_manager->wq, |
363 | radeon_sa_event(sa_manager, size, align) | 359 | radeon_sa_event(sa_manager, size, align) |
364 | ); | 360 | ); |
361 | |||
362 | } else if (r == -ENOENT) { | ||
363 | r = -ENOMEM; | ||
365 | } | 364 | } |
366 | if (r) { | ||
367 | goto out_err; | ||
368 | } | ||
369 | }; | ||
370 | 365 | ||
371 | out_err: | 366 | } while (!r); |
367 | |||
372 | spin_unlock(&sa_manager->wq.lock); | 368 | spin_unlock(&sa_manager->wq.lock); |
373 | kfree(*sa_bo); | 369 | kfree(*sa_bo); |
374 | *sa_bo = NULL; | 370 | *sa_bo = NULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 7c16540c10ff..587c09a00ba2 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
@@ -313,7 +313,7 @@ out_cleanup: | |||
313 | printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); | 313 | printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); |
314 | } | 314 | } |
315 | 315 | ||
316 | void radeon_test_ring_sync2(struct radeon_device *rdev, | 316 | static void radeon_test_ring_sync2(struct radeon_device *rdev, |
317 | struct radeon_ring *ringA, | 317 | struct radeon_ring *ringA, |
318 | struct radeon_ring *ringB, | 318 | struct radeon_ring *ringB, |
319 | struct radeon_ring *ringC) | 319 | struct radeon_ring *ringC) |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 5b71c716d83f..5ebe1b3e5db2 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -549,7 +549,7 @@ static struct ttm_backend_func radeon_backend_func = { | |||
549 | .destroy = &radeon_ttm_backend_destroy, | 549 | .destroy = &radeon_ttm_backend_destroy, |
550 | }; | 550 | }; |
551 | 551 | ||
552 | struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device *bdev, | 552 | static struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device *bdev, |
553 | unsigned long size, uint32_t page_flags, | 553 | unsigned long size, uint32_t page_flags, |
554 | struct page *dummy_read_page) | 554 | struct page *dummy_read_page) |
555 | { | 555 | { |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 2752f7f78237..73051ce3121e 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -242,7 +242,7 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev) | |||
242 | return -1; | 242 | return -1; |
243 | } | 243 | } |
244 | 244 | ||
245 | void rs400_gpu_init(struct radeon_device *rdev) | 245 | static void rs400_gpu_init(struct radeon_device *rdev) |
246 | { | 246 | { |
247 | /* FIXME: is this correct ? */ | 247 | /* FIXME: is this correct ? */ |
248 | r420_pipes_init(rdev); | 248 | r420_pipes_init(rdev); |
@@ -252,7 +252,7 @@ void rs400_gpu_init(struct radeon_device *rdev) | |||
252 | } | 252 | } |
253 | } | 253 | } |
254 | 254 | ||
255 | void rs400_mc_init(struct radeon_device *rdev) | 255 | static void rs400_mc_init(struct radeon_device *rdev) |
256 | { | 256 | { |
257 | u64 base; | 257 | u64 base; |
258 | 258 | ||
@@ -370,7 +370,7 @@ static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev) | |||
370 | #endif | 370 | #endif |
371 | } | 371 | } |
372 | 372 | ||
373 | void rs400_mc_program(struct radeon_device *rdev) | 373 | static void rs400_mc_program(struct radeon_device *rdev) |
374 | { | 374 | { |
375 | struct r100_mc_save save; | 375 | struct r100_mc_save save; |
376 | 376 | ||
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 5301b3df8466..dc8d021a999b 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -43,22 +43,30 @@ | |||
43 | 43 | ||
44 | #include "rs600_reg_safe.h" | 44 | #include "rs600_reg_safe.h" |
45 | 45 | ||
46 | void rs600_gpu_init(struct radeon_device *rdev); | 46 | static void rs600_gpu_init(struct radeon_device *rdev); |
47 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); | 47 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); |
48 | 48 | ||
49 | static const u32 crtc_offsets[2] = | ||
50 | { | ||
51 | 0, | ||
52 | AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL | ||
53 | }; | ||
54 | |||
49 | void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc) | 55 | void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc) |
50 | { | 56 | { |
51 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; | ||
52 | int i; | 57 | int i; |
53 | 58 | ||
54 | if (RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset) & AVIVO_CRTC_EN) { | 59 | if (crtc >= rdev->num_crtc) |
60 | return; | ||
61 | |||
62 | if (RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN) { | ||
55 | for (i = 0; i < rdev->usec_timeout; i++) { | 63 | for (i = 0; i < rdev->usec_timeout; i++) { |
56 | if (!(RREG32(AVIVO_D1CRTC_STATUS + radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK)) | 64 | if (!(RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK)) |
57 | break; | 65 | break; |
58 | udelay(1); | 66 | udelay(1); |
59 | } | 67 | } |
60 | for (i = 0; i < rdev->usec_timeout; i++) { | 68 | for (i = 0; i < rdev->usec_timeout; i++) { |
61 | if (RREG32(AVIVO_D1CRTC_STATUS + radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK) | 69 | if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK) |
62 | break; | 70 | break; |
63 | udelay(1); | 71 | udelay(1); |
64 | } | 72 | } |
@@ -424,7 +432,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev) | |||
424 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); | 432 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
425 | } | 433 | } |
426 | 434 | ||
427 | int rs600_gart_init(struct radeon_device *rdev) | 435 | static int rs600_gart_init(struct radeon_device *rdev) |
428 | { | 436 | { |
429 | int r; | 437 | int r; |
430 | 438 | ||
@@ -506,7 +514,7 @@ static int rs600_gart_enable(struct radeon_device *rdev) | |||
506 | return 0; | 514 | return 0; |
507 | } | 515 | } |
508 | 516 | ||
509 | void rs600_gart_disable(struct radeon_device *rdev) | 517 | static void rs600_gart_disable(struct radeon_device *rdev) |
510 | { | 518 | { |
511 | u32 tmp; | 519 | u32 tmp; |
512 | 520 | ||
@@ -517,7 +525,7 @@ void rs600_gart_disable(struct radeon_device *rdev) | |||
517 | radeon_gart_table_vram_unpin(rdev); | 525 | radeon_gart_table_vram_unpin(rdev); |
518 | } | 526 | } |
519 | 527 | ||
520 | void rs600_gart_fini(struct radeon_device *rdev) | 528 | static void rs600_gart_fini(struct radeon_device *rdev) |
521 | { | 529 | { |
522 | radeon_gart_fini(rdev); | 530 | radeon_gart_fini(rdev); |
523 | rs600_gart_disable(rdev); | 531 | rs600_gart_disable(rdev); |
@@ -567,9 +575,6 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
567 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { | 575 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
568 | tmp |= S_000040_SW_INT_EN(1); | 576 | tmp |= S_000040_SW_INT_EN(1); |
569 | } | 577 | } |
570 | if (rdev->irq.gui_idle) { | ||
571 | tmp |= S_000040_GUI_IDLE(1); | ||
572 | } | ||
573 | if (rdev->irq.crtc_vblank_int[0] || | 578 | if (rdev->irq.crtc_vblank_int[0] || |
574 | atomic_read(&rdev->irq.pflip[0])) { | 579 | atomic_read(&rdev->irq.pflip[0])) { |
575 | mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); | 580 | mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); |
@@ -602,12 +607,6 @@ static inline u32 rs600_irq_ack(struct radeon_device *rdev) | |||
602 | uint32_t irq_mask = S_000044_SW_INT(1); | 607 | uint32_t irq_mask = S_000044_SW_INT(1); |
603 | u32 tmp; | 608 | u32 tmp; |
604 | 609 | ||
605 | /* the interrupt works, but the status bit is permanently asserted */ | ||
606 | if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { | ||
607 | if (!rdev->irq.gui_idle_acked) | ||
608 | irq_mask |= S_000044_GUI_IDLE_STAT(1); | ||
609 | } | ||
610 | |||
611 | if (G_000044_DISPLAY_INT_STAT(irqs)) { | 610 | if (G_000044_DISPLAY_INT_STAT(irqs)) { |
612 | rdev->irq.stat_regs.r500.disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); | 611 | rdev->irq.stat_regs.r500.disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); |
613 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { | 612 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
@@ -667,9 +666,6 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
667 | bool queue_hotplug = false; | 666 | bool queue_hotplug = false; |
668 | bool queue_hdmi = false; | 667 | bool queue_hdmi = false; |
669 | 668 | ||
670 | /* reset gui idle ack. the status bit is broken */ | ||
671 | rdev->irq.gui_idle_acked = false; | ||
672 | |||
673 | status = rs600_irq_ack(rdev); | 669 | status = rs600_irq_ack(rdev); |
674 | if (!status && | 670 | if (!status && |
675 | !rdev->irq.stat_regs.r500.disp_int && | 671 | !rdev->irq.stat_regs.r500.disp_int && |
@@ -683,11 +679,6 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
683 | if (G_000044_SW_INT(status)) { | 679 | if (G_000044_SW_INT(status)) { |
684 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | 680 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |
685 | } | 681 | } |
686 | /* GUI idle */ | ||
687 | if (G_000040_GUI_IDLE(status)) { | ||
688 | rdev->irq.gui_idle_acked = true; | ||
689 | wake_up(&rdev->irq.idle_queue); | ||
690 | } | ||
691 | /* Vertical blank interrupts */ | 682 | /* Vertical blank interrupts */ |
692 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { | 683 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { |
693 | if (rdev->irq.crtc_vblank_int[0]) { | 684 | if (rdev->irq.crtc_vblank_int[0]) { |
@@ -721,8 +712,6 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
721 | } | 712 | } |
722 | status = rs600_irq_ack(rdev); | 713 | status = rs600_irq_ack(rdev); |
723 | } | 714 | } |
724 | /* reset gui idle ack. the status bit is broken */ | ||
725 | rdev->irq.gui_idle_acked = false; | ||
726 | if (queue_hotplug) | 715 | if (queue_hotplug) |
727 | schedule_work(&rdev->hotplug_work); | 716 | schedule_work(&rdev->hotplug_work); |
728 | if (queue_hdmi) | 717 | if (queue_hdmi) |
@@ -764,7 +753,7 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev) | |||
764 | return -1; | 753 | return -1; |
765 | } | 754 | } |
766 | 755 | ||
767 | void rs600_gpu_init(struct radeon_device *rdev) | 756 | static void rs600_gpu_init(struct radeon_device *rdev) |
768 | { | 757 | { |
769 | r420_pipes_init(rdev); | 758 | r420_pipes_init(rdev); |
770 | /* Wait for mc idle */ | 759 | /* Wait for mc idle */ |
@@ -772,7 +761,7 @@ void rs600_gpu_init(struct radeon_device *rdev) | |||
772 | dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); | 761 | dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); |
773 | } | 762 | } |
774 | 763 | ||
775 | void rs600_mc_init(struct radeon_device *rdev) | 764 | static void rs600_mc_init(struct radeon_device *rdev) |
776 | { | 765 | { |
777 | u64 base; | 766 | u64 base; |
778 | 767 | ||
@@ -834,7 +823,7 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
834 | WREG32(R_000074_MC_IND_DATA, v); | 823 | WREG32(R_000074_MC_IND_DATA, v); |
835 | } | 824 | } |
836 | 825 | ||
837 | void rs600_debugfs(struct radeon_device *rdev) | 826 | static void rs600_debugfs(struct radeon_device *rdev) |
838 | { | 827 | { |
839 | if (r100_debugfs_rbbm_init(rdev)) | 828 | if (r100_debugfs_rbbm_init(rdev)) |
840 | DRM_ERROR("Failed to register debugfs file for RBBM !\n"); | 829 | DRM_ERROR("Failed to register debugfs file for RBBM !\n"); |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 3b663fcfe061..5cd5aceb69fa 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -145,7 +145,7 @@ void rs690_pm_info(struct radeon_device *rdev) | |||
145 | rdev->pm.sideport_bandwidth.full = dfixed_div(rdev->pm.sideport_bandwidth, tmp); | 145 | rdev->pm.sideport_bandwidth.full = dfixed_div(rdev->pm.sideport_bandwidth, tmp); |
146 | } | 146 | } |
147 | 147 | ||
148 | void rs690_mc_init(struct radeon_device *rdev) | 148 | static void rs690_mc_init(struct radeon_device *rdev) |
149 | { | 149 | { |
150 | u64 base; | 150 | u64 base; |
151 | 151 | ||
@@ -224,7 +224,7 @@ struct rs690_watermark { | |||
224 | fixed20_12 sclk; | 224 | fixed20_12 sclk; |
225 | }; | 225 | }; |
226 | 226 | ||
227 | void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, | 227 | static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, |
228 | struct radeon_crtc *crtc, | 228 | struct radeon_crtc *crtc, |
229 | struct rs690_watermark *wm) | 229 | struct rs690_watermark *wm) |
230 | { | 230 | { |
@@ -581,7 +581,7 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
581 | WREG32(R_000078_MC_INDEX, 0x7F); | 581 | WREG32(R_000078_MC_INDEX, 0x7F); |
582 | } | 582 | } |
583 | 583 | ||
584 | void rs690_mc_program(struct radeon_device *rdev) | 584 | static void rs690_mc_program(struct radeon_device *rdev) |
585 | { | 585 | { |
586 | struct rv515_mc_save save; | 586 | struct rv515_mc_save save; |
587 | 587 | ||
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index aa8ef491ef3c..2d75d30be5b4 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -35,9 +35,9 @@ | |||
35 | #include "rv515_reg_safe.h" | 35 | #include "rv515_reg_safe.h" |
36 | 36 | ||
37 | /* This files gather functions specifics to: rv515 */ | 37 | /* This files gather functions specifics to: rv515 */ |
38 | int rv515_debugfs_pipes_info_init(struct radeon_device *rdev); | 38 | static int rv515_debugfs_pipes_info_init(struct radeon_device *rdev); |
39 | int rv515_debugfs_ga_info_init(struct radeon_device *rdev); | 39 | static int rv515_debugfs_ga_info_init(struct radeon_device *rdev); |
40 | void rv515_gpu_init(struct radeon_device *rdev); | 40 | static void rv515_gpu_init(struct radeon_device *rdev); |
41 | int rv515_mc_wait_for_idle(struct radeon_device *rdev); | 41 | int rv515_mc_wait_for_idle(struct radeon_device *rdev); |
42 | 42 | ||
43 | void rv515_debugfs(struct radeon_device *rdev) | 43 | void rv515_debugfs(struct radeon_device *rdev) |
@@ -143,7 +143,7 @@ void rv515_vga_render_disable(struct radeon_device *rdev) | |||
143 | RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); | 143 | RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); |
144 | } | 144 | } |
145 | 145 | ||
146 | void rv515_gpu_init(struct radeon_device *rdev) | 146 | static void rv515_gpu_init(struct radeon_device *rdev) |
147 | { | 147 | { |
148 | unsigned pipe_select_current, gb_pipe_select, tmp; | 148 | unsigned pipe_select_current, gb_pipe_select, tmp; |
149 | 149 | ||
@@ -189,7 +189,7 @@ static void rv515_vram_get_type(struct radeon_device *rdev) | |||
189 | } | 189 | } |
190 | } | 190 | } |
191 | 191 | ||
192 | void rv515_mc_init(struct radeon_device *rdev) | 192 | static void rv515_mc_init(struct radeon_device *rdev) |
193 | { | 193 | { |
194 | 194 | ||
195 | rv515_vram_get_type(rdev); | 195 | rv515_vram_get_type(rdev); |
@@ -261,7 +261,7 @@ static struct drm_info_list rv515_ga_info_list[] = { | |||
261 | }; | 261 | }; |
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | int rv515_debugfs_pipes_info_init(struct radeon_device *rdev) | 264 | static int rv515_debugfs_pipes_info_init(struct radeon_device *rdev) |
265 | { | 265 | { |
266 | #if defined(CONFIG_DEBUG_FS) | 266 | #if defined(CONFIG_DEBUG_FS) |
267 | return radeon_debugfs_add_files(rdev, rv515_pipes_info_list, 1); | 267 | return radeon_debugfs_add_files(rdev, rv515_pipes_info_list, 1); |
@@ -270,7 +270,7 @@ int rv515_debugfs_pipes_info_init(struct radeon_device *rdev) | |||
270 | #endif | 270 | #endif |
271 | } | 271 | } |
272 | 272 | ||
273 | int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | 273 | static int rv515_debugfs_ga_info_init(struct radeon_device *rdev) |
274 | { | 274 | { |
275 | #if defined(CONFIG_DEBUG_FS) | 275 | #if defined(CONFIG_DEBUG_FS) |
276 | return radeon_debugfs_add_files(rdev, rv515_ga_info_list, 1); | 276 | return radeon_debugfs_add_files(rdev, rv515_ga_info_list, 1); |
@@ -310,7 +310,7 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
310 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 310 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
311 | } | 311 | } |
312 | 312 | ||
313 | void rv515_mc_program(struct radeon_device *rdev) | 313 | static void rv515_mc_program(struct radeon_device *rdev) |
314 | { | 314 | { |
315 | struct rv515_mc_save save; | 315 | struct rv515_mc_save save; |
316 | 316 | ||
@@ -787,7 +787,7 @@ struct rv515_watermark { | |||
787 | fixed20_12 sclk; | 787 | fixed20_12 sclk; |
788 | }; | 788 | }; |
789 | 789 | ||
790 | void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, | 790 | static void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, |
791 | struct radeon_crtc *crtc, | 791 | struct radeon_crtc *crtc, |
792 | struct rv515_watermark *wm) | 792 | struct rv515_watermark *wm) |
793 | { | 793 | { |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index ca8ffec10ff6..2469afe11b85 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -124,7 +124,7 @@ void rv770_pm_misc(struct radeon_device *rdev) | |||
124 | /* | 124 | /* |
125 | * GART | 125 | * GART |
126 | */ | 126 | */ |
127 | int rv770_pcie_gart_enable(struct radeon_device *rdev) | 127 | static int rv770_pcie_gart_enable(struct radeon_device *rdev) |
128 | { | 128 | { |
129 | u32 tmp; | 129 | u32 tmp; |
130 | int r, i; | 130 | int r, i; |
@@ -175,7 +175,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) | |||
175 | return 0; | 175 | return 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | void rv770_pcie_gart_disable(struct radeon_device *rdev) | 178 | static void rv770_pcie_gart_disable(struct radeon_device *rdev) |
179 | { | 179 | { |
180 | u32 tmp; | 180 | u32 tmp; |
181 | int i; | 181 | int i; |
@@ -201,7 +201,7 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev) | |||
201 | radeon_gart_table_vram_unpin(rdev); | 201 | radeon_gart_table_vram_unpin(rdev); |
202 | } | 202 | } |
203 | 203 | ||
204 | void rv770_pcie_gart_fini(struct radeon_device *rdev) | 204 | static void rv770_pcie_gart_fini(struct radeon_device *rdev) |
205 | { | 205 | { |
206 | radeon_gart_fini(rdev); | 206 | radeon_gart_fini(rdev); |
207 | rv770_pcie_gart_disable(rdev); | 207 | rv770_pcie_gart_disable(rdev); |
@@ -209,7 +209,7 @@ void rv770_pcie_gart_fini(struct radeon_device *rdev) | |||
209 | } | 209 | } |
210 | 210 | ||
211 | 211 | ||
212 | void rv770_agp_enable(struct radeon_device *rdev) | 212 | static void rv770_agp_enable(struct radeon_device *rdev) |
213 | { | 213 | { |
214 | u32 tmp; | 214 | u32 tmp; |
215 | int i; | 215 | int i; |
@@ -839,7 +839,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
839 | } | 839 | } |
840 | } | 840 | } |
841 | 841 | ||
842 | int rv770_mc_init(struct radeon_device *rdev) | 842 | static int rv770_mc_init(struct radeon_device *rdev) |
843 | { | 843 | { |
844 | u32 tmp; | 844 | u32 tmp; |
845 | int chansize, numchan; | 845 | int chansize, numchan; |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 0139e227e3c7..c76825ffa37f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -1806,13 +1806,14 @@ void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
1806 | #endif | 1806 | #endif |
1807 | (ib->gpu_addr & 0xFFFFFFFC)); | 1807 | (ib->gpu_addr & 0xFFFFFFFC)); |
1808 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); | 1808 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); |
1809 | radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24)); | 1809 | radeon_ring_write(ring, ib->length_dw | |
1810 | (ib->vm ? (ib->vm->id << 24) : 0)); | ||
1810 | 1811 | ||
1811 | if (!ib->is_const_ib) { | 1812 | if (!ib->is_const_ib) { |
1812 | /* flush read cache over gart for this vmid */ | 1813 | /* flush read cache over gart for this vmid */ |
1813 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 1814 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
1814 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); | 1815 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); |
1815 | radeon_ring_write(ring, ib->vm_id); | 1816 | radeon_ring_write(ring, ib->vm ? ib->vm->id : 0); |
1816 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 1817 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
1817 | radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | | 1818 | radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | |
1818 | PACKET3_TC_ACTION_ENA | | 1819 | PACKET3_TC_ACTION_ENA | |
@@ -2363,7 +2364,7 @@ void si_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
2363 | WREG32(VM_INVALIDATE_REQUEST, 1); | 2364 | WREG32(VM_INVALIDATE_REQUEST, 1); |
2364 | } | 2365 | } |
2365 | 2366 | ||
2366 | int si_pcie_gart_enable(struct radeon_device *rdev) | 2367 | static int si_pcie_gart_enable(struct radeon_device *rdev) |
2367 | { | 2368 | { |
2368 | int r, i; | 2369 | int r, i; |
2369 | 2370 | ||
@@ -2425,7 +2426,7 @@ int si_pcie_gart_enable(struct radeon_device *rdev) | |||
2425 | WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR, | 2426 | WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR, |
2426 | (u32)(rdev->dummy_page.addr >> 12)); | 2427 | (u32)(rdev->dummy_page.addr >> 12)); |
2427 | WREG32(VM_CONTEXT1_CNTL2, 0); | 2428 | WREG32(VM_CONTEXT1_CNTL2, 0); |
2428 | WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | | 2429 | WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) | |
2429 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); | 2430 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); |
2430 | 2431 | ||
2431 | si_pcie_gart_tlb_flush(rdev); | 2432 | si_pcie_gart_tlb_flush(rdev); |
@@ -2436,7 +2437,7 @@ int si_pcie_gart_enable(struct radeon_device *rdev) | |||
2436 | return 0; | 2437 | return 0; |
2437 | } | 2438 | } |
2438 | 2439 | ||
2439 | void si_pcie_gart_disable(struct radeon_device *rdev) | 2440 | static void si_pcie_gart_disable(struct radeon_device *rdev) |
2440 | { | 2441 | { |
2441 | /* Disable all tables */ | 2442 | /* Disable all tables */ |
2442 | WREG32(VM_CONTEXT0_CNTL, 0); | 2443 | WREG32(VM_CONTEXT0_CNTL, 0); |
@@ -2455,7 +2456,7 @@ void si_pcie_gart_disable(struct radeon_device *rdev) | |||
2455 | radeon_gart_table_vram_unpin(rdev); | 2456 | radeon_gart_table_vram_unpin(rdev); |
2456 | } | 2457 | } |
2457 | 2458 | ||
2458 | void si_pcie_gart_fini(struct radeon_device *rdev) | 2459 | static void si_pcie_gart_fini(struct radeon_device *rdev) |
2459 | { | 2460 | { |
2460 | si_pcie_gart_disable(rdev); | 2461 | si_pcie_gart_disable(rdev); |
2461 | radeon_gart_table_vram_free(rdev); | 2462 | radeon_gart_table_vram_free(rdev); |
@@ -2788,41 +2789,84 @@ void si_vm_fini(struct radeon_device *rdev) | |||
2788 | { | 2789 | { |
2789 | } | 2790 | } |
2790 | 2791 | ||
2791 | int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id) | 2792 | /** |
2793 | * si_vm_set_page - update the page tables using the CP | ||
2794 | * | ||
2795 | * @rdev: radeon_device pointer | ||
2796 | * @pe: addr of the page entry | ||
2797 | * @addr: dst addr to write into pe | ||
2798 | * @count: number of page entries to update | ||
2799 | * @incr: increase next addr by incr bytes | ||
2800 | * @flags: access flags | ||
2801 | * | ||
2802 | * Update the page tables using the CP (cayman-si). | ||
2803 | */ | ||
2804 | void si_vm_set_page(struct radeon_device *rdev, uint64_t pe, | ||
2805 | uint64_t addr, unsigned count, | ||
2806 | uint32_t incr, uint32_t flags) | ||
2792 | { | 2807 | { |
2793 | if (id < 8) | 2808 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; |
2794 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (id << 2), vm->pt_gpu_addr >> 12); | 2809 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); |
2795 | else | 2810 | int i; |
2796 | WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((id - 8) << 2), | 2811 | uint64_t value; |
2797 | vm->pt_gpu_addr >> 12); | 2812 | |
2798 | /* flush hdp cache */ | 2813 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 2 + count * 2)); |
2799 | WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | 2814 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | |
2800 | /* bits 0-15 are the VM contexts0-15 */ | 2815 | WRITE_DATA_DST_SEL(1))); |
2801 | WREG32(VM_INVALIDATE_REQUEST, 1 << id); | 2816 | radeon_ring_write(ring, pe); |
2802 | return 0; | 2817 | radeon_ring_write(ring, upper_32_bits(pe)); |
2818 | for (i = 0; i < count; ++i) { | ||
2819 | if (flags & RADEON_VM_PAGE_SYSTEM) { | ||
2820 | value = radeon_vm_map_gart(rdev, addr); | ||
2821 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
2822 | } else if (flags & RADEON_VM_PAGE_VALID) | ||
2823 | value = addr; | ||
2824 | else | ||
2825 | value = 0; | ||
2826 | addr += incr; | ||
2827 | value |= r600_flags; | ||
2828 | radeon_ring_write(ring, value); | ||
2829 | radeon_ring_write(ring, upper_32_bits(value)); | ||
2830 | } | ||
2803 | } | 2831 | } |
2804 | 2832 | ||
2805 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) | 2833 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) |
2806 | { | 2834 | { |
2807 | if (vm->id < 8) | 2835 | struct radeon_ring *ring = &rdev->ring[ridx]; |
2808 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0); | ||
2809 | else | ||
2810 | WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2), 0); | ||
2811 | /* flush hdp cache */ | ||
2812 | WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
2813 | /* bits 0-15 are the VM contexts0-15 */ | ||
2814 | WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); | ||
2815 | } | ||
2816 | 2836 | ||
2817 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm) | 2837 | if (vm == NULL) |
2818 | { | ||
2819 | if (vm->id == -1) | ||
2820 | return; | 2838 | return; |
2821 | 2839 | ||
2840 | /* write new base address */ | ||
2841 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | ||
2842 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | ||
2843 | WRITE_DATA_DST_SEL(0))); | ||
2844 | |||
2845 | if (vm->id < 8) { | ||
2846 | radeon_ring_write(ring, | ||
2847 | (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); | ||
2848 | } else { | ||
2849 | radeon_ring_write(ring, | ||
2850 | (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2); | ||
2851 | } | ||
2852 | radeon_ring_write(ring, 0); | ||
2853 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | ||
2854 | |||
2822 | /* flush hdp cache */ | 2855 | /* flush hdp cache */ |
2823 | WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | 2856 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
2857 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | ||
2858 | WRITE_DATA_DST_SEL(0))); | ||
2859 | radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); | ||
2860 | radeon_ring_write(ring, 0); | ||
2861 | radeon_ring_write(ring, 0x1); | ||
2862 | |||
2824 | /* bits 0-15 are the VM contexts0-15 */ | 2863 | /* bits 0-15 are the VM contexts0-15 */ |
2825 | WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); | 2864 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
2865 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | ||
2866 | WRITE_DATA_DST_SEL(0))); | ||
2867 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | ||
2868 | radeon_ring_write(ring, 0); | ||
2869 | radeon_ring_write(ring, 1 << vm->id); | ||
2826 | } | 2870 | } |
2827 | 2871 | ||
2828 | /* | 2872 | /* |
@@ -3199,10 +3243,6 @@ int si_irq_set(struct radeon_device *rdev) | |||
3199 | DRM_DEBUG("si_irq_set: hpd 6\n"); | 3243 | DRM_DEBUG("si_irq_set: hpd 6\n"); |
3200 | hpd6 |= DC_HPDx_INT_EN; | 3244 | hpd6 |= DC_HPDx_INT_EN; |
3201 | } | 3245 | } |
3202 | if (rdev->irq.gui_idle) { | ||
3203 | DRM_DEBUG("gui idle\n"); | ||
3204 | grbm_int_cntl |= GUI_IDLE_INT_ENABLE; | ||
3205 | } | ||
3206 | 3246 | ||
3207 | WREG32(CP_INT_CNTL_RING0, cp_int_cntl); | 3247 | WREG32(CP_INT_CNTL_RING0, cp_int_cntl); |
3208 | WREG32(CP_INT_CNTL_RING1, cp_int_cntl1); | 3248 | WREG32(CP_INT_CNTL_RING1, cp_int_cntl1); |
@@ -3658,7 +3698,6 @@ restart_ih: | |||
3658 | break; | 3698 | break; |
3659 | case 233: /* GUI IDLE */ | 3699 | case 233: /* GUI IDLE */ |
3660 | DRM_DEBUG("IH: GUI idle\n"); | 3700 | DRM_DEBUG("IH: GUI idle\n"); |
3661 | wake_up(&rdev->irq.idle_queue); | ||
3662 | break; | 3701 | break; |
3663 | default: | 3702 | default: |
3664 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | 3703 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index ef4815c27b1c..7d2a20e56577 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -812,6 +812,21 @@ | |||
812 | #define PACKET3_DRAW_INDEX_OFFSET_2 0x35 | 812 | #define PACKET3_DRAW_INDEX_OFFSET_2 0x35 |
813 | #define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36 | 813 | #define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36 |
814 | #define PACKET3_WRITE_DATA 0x37 | 814 | #define PACKET3_WRITE_DATA 0x37 |
815 | #define WRITE_DATA_DST_SEL(x) ((x) << 8) | ||
816 | /* 0 - register | ||
817 | * 1 - memory (sync - via GRBM) | ||
818 | * 2 - tc/l2 | ||
819 | * 3 - gds | ||
820 | * 4 - reserved | ||
821 | * 5 - memory (async - direct) | ||
822 | */ | ||
823 | #define WR_ONE_ADDR (1 << 16) | ||
824 | #define WR_CONFIRM (1 << 20) | ||
825 | #define WRITE_DATA_ENGINE_SEL(x) ((x) << 30) | ||
826 | /* 0 - me | ||
827 | * 1 - pfp | ||
828 | * 2 - ce | ||
829 | */ | ||
815 | #define PACKET3_DRAW_INDEX_INDIRECT_MULTI 0x38 | 830 | #define PACKET3_DRAW_INDEX_INDIRECT_MULTI 0x38 |
816 | #define PACKET3_MEM_SEMAPHORE 0x39 | 831 | #define PACKET3_MEM_SEMAPHORE 0x39 |
817 | #define PACKET3_MPEG_INDEX 0x3A | 832 | #define PACKET3_MPEG_INDEX 0x3A |