Merge branch 'drm-radeon-ni' of ../drm-radeon-next into drm-core-next
authorDave Airlie <airlied@redhat.com>
Sun, 9 Jan 2011 23:27:06 +0000 (09:27 +1000)
committerDave Airlie <airlied@redhat.com>
Sun, 9 Jan 2011 23:27:06 +0000 (09:27 +1000)
* 'drm-radeon-ni' of ../drm-radeon-next: (30 commits)
  radeon: consolidate asic-specific function decls for pre-r600
  drm/radeon/kms: add NI pci ids
  drm/radeon/kms: don't enable pcie gen2 on NI yet
  drm/radeon/kms: add radeon_asic struct for NI asics
  drm/radeon/kms/ni: load default sclk/mclk/vddc at pm init
  drm/radeon/kms: add ucode loader for NI
  drm/radeon/kms: add support for DCE5 display LUTs
  drm/radeon/kms: add ni_reg.h
  drm/radeon/kms: add bo blit support for NI
  drm/radeon/kms: always use writeback/events for fences on NI
  drm/radeon/kms: adjust default clock/vddc tracking for pm on DCE5
  drm/radeon/kms: add backend map workaround for barts
  drm/radeon/kms: fill gpu init for NI asics
  drm/radeon/kms: add disabled vbios accessor for NI asics
  drm/radeon/kms: handle NI thermal controller
  drm/radeon/kms: parse DCE5 encoder caps when setting up encoders
  drm/radeon/kms: dvo dpms updates for DCE5
  drm/radeon/kms: dac dpms updates for DCE5
  drm/radeon/kms: DCE5 atom dig encoder updates
  drm/radeon/kms: DCE5 atom transmitter control updates
  ...

26 files changed:
drivers/gpu/drm/radeon/Makefile
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_blit_kms.c
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/ni.c [new file with mode: 0644]
drivers/gpu/drm/radeon/ni_reg.h [new file with mode: 0644]
drivers/gpu/drm/radeon/nid.h [new file with mode: 0644]
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_family.h
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/radeon_reg.h
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/rv770d.h
include/drm/drm_pciids.h

index e97e6f8..e47eecf 100644 (file)
@@ -66,7 +66,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
        r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
        r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
        evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
-       radeon_trace_points.o
+       radeon_trace_points.o ni.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
index 9fbabaa..b0ab185 100644 (file)
@@ -403,6 +403,7 @@ union atom_enable_ss {
        ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2;
        ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
        ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2;
+       ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3;
 };
 
 static void atombios_crtc_program_ss(struct drm_crtc *crtc,
@@ -417,7 +418,30 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
 
        memset(&args, 0, sizeof(args));
 
-       if (ASIC_IS_DCE4(rdev)) {
+       if (ASIC_IS_DCE5(rdev)) {
+               args.v3.usSpreadSpectrumAmountFrac = 0;
+               args.v3.ucSpreadSpectrumType = ss->type;
+               switch (pll_id) {
+               case ATOM_PPLL1:
+                       args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL;
+                       args.v3.usSpreadSpectrumAmount = ss->amount;
+                       args.v3.usSpreadSpectrumStep = ss->step;
+                       break;
+               case ATOM_PPLL2:
+                       args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL;
+                       args.v3.usSpreadSpectrumAmount = ss->amount;
+                       args.v3.usSpreadSpectrumStep = ss->step;
+                       break;
+               case ATOM_DCPLL:
+                       args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL;
+                       args.v3.usSpreadSpectrumAmount = 0;
+                       args.v3.usSpreadSpectrumStep = 0;
+                       break;
+               case ATOM_PPLL_INVALID:
+                       return;
+               }
+               args.v2.ucEnable = enable;
+       } else if (ASIC_IS_DCE4(rdev)) {
                args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
                args.v2.ucSpreadSpectrumType = ss->type;
                switch (pll_id) {
@@ -673,9 +697,14 @@ union set_pixel_clock {
        PIXEL_CLOCK_PARAMETERS_V2 v2;
        PIXEL_CLOCK_PARAMETERS_V3 v3;
        PIXEL_CLOCK_PARAMETERS_V5 v5;
+       PIXEL_CLOCK_PARAMETERS_V6 v6;
 };
 
-static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
+/* on DCE5, make sure the voltage is high enough to support the
+ * required disp clk.
+ */
+static void atombios_crtc_set_dcpll(struct drm_crtc *crtc,
+                                   u32 dispclk)
 {
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
@@ -698,9 +727,16 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
                         * SetPixelClock provides the dividers
                         */
                        args.v5.ucCRTC = ATOM_CRTC_INVALID;
-                       args.v5.usPixelClock = rdev->clock.default_dispclk;
+                       args.v5.usPixelClock = dispclk;
                        args.v5.ucPpll = ATOM_DCPLL;
                        break;
+               case 6:
+                       /* if the default dcpll clock is specified,
+                        * SetPixelClock provides the dividers
+                        */
+                       args.v6.ulDispEngClkFreq = dispclk;
+                       args.v6.ucPpll = ATOM_DCPLL;
+                       break;
                default:
                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
                        return;
@@ -784,6 +820,18 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
                        args.v5.ucEncoderMode = encoder_mode;
                        args.v5.ucPpll = pll_id;
                        break;
+               case 6:
+                       args.v6.ulCrtcPclkFreq.ucCRTC = crtc_id;
+                       args.v6.ulCrtcPclkFreq.ulPixelClock = cpu_to_le32(clock / 10);
+                       args.v6.ucRefDiv = ref_div;
+                       args.v6.usFbDiv = cpu_to_le16(fb_div);
+                       args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
+                       args.v6.ucPostDiv = post_div;
+                       args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
+                       args.v6.ucTransmitterID = encoder_id;
+                       args.v6.ucEncoderMode = encoder_mode;
+                       args.v6.ucPpll = pll_id;
+                       break;
                default:
                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
                        return;
@@ -1377,7 +1425,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
                                                                   rdev->clock.default_dispclk);
                if (ss_enabled)
                        atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss);
-               atombios_crtc_set_dcpll(crtc);
+               /* XXX: DCE5, make sure voltage, dispclk is high enough */
+               atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk);
                if (ss_enabled)
                        atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss);
        }
index eaf4fba..7fe8ebd 100644 (file)
@@ -39,6 +39,7 @@
 
 static void evergreen_gpu_init(struct radeon_device *rdev);
 void evergreen_fini(struct radeon_device *rdev);
+static void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
 
 void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)
 {
@@ -400,16 +401,28 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev,
        case 0:
        case 4:
        default:
-               return 3840 * 2;
+               if (ASIC_IS_DCE5(rdev))
+                       return 4096 * 2;
+               else
+                       return 3840 * 2;
        case 1:
        case 5:
-               return 5760 * 2;
+               if (ASIC_IS_DCE5(rdev))
+                       return 6144 * 2;
+               else
+                       return 5760 * 2;
        case 2:
        case 6:
-               return 7680 * 2;
+               if (ASIC_IS_DCE5(rdev))
+                       return 8192 * 2;
+               else
+                       return 7680 * 2;
        case 3:
        case 7:
-               return 1920 * 2;
+               if (ASIC_IS_DCE5(rdev))
+                       return 2048 * 2;
+               else
+                       return 1920 * 2;
        }
 }
 
@@ -1146,7 +1159,7 @@ static void evergreen_mc_program(struct radeon_device *rdev)
        tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
        WREG32(MC_VM_FB_LOCATION, tmp);
        WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
-       WREG32(HDP_NONSURFACE_INFO, (2 << 7));
+       WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
        WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
        if (rdev->flags & RADEON_IS_AGP) {
                WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16);
@@ -1371,11 +1384,14 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev,
        case CHIP_CEDAR:
        case CHIP_REDWOOD:
        case CHIP_PALM:
+       case CHIP_TURKS:
+       case CHIP_CAICOS:
                force_no_swizzle = false;
                break;
        case CHIP_CYPRESS:
        case CHIP_HEMLOCK:
        case CHIP_JUNIPER:
+       case CHIP_BARTS:
        default:
                force_no_swizzle = true;
                break;
@@ -1489,6 +1505,7 @@ static void evergreen_program_channel_remap(struct radeon_device *rdev)
        switch (rdev->family) {
        case CHIP_HEMLOCK:
        case CHIP_CYPRESS:
+       case CHIP_BARTS:
                tcp_chan_steer_lo = 0x54763210;
                tcp_chan_steer_hi = 0x0000ba98;
                break;
@@ -1496,6 +1513,8 @@ static void evergreen_program_channel_remap(struct radeon_device *rdev)
        case CHIP_REDWOOD:
        case CHIP_CEDAR:
        case CHIP_PALM:
+       case CHIP_TURKS:
+       case CHIP_CAICOS:
        default:
                tcp_chan_steer_lo = 0x76543210;
                tcp_chan_steer_hi = 0x0000ba98;
@@ -1635,6 +1654,69 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
                rdev->config.evergreen.max_hw_contexts = 4;
                rdev->config.evergreen.sq_num_cf_insts = 1;
 
+               rdev->config.evergreen.sc_prim_fifo_size = 0x40;
+               rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
+               rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
+               break;
+       case CHIP_BARTS:
+               rdev->config.evergreen.num_ses = 2;
+               rdev->config.evergreen.max_pipes = 4;
+               rdev->config.evergreen.max_tile_pipes = 8;
+               rdev->config.evergreen.max_simds = 7;
+               rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses;
+               rdev->config.evergreen.max_gprs = 256;
+               rdev->config.evergreen.max_threads = 248;
+               rdev->config.evergreen.max_gs_threads = 32;
+               rdev->config.evergreen.max_stack_entries = 512;
+               rdev->config.evergreen.sx_num_of_sets = 4;
+               rdev->config.evergreen.sx_max_export_size = 256;
+               rdev->config.evergreen.sx_max_export_pos_size = 64;
+               rdev->config.evergreen.sx_max_export_smx_size = 192;
+               rdev->config.evergreen.max_hw_contexts = 8;
+               rdev->config.evergreen.sq_num_cf_insts = 2;
+
+               rdev->config.evergreen.sc_prim_fifo_size = 0x100;
+               rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
+               rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
+               break;
+       case CHIP_TURKS:
+               rdev->config.evergreen.num_ses = 1;
+               rdev->config.evergreen.max_pipes = 4;
+               rdev->config.evergreen.max_tile_pipes = 4;
+               rdev->config.evergreen.max_simds = 6;
+               rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
+               rdev->config.evergreen.max_gprs = 256;
+               rdev->config.evergreen.max_threads = 248;
+               rdev->config.evergreen.max_gs_threads = 32;
+               rdev->config.evergreen.max_stack_entries = 256;
+               rdev->config.evergreen.sx_num_of_sets = 4;
+               rdev->config.evergreen.sx_max_export_size = 256;
+               rdev->config.evergreen.sx_max_export_pos_size = 64;
+               rdev->config.evergreen.sx_max_export_smx_size = 192;
+               rdev->config.evergreen.max_hw_contexts = 8;
+               rdev->config.evergreen.sq_num_cf_insts = 2;
+
+               rdev->config.evergreen.sc_prim_fifo_size = 0x100;
+               rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
+               rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
+               break;
+       case CHIP_CAICOS:
+               rdev->config.evergreen.num_ses = 1;
+               rdev->config.evergreen.max_pipes = 4;
+               rdev->config.evergreen.max_tile_pipes = 2;
+               rdev->config.evergreen.max_simds = 2;
+               rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
+               rdev->config.evergreen.max_gprs = 256;
+               rdev->config.evergreen.max_threads = 192;
+               rdev->config.evergreen.max_gs_threads = 16;
+               rdev->config.evergreen.max_stack_entries = 256;
+               rdev->config.evergreen.sx_num_of_sets = 4;
+               rdev->config.evergreen.sx_max_export_size = 128;
+               rdev->config.evergreen.sx_max_export_pos_size = 32;
+               rdev->config.evergreen.sx_max_export_smx_size = 96;
+               rdev->config.evergreen.max_hw_contexts = 4;
+               rdev->config.evergreen.sq_num_cf_insts = 1;
+
                rdev->config.evergreen.sc_prim_fifo_size = 0x40;
                rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
                rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
@@ -1780,6 +1862,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
                switch (rdev->family) {
                case CHIP_CYPRESS:
                case CHIP_HEMLOCK:
+               case CHIP_BARTS:
                        gb_backend_map = 0x66442200;
                        break;
                case CHIP_JUNIPER:
@@ -1918,6 +2001,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
        switch (rdev->family) {
        case CHIP_CEDAR:
        case CHIP_PALM:
+       case CHIP_CAICOS:
                /* no vertex cache */
                sq_config &= ~VC_ENABLE;
                break;
@@ -1977,6 +2061,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
        switch (rdev->family) {
        case CHIP_CEDAR:
        case CHIP_PALM:
+       case CHIP_CAICOS:
                vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY);
                break;
        default:
@@ -2767,12 +2852,31 @@ static int evergreen_startup(struct radeon_device *rdev)
 {
        int r;
 
-       if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
-               r = r600_init_microcode(rdev);
+       /* enable pcie gen2 link */
+       if (!ASIC_IS_DCE5(rdev))
+               evergreen_pcie_gen2_enable(rdev);
+
+       if (ASIC_IS_DCE5(rdev)) {
+               if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
+                       r = ni_init_microcode(rdev);
+                       if (r) {
+                               DRM_ERROR("Failed to load firmware!\n");
+                               return r;
+                       }
+               }
+               r = btc_mc_load_microcode(rdev);
                if (r) {
-                       DRM_ERROR("Failed to load firmware!\n");
+                       DRM_ERROR("Failed to load MC firmware!\n");
                        return r;
                }
+       } else {
+               if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+                       r = r600_init_microcode(rdev);
+                       if (r) {
+                               DRM_ERROR("Failed to load firmware!\n");
+                               return r;
+                       }
+               }
        }
 
        evergreen_mc_program(rdev);
@@ -3049,3 +3153,52 @@ void evergreen_fini(struct radeon_device *rdev)
        rdev->bios = NULL;
        radeon_dummy_page_fini(rdev);
 }
+
+static void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
+{
+       u32 link_width_cntl, speed_cntl;
+
+       if (rdev->flags & RADEON_IS_IGP)
+               return;
+
+       if (!(rdev->flags & RADEON_IS_PCIE))
+               return;
+
+       /* x2 cards have a special sequence */
+       if (ASIC_IS_X2(rdev))
+               return;
+
+       speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+       if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
+           (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+
+               link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
+               link_width_cntl &= ~LC_UPCONFIGURE_DIS;
+               WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+
+               speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+               speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+               speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+               speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+               speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+               speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+               speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+               speed_cntl |= LC_GEN2_EN_STRAP;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+       } else {
+               link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
+               /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */
+               if (1)
+                       link_width_cntl |= LC_UPCONFIGURE_DIS;
+               else
+                       link_width_cntl &= ~LC_UPCONFIGURE_DIS;
+               WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+       }
+}
index 2ccd1f0..b758dc7 100644 (file)
@@ -148,7 +148,8 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
        radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30);
 
        if ((rdev->family == CHIP_CEDAR) ||
-           (rdev->family == CHIP_PALM))
+           (rdev->family == CHIP_PALM) ||
+           (rdev->family == CHIP_CAICOS))
                cp_set_surface_sync(rdev,
                                    PACKET3_TC_ACTION_ENA, 48, gpu_addr);
        else
