]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/gpu/drm/radeon/r100.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[mv-sheeva.git] / drivers / gpu / drm / radeon / r100.c
index c0d4650cdb794103a3fa7fe79d0a43c4806713c9..91eb762eb3f918625f3b17f0a8360551d628480e 100644 (file)
@@ -197,13 +197,13 @@ int r100_pci_gart_enable(struct radeon_device *rdev)
 {
        uint32_t tmp;
 
+       radeon_gart_restore(rdev);
        /* discard memory request outside of configured range */
        tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
        WREG32(RADEON_AIC_CNTL, tmp);
        /* set address range for PCI address translate */
-       WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_location);
-       tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-       WREG32(RADEON_AIC_HI_ADDR, tmp);
+       WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_start);
+       WREG32(RADEON_AIC_HI_ADDR, rdev->mc.gtt_end);
        /* set PCI GART page-table base address */
        WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
        tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
@@ -312,9 +312,11 @@ int r100_irq_process(struct radeon_device *rdev)
                /* Vertical blank interrupts */
                if (status & RADEON_CRTC_VBLANK_STAT) {
                        drm_handle_vblank(rdev->ddev, 0);
+                       wake_up(&rdev->irq.vblank_queue);
                }
                if (status & RADEON_CRTC2_VBLANK_STAT) {
                        drm_handle_vblank(rdev->ddev, 1);
+                       wake_up(&rdev->irq.vblank_queue);
                }
                if (status & RADEON_FP_DETECT_STAT) {
                        queue_hotplug = true;
@@ -366,8 +368,8 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
        radeon_ring_write(rdev, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0));
        radeon_ring_write(rdev, RADEON_RB3D_ZC_FLUSH_ALL);
        /* Wait until IDLE & CLEAN */
-       radeon_ring_write(rdev, PACKET0(0x1720, 0));
-       radeon_ring_write(rdev, (1 << 16) | (1 << 17));
+       radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
+       radeon_ring_write(rdev, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
        radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
        radeon_ring_write(rdev, rdev->config.r100.hdp_cntl |
                                RADEON_HDP_READ_BUFFER_INVALIDATE);
@@ -1701,7 +1703,7 @@ int r100_gui_wait_for_idle(struct radeon_device *rdev)
        }
        for (i = 0; i < rdev->usec_timeout; i++) {
                tmp = RREG32(RADEON_RBBM_STATUS);
-               if (!(tmp & (1 << 31))) {
+               if (!(tmp & RADEON_RBBM_ACTIVE)) {
                        return 0;
                }
                DRM_UDELAY(1);
@@ -1716,8 +1718,8 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev)
 
        for (i = 0; i < rdev->usec_timeout; i++) {
                /* read MC_STATUS */
-               tmp = RREG32(0x0150);
-               if (tmp & (1 << 2)) {
+               tmp = RREG32(RADEON_MC_STATUS);
+               if (tmp & RADEON_MC_IDLE) {
                        return 0;
                }
                DRM_UDELAY(1);
@@ -1790,7 +1792,7 @@ int r100_gpu_reset(struct radeon_device *rdev)
        }
        /* Check if GPU is idle */
        status = RREG32(RADEON_RBBM_STATUS);
-       if (status & (1 << 31)) {
+       if (status & RADEON_RBBM_ACTIVE) {
                DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status);
                return -1;
        }
@@ -1800,6 +1802,9 @@ int r100_gpu_reset(struct radeon_device *rdev)
 
 void r100_set_common_regs(struct radeon_device *rdev)
 {
+       struct drm_device *dev = rdev->ddev;
+       bool force_dac2 = false;
+
        /* set these so they don't interfere with anything */
        WREG32(RADEON_OV0_SCALE_CNTL, 0);
        WREG32(RADEON_SUBPIC_CNTL, 0);
@@ -1808,6 +1813,68 @@ void r100_set_common_regs(struct radeon_device *rdev)
        WREG32(RADEON_DVI_I2C_CNTL_1, 0);
        WREG32(RADEON_CAP0_TRIG_CNTL, 0);
        WREG32(RADEON_CAP1_TRIG_CNTL, 0);
+
+       /* always set up dac2 on rn50 and some rv100 as lots
+        * of servers seem to wire it up to a VGA port but
+        * don't report it in the bios connector
+        * table.
+        */
+       switch (dev->pdev->device) {
+               /* RN50 */
+       case 0x515e:
+       case 0x5969:
+               force_dac2 = true;
+               break;
+               /* RV100*/
+       case 0x5159:
+       case 0x515a:
+               /* DELL triple head servers */
+               if ((dev->pdev->subsystem_vendor == 0x1028 /* DELL */) &&
+                   ((dev->pdev->subsystem_device == 0x016c) ||
+                    (dev->pdev->subsystem_device == 0x016d) ||
+                    (dev->pdev->subsystem_device == 0x016e) ||
+                    (dev->pdev->subsystem_device == 0x016f) ||
+                    (dev->pdev->subsystem_device == 0x0170) ||
+                    (dev->pdev->subsystem_device == 0x017d) ||
+                    (dev->pdev->subsystem_device == 0x017e) ||
+                    (dev->pdev->subsystem_device == 0x0183) ||
+                    (dev->pdev->subsystem_device == 0x018a) ||
+                    (dev->pdev->subsystem_device == 0x019a)))
+                       force_dac2 = true;
+               break;
+       }
+
+       if (force_dac2) {
+               u32 disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
+               u32 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
+               u32 dac2_cntl = RREG32(RADEON_DAC_CNTL2);
+
+               /* For CRT on DAC2, don't turn it on if BIOS didn't
+                  enable it, even it's detected.
+               */
+
+               /* force it to crtc0 */
+               dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
+               dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+               disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+
+               /* set up the TV DAC */
+               tv_dac_cntl &= ~(RADEON_TV_DAC_PEDESTAL |
+                                RADEON_TV_DAC_STD_MASK |
+                                RADEON_TV_DAC_RDACPD |
+                                RADEON_TV_DAC_GDACPD |
+                                RADEON_TV_DAC_BDACPD |
+                                RADEON_TV_DAC_BGADJ_MASK |
+                                RADEON_TV_DAC_DACADJ_MASK);
+               tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
+                               RADEON_TV_DAC_NHOLD |
+                               RADEON_TV_DAC_STD_PS2 |
+                               (0x58 << 16));
+
+               WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+               WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
+               WREG32(RADEON_DAC_CNTL2, dac2_cntl);
+       }
 }
 
 /*
@@ -1889,17 +1956,20 @@ static u32 r100_get_accessible_vram(struct radeon_device *rdev)
 void r100_vram_init_sizes(struct radeon_device *rdev)
 {
        u64 config_aper_size;
-       u32 accessible;
 
+       /* work out accessible VRAM */
+       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev);
+       /* FIXME we don't use the second aperture yet when we could use it */
+       if (rdev->mc.visible_vram_size > rdev->mc.aper_size)
+               rdev->mc.visible_vram_size = rdev->mc.aper_size;
        config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE);
-
        if (rdev->flags & RADEON_IS_IGP) {
                uint32_t tom;
                /* read NB_TOM to get the amount of ram stolen for the GPU */
                tom = RREG32(RADEON_NB_TOM);
                rdev->mc.real_vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16);
-               /* for IGPs we need to keep VRAM where it was put by the BIOS */
-               rdev->mc.vram_location = (tom & 0xffff) << 16;
                WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
                rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
        } else {
@@ -1911,30 +1981,19 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
                        rdev->mc.real_vram_size = 8192 * 1024;
                        WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
                }
-               /* let driver place VRAM */
-               rdev->mc.vram_location = 0xFFFFFFFFUL;
-                /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - 
-                 * Novell bug 204882 + along with lots of ubuntu ones */
+               /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - 
+                * Novell bug 204882 + along with lots of ubuntu ones
+                */
                if (config_aper_size > rdev->mc.real_vram_size)
                        rdev->mc.mc_vram_size = config_aper_size;
                else
                        rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
        }
-
-       /* work out accessible VRAM */
-       accessible = r100_get_accessible_vram(rdev);
-
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
-
-       if (accessible > rdev->mc.aper_size)
-               accessible = rdev->mc.aper_size;
-
-       if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
+       /* FIXME remove this once we support unmappable VRAM */
+       if (rdev->mc.mc_vram_size > rdev->mc.aper_size) {
                rdev->mc.mc_vram_size = rdev->mc.aper_size;
-
-       if (rdev->mc.real_vram_size > rdev->mc.aper_size)
                rdev->mc.real_vram_size = rdev->mc.aper_size;
+       }
 }
 
 void r100_vga_set_state(struct radeon_device *rdev, bool state)
@@ -1951,11 +2010,18 @@ void r100_vga_set_state(struct radeon_device *rdev, bool state)
        WREG32(RADEON_CONFIG_CNTL, temp);
 }
 
-void r100_vram_info(struct radeon_device *rdev)
+void r100_mc_init(struct radeon_device *rdev)
 {
-       r100_vram_get_type(rdev);
+       u64 base;
 
+       r100_vram_get_type(rdev);
        r100_vram_init_sizes(rdev);
+       base = rdev->mc.aper_base;
+       if (rdev->flags & RADEON_IS_IGP)
+               base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
+       radeon_vram_location(rdev, &rdev->mc, base);
+       if (!(rdev->flags & RADEON_IS_AGP))
+               radeon_gtt_location(rdev, &rdev->mc);
 }
 
 
@@ -3226,10 +3292,9 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
 void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
 {
        /* Update base address for crtc */
-       WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_location);
+       WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_start);
        if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
-               WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR,
-                               rdev->mc.vram_location);
+               WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, rdev->mc.vram_start);
        }
        /* Restore CRTC registers */
        WREG8(R_0003C2_GENMO_WT, save->GENMO_WT);
@@ -3390,32 +3455,6 @@ void r100_fini(struct radeon_device *rdev)
        rdev->bios = NULL;
 }
 
-int r100_mc_init(struct radeon_device *rdev)
-{
-       int r;
-       u32 tmp;
-
-       /* Setup GPU memory space */
-       rdev->mc.vram_location = 0xFFFFFFFFUL;
-       rdev->mc.gtt_location = 0xFFFFFFFFUL;
-       if (rdev->flags & RADEON_IS_IGP) {
-               tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
-               rdev->mc.vram_location = tmp << 16;
-       }
-       if (rdev->flags & RADEON_IS_AGP) {
-               r = radeon_agp_init(rdev);
-               if (r) {
-                       radeon_agp_disable(rdev);
-               } else {
-                       rdev->mc.gtt_location = rdev->mc.agp_base;
-               }
-       }
-       r = radeon_mc_setup(rdev);
-       if (r)
-               return r;
-       return 0;
-}
-
 int r100_init(struct radeon_device *rdev)
 {
        int r;
@@ -3458,12 +3497,15 @@ int r100_init(struct radeon_device *rdev)
        radeon_get_clock_info(rdev->ddev);
        /* Initialize power management */
        radeon_pm_init(rdev);
-       /* Get vram informations */
-       r100_vram_info(rdev);
-       /* Initialize memory controller (also test AGP) */
-       r = r100_mc_init(rdev);
-       if (r)
-               return r;
+       /* initialize AGP */
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r) {
+                       radeon_agp_disable(rdev);
+               }
+       }
+       /* initialize VRAM */
+       r100_mc_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
        if (r)