Merge branch 'topic/oss' into for-linus
[pandora-kernel.git] / drivers / gpu / drm / radeon / r300.c
index e2ed5bc..051bca6 100644 (file)
@@ -30,6 +30,8 @@
 #include "drm.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_drm.h"
+#include "radeon_share.h"
 
 /* r300,r350,rv350,rv370,rv380 depends on : */
 void r100_hdp_reset(struct radeon_device *rdev);
@@ -44,6 +46,7 @@ int r100_gui_wait_for_idle(struct radeon_device *rdev);
 int r100_cs_packet_parse(struct radeon_cs_parser *p,
                         struct radeon_cs_packet *pkt,
                         unsigned idx);
+int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
 int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
                              struct radeon_cs_reloc **cs_reloc);
 int r100_cs_parse_packet0(struct radeon_cs_parser *p,
@@ -80,8 +83,8 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
                WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp | RADEON_PCIE_TX_GART_INVALIDATE_TLB);
                (void)RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
                WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
-               mb();
        }
+       mb();
 }
 
 int rv370_pcie_gart_enable(struct radeon_device *rdev)
@@ -150,8 +153,13 @@ int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
        if (i < 0 || i > rdev->gart.num_gpu_pages) {
                return -EINVAL;
        }
-       addr = (((u32)addr) >> 8) | ((upper_32_bits(addr) & 0xff) << 4) | 0xC;
-       writel(cpu_to_le32(addr), ((void __iomem *)ptr) + (i * 4));
+       addr = (lower_32_bits(addr) >> 8) |
+              ((upper_32_bits(addr) & 0xff) << 24) |
+              0xc;
+       /* on x86 we want this to be CPU endian, on powerpc
+        * on powerpc without HW swappers, it'll get swapped on way
+        * into VRAM - so no need for cpu_to_le32 on VRAM tables */
+       writel(addr, ((void __iomem *)ptr) + (i * 4));
        return 0;
 }
 
@@ -440,6 +448,7 @@ void r300_gpu_init(struct radeon_device *rdev)
                /* rv350,rv370,rv380 */
                rdev->num_gb_pipes = 1;
        }
+       rdev->num_z_pipes = 1;
        gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16);
        switch (rdev->num_gb_pipes) {
        case 2:
@@ -478,7 +487,8 @@ void r300_gpu_init(struct radeon_device *rdev)
                printk(KERN_WARNING "Failed to wait MC idle while "
                       "programming pipes. Bad things might happen.\n");
        }
-       DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes);
+       DRM_INFO("radeon: %d quad pipes, %d Z pipes initialized.\n",
+                rdev->num_gb_pipes, rdev->num_z_pipes);
 }
 
 int r300_ga_reset(struct radeon_device *rdev)
@@ -579,34 +589,11 @@ void r300_vram_info(struct radeon_device *rdev)
        } else {
                rdev->mc.vram_width = 64;
        }
-       rdev->mc.vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
 
-       rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-       rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+       r100_vram_init_sizes(rdev);
 }
 
 
-/*
- * Indirect registers accessor
- */
-uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg)
-{
-       uint32_t r;
-
-       WREG8(RADEON_PCIE_INDEX, ((reg) & 0xff));
-       (void)RREG32(RADEON_PCIE_INDEX);
-       r = RREG32(RADEON_PCIE_DATA);
-       return r;
-}
-
-void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
-{
-       WREG8(RADEON_PCIE_INDEX, ((reg) & 0xff));
-       (void)RREG32(RADEON_PCIE_INDEX);
-       WREG32(RADEON_PCIE_DATA, (v));
-       (void)RREG32(RADEON_PCIE_DATA);
-}
-
 /*
  * PCIE Lanes
  */
@@ -970,7 +957,7 @@ static inline void r300_cs_track_clear(struct r300_cs_track *track)
 
 static const unsigned r300_reg_safe_bm[159] = {
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-       0xFFFFFFBF, 0xFFFFFFFF, 0xFFFFFFBF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
@@ -1008,7 +995,7 @@ static const unsigned r300_reg_safe_bm[159] = {
        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
        0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x0003FC01, 0xFFFFFFF8, 0xFE800B19,
+       0x0003FC01, 0xFFFFFCF8, 0xFF800B19,
 };
 
 static int r300_packet0_check(struct radeon_cs_parser *p,
@@ -1019,7 +1006,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
        struct radeon_cs_reloc *reloc;
        struct r300_cs_track *track;
        volatile uint32_t *ib;
-       uint32_t tmp;
+       uint32_t tmp, tile_flags = 0;
        unsigned i;
        int r;
 
@@ -1027,6 +1014,16 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
        ib_chunk = &p->chunks[p->chunk_ib_idx];
        track = (struct r300_cs_track*)p->track;
        switch(reg) {
+       case AVIVO_D1MODE_VLINE_START_END:
+       case RADEON_CRTC_GUI_TRIG_VLINE:
+               r = r100_cs_packet_parse_vline(p);
+               if (r) {
+                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                       idx, reg);
+                       r100_cs_dump_packet(p, pkt);
+                       return r;
+               }
+               break;
        case RADEON_DST_PITCH_OFFSET:
        case RADEON_SRC_PITCH_OFFSET:
                r = r100_cs_packet_next_reloc(p, &reloc);
@@ -1038,7 +1035,19 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                }
                tmp = ib_chunk->kdata[idx] & 0x003fffff;
                tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
-               ib[idx] = (ib_chunk->kdata[idx] & 0xffc00000) | tmp;
+
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                       tile_flags |= RADEON_DST_TILE_MACRO;
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+                       if (reg == RADEON_SRC_PITCH_OFFSET) {
+                               DRM_ERROR("Cannot src blit from microtiled surface\n");
+                               r100_cs_dump_packet(p, pkt);
+                               return -EINVAL;
+                       }
+                       tile_flags |= RADEON_DST_TILE_MICRO;
+               }
+               tmp |= tile_flags;
+               ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
                break;
        case R300_RB3D_COLOROFFSET0:
        case R300_RB3D_COLOROFFSET1:
@@ -1127,6 +1136,23 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                /* RB3D_COLORPITCH1 */
                /* RB3D_COLORPITCH2 */
                /* RB3D_COLORPITCH3 */
+               r = r100_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                 idx, reg);
+                       r100_cs_dump_packet(p, pkt);
+                       return r;
+               }
+
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                       tile_flags |= R300_COLOR_TILE_ENABLE;
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                       tile_flags |= R300_COLOR_MICROTILE_ENABLE;
+
+               tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
+               tmp |= tile_flags;
+               ib[idx] = tmp;
+
                i = (reg - 0x4E38) >> 2;
                track->cb[i].pitch = ib_chunk->kdata[idx] & 0x3FFE;
                switch (((ib_chunk->kdata[idx] >> 21) & 0xF)) {
@@ -1182,6 +1208,23 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                break;
        case 0x4F24:
                /* ZB_DEPTHPITCH */
+               r = r100_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                 idx, reg);
+                       r100_cs_dump_packet(p, pkt);
+                       return r;
+               }
+
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                       tile_flags |= R300_DEPTHMACROTILE_ENABLE;
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                       tile_flags |= R300_DEPTHMICROTILE_TILED;;
+
+               tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
+               tmp |= tile_flags;
+               ib[idx] = tmp;
+
                track->zb.pitch = ib_chunk->kdata[idx] & 0x3FFC;
                break;
        case 0x4104:
@@ -1341,6 +1384,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                tmp = (ib_chunk->kdata[idx] >> 22) & 0xF;
                track->textures[i].txdepth = tmp;
                break;
+       case R300_ZB_ZPASS_ADDR:
+               r = r100_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                       idx, reg);
+                       r100_cs_dump_packet(p, pkt);
+                       return r;
+               }
+               ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+               break;
+       case 0x4be8:
+               /* valid register only on RV530 */
+               if (p->rdev->family == CHIP_RV530)
+                       break;
+               /* fallthrough do not move */
        default:
                printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
                       reg, idx);