@@ -353,10 +354,74 @@ set_default_state(struct radeon_device *rdev)
                num_hs_stack_entries = 42;
                num_ls_stack_entries = 42;
                break;
+       case CHIP_BARTS:
+               num_ps_gprs = 93;
+               num_vs_gprs = 46;
+               num_temp_gprs = 4;
+               num_gs_gprs = 31;
+               num_es_gprs = 31;
+               num_hs_gprs = 23;
+               num_ls_gprs = 23;
+               num_ps_threads = 128;
+               num_vs_threads = 20;
+               num_gs_threads = 20;
+               num_es_threads = 20;
+               num_hs_threads = 20;
+               num_ls_threads = 20;
+               num_ps_stack_entries = 85;
+               num_vs_stack_entries = 85;
+               num_gs_stack_entries = 85;
+               num_es_stack_entries = 85;
+               num_hs_stack_entries = 85;
+               num_ls_stack_entries = 85;
+               break;
+       case CHIP_TURKS:
+               num_ps_gprs = 93;
+               num_vs_gprs = 46;
+               num_temp_gprs = 4;
+               num_gs_gprs = 31;
+               num_es_gprs = 31;
+               num_hs_gprs = 23;
+               num_ls_gprs = 23;
+               num_ps_threads = 128;
+               num_vs_threads = 20;
+               num_gs_threads = 20;
+               num_es_threads = 20;
+               num_hs_threads = 20;
+               num_ls_threads = 20;
+               num_ps_stack_entries = 42;
+               num_vs_stack_entries = 42;
+               num_gs_stack_entries = 42;
+               num_es_stack_entries = 42;
+               num_hs_stack_entries = 42;
+               num_ls_stack_entries = 42;
+               break;
+       case CHIP_CAICOS:
+               num_ps_gprs = 93;
+               num_vs_gprs = 46;
+               num_temp_gprs = 4;
+               num_gs_gprs = 31;
+               num_es_gprs = 31;
+               num_hs_gprs = 23;
+               num_ls_gprs = 23;
+               num_ps_threads = 128;
+               num_vs_threads = 10;
+               num_gs_threads = 10;
+               num_es_threads = 10;
+               num_hs_threads = 10;
+               num_ls_threads = 10;
+               num_ps_stack_entries = 42;
+               num_vs_stack_entries = 42;
+               num_gs_stack_entries = 42;
+               num_es_stack_entries = 42;
+               num_hs_stack_entries = 42;
+               num_ls_stack_entries = 42;
+               break;
        }
 
        if ((rdev->family == CHIP_CEDAR) ||
-           (rdev->family == CHIP_PALM))
+           (rdev->family == CHIP_PALM) ||
+           (rdev->family == CHIP_CAICOS))
                sq_config = 0;
        else
                sq_config = VC_ENABLE;
index 94140e1..36d32d8 100644 (file)
 #       define DC_HPDx_RX_INT_TIMER(x)                    ((x) << 16)
 #       define DC_HPDx_EN                                 (1 << 28)
 
+/* PCIE link stuff */
+#define PCIE_LC_TRAINING_CNTL                             0xa1 /* PCIE_P */
+#define PCIE_LC_LINK_WIDTH_CNTL                           0xa2 /* PCIE_P */
+#       define LC_LINK_WIDTH_SHIFT                        0
+#       define LC_LINK_WIDTH_MASK                         0x7
+#       define LC_LINK_WIDTH_X0                           0
+#       define LC_LINK_WIDTH_X1                           1
+#       define LC_LINK_WIDTH_X2                           2
+#       define LC_LINK_WIDTH_X4                           3
+#       define LC_LINK_WIDTH_X8                           4
+#       define LC_LINK_WIDTH_X16                          6
+#       define LC_LINK_WIDTH_RD_SHIFT                     4
+#       define LC_LINK_WIDTH_RD_MASK                      0x70
+#       define LC_RECONFIG_ARC_MISSING_ESCAPE             (1 << 7)
+#       define LC_RECONFIG_NOW                            (1 << 8)
+#       define LC_RENEGOTIATION_SUPPORT                   (1 << 9)
+#       define LC_RENEGOTIATE_EN                          (1 << 10)
+#       define LC_SHORT_RECONFIG_EN                       (1 << 11)
+#       define LC_UPCONFIGURE_SUPPORT                     (1 << 12)
+#       define LC_UPCONFIGURE_DIS                         (1 << 13)
+#define PCIE_LC_SPEED_CNTL                                0xa4 /* PCIE_P */
+#       define LC_GEN2_EN_STRAP                           (1 << 0)
+#       define LC_TARGET_LINK_SPEED_OVERRIDE_EN           (1 << 1)
+#       define LC_FORCE_EN_HW_SPEED_CHANGE                (1 << 5)
+#       define LC_FORCE_DIS_HW_SPEED_CHANGE               (1 << 6)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK      (0x3 << 8)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT     3
+#       define LC_CURRENT_DATA_RATE                       (1 << 11)
+#       define LC_VOLTAGE_TIMER_SEL_MASK                  (0xf << 14)
+#       define LC_CLR_FAILED_SPD_CHANGE_CNT               (1 << 21)
+#       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 23)
+#       define LC_OTHER_SIDE_SUPPORTS_GEN2                (1 << 24)
+#define MM_CFGREGS_CNTL                                   0x544c
+#       define MM_WR_TO_CFG_EN                            (1 << 3)
+#define LINK_CNTL2                                        0x88 /* F0 */
+#       define TARGET_LINK_SPEED_MASK                     (0xf << 0)
+#       define SELECTABLE_DEEMPHASIS                      (1 << 6)
+
 /*
  * PM4
  */
 #define        PACKET3_NOP                                     0x10
 #define        PACKET3_SET_BASE                                0x11
 #define        PACKET3_CLEAR_STATE                             0x12
-#define        PACKET3_INDIRECT_BUFFER_SIZE                    0x13
+#define        PACKET3_INDEX_BUFFER_SIZE                       0x13
 #define        PACKET3_DISPATCH_DIRECT                         0x15
 #define        PACKET3_DISPATCH_INDIRECT                       0x16
 #define        PACKET3_INDIRECT_BUFFER_END                     0x17
 #              define PACKET3_CB8_DEST_BASE_ENA    (1 << 15)
 #              define PACKET3_CB9_DEST_BASE_ENA    (1 << 16)
 #              define PACKET3_CB10_DEST_BASE_ENA   (1 << 17)
-#              define PACKET3_CB11_DEST_BASE_ENA   (1 << 17)
+#              define PACKET3_CB11_DEST_BASE_ENA   (1 << 18)
 #              define PACKET3_FULL_CACHE_ENA       (1 << 20)
 #              define PACKET3_TC_ACTION_ENA        (1 << 23)
 #              define PACKET3_VC_ACTION_ENA        (1 << 24)
 #              define PACKET3_CB_ACTION_ENA        (1 << 25)
 #              define PACKET3_DB_ACTION_ENA        (1 << 26)
 #              define PACKET3_SH_ACTION_ENA        (1 << 27)
-#              define PACKET3_SMX_ACTION_ENA       (1 << 28)
+#              define PACKET3_SX_ACTION_ENA        (1 << 28)
 #define        PACKET3_ME_INITIALIZE                           0x44
 #define                PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
 #define        PACKET3_COND_WRITE                              0x45
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
new file mode 100644 (file)
index 0000000..5e0bef8
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2010 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ */
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "drmP.h"
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "radeon_drm.h"
+#include "nid.h"
+#include "atom.h"
+#include "ni_reg.h"
+
+#define EVERGREEN_PFP_UCODE_SIZE 1120
+#define EVERGREEN_PM4_UCODE_SIZE 1376
+#define EVERGREEN_RLC_UCODE_SIZE 768
+#define BTC_MC_UCODE_SIZE 6024
+
+/* Firmware Names */
+MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
+MODULE_FIRMWARE("radeon/BARTS_me.bin");
+MODULE_FIRMWARE("radeon/BARTS_mc.bin");
+MODULE_FIRMWARE("radeon/BTC_rlc.bin");
+MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
+MODULE_FIRMWARE("radeon/TURKS_me.bin");
+MODULE_FIRMWARE("radeon/TURKS_mc.bin");
+MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
+MODULE_FIRMWARE("radeon/CAICOS_me.bin");
+MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
+
+#define BTC_IO_MC_REGS_SIZE 29
+
+static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
+       {0x00000077, 0xff010100},
+       {0x00000078, 0x00000000},
+       {0x00000079, 0x00001434},
+       {0x0000007a, 0xcc08ec08},
+       {0x0000007b, 0x00040000},
+       {0x0000007c, 0x000080c0},
+       {0x0000007d, 0x09000000},
+       {0x0000007e, 0x00210404},
+       {0x00000081, 0x08a8e800},
+       {0x00000082, 0x00030444},
+       {0x00000083, 0x00000000},
+       {0x00000085, 0x00000001},
+       {0x00000086, 0x00000002},
+       {0x00000087, 0x48490000},
+       {0x00000088, 0x20244647},
+       {0x00000089, 0x00000005},
+       {0x0000008b, 0x66030000},
+       {0x0000008c, 0x00006603},
+       {0x0000008d, 0x00000100},
+       {0x0000008f, 0x00001c0a},
+       {0x00000090, 0xff000001},
+       {0x00000094, 0x00101101},
+       {0x00000095, 0x00000fff},
+       {0x00000096, 0x00116fff},
+       {0x00000097, 0x60010000},
+       {0x00000098, 0x10010000},
+       {0x00000099, 0x00006000},
+       {0x0000009a, 0x00001000},
+       {0x0000009f, 0x00946a00}
+};
+
+static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
+       {0x00000077, 0xff010100},
+       {0x00000078, 0x00000000},
+       {0x00000079, 0x00001434},
+       {0x0000007a, 0xcc08ec08},
+       {0x0000007b, 0x00040000},
+       {0x0000007c, 0x000080c0},
+       {0x0000007d, 0x09000000},
+       {0x0000007e, 0x00210404},
+       {0x00000081, 0x08a8e800},
+       {0x00000082, 0x00030444},
+       {0x00000083, 0x00000000},
+       {0x00000085, 0x00000001},
+       {0x00000086, 0x00000002},
+       {0x00000087, 0x48490000},
+       {0x00000088, 0x20244647},
+       {0x00000089, 0x00000005},
+       {0x0000008b, 0x66030000},
+       {0x0000008c, 0x00006603},
+       {0x0000008d, 0x00000100},
+       {0x0000008f, 0x00001c0a},
+       {0x00000090, 0xff000001},
+       {0x00000094, 0x00101101},
+       {0x00000095, 0x00000fff},
+       {0x00000096, 0x00116fff},
+       {0x00000097, 0x60010000},
+       {0x00000098, 0x10010000},
+       {0x00000099, 0x00006000},
+       {0x0000009a, 0x00001000},
+       {0x0000009f, 0x00936a00}
+};
+
+static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
+       {0x00000077, 0xff010100},
+       {0x00000078, 0x00000000},
+       {0x00000079, 0x00001434},
+       {0x0000007a, 0xcc08ec08},
+       {0x0000007b, 0x00040000},
+       {0x0000007c, 0x000080c0},
+       {0x0000007d, 0x09000000},
+       {0x0000007e, 0x00210404},
+       {0x00000081, 0x08a8e800},
+       {0x00000082, 0x00030444},
+       {0x00000083, 0x00000000},
+       {0x00000085, 0x00000001},
+       {0x00000086, 0x00000002},
+       {0x00000087, 0x48490000},
+       {0x00000088, 0x20244647},
+       {0x00000089, 0x00000005},
+       {0x0000008b, 0x66030000},
+       {0x0000008c, 0x00006603},
+       {0x0000008d, 0x00000100},
+       {0x0000008f, 0x00001c0a},
+       {0x00000090, 0xff000001},
+       {0x00000094, 0x00101101},
+       {0x00000095, 0x00000fff},
+       {0x00000096, 0x00116fff},
+       {0x00000097, 0x60010000},
+       {0x00000098, 0x10010000},
+       {0x00000099, 0x00006000},
+       {0x0000009a, 0x00001000},
+       {0x0000009f, 0x00916a00}
+};
+
+int btc_mc_load_microcode(struct radeon_device *rdev)
+{
+       const __be32 *fw_data;
+       u32 mem_type, running, blackout = 0;
+       u32 *io_mc_regs;
+       int i;
+
+       if (!rdev->mc_fw)
+               return -EINVAL;
+
+       switch (rdev->family) {
+       case CHIP_BARTS:
+               io_mc_regs = (u32 *)&barts_io_mc_regs;
+               break;
+       case CHIP_TURKS:
+               io_mc_regs = (u32 *)&turks_io_mc_regs;
+               break;
+       case CHIP_CAICOS:
+       default:
+               io_mc_regs = (u32 *)&caicos_io_mc_regs;
+               break;
+       }
+
+       mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
+       running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
+
+       if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
+               if (running) {
+                       blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
+                       WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
+               }
+
+               /* reset the engine and set to writable */
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
+
+               /* load mc io regs */
+               for (i = 0; i < BTC_IO_MC_REGS_SIZE; i++) {
+                       WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
+                       WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
+               }
+               /* load the MC ucode */
+               fw_data = (const __be32 *)rdev->mc_fw->data;
+               for (i = 0; i < BTC_MC_UCODE_SIZE; i++)
+                       WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+
+               /* put the engine back into the active state */
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
+
+               /* wait for training to complete */
+               while (!(RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD))
+                       udelay(10);
+
+               if (running)
+                       WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
+       }
+
+       return 0;
+}
+
+int ni_init_microcode(struct radeon_device *rdev)
+{
+       struct platform_device *pdev;
+       const char *chip_name;
+       const char *rlc_chip_name;
+       size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
+       char fw_name[30];
+       int err;
+
+       DRM_DEBUG("\n");
+
+       pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
+       err = IS_ERR(pdev);
+       if (err) {
+               printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
+               return -EINVAL;
+       }
+
+       switch (rdev->family) {
+       case CHIP_BARTS:
+               chip_name = "BARTS";
+               rlc_chip_name = "BTC";
+               break;
+       case CHIP_TURKS:
+               chip_name = "TURKS";
+               rlc_chip_name = "BTC";
+               break;
+       case CHIP_CAICOS:
+               chip_name = "CAICOS";
+               rlc_chip_name = "BTC";
+               break;
+       default: BUG();
+       }
+
+       pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
+       me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
+       rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
+       mc_req_size = BTC_MC_UCODE_SIZE * 4;
+
+       DRM_INFO("Loading %s Microcode\n", chip_name);
+
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
+       err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
+       if (err)
+               goto out;
+       if (rdev->pfp_fw->size != pfp_req_size) {
+               printk(KERN_ERR
+                      "ni_cp: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->pfp_fw->size, fw_name);
+               err = -EINVAL;
+               goto out;
+       }
+
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
+       err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
+       if (err)
+               goto out;
+       if (rdev->me_fw->size != me_req_size) {
+               printk(KERN_ERR
+                      "ni_cp: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->me_fw->size, fw_name);
+               err = -EINVAL;
+       }
+
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
+       err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
+       if (err)
+               goto out;
+       if (rdev->rlc_fw->size != rlc_req_size) {
+               printk(KERN_ERR
+                      "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->rlc_fw->size, fw_name);
+               err = -EINVAL;
+       }
+
+       snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+       err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
+       if (err)
+               goto out;
+       if (rdev->mc_fw->size != mc_req_size) {
+               printk(KERN_ERR
+                      "ni_mc: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->mc_fw->size, fw_name);
+               err = -EINVAL;
+       }
+out:
+       platform_device_unregister(pdev);
+
+       if (err) {
+               if (err != -EINVAL)
+                       printk(KERN_ERR
+                              "ni_cp: Failed to load firmware \"%s\"\n",
+                              fw_name);
+               release_firmware(rdev->pfp_fw);
+               rdev->pfp_fw = NULL;
+               release_firmware(rdev->me_fw);
+               rdev->me_fw = NULL;
+               release_firmware(rdev->rlc_fw);
+               rdev->rlc_fw = NULL;
+               release_firmware(rdev->mc_fw);
+               rdev->mc_fw = NULL;
+       }
+       return err;
+}
+
diff --git a/drivers/gpu/drm/radeon/ni_reg.h b/drivers/gpu/drm/radeon/ni_reg.h
new file mode 100644 (file)
index 0000000..5db7b7d
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ */
+#ifndef __NI_REG_H__
+#define __NI_REG_H__
+
+/* northern islands - DCE5 */
+
+#define NI_INPUT_GAMMA_CONTROL                         0x6840
+#       define NI_GRPH_INPUT_GAMMA_MODE(x)             (((x) & 0x3) << 0)
+#       define NI_INPUT_GAMMA_USE_LUT                  0
+#       define NI_INPUT_GAMMA_BYPASS                   1
+#       define NI_INPUT_GAMMA_SRGB_24                  2
+#       define NI_INPUT_GAMMA_XVYCC_222                3
+#       define NI_OVL_INPUT_GAMMA_MODE(x)              (((x) & 0x3) << 4)
+
+#define NI_PRESCALE_GRPH_CONTROL                       0x68b4
+#       define NI_GRPH_PRESCALE_BYPASS                 (1 << 4)
+
+#define NI_PRESCALE_OVL_CONTROL                        0x68c4
+#       define NI_OVL_PRESCALE_BYPASS                  (1 << 4)
+
+#define NI_INPUT_CSC_CONTROL                           0x68d4
+#       define NI_INPUT_CSC_GRPH_MODE(x)               (((x) & 0x3) << 0)
+#       define NI_INPUT_CSC_BYPASS                     0
+#       define NI_INPUT_CSC_PROG_COEFF                 1
+#       define NI_INPUT_CSC_PROG_SHARED_MATRIXA        2
+#       define NI_INPUT_CSC_OVL_MODE(x)                (((x) & 0x3) << 4)
+
+#define NI_OUTPUT_CSC_CONTROL                          0x68f0
+#       define NI_OUTPUT_CSC_GRPH_MODE(x)              (((x) & 0x7) << 0)
+#       define NI_OUTPUT_CSC_BYPASS                    0
+#       define NI_OUTPUT_CSC_TV_RGB                    1
+#       define NI_OUTPUT_CSC_YCBCR_601                 2
+#       define NI_OUTPUT_CSC_YCBCR_709                 3
+#       define NI_OUTPUT_CSC_PROG_COEFF                4
+#       define NI_OUTPUT_CSC_PROG_SHARED_MATRIXB       5
+#       define NI_OUTPUT_CSC_OVL_MODE(x)               (((x) & 0x7) << 4)
+
+#define NI_DEGAMMA_CONTROL                             0x6960
+#       define NI_GRPH_DEGAMMA_MODE(x)                 (((x) & 0x3) << 0)
+#       define NI_DEGAMMA_BYPASS                       0
+#       define NI_DEGAMMA_SRGB_24                      1
+#       define NI_DEGAMMA_XVYCC_222                    2
+#       define NI_OVL_DEGAMMA_MODE(x)                  (((x) & 0x3) << 4)
+#       define NI_ICON_DEGAMMA_MODE(x)                 (((x) & 0x3) << 8)
+#       define NI_CURSOR_DEGAMMA_MODE(x)               (((x) & 0x3) << 12)
+
+#define NI_GAMUT_REMAP_CONTROL                         0x6964
+#       define NI_GRPH_GAMUT_REMAP_MODE(x)             (((x) & 0x3) << 0)
+#       define NI_GAMUT_REMAP_BYPASS                   0
+#       define NI_GAMUT_REMAP_PROG_COEFF               1
+#       define NI_GAMUT_REMAP_PROG_SHARED_MATRIXA      2
+#       define NI_GAMUT_REMAP_PROG_SHARED_MATRIXB      3
+#       define NI_OVL_GAMUT_REMAP_MODE(x)              (((x) & 0x3) << 4)
+
+#define NI_REGAMMA_CONTROL                             0x6a80
+#       define NI_GRPH_REGAMMA_MODE(x)                 (((x) & 0x7) << 0)
+#       define NI_REGAMMA_BYPASS                       0
+#       define NI_REGAMMA_SRGB_24                      1
+#       define NI_REGAMMA_XVYCC_222                    2
+#       define NI_REGAMMA_PROG_A                       3
+#       define NI_REGAMMA_PROG_B                       4
+#       define NI_OVL_REGAMMA_MODE(x)                  (((x) & 0x7) << 4)
+
+#endif
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
new file mode 100644 (file)
index 0000000..f7b4453
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ */
+#ifndef NI_H
+#define NI_H
+
+#define MC_SHARED_BLACKOUT_CNTL                        0x20ac
+#define MC_SEQ_SUP_CNTL                                0x28c8
+#define                RUN_MASK                                (1 << 0)
+#define MC_SEQ_SUP_PGM                                 0x28cc
+#define MC_IO_PAD_CNTL_D0                              0x29d0
+#define                MEM_FALL_OUT_CMD                        (1 << 8)
+#define MC_SEQ_MISC0                                           0x2a00
+#define                MC_SEQ_MISC0_GDDR5_SHIFT                28
+#define                MC_SEQ_MISC0_GDDR5_MASK                 0xf0000000
+#define                MC_SEQ_MISC0_GDDR5_VALUE                5
+#define MC_SEQ_IO_DEBUG_INDEX                          0x2a44
+#define MC_SEQ_IO_DEBUG_DATA                                   0x2a48
+
+#endif
+
index 23fee54..fae5e70 100644 (file)
@@ -558,10 +558,7 @@ int rv370_get_pcie_lanes(struct radeon_device *rdev)
 
        /* FIXME wait for idle */
 
-       if (rdev->family < CHIP_R600)
-               link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
-       else
-               link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
+       link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
 
        switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) {
        case RADEON_PCIE_LC_LINK_WIDTH_X0:
index 279794c..6b50716 100644 (file)
@@ -94,6 +94,7 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev);
 void r600_gpu_init(struct radeon_device *rdev);
 void r600_fini(struct radeon_device *rdev);
 void r600_irq_disable(struct radeon_device *rdev);
+static void r600_pcie_gen2_enable(struct radeon_device *rdev);
 
 /* get temperature in millidegrees */
 u32 rv6xx_get_temp(struct radeon_device *rdev)
@@ -2379,6 +2380,9 @@ int r600_startup(struct radeon_device *rdev)
 {
        int r;
 
+       /* enable pcie gen2 link */
+       r600_pcie_gen2_enable(rdev);
+
        if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
                r = r600_init_microcode(rdev);
                if (r) {
@@ -3531,3 +3535,219 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
        } else
                WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
 }
+
+void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes)
+{
+       u32 link_width_cntl, mask, target_reg;
+
+       if (rdev->flags & RADEON_IS_IGP)
+               return;
+
+       if (!(rdev->flags & RADEON_IS_PCIE))
+               return;
+
+       /* x2 cards have a special sequence */
+       if (ASIC_IS_X2(rdev))
+               return;
+
+       /* FIXME wait for idle */
+
+       switch (lanes) {
+       case 0:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X0;
+               break;
+       case 1:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X1;
+               break;
+       case 2:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X2;
+               break;
+       case 4:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X4;
+               break;
+       case 8:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X8;
+               break;
+       case 12:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X12;
+               break;
+       case 16:
+       default:
+               mask = RADEON_PCIE_LC_LINK_WIDTH_X16;
+               break;
+       }
+
+       link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
+
+       if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) ==
+           (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT))
+               return;
+
+       if (link_width_cntl & R600_PCIE_LC_UPCONFIGURE_DIS)
+               return;
+
+       link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK |
+                            RADEON_PCIE_LC_RECONFIG_NOW |
+                            R600_PCIE_LC_RENEGOTIATE_EN |
+                            R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE);
+       link_width_cntl |= mask;
+
+       WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+
+        /* some northbridges can renegotiate the link rather than requiring                                  
+         * a complete re-config.                                                                             
+         * e.g., AMD 780/790 northbridges (pci ids: 0x5956, 0x5957, 0x5958, etc.)                            
+         */
+        if (link_width_cntl & R600_PCIE_LC_RENEGOTIATION_SUPPORT)
+               link_width_cntl |= R600_PCIE_LC_RENEGOTIATE_EN | R600_PCIE_LC_UPCONFIGURE_SUPPORT;
+        else
+               link_width_cntl |= R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE;
+
+       WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, (link_width_cntl |
+                                                      RADEON_PCIE_LC_RECONFIG_NOW));
+
+        if (rdev->family >= CHIP_RV770)
+               target_reg = R700_TARGET_AND_CURRENT_PROFILE_INDEX;
+        else
+               target_reg = R600_TARGET_AND_CURRENT_PROFILE_INDEX;
+
+        /* wait for lane set to complete */
+        link_width_cntl = RREG32(target_reg);
+        while (link_width_cntl == 0xffffffff)
+               link_width_cntl = RREG32(target_reg);
+
+}
+
+int r600_get_pcie_lanes(struct radeon_device *rdev)
+{
+       u32 link_width_cntl;
+
+       if (rdev->flags & RADEON_IS_IGP)
+               return 0;
+
+       if (!(rdev->flags & RADEON_IS_PCIE))
+               return 0;
+
+       /* x2 cards have a special sequence */
+       if (ASIC_IS_X2(rdev))
+               return 0;
+
+       /* FIXME wait for idle */
+
+       link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
+
+       switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) {
+       case RADEON_PCIE_LC_LINK_WIDTH_X0:
+               return 0;
+       case RADEON_PCIE_LC_LINK_WIDTH_X1:
+               return 1;
+       case RADEON_PCIE_LC_LINK_WIDTH_X2:
+               return 2;
+       case RADEON_PCIE_LC_LINK_WIDTH_X4:
+               return 4;
+       case RADEON_PCIE_LC_LINK_WIDTH_X8:
+               return 8;
+       case RADEON_PCIE_LC_LINK_WIDTH_X16:
+       default:
+               return 16;
+       }
+}
+
+static void r600_pcie_gen2_enable(struct radeon_device *rdev)
+{
+       u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp;
+       u16 link_cntl2;
+
+       if (rdev->flags & RADEON_IS_IGP)
+               return;
+
+       if (!(rdev->flags & RADEON_IS_PCIE))
+               return;
+
+       /* x2 cards have a special sequence */
+       if (ASIC_IS_X2(rdev))
+               return;
+
+       /* only RV6xx+ chips are supported */
+       if (rdev->family <= CHIP_R600)
+               return;
+
+       /* 55 nm r6xx asics */
+       if ((rdev->family == CHIP_RV670) ||
+           (rdev->family == CHIP_RV620) ||
+           (rdev->family == CHIP_RV635)) {
+               /* advertise upconfig capability */
+               link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
+               link_width_cntl &= ~LC_UPCONFIGURE_DIS;
+               WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+               link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
+               if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) {
+                       lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT;
+                       link_width_cntl &= ~(LC_LINK_WIDTH_MASK |
+                                            LC_RECONFIG_ARC_MISSING_ESCAPE);
+                       link_width_cntl |= lanes | LC_RECONFIG_NOW | LC_RENEGOTIATE_EN;
+                       WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+               } else {
+                       link_width_cntl |= LC_UPCONFIGURE_DIS;
+                       WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+               }
+       }
+
+       speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+       if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+           (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+
+               /* 55 nm r6xx asics */
+               if ((rdev->family == CHIP_RV670) ||
+                   (rdev->family == CHIP_RV620) ||
+                   (rdev->family == CHIP_RV635)) {
+                       WREG32(MM_CFGREGS_CNTL, 0x8);
+                       link_cntl2 = RREG32(0x4088);
+                       WREG32(MM_CFGREGS_CNTL, 0);
+                       /* not supported yet */
+                       if (link_cntl2 & SELECTABLE_DEEMPHASIS)
+                               return;
+               }
+
+               speed_cntl &= ~LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK;
+               speed_cntl |= (0x3 << LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT);
+               speed_cntl &= ~LC_VOLTAGE_TIMER_SEL_MASK;
+               speed_cntl &= ~LC_FORCE_DIS_HW_SPEED_CHANGE;
+               speed_cntl |= LC_FORCE_EN_HW_SPEED_CHANGE;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+               tmp = RREG32(0x541c);
+               WREG32(0x541c, tmp | 0x8);
+               WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN);
+               link_cntl2 = RREG16(0x4088);
+               link_cntl2 &= ~TARGET_LINK_SPEED_MASK;
+               link_cntl2 |= 0x2;
+               WREG16(0x4088, link_cntl2);
+               WREG32(MM_CFGREGS_CNTL, 0);
+
+               if ((rdev->family == CHIP_RV670) ||
+                   (rdev->family == CHIP_RV620) ||
+                   (rdev->family == CHIP_RV635)) {
+                       training_cntl = RREG32_PCIE_P(PCIE_LC_TRAINING_CNTL);
+                       training_cntl &= ~LC_POINT_7_PLUS_EN;
+                       WREG32_PCIE_P(PCIE_LC_TRAINING_CNTL, training_cntl);
+               } else {
+                       speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+                       speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
+                       WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+               }
+
+               speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+               speed_cntl |= LC_GEN2_EN_STRAP;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+       } else {
+               link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
+               /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */
+               if (1)
+                       link_width_cntl |= LC_UPCONFIGURE_DIS;
+               else
+                       link_width_cntl &= ~LC_UPCONFIGURE_DIS;
+               WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+       }
+}
index c89cfa8..a5d898b 100644 (file)
 #       define DxGRPH_PFLIP_INT_MASK                      (1 << 0)
 #       define DxGRPH_PFLIP_INT_TYPE                      (1 << 8)
 
+/* PCIE link stuff */
+#define PCIE_LC_TRAINING_CNTL                             0xa1 /* PCIE_P */
+#       define LC_POINT_7_PLUS_EN                         (1 << 6)
+#define PCIE_LC_LINK_WIDTH_CNTL                           0xa2 /* PCIE_P */
+#       define LC_LINK_WIDTH_SHIFT                        0
+#       define LC_LINK_WIDTH_MASK                         0x7
+#       define LC_LINK_WIDTH_X0                           0
+#       define LC_LINK_WIDTH_X1                           1
+#       define LC_LINK_WIDTH_X2                           2
+#       define LC_LINK_WIDTH_X4                           3
+#       define LC_LINK_WIDTH_X8                           4
+#       define LC_LINK_WIDTH_X16                          6
+#       define LC_LINK_WIDTH_RD_SHIFT                     4
+#       define LC_LINK_WIDTH_RD_MASK                      0x70
+#       define LC_RECONFIG_ARC_MISSING_ESCAPE             (1 << 7)
+#       define LC_RECONFIG_NOW                            (1 << 8)
+#       define LC_RENEGOTIATION_SUPPORT                   (1 << 9)
+#       define LC_RENEGOTIATE_EN                          (1 << 10)
+#       define LC_SHORT_RECONFIG_EN                       (1 << 11)
+#       define LC_UPCONFIGURE_SUPPORT                     (1 << 12)
+#       define LC_UPCONFIGURE_DIS                         (1 << 13)
+#define PCIE_LC_SPEED_CNTL                                0xa4 /* PCIE_P */
+#       define LC_GEN2_EN_STRAP                           (1 << 0)
+#       define LC_TARGET_LINK_SPEED_OVERRIDE_EN           (1 << 1)
+#       define LC_FORCE_EN_HW_SPEED_CHANGE                (1 << 5)
+#       define LC_FORCE_DIS_HW_SPEED_CHANGE               (1 << 6)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK      (0x3 << 8)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT     3
+#       define LC_CURRENT_DATA_RATE                       (1 << 11)
+#       define LC_VOLTAGE_TIMER_SEL_MASK                  (0xf << 14)
+#       define LC_CLR_FAILED_SPD_CHANGE_CNT               (1 << 21)
+#       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 23)
+#       define LC_OTHER_SIDE_SUPPORTS_GEN2                (1 << 24)
+#define MM_CFGREGS_CNTL                                   0x544c
+#       define MM_WR_TO_CFG_EN                            (1 << 3)
+#define LINK_CNTL2                                        0x88 /* F0 */
+#       define TARGET_LINK_SPEED_MASK                     (0xf << 0)
+#       define SELECTABLE_DEEMPHASIS                      (1 << 6)
+
 /*
  * PM4
  */
index aff8080..e948663 100644 (file)
@@ -739,6 +739,7 @@ enum radeon_int_thermal_type {
        THERMAL_TYPE_RV770,
        THERMAL_TYPE_EVERGREEN,
        THERMAL_TYPE_SUMO,
+       THERMAL_TYPE_NI,
 };
 
 struct radeon_voltage {
@@ -822,6 +823,9 @@ struct radeon_pm {
        u32                     current_sclk;
        u32                     current_mclk;
        u32                     current_vddc;
+       u32                     default_sclk;
+       u32                     default_mclk;
+       u32                     default_vddc;
        struct radeon_i2c_chan *i2c_bus;
        /* selected pm method */
        enum radeon_pm_method     pm_method;
@@ -1148,6 +1152,7 @@ struct radeon_device {
        const struct firmware *me_fw;   /* all family ME firmware */
        const struct firmware *pfp_fw;  /* r6/700 PFP firmware */
        const struct firmware *rlc_fw;  /* r6/700 RLC firmware */
+       const struct firmware *mc_fw;   /* NI MC firmware */
        struct r600_blit r600_blit;
        struct r700_vram_scratch vram_scratch;
        int msi_enabled; /* msi enabled */
@@ -1244,6 +1249,8 @@ static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v)
  */
 #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg))
 #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg))
+#define RREG16(reg) readw(((void __iomem *)rdev->rmmio) + (reg))
+#define WREG16(reg, v) writew(v, ((void __iomem *)rdev->rmmio) + (reg))
 #define RREG32(reg) r100_mm_rreg(rdev, (reg))
 #define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg)))
 #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v))
@@ -1317,6 +1324,14 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
                (rdev->family == CHIP_RV410) ||                 \
                (rdev->family == CHIP_RS400) ||                 \
                (rdev->family == CHIP_RS480))
+#define ASIC_IS_X2(rdev) ((rdev->ddev->pdev->device == 0x9441) || \
+               (rdev->ddev->pdev->device == 0x9443) || \
+               (rdev->ddev->pdev->device == 0x944B) || \
+               (rdev->ddev->pdev->device == 0x9506) || \
+               (rdev->ddev->pdev->device == 0x9509) || \
+               (rdev->ddev->pdev->device == 0x950F) || \
+               (rdev->ddev->pdev->device == 0x689C) || \
+               (rdev->ddev->pdev->device == 0x689D))
 #define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600))
 #define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600)  ||   \
                            (rdev->family == CHIP_RS690)  ||    \
@@ -1325,7 +1340,9 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
 #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620))
 #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730))
 #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR))
-#define ASIC_IS_DCE41(rdev) ((rdev->family >= CHIP_PALM))
+#define ASIC_IS_DCE41(rdev) ((rdev->family >= CHIP_PALM) && \
+                            (rdev->flags & RADEON_IS_IGP))
+#define ASIC_IS_DCE5(rdev) ((rdev->family >= CHIP_BARTS))
 
 /*
  * BIOS helpers.
@@ -1432,65 +1449,6 @@ extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc
 extern int radeon_resume_kms(struct drm_device *dev);
 extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
 
-/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
-extern void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp);
-extern bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_cp *cp);
-
-/* rv200,rv250,rv280 */
-extern void r200_set_safe_registers(struct radeon_device *rdev);
-
-/* r300,r350,rv350,rv370,rv380 */
-extern void r300_set_reg_safe(struct radeon_device *rdev);
-extern void r300_mc_program(struct radeon_device *rdev);
-extern void r300_mc_init(struct radeon_device *rdev);
-extern void r300_clock_startup(struct radeon_device *rdev);
-extern int r300_mc_wait_for_idle(struct radeon_device *rdev);
-extern int rv370_pcie_gart_init(struct radeon_device *rdev);
-extern void rv370_pcie_gart_fini(struct radeon_device *rdev);
-extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
-extern void rv370_pcie_gart_disable(struct radeon_device *rdev);
-
-/* r420,r423,rv410 */
-extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg);
-extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v);
-extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev);
-extern void r420_pipes_init(struct radeon_device *rdev);
-
-/* rv515 */
-struct rv515_mc_save {
-       u32 d1vga_control;
-       u32 d2vga_control;
-       u32 vga_render_control;
-       u32 vga_hdp_control;
-       u32 d1crtc_control;
-       u32 d2crtc_control;
-};
-extern void rv515_bandwidth_avivo_update(struct radeon_device *rdev);
-extern void rv515_vga_render_disable(struct radeon_device *rdev);
-extern void rv515_set_safe_registers(struct radeon_device *rdev);
-extern void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save);
-extern void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save);
-extern void rv515_clock_startup(struct radeon_device *rdev);
-extern void rv515_debugfs(struct radeon_device *rdev);
-extern int rv515_suspend(struct radeon_device *rdev);
-
-/* rs400 */
-extern int rs400_gart_init(struct radeon_device *rdev);
-extern int rs400_gart_enable(struct radeon_device *rdev);
-extern void rs400_gart_adjust_size(struct radeon_device *rdev);
-extern void rs400_gart_disable(struct radeon_device *rdev);
-extern void rs400_gart_fini(struct radeon_device *rdev);
-
-/* rs600 */
-extern void rs600_set_safe_registers(struct radeon_device *rdev);
-extern int rs600_irq_set(struct radeon_device *rdev);
-extern void rs600_irq_disable(struct radeon_device *rdev);
-
-/* rs690, rs740 */
-extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
-                                       struct drm_display_mode *mode1,
-                                       struct drm_display_mode *mode2);
-
 /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */
 extern bool r600_card_posted(struct radeon_device *rdev);
 extern void r600_cp_stop(struct radeon_device *rdev);
@@ -1545,6 +1503,9 @@ extern int evergreen_irq_set(struct radeon_device *rdev);
 extern int evergreen_blit_init(struct radeon_device *rdev);
 extern void evergreen_blit_fini(struct radeon_device *rdev);
 
+extern int ni_init_microcode(struct radeon_device *rdev);
+extern int btc_mc_load_microcode(struct radeon_device *rdev);
+
 /* radeon_acpi.c */ 
 #if defined(CONFIG_ACPI) 
 extern int radeon_acpi_init(struct radeon_device *rdev); 
index 3d73fe4..3a1b161 100644 (file)
@@ -94,7 +94,7 @@ static void radeon_register_accessor_init(struct radeon_device *rdev)
                rdev->mc_rreg = &rs600_mc_rreg;
                rdev->mc_wreg = &rs600_mc_wreg;
        }
-       if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) {
+       if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_HEMLOCK)) {
                rdev->pciep_rreg = &r600_pciep_rreg;
                rdev->pciep_wreg = &r600_pciep_wreg;
        }
@@ -631,8 +631,8 @@ static struct radeon_asic r600_asic = {
        .set_engine_clock = &radeon_atom_set_engine_clock,
        .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
-       .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = NULL,
+       .get_pcie_lanes = &r600_get_pcie_lanes,
+       .set_pcie_lanes = &r600_set_pcie_lanes,
        .set_clock_gating = NULL,
        .set_surface_reg = r600_set_surface_reg,
        .clear_surface_reg = r600_clear_surface_reg,
@@ -725,8 +725,8 @@ static struct radeon_asic rv770_asic = {
        .set_engine_clock = &radeon_atom_set_engine_clock,
        .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
-       .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = NULL,
+       .get_pcie_lanes = &r600_get_pcie_lanes,
+       .set_pcie_lanes = &r600_set_pcie_lanes,
        .set_clock_gating = &radeon_atom_set_clock_gating,
        .set_surface_reg = r600_set_surface_reg,
        .clear_surface_reg = r600_clear_surface_reg,
@@ -772,8 +772,8 @@ static struct radeon_asic evergreen_asic = {
        .set_engine_clock = &radeon_atom_set_engine_clock,
        .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
-       .get_pcie_lanes = NULL,
-       .set_pcie_lanes = NULL,
+       .get_pcie_lanes = &r600_get_pcie_lanes,
+       .set_pcie_lanes = &r600_set_pcie_lanes,
        .set_clock_gating = NULL,
        .set_surface_reg = r600_set_surface_reg,
        .clear_surface_reg = r600_clear_surface_reg,
@@ -836,6 +836,52 @@ static struct radeon_asic sumo_asic = {
        .pm_get_dynpm_state = &r600_pm_get_dynpm_state,
 };
 
+static struct radeon_asic btc_asic = {
+       .init = &evergreen_init,
+       .fini = &evergreen_fini,
+       .suspend = &evergreen_suspend,
+       .resume = &evergreen_resume,
+       .cp_commit = &r600_cp_commit,
+       .gpu_is_lockup = &evergreen_gpu_is_lockup,
+       .asic_reset = &evergreen_asic_reset,
+       .vga_set_state = &r600_vga_set_state,
+       .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush,
+       .gart_set_page = &rs600_gart_set_page,
+       .ring_test = &r600_ring_test,
+       .ring_ib_execute = &r600_ring_ib_execute,
+       .irq_set = &evergreen_irq_set,
+       .irq_process = &evergreen_irq_process,
+       .get_vblank_counter = &evergreen_get_vblank_counter,
+       .fence_ring_emit = &r600_fence_ring_emit,
+       .cs_parse = &evergreen_cs_parse,
+       .copy_blit = &evergreen_copy_blit,
+       .copy_dma = &evergreen_copy_blit,
+       .copy = &evergreen_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
+       .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
+       .set_memory_clock = &radeon_atom_set_memory_clock,
+       .get_pcie_lanes = NULL,
+       .set_pcie_lanes = NULL,
+       .set_clock_gating = NULL,
+       .set_surface_reg = r600_set_surface_reg,
+       .clear_surface_reg = r600_clear_surface_reg,
+       .bandwidth_update = &evergreen_bandwidth_update,
+       .hpd_init = &evergreen_hpd_init,
+       .hpd_fini = &evergreen_hpd_fini,
+       .hpd_sense = &evergreen_hpd_sense,
+       .hpd_set_polarity = &evergreen_hpd_set_polarity,
+       .gui_idle = &r600_gui_idle,
+       .pm_misc = &evergreen_pm_misc,
+       .pm_prepare = &evergreen_pm_prepare,
+       .pm_finish = &evergreen_pm_finish,
+       .pm_init_profile = &r600_pm_init_profile,
+       .pm_get_dynpm_state = &r600_pm_get_dynpm_state,
+       .pre_page_flip = &evergreen_pre_page_flip,
+       .page_flip = &evergreen_page_flip,
+       .post_page_flip = &evergreen_post_page_flip,
+};
+
 int radeon_asic_init(struct radeon_device *rdev)
 {
        radeon_register_accessor_init(rdev);
@@ -923,6 +969,11 @@ int radeon_asic_init(struct radeon_device *rdev)
        case CHIP_PALM:
                rdev->asic = &sumo_asic;
                break;
+       case CHIP_BARTS:
+       case CHIP_TURKS:
+       case CHIP_CAICOS:
+               rdev->asic = &btc_asic;
+               break;
        default:
                /* FIXME: not supported yet */
                return -EINVAL;
index 4970eda..e01f077 100644 (file)
@@ -102,6 +102,11 @@ int r100_pci_gart_enable(struct radeon_device *rdev);
 void r100_pci_gart_disable(struct radeon_device *rdev);
 int r100_debugfs_mc_info_init(struct radeon_device *rdev);
 int r100_gui_wait_for_idle(struct radeon_device *rdev);
+void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup,
+                           struct radeon_cp *cp);
+bool r100_gpu_cp_is_lockup(struct radeon_device *rdev,
+                          struct r100_gpu_lockup *lockup,
+                          struct radeon_cp *cp);
 void r100_ib_fini(struct radeon_device *rdev);
 int r100_ib_init(struct radeon_device *rdev);
 void r100_irq_disable(struct radeon_device *rdev);
@@ -138,10 +143,11 @@ extern void r100_post_page_flip(struct radeon_device *rdev, int crtc);
  * r200,rv250,rs300,rv280
  */
 extern int r200_copy_dma(struct radeon_device *rdev,
-                       uint64_t src_offset,
-                       uint64_t dst_offset,
-                       unsigned num_pages,
+                        uint64_t src_offset,
+                        uint64_t dst_offset,
+                        unsigned num_pages,
                         struct radeon_fence *fence);
+void r200_set_safe_registers(struct radeon_device *rdev);
 
 /*
  * r300,r350,rv350,rv380
@@ -162,6 +168,15 @@ extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
 extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
 extern int rv370_get_pcie_lanes(struct radeon_device *rdev);
+extern void r300_set_reg_safe(struct radeon_device *rdev);
+extern void r300_mc_program(struct radeon_device *rdev);
+extern void r300_mc_init(struct radeon_device *rdev);
+extern void r300_clock_startup(struct radeon_device *rdev);
+extern int r300_mc_wait_for_idle(struct radeon_device *rdev);
+extern int rv370_pcie_gart_init(struct radeon_device *rdev);
+extern void rv370_pcie_gart_fini(struct radeon_device *rdev);
+extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
+extern void rv370_pcie_gart_disable(struct radeon_device *rdev);
 
 /*
  * r420,r423,rv410
@@ -171,6 +186,10 @@ extern void r420_fini(struct radeon_device *rdev);
 extern int r420_suspend(struct radeon_device *rdev);
 extern int r420_resume(struct radeon_device *rdev);
 extern void r420_pm_init_profile(struct radeon_device *rdev);
+extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg);
+extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v);
+extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev);
+extern void r420_pipes_init(struct radeon_device *rdev);
 
 /*
  * rs400,rs480
@@ -183,6 +202,12 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev);
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
 uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
+int rs400_gart_init(struct radeon_device *rdev);
+int rs400_gart_enable(struct radeon_device *rdev);
+void rs400_gart_adjust_size(struct radeon_device *rdev);
+void rs400_gart_disable(struct radeon_device *rdev);
+void rs400_gart_fini(struct radeon_device *rdev);
+
 
 /*
  * rs600.
@@ -194,6 +219,7 @@ extern int rs600_suspend(struct radeon_device *rdev);
 extern int rs600_resume(struct radeon_device *rdev);
 int rs600_irq_set(struct radeon_device *rdev);
 int rs600_irq_process(struct radeon_device *rdev);
+void rs600_irq_disable(struct radeon_device *rdev);
 u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
 void rs600_gart_tlb_flush(struct radeon_device *rdev);
 int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
@@ -211,6 +237,8 @@ extern void rs600_pm_finish(struct radeon_device *rdev);
 extern void rs600_pre_page_flip(struct radeon_device *rdev, int crtc);
 extern u32 rs600_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
 extern void rs600_post_page_flip(struct radeon_device *rdev, int crtc);
+void rs600_set_safe_registers(struct radeon_device *rdev);
+
 
 /*
  * rs690,rs740
@@ -222,10 +250,21 @@ int rs690_suspend(struct radeon_device *rdev);
 uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rs690_bandwidth_update(struct radeon_device *rdev);
+void rs690_line_buffer_adjust(struct radeon_device *rdev,
+                                       struct drm_display_mode *mode1,
+                                       struct drm_display_mode *mode2);
 
 /*
  * rv515
  */
+struct rv515_mc_save {
+       u32 d1vga_control;
+       u32 d2vga_control;
+       u32 vga_render_control;
+       u32 vga_hdp_control;
+       u32 d1crtc_control;
+       u32 d2crtc_control;
+};
 int rv515_init(struct radeon_device *rdev);
 void rv515_fini(struct radeon_device *rdev);
 uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg);
@@ -236,6 +275,14 @@ void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rv515_bandwidth_update(struct radeon_device *rdev);
 int rv515_resume(struct radeon_device *rdev);
 int rv515_suspend(struct radeon_device *rdev);
+void rv515_bandwidth_avivo_update(struct radeon_device *rdev);
+void rv515_vga_render_disable(struct radeon_device *rdev);
+void rv515_set_safe_registers(struct radeon_device *rdev);
+void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save);
+void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save);
+void rv515_clock_startup(struct radeon_device *rdev);
+void rv515_debugfs(struct radeon_device *rdev);
+
 
 /*
  * r520,rv530,rv560,rv570,r580
@@ -284,6 +331,8 @@ extern void r600_pm_misc(struct radeon_device *rdev);
 extern void r600_pm_init_profile(struct radeon_device *rdev);
 extern void rs780_pm_init_profile(struct radeon_device *rdev);
 extern void r600_pm_get_dynpm_state(struct radeon_device *rdev);
+extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes);
+extern int r600_get_pcie_lanes(struct radeon_device *rdev);
 
 /*
  * rv770,rv730,rv710,rv740
index e4f7e3e..1573202 100644 (file)
@@ -37,7 +37,7 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device,
 extern void radeon_link_encoder_connector(struct drm_device *dev);
 extern void
 radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum,
-                       uint32_t supported_device);
+                       uint32_t supported_device, u16 caps);
 
 /* from radeon_connector.c */
 extern void
@@ -537,6 +537,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
        u16 size, data_offset;
        u8 frev, crev;
        ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
+       ATOM_ENCODER_OBJECT_TABLE *enc_obj;
        ATOM_OBJECT_TABLE *router_obj;
        ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
        ATOM_OBJECT_HEADER *obj_header;
@@ -561,6 +562,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
        con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
            (ctx->bios + data_offset +
             le16_to_cpu(obj_header->usConnectorObjectTableOffset));
+       enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)
+           (ctx->bios + data_offset +
+            le16_to_cpu(obj_header->usEncoderObjectTableOffset));
        router_obj = (ATOM_OBJECT_TABLE *)
                (ctx->bios + data_offset +
                 le16_to_cpu(obj_header->usRouterObjectTableOffset));
@@ -666,14 +670,35 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                     OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
 
                                if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
-                                       u16 encoder_obj = le16_to_cpu(path->usGraphicObjIds[j]);
-
-                                       radeon_add_atom_encoder(dev,
-                                                               encoder_obj,
-                                                               le16_to_cpu
-                                                               (path->
-                                                                usDeviceTag));
+                                       for (k = 0; k < enc_obj->ucNumberOfObjects; k++) {
+                                               u16 encoder_obj = le16_to_cpu(enc_obj->asObjects[k].usObjectID);
+                                               if (le16_to_cpu(path->usGraphicObjIds[j]) == encoder_obj) {
+                                                       ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)
+                                                               (ctx->bios + data_offset +
+                                                                le16_to_cpu(enc_obj->asObjects[k].usRecordOffset));
+                                                       ATOM_ENCODER_CAP_RECORD *cap_record;
+                                                       u16 caps = 0;
 
+                                                       while (record->ucRecordType > 0 &&
+                                                              record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) {
+                                                               switch (record->ucRecordType) {
+                                                               case ATOM_ENCODER_CAP_RECORD_TYPE:
+                                                                       cap_record =(ATOM_ENCODER_CAP_RECORD *)
+                                                                               record;
+                                                                       caps = le16_to_cpu(cap_record->usEncoderCap);
+                                                                       break;
+                                                               }
+                                                               record = (ATOM_COMMON_RECORD_HEADER *)
+                                                                       ((char *)record + record->ucRecordSize);
+                                                       }
+                                                       radeon_add_atom_encoder(dev,
+                                                                               encoder_obj,
+                                                                               le16_to_cpu
+                                                                               (path->
+                                                                                usDeviceTag),
+                                                                               caps);
+                                               }
+                                       }
                                } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) {
                                        for (k = 0; k < router_obj->ucNumberOfObjects; k++) {
                                                u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID);
@@ -1007,7 +1032,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
                                                radeon_get_encoder_enum(dev,
                                                                      (1 << i),
                                                                      dac),
-                                               (1 << i));
+                                               (1 << i),
+                                               0);
                else
                        radeon_add_legacy_encoder(dev,
                                                  radeon_get_encoder_enum(dev,
@@ -1086,6 +1112,7 @@ union firmware_info {
        ATOM_FIRMWARE_INFO_V1_3 info_13;
        ATOM_FIRMWARE_INFO_V1_4 info_14;
        ATOM_FIRMWARE_INFO_V2_1 info_21;
+       ATOM_FIRMWARE_INFO_V2_2 info_22;
 };
 
 bool radeon_atom_get_clock_info(struct drm_device *dev)
@@ -1160,8 +1187,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                *p2pll = *p1pll;
 
                /* system clock */
-               spll->reference_freq =
-                   le16_to_cpu(firmware_info->info.usReferenceClock);
+               if (ASIC_IS_DCE4(rdev))
+                       spll->reference_freq =
+                               le16_to_cpu(firmware_info->info_21.usCoreReferenceClock);
+               else
+                       spll->reference_freq =
+                               le16_to_cpu(firmware_info->info.usReferenceClock);
                spll->reference_div = 0;
 
                spll->pll_out_min =
@@ -1183,8 +1214,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                    le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input);
 
                /* memory clock */
-               mpll->reference_freq =
-                   le16_to_cpu(firmware_info->info.usReferenceClock);
+               if (ASIC_IS_DCE4(rdev))
+                       mpll->reference_freq =
+                               le16_to_cpu(firmware_info->info_21.usMemoryReferenceClock);
+               else
+                       mpll->reference_freq =
+                               le16_to_cpu(firmware_info->info.usReferenceClock);
                mpll->reference_div = 0;
 
                mpll->pll_out_min =
@@ -1213,8 +1248,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                if (ASIC_IS_DCE4(rdev)) {
                        rdev->clock.default_dispclk =
                                le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
-                       if (rdev->clock.default_dispclk == 0)
-                               rdev->clock.default_dispclk = 60000; /* 600 Mhz */
+                       if (rdev->clock.default_dispclk == 0) {
+                               if (ASIC_IS_DCE5(rdev))
+                                       rdev->clock.default_dispclk = 54000; /* 540 Mhz */
+                               else
+                                       rdev->clock.default_dispclk = 60000; /* 600 Mhz */
+                       }
                        rdev->clock.dp_extclk =
                                le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
                }
@@ -1852,6 +1891,7 @@ static const char *pp_lib_thermal_controller_names[] = {
        "Evergreen",
        "emc2103",
        "Sumo",
+       "Northern Islands",
 };
 
 union power_info {
@@ -2115,6 +2155,11 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
                                 (controller->ucFanParameters &
                                  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
                        rdev->pm.int_thermal_type = THERMAL_TYPE_SUMO;
+               } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) {
+                       DRM_INFO("Internal thermal controller %s fan control\n",
+                                (controller->ucFanParameters &
+                                 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+                       rdev->pm.int_thermal_type = THERMAL_TYPE_NI;
                } else if ((controller->ucType ==
                            ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) ||
                           (controller->ucType ==
@@ -2204,15 +2249,22 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
                rdev->pm.default_power_state_index = state_index;
                rdev->pm.power_state[state_index].default_clock_mode =
                        &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
-               /* patch the table values with the default slck/mclk from firmware info */
-               for (j = 0; j < mode_index; j++) {
-                       rdev->pm.power_state[state_index].clock_info[j].mclk =
-                               rdev->clock.default_mclk;
-                       rdev->pm.power_state[state_index].clock_info[j].sclk =
-                               rdev->clock.default_sclk;
-                       if (vddc)
-                               rdev->pm.power_state[state_index].clock_info[j].voltage.voltage =
-                                       vddc;
+               if (ASIC_IS_DCE5(rdev)) {
+                       /* NI chips post without MC ucode, so default clocks are strobe mode only */
+                       rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
+                       rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
+                       rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;
+               } else {
+                       /* patch the table values with the default slck/mclk from firmware info */
+                       for (j = 0; j < mode_index; j++) {
+                               rdev->pm.power_state[state_index].clock_info[j].mclk =
+                                       rdev->clock.default_mclk;
+                               rdev->pm.power_state[state_index].clock_info[j].sclk =
+                                       rdev->clock.default_sclk;
+                               if (vddc)
+                                       rdev->pm.power_state[state_index].clock_info[j].voltage.voltage =
+                                               vddc;
+                       }
                }
        }
 }
index 8f2c7b5..1aba85c 100644 (file)
@@ -131,6 +131,45 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
        return true;
 }
 
+static bool ni_read_disabled_bios(struct radeon_device *rdev)
+{
+       u32 bus_cntl;
+       u32 d1vga_control;
+       u32 d2vga_control;
+       u32 vga_render_control;
+       u32 rom_cntl;
+       bool r;
+
+       bus_cntl = RREG32(R600_BUS_CNTL);
+       d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
+       d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
+       vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
+       rom_cntl = RREG32(R600_ROM_CNTL);
+
+       /* enable the rom */
+       WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
+       /* Disable VGA mode */
+       WREG32(AVIVO_D1VGA_CONTROL,
+              (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
+               AVIVO_DVGA_CONTROL_TIMING_SELECT)));
+       WREG32(AVIVO_D2VGA_CONTROL,
+              (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
+               AVIVO_DVGA_CONTROL_TIMING_SELECT)));
+       WREG32(AVIVO_VGA_RENDER_CONTROL,
+              (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK));
+       WREG32(R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE);
+
+       r = radeon_read_bios(rdev);
+
+       /* restore regs */
+       WREG32(R600_BUS_CNTL, bus_cntl);
+       WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
+       WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
+       WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
+       WREG32(R600_ROM_CNTL, rom_cntl);
+       return r;
+}
+
 static bool r700_read_disabled_bios(struct radeon_device *rdev)
 {
        uint32_t viph_control;
@@ -416,6 +455,8 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
 {
        if (rdev->flags & RADEON_IS_IGP)
                return igp_read_bios_from_vram(rdev);
+       else if (rdev->family >= CHIP_BARTS)
+               return ni_read_disabled_bios(rdev);
        else if (rdev->family >= CHIP_RV770)
                return r700_read_disabled_bios(rdev);
        else if (rdev->family >= CHIP_R600)
index 44cf0d7..26091d6 100644 (file)
@@ -82,6 +82,9 @@ static const char radeon_family_name[][16] = {
        "CYPRESS",
        "HEMLOCK",
        "PALM",
+       "BARTS",
+       "TURKS",
+       "CAICOS",
        "LAST",
 };
 
@@ -225,6 +228,11 @@ int radeon_wb_init(struct radeon_device *rdev)
                                rdev->wb.use_event = true;
                }
        }
+       /* always use writeback/events on NI */
+       if (ASIC_IS_DCE5(rdev)) {
+               rdev->wb.enabled = true;
+               rdev->wb.use_event = true;
+       }
 
        dev_info(rdev->dev, "WB %sabled\n", rdev->wb.enabled ? "en" : "dis");
 
index acebbc7..d26dabf 100644 (file)
@@ -68,7 +68,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
        WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id);
 }
 
-static void evergreen_crtc_load_lut(struct drm_crtc *crtc)
+static void dce4_crtc_load_lut(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
@@ -98,6 +98,66 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc)
        }
 }
 
+static void dce5_crtc_load_lut(struct drm_crtc *crtc)
+{
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       int i;
+
+       DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
+
+       WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
+              (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) |
+               NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS)));
+       WREG32(NI_PRESCALE_GRPH_CONTROL + radeon_crtc->crtc_offset,
+              NI_GRPH_PRESCALE_BYPASS);
+       WREG32(NI_PRESCALE_OVL_CONTROL + radeon_crtc->crtc_offset,
+              NI_OVL_PRESCALE_BYPASS);
+       WREG32(NI_INPUT_GAMMA_CONTROL + radeon_crtc->crtc_offset,
+              (NI_GRPH_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT) |
+               NI_OVL_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT)));
+
+       WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
+
+       WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
+       WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
+       WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
+
+       WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
+       WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
+       WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
+
+       WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
+       WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
+
+       WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
+       for (i = 0; i < 256; i++) {
+               WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
+                      (radeon_crtc->lut_r[i] << 20) |
+                      (radeon_crtc->lut_g[i] << 10) |
+                      (radeon_crtc->lut_b[i] << 0));
+       }
+
+       WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset,
+              (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
+               NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
+               NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) |
+               NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS)));
+       WREG32(NI_GAMUT_REMAP_CONTROL + radeon_crtc->crtc_offset,
+              (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS) |
+               NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS)));
+       WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset,
+              (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) |
+               NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS)));
+       WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
+              (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) |
+               NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
+       /* XXX match this to the depth of the crtc fmt block, move to modeset? */
+       WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
+
+}
+
 static void legacy_crtc_load_lut(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
@@ -130,8 +190,10 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc)
        if (!crtc->enabled)
                return;
 
-       if (ASIC_IS_DCE4(rdev))
-               evergreen_crtc_load_lut(crtc);
+       if (ASIC_IS_DCE5(rdev))
+               dce5_crtc_load_lut(crtc);
+       else if (ASIC_IS_DCE4(rdev))
+               dce4_crtc_load_lut(crtc);
        else if (ASIC_IS_AVIVO(rdev))
                avivo_crtc_load_lut(crtc);
        else
@@ -1119,7 +1181,10 @@ int radeon_modeset_init(struct radeon_device *rdev)
 
        rdev->ddev->mode_config.funcs = (void *)&radeon_mode_funcs;
 
-       if (ASIC_IS_AVIVO(rdev)) {
+       if (ASIC_IS_DCE5(rdev)) {
+               rdev->ddev->mode_config.max_width = 16384;
+               rdev->ddev->mode_config.max_height = 16384;
+       } else if (ASIC_IS_AVIVO(rdev)) {
                rdev->ddev->mode_config.max_width = 8192;
                rdev->ddev->mode_config.max_height = 8192;
        } else {
index 55b84b8..e7a948f 100644 (file)
@@ -712,7 +712,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
  * - 2 DIG encoder blocks.
  * DIG1/2 can drive UNIPHY0/1/2 link A or link B
  *
- * DCE 4.0
+ * DCE 4.0/5.0
  * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
  * Supports up to 6 digital outputs
  * - 6 DIG encoder blocks.
@@ -743,6 +743,7 @@ union dig_encoder_control {
        DIG_ENCODER_CONTROL_PS_ALLOCATION v1;
        DIG_ENCODER_CONTROL_PARAMETERS_V2 v2;
        DIG_ENCODER_CONTROL_PARAMETERS_V3 v3;
+       DIG_ENCODER_CONTROL_PARAMETERS_V4 v4;
 };
 
 void
@@ -758,6 +759,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
        uint8_t frev, crev;
        int dp_clock = 0;
        int dp_lane_count = 0;
+       int hpd_id = RADEON_HPD_NONE;
 
        if (connector) {
                struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -766,6 +768,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
 
                dp_clock = dig_connector->dp_clock;
                dp_lane_count = dig_connector->dp_lane_count;
+               hpd_id = radeon_connector->hpd.hpd;
        }
 
        /* no dig encoder assigned */
@@ -790,19 +793,36 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
        args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
        args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
 
-       if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
-               if (dp_clock == 270000)
-                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+       if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) ||
+           (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST))
                args.v1.ucLaneNum = dp_lane_count;
-       else if (radeon_encoder->pixel_clock > 165000)
+       else if (radeon_encoder->pixel_clock > 165000)
                args.v1.ucLaneNum = 8;
        else
                args.v1.ucLaneNum = 4;
 
-       if (ASIC_IS_DCE4(rdev)) {
+       if (ASIC_IS_DCE5(rdev)) {
+               if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) ||
+                   (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) {
+                       if (dp_clock == 270000)
+                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
+                       else if (dp_clock == 540000)
+                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
+               }
+               args.v4.acConfig.ucDigSel = dig->dig_encoder;
+               args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+               if (hpd_id == RADEON_HPD_NONE)
+                       args.v4.ucHPD_ID = 0;
+               else
+                       args.v4.ucHPD_ID = hpd_id + 1;
+       } else if (ASIC_IS_DCE4(rdev)) {
+               if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
+                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
                args.v3.acConfig.ucDigSel = dig->dig_encoder;
                args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
        } else {
+               if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
+                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
                switch (radeon_encoder->encoder_id) {
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
                        args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
@@ -829,6 +849,7 @@ union dig_transmitter_control {
        DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
        DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
        DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;
+       DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4;
 };
 
 void
@@ -923,10 +944,18 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                        struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
                        pll_id = radeon_crtc->pll_id;
                }
-               if (is_dp && rdev->clock.dp_extclk)
-                       args.v3.acConfig.ucRefClkSource = 2; /* external src */
-               else
-                       args.v3.acConfig.ucRefClkSource = pll_id;
+
+               if (ASIC_IS_DCE5(rdev)) {
+                       if (is_dp && rdev->clock.dp_extclk)
+                               args.v4.acConfig.ucRefClkSource = 3; /* external src */
+                       else
+                               args.v4.acConfig.ucRefClkSource = pll_id;
+               } else {
+                       if (is_dp && rdev->clock.dp_extclk)
+                               args.v3.acConfig.ucRefClkSource = 2; /* external src */
+                       else
+                               args.v3.acConfig.ucRefClkSource = pll_id;
+               }
 
                switch (radeon_encoder->encoder_id) {
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
@@ -1198,6 +1227,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
        DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
        int index = 0;
        bool is_dig = false;
+       bool is_dce5_dac = false;
+       bool is_dce5_dvo = false;
 
        memset(&args, 0, sizeof(args));
 
@@ -1220,7 +1251,9 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
                break;
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-               if (ASIC_IS_DCE3(rdev))
+               if (ASIC_IS_DCE5(rdev))
+                       is_dce5_dvo = true;
+               else if (ASIC_IS_DCE3(rdev))
                        is_dig = true;
                else
                        index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
@@ -1236,12 +1269,16 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
-                       index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
-               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-                       index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
-               else
-                       index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
+               if (ASIC_IS_DCE5(rdev))
+                       is_dce5_dac = true;
+               else {
+                       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+                               index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+                       else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+                               index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+                       else
+                               index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
+               }
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
@@ -1300,6 +1337,28 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                                atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
                        break;
                }
+       } else if (is_dce5_dac) {
+               switch (mode) {
+               case DRM_MODE_DPMS_ON:
+                       atombios_dac_setup(encoder, ATOM_ENABLE);
+                       break;
+               case DRM_MODE_DPMS_STANDBY:
+               case DRM_MODE_DPMS_SUSPEND:
+               case DRM_MODE_DPMS_OFF:
+                       atombios_dac_setup(encoder, ATOM_DISABLE);
+                       break;
+               }
+       } else if (is_dce5_dvo) {
+               switch (mode) {
+               case DRM_MODE_DPMS_ON:
+                       atombios_dvo_setup(encoder, ATOM_ENABLE);
+                       break;
+               case DRM_MODE_DPMS_STANDBY:
+               case DRM_MODE_DPMS_SUSPEND:
+               case DRM_MODE_DPMS_OFF:
+                       atombios_dvo_setup(encoder, ATOM_DISABLE);
+                       break;
+               }
        } else {
                switch (mode) {
                case DRM_MODE_DPMS_ON:
@@ -1329,7 +1388,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                switch (mode) {
                case DRM_MODE_DPMS_ON:
                default:
-                       if (ASIC_IS_DCE41(rdev) && (rdev->flags & RADEON_IS_IGP))
+                       if (ASIC_IS_DCE41(rdev))
                                action = EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT;
                        else
                                action = ATOM_ENABLE;
@@ -1337,7 +1396,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
                case DRM_MODE_DPMS_STANDBY:
                case DRM_MODE_DPMS_SUSPEND:
                case DRM_MODE_DPMS_OFF:
-                       if (ASIC_IS_DCE41(rdev) && (rdev->flags & RADEON_IS_IGP))
+                       if (ASIC_IS_DCE41(rdev))
                                action = EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT;
                        else
                                action = ATOM_DISABLE;
@@ -1529,6 +1588,7 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
        struct radeon_encoder_atom_dig *dig;
        uint32_t dig_enc_in_use = 0;
 
+       /* DCE4/5 */
        if (ASIC_IS_DCE4(rdev)) {
                dig = radeon_encoder->enc_priv;
                if (ASIC_IS_DCE41(rdev)) {
@@ -1663,7 +1723,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        }
 
        if (ext_encoder) {
-               if (ASIC_IS_DCE41(rdev) && (rdev->flags & RADEON_IS_IGP)) {
+               if (ASIC_IS_DCE41(rdev)) {
                        atombios_external_encoder_setup(encoder, ext_encoder,
                                                        EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
                        atombios_external_encoder_setup(encoder, ext_encoder,
@@ -1986,7 +2046,10 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
 }
 
 void
-radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device)
+radeon_add_atom_encoder(struct drm_device *dev,
+                       uint32_t encoder_enum,
+                       uint32_t supported_device,
+                       u16 caps)
 {
        struct radeon_device *rdev = dev->dev_private;
        struct drm_encoder *encoder;
@@ -2029,6 +2092,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
        radeon_encoder->rmx_type = RMX_OFF;
        radeon_encoder->underscan_type = UNDERSCAN_OFF;
        radeon_encoder->is_ext_encoder = false;
+       radeon_encoder->caps = caps;
 
        switch (radeon_encoder->encoder_id) {
        case ENCODER_OBJECT_ID_INTERNAL_LVDS:
index 4c222d5..1ca55eb 100644 (file)
@@ -81,6 +81,9 @@ enum radeon_family {
        CHIP_CYPRESS,
        CHIP_HEMLOCK,
        CHIP_PALM,
+       CHIP_BARTS,
+       CHIP_TURKS,
+       CHIP_CAICOS,
        CHIP_LAST,
 };
 
index fd185f7..12bdeab 100644 (file)
@@ -379,6 +379,7 @@ struct radeon_encoder {
        int hdmi_audio_workaround;
        int hdmi_buffer_status;
        bool is_ext_encoder;
+       u16 caps;
 };
 
 struct radeon_connector_atom_dig {
index 0afd26c..3b1b2bf 100644 (file)
@@ -167,13 +167,13 @@ static void radeon_set_power_state(struct radeon_device *rdev)
        if (radeon_gui_idle(rdev)) {
                sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
                        clock_info[rdev->pm.requested_clock_mode_index].sclk;
-               if (sclk > rdev->clock.default_sclk)
-                       sclk = rdev->clock.default_sclk;
+               if (sclk > rdev->pm.default_sclk)
+                       sclk = rdev->pm.default_sclk;
 
                mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
                        clock_info[rdev->pm.requested_clock_mode_index].mclk;
-               if (mclk > rdev->clock.default_mclk)
-                       mclk = rdev->clock.default_mclk;
+               if (mclk > rdev->pm.default_mclk)
+                       mclk = rdev->pm.default_mclk;
 
                /* upvolt before raising clocks, downvolt after lowering clocks */
                if (sclk < rdev->pm.current_sclk)
@@ -440,6 +440,7 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev,
                temp = rv770_get_temp(rdev);
                break;
        case THERMAL_TYPE_EVERGREEN:
+       case THERMAL_TYPE_NI:
                temp = evergreen_get_temp(rdev);
                break;
        case THERMAL_TYPE_SUMO:
@@ -529,12 +530,21 @@ void radeon_pm_suspend(struct radeon_device *rdev)
 
 void radeon_pm_resume(struct radeon_device *rdev)
 {
+       /* set up the default clocks if the MC ucode is loaded */
+       if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
+               if (rdev->pm.default_vddc)
+                       radeon_atom_set_voltage(rdev, rdev->pm.default_vddc);
+               if (rdev->pm.default_sclk)
+                       radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
+               if (rdev->pm.default_mclk)
+                       radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
+       }
        /* asic init will reset the default power state */
        mutex_lock(&rdev->pm.mutex);
        rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
        rdev->pm.current_clock_mode_index = 0;
-       rdev->pm.current_sclk = rdev->clock.default_sclk;
-       rdev->pm.current_mclk = rdev->clock.default_mclk;
+       rdev->pm.current_sclk = rdev->pm.default_sclk;
+       rdev->pm.current_mclk = rdev->pm.default_mclk;
        rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
        if (rdev->pm.pm_method == PM_METHOD_DYNPM
            && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) {
@@ -557,6 +567,8 @@ int radeon_pm_init(struct radeon_device *rdev)
        rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
        rdev->pm.dynpm_can_upclock = true;
        rdev->pm.dynpm_can_downclock = true;
+       rdev->pm.default_sclk = rdev->clock.default_sclk;
+       rdev->pm.default_mclk = rdev->clock.default_mclk;
        rdev->pm.current_sclk = rdev->clock.default_sclk;
        rdev->pm.current_mclk = rdev->clock.default_mclk;
        rdev->pm.int_thermal_type = THERMAL_TYPE_NONE;
@@ -568,6 +580,15 @@ int radeon_pm_init(struct radeon_device *rdev)
                        radeon_combios_get_power_modes(rdev);
                radeon_pm_print_states(rdev);
                radeon_pm_init_profile(rdev);
+               /* set up the default clocks if the MC ucode is loaded */
+               if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
+                       if (rdev->pm.default_vddc)
+                               radeon_atom_set_voltage(rdev, rdev->pm.default_vddc);
+                       if (rdev->pm.default_sclk)
+                               radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
+                       if (rdev->pm.default_mclk)
+                               radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
+               }
        }
 
        /* set up the internal thermal sensor if applicable */
@@ -803,9 +824,9 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
        struct drm_device *dev = node->minor->dev;
        struct radeon_device *rdev = dev->dev_private;
 
-       seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk);
+       seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk);
        seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
-       seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk);
+       seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk);
        if (rdev->asic->get_memory_clock)
                seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
        if (rdev->pm.current_vddc)
index 0a310b7..3cd4dac 100644 (file)
@@ -55,6 +55,7 @@
 #include "r500_reg.h"
 #include "r600_reg.h"
 #include "evergreen_reg.h"
+#include "ni_reg.h"
 
 #define RADEON_MC_AGP_LOCATION         0x014c
 #define                RADEON_MC_AGP_START_MASK        0x0000FFFF
 #       define RADEON_PCIE_LC_RECONFIG_NOW         (1 << 8)
 #       define RADEON_PCIE_LC_RECONFIG_LATER       (1 << 9)
 #       define RADEON_PCIE_LC_SHORT_RECONFIG_EN    (1 << 10)
+#       define R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE   (1 << 7)
+#       define R600_PCIE_LC_RENEGOTIATION_SUPPORT  (1 << 9)
+#       define R600_PCIE_LC_RENEGOTIATE_EN         (1 << 10)
+#       define R600_PCIE_LC_SHORT_RECONFIG_EN      (1 << 11)
+#       define R600_PCIE_LC_UPCONFIGURE_SUPPORT    (1 << 12)
+#       define R600_PCIE_LC_UPCONFIGURE_DIS        (1 << 13)
+
+#define R600_TARGET_AND_CURRENT_PROFILE_INDEX      0x70c
+#define R700_TARGET_AND_CURRENT_PROFILE_INDEX      0x66c
 
 #define RADEON_CACHE_CNTL                   0x1724
 #define RADEON_CACHE_LINE                   0x0f0c /* PCI */
index 645aa1f..3a264aa 100644 (file)
@@ -41,6 +41,7 @@
 
 static void rv770_gpu_init(struct radeon_device *rdev);
 void rv770_fini(struct radeon_device *rdev);
+static void rv770_pcie_gen2_enable(struct radeon_device *rdev);
 
 u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
@@ -1124,6 +1125,9 @@ static int rv770_startup(struct radeon_device *rdev)
 {
        int r;
 
+       /* enable pcie gen2 link */
+       rv770_pcie_gen2_enable(rdev);
+
        if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
                r = r600_init_microcode(rdev);
                if (r) {
@@ -1362,3 +1366,75 @@ void rv770_fini(struct radeon_device *rdev)
        rdev->bios = NULL;
        radeon_dummy_page_fini(rdev);
 }
+
+static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
+{
+       u32 link_width_cntl, lanes, speed_cntl, tmp;
+       u16 link_cntl2;
+
+       if (rdev->flags & RADEON_IS_IGP)
+               return;
+
+       if (!(rdev->flags & RADEON_IS_PCIE))
+               return;
+
+       /* x2 cards have a special sequence */
+       if (ASIC_IS_X2(rdev))
+               return;
+
+       /* advertise upconfig capability */
+       link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
+       link_width_cntl &= ~LC_UPCONFIGURE_DIS;
+       WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+       link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
+       if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) {
+               lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT;
+               link_width_cntl &= ~(LC_LINK_WIDTH_MASK |
+                                    LC_RECONFIG_ARC_MISSING_ESCAPE);
+               link_width_cntl |= lanes | LC_RECONFIG_NOW |
+                       LC_RENEGOTIATE_EN | LC_UPCONFIGURE_SUPPORT;
+               WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+       } else {
+               link_width_cntl |= LC_UPCONFIGURE_DIS;
+               WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+       }
+
+       speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+       if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+           (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+
+               tmp = RREG32(0x541c);
+               WREG32(0x541c, tmp | 0x8);
+               WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN);
+               link_cntl2 = RREG16(0x4088);
+               link_cntl2 &= ~TARGET_LINK_SPEED_MASK;
+               link_cntl2 |= 0x2;
+               WREG16(0x4088, link_cntl2);
+               WREG32(MM_CFGREGS_CNTL, 0);
+
+               speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+               speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+               speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+               speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+               speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+               speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+               speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+               speed_cntl |= LC_GEN2_EN_STRAP;
+               WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+       } else {
+               link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL);
+               /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */
+               if (1)
+                       link_width_cntl |= LC_UPCONFIGURE_DIS;
+               else
+                       link_width_cntl &= ~LC_UPCONFIGURE_DIS;
+               WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
+       }
+}
index fc77e1e..abc8cf5 100644 (file)
 #define D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH             0x691c
 #define D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH             0x611c
 
+/* PCIE link stuff */
+#define PCIE_LC_TRAINING_CNTL                             0xa1 /* PCIE_P */
+#define PCIE_LC_LINK_WIDTH_CNTL                           0xa2 /* PCIE_P */
+#       define LC_LINK_WIDTH_SHIFT                        0
+#       define LC_LINK_WIDTH_MASK                         0x7
+#       define LC_LINK_WIDTH_X0                           0
+#       define LC_LINK_WIDTH_X1                           1
+#       define LC_LINK_WIDTH_X2                           2
+#       define LC_LINK_WIDTH_X4                           3
+#       define LC_LINK_WIDTH_X8                           4
+#       define LC_LINK_WIDTH_X16                          6
+#       define LC_LINK_WIDTH_RD_SHIFT                     4
+#       define LC_LINK_WIDTH_RD_MASK                      0x70
+#       define LC_RECONFIG_ARC_MISSING_ESCAPE             (1 << 7)
+#       define LC_RECONFIG_NOW                            (1 << 8)
+#       define LC_RENEGOTIATION_SUPPORT                   (1 << 9)
+#       define LC_RENEGOTIATE_EN                          (1 << 10)
+#       define LC_SHORT_RECONFIG_EN                       (1 << 11)
+#       define LC_UPCONFIGURE_SUPPORT                     (1 << 12)
+#       define LC_UPCONFIGURE_DIS                         (1 << 13)
+#define PCIE_LC_SPEED_CNTL                                0xa4 /* PCIE_P */
+#       define LC_GEN2_EN_STRAP                           (1 << 0)
+#       define LC_TARGET_LINK_SPEED_OVERRIDE_EN           (1 << 1)
+#       define LC_FORCE_EN_HW_SPEED_CHANGE                (1 << 5)
+#       define LC_FORCE_DIS_HW_SPEED_CHANGE               (1 << 6)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK      (0x3 << 8)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT     3
+#       define LC_CURRENT_DATA_RATE                       (1 << 11)
+#       define LC_VOLTAGE_TIMER_SEL_MASK                  (0xf << 14)
+#       define LC_CLR_FAILED_SPD_CHANGE_CNT               (1 << 21)
+#       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 23)
+#       define LC_OTHER_SIDE_SUPPORTS_GEN2                (1 << 24)
+#define MM_CFGREGS_CNTL                                   0x544c
+#       define MM_WR_TO_CFG_EN                            (1 << 3)
+#define LINK_CNTL2                                        0x88 /* F0 */
+#       define TARGET_LINK_SPEED_MASK                     (0xf << 0)
+#       define SELECTABLE_DEEMPHASIS                      (1 << 6)
+
 #endif
index e6b28a3..fe29ae3 100644 (file)
        {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6721, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6722, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6723, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6725, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6726, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6728, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6729, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6739, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BARTS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6740, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6741, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6742, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6743, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6744, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6745, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6746, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6747, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6748, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6758, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6759, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6761, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6763, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6764, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6765, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6766, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6767, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6768, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \