Index: conf/files =================================================================== --- conf/files (revision 189388) +++ conf/files (working copy) @@ -801,6 +801,7 @@ dev/drm/r128_state.c optional r128drm \ compile-with "${NORMAL_C} -finline-limit=13500" dev/drm/r300_cmdbuf.c optional radeondrm +dev/drm/r600_cp.c optional radeondrm dev/drm/radeon_cp.c optional radeondrm dev/drm/radeon_drv.c optional radeondrm dev/drm/radeon_irq.c optional radeondrm Index: modules/drm/radeon/Makefile =================================================================== --- modules/drm/radeon/Makefile (revision 189388) +++ modules/drm/radeon/Makefile (working copy) @@ -2,7 +2,7 @@ .PATH: ${.CURDIR}/../../../dev/drm KMOD = radeon -SRCS = r300_cmdbuf.c radeon_cp.c radeon_drv.c radeon_irq.c \ +SRCS = r300_cmdbuf.c r600_cp.c radeon_cp.c radeon_drv.c radeon_irq.c \ radeon_mem.c radeon_state.c SRCS +=device_if.h bus_if.h pci_if.h opt_drm.h Index: dev/drm/radeon_cp.c =================================================================== --- dev/drm/radeon_cp.c (revision 189388) +++ dev/drm/radeon_cp.c (working copy) @@ -1,4 +1,3 @@ -/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */ /*- * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Fremont, California. @@ -34,16 +33,90 @@ #include "dev/drm/drmP.h" #include "dev/drm/drm.h" +#include "dev/drm/drm_sarea.h" #include "dev/drm/radeon_drm.h" #include "dev/drm/radeon_drv.h" #include "dev/drm/r300_reg.h" #include "dev/drm/radeon_microcode.h" + #define RADEON_FIFO_DEBUG 0 static int radeon_do_cleanup_cp(struct drm_device * dev); static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); +u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off) +{ + u32 val; + + if (dev_priv->flags & RADEON_IS_AGP) { + val = DRM_READ32(dev_priv->ring_rptr, off); + } else { + val = *(((volatile u32 *) + dev_priv->ring_rptr->handle) + + (off / sizeof(u32))); + val = le32_to_cpu(val); + } + return val; +} + +u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv) +{ + if (dev_priv->writeback_works) + return radeon_read_ring_rptr(dev_priv, 0); + else { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return RADEON_READ(R600_CP_RB_RPTR); + else + return RADEON_READ(RADEON_CP_RB_RPTR); + } +} + +void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val) +{ + if (dev_priv->flags & RADEON_IS_AGP) + DRM_WRITE32(dev_priv->ring_rptr, off, val); + else + *(((volatile u32 *) dev_priv->ring_rptr->handle) + + (off / sizeof(u32))) = cpu_to_le32(val); +} + +void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val) +{ + radeon_write_ring_rptr(dev_priv, 0, val); +} + +u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index) +{ + if (dev_priv->writeback_works) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return radeon_read_ring_rptr(dev_priv, + R600_SCRATCHOFF(index)); + else + return radeon_read_ring_rptr(dev_priv, + RADEON_SCRATCHOFF(index)); + } else { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return RADEON_READ(R600_SCRATCH_REG0 + 4*index); + else + return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index); + } +} + +u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr) +{ + u32 ret; + + if (addr < 0x10000) + ret = DRM_READ32(dev_priv->mmio, addr); + else { + DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr); + ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA); + } + + return ret; +} + static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) { u32 ret; @@ -71,23 +144,40 @@ return ret; } +static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) +{ + u32 ret; + RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) | + RS600_MC_IND_CITF_ARB0)); + ret = RADEON_READ(RS600_MC_DATA); + return ret; +} + static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) { if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) - return RS690_READ_MCIND(dev_priv, addr); + return RS690_READ_MCIND(dev_priv, addr); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + return RS600_READ_MCIND(dev_priv, addr); else - return RS480_READ_MCIND(dev_priv, addr); + return RS480_READ_MCIND(dev_priv, addr); } u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + return RADEON_READ(R700_MC_VM_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return RADEON_READ(R600_MC_VM_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); else @@ -96,42 +186,66 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); else RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); } -static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) +void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { + RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ + RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ + RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); else RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); } -static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) +void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) { u32 agp_base_hi = upper_32_bits(agp_base); u32 agp_base_lo = agp_base & 0xffffffff; + u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff; - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { + /* R6xx/R7xx must be aligned to a 4MB boundry */ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { + RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo); + RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi); } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); @@ -146,6 +260,25 @@ } } +void radeon_enable_bm(struct drm_radeon_private *dev_priv) +{ + u32 tmp; + /* Turn on bus mastering */ + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + /* rs600/rs690/rs740 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { + /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + } /* PCIE cards appears to not need this */ +} + static int RADEON_READ_PLL(struct drm_device * dev, int addr) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -163,7 +296,7 @@ #if RADEON_FIFO_DEBUG static void radeon_status(drm_radeon_private_t * dev_priv) { - printk("%s:\n", __FUNCTION__); + printk("%s:\n", __func__); printk("RBBM_STATUS = 0x%08x\n", (unsigned int)RADEON_READ(RADEON_RBBM_STATUS)); printk("CP_RB_RTPR = 0x%08x\n", @@ -231,7 +364,7 @@ return 0; DRM_UDELAY(1); } - DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n", + DRM_DEBUG("wait for fifo failed status : 0x%08X 0x%08X\n", RADEON_READ(RADEON_RBBM_STATUS), RADEON_READ(R300_VAP_CNTL_STATUS)); @@ -260,7 +393,7 @@ } DRM_UDELAY(1); } - DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n", + DRM_DEBUG("wait idle failed status : 0x%08X 0x%08X\n", RADEON_READ(RADEON_RBBM_STATUS), RADEON_READ(R300_VAP_CNTL_STATUS)); @@ -271,7 +404,7 @@ return -EBUSY; } -static void radeon_init_pipes(drm_radeon_private_t * dev_priv) +static void radeon_init_pipes(drm_radeon_private_t *dev_priv) { uint32_t gb_tile_config, gb_pipe_sel = 0; @@ -293,7 +426,7 @@ gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 /*| R300_SUBPIXEL_1_16*/); - switch(dev_priv->num_gb_pipes) { + switch (dev_priv->num_gb_pipes) { case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break; case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break; case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break; @@ -328,7 +461,6 @@ radeon_do_wait_for_idle(dev_priv); RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) || @@ -384,6 +516,14 @@ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, RS690_cp_microcode[i][0]); } + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { + DRM_INFO("Loading RS600 Microcode\n"); + for (i = 0; i < 256; i++) { + RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, + RS600_cp_microcode[i][1]); + RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, + RS600_cp_microcode[i][0]); + } } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || @@ -502,7 +642,7 @@ radeon_do_pixcache_flush(dev_priv); if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { - /* may need something similar for newer chips */ + /* may need something similar for newer chips */ clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); @@ -559,10 +699,10 @@ } static void radeon_cp_init_ring_buffer(struct drm_device * dev, - drm_radeon_private_t * dev_priv) + drm_radeon_private_t *dev_priv, + struct drm_file *file_priv) { u32 ring_start, cur_read_ptr; - u32 tmp; /* Initialize the memory controller. With new memory map, the fb location * is not changed, it should have been properly initialized already. Part @@ -611,17 +751,10 @@ } else #endif { - struct drm_sg_mem *entry = dev->sg; - unsigned long tmp_ofs, page_ofs; - - tmp_ofs = dev_priv->ring_rptr->offset - - (unsigned long)dev->sg->virtual; - page_ofs = tmp_ofs >> PAGE_SHIFT; - - RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); - DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n", - (unsigned long)entry->busaddr[page_ofs], - entry->handle + tmp_ofs); + RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, + dev_priv->ring_rptr->offset + - ((unsigned long) dev->sg->virtual) + + dev_priv->gart_vm_start); } /* Set ring buffer size */ @@ -638,6 +771,7 @@ dev_priv->ring.size_l2qw); #endif + /* Initialize the scratch register pointer. This will cause * the scratch register values to be written out to memory * whenever they are updated. @@ -648,37 +782,26 @@ RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + RADEON_SCRATCH_REG_OFFSET); - dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle + - (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); - /* Turn on bus mastering */ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - /* rs600/rs690/rs740 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { - /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } /* PCIE cards appears to not need this */ + radeon_enable_bm(dev_priv); - dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; - RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); + radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0); + RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); - dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; - RADEON_WRITE(RADEON_LAST_DISPATCH_REG, - dev_priv->sarea_priv->last_dispatch); + radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); + RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); - dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; - RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); + radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0); + RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); + /* reset sarea copies of these */ + if (dev_priv->sarea_priv) { + dev_priv->sarea_priv->last_frame = 0; + dev_priv->sarea_priv->last_dispatch = 0; + dev_priv->sarea_priv->last_clear = 0; + } + radeon_do_wait_for_idle(dev_priv); /* Sync everything up */ @@ -694,15 +817,21 @@ { u32 tmp; + /* Start with assuming that writeback doesn't work */ + dev_priv->writeback_works = 0; + /* Writeback doesn't seem to work everywhere, test it here and possibly * enable it if it appears to work */ - DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); + radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); + RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { - if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == - 0xdeadbeef) + u32 val; + + val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); + if (val == 0xdeadbeef) break; DRM_UDELAY(1); } @@ -720,8 +849,9 @@ } if (!dev_priv->writeback_works) { - /* Disable writeback to avoid unnecessary bus master transfers */ - RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | RADEON_RB_NO_UPDATE); + /* Disable writeback to avoid unnecessary bus master transfer */ + RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | + RADEON_RB_NO_UPDATE); RADEON_WRITE(RADEON_SCRATCH_UMSK, 0); } } @@ -733,12 +863,11 @@ if (on) { DRM_DEBUG("programming igp gart %08X %08lX %08X\n", - dev_priv->gart_vm_start, - (long)dev_priv->gart_info.bus_addr, - dev_priv->gart_size); + dev_priv->gart_vm_start, + (long)dev_priv->gart_info.bus_addr, + dev_priv->gart_size); temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | @@ -766,8 +895,8 @@ radeon_write_agp_base(dev_priv, dev_priv->gart_vm_start); dev_priv->gart_size = 32*1024*1024; - temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & - 0xffff0000) | (dev_priv->gart_vm_start >> 16)); + temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & + 0xffff0000) | (dev_priv->gart_vm_start >> 16)); radeon_write_agp_location(dev_priv, temp); @@ -780,7 +909,7 @@ if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) break; DRM_UDELAY(1); - } while(1); + } while (1); IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, RS480_GART_CACHE_INVALIDATE); @@ -790,7 +919,7 @@ if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) break; DRM_UDELAY(1); - } while(1); + } while (1); IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); } else { @@ -798,6 +927,82 @@ } } +/* Enable or disable IGP GART on the chip */ +static void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on) +{ + u32 temp; + int i; + + if (on) { + DRM_DEBUG("programming igp gart %08X %08lX %08X\n", + dev_priv->gart_vm_start, + (long)dev_priv->gart_info.bus_addr, + dev_priv->gart_size); + + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | + RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); + + for (i = 0; i < 19; i++) + IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, + (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | + RS600_SYSTEM_ACCESS_MODE_IN_SYS | + RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH | + RS600_EFFECTIVE_L1_CACHE_SIZE(3) | + RS600_ENABLE_FRAGMENT_PROCESSING | + RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); + + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | + RS600_PAGE_TABLE_TYPE_FLAT)); + + /* disable all other contexts */ + for (i = 1; i < 8; i++) + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); + + /* setup the page table aperture */ + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, + dev_priv->gart_info.bus_addr); + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, + dev_priv->gart_vm_start); + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, + (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); + + /* setup the system aperture */ + IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, + dev_priv->gart_vm_start); + IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, + (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); + + /* enable page tables */ + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); + + temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); + IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); + + /* invalidate the cache */ + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + } else { + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); + temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); + temp &= ~RS600_ENABLE_PAGE_TABLES; + IGP_WRITE_MCIND(RS600_MC_CNTL1, temp); + } +} + static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) { u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); @@ -839,6 +1044,11 @@ return; } + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { + rs600_set_igpgart(dev_priv, on); + return; + } + if (dev_priv->flags & RADEON_IS_PCIE) { radeon_set_pciegart(dev_priv, on); return; @@ -870,8 +1080,49 @@ } } -static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) +static int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv) { + struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; + struct radeon_virt_surface *vp; + int i; + + for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) { + if (!dev_priv->virt_surfaces[i].file_priv || + dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV) + break; + } + if (i >= 2 * RADEON_MAX_SURFACES) + return -ENOMEM; + vp = &dev_priv->virt_surfaces[i]; + + for (i = 0; i < RADEON_MAX_SURFACES; i++) { + struct radeon_surface *sp = &dev_priv->surfaces[i]; + if (sp->refcount) + continue; + + vp->surface_index = i; + vp->lower = gart_info->bus_addr; + vp->upper = vp->lower + gart_info->table_size; + vp->flags = 0; + vp->file_priv = PCIGART_FILE_PRIV; + + sp->refcount = 1; + sp->lower = vp->lower; + sp->upper = vp->upper; + sp->flags = 0; + + RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags); + RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower); + RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper); + return 0; + } + + return -ENOMEM; +} + +static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, + struct drm_file *file_priv) +{ drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); @@ -883,14 +1134,11 @@ return -EINVAL; } - if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) - { + if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { DRM_DEBUG("Forcing AGP card to PCI mode\n"); dev_priv->flags &= ~RADEON_IS_AGP; - } - else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) - && !init->is_pci) - { + } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) + && !init->is_pci) { DRM_DEBUG("Restoring AGP flag\n"); dev_priv->flags |= RADEON_IS_AGP; } @@ -913,6 +1161,17 @@ */ dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; + switch(init->func) { + case RADEON_INIT_R200_CP: + dev_priv->microcode_version = UCODE_R200; + break; + case RADEON_INIT_R300_CP: + dev_priv->microcode_version = UCODE_R300; + break; + default: + dev_priv->microcode_version = UCODE_R100; + } + dev_priv->do_boxes = 0; dev_priv->cp_mode = init->cp_mode; @@ -960,7 +1219,8 @@ */ dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | (dev_priv->color_fmt << 10) | - (dev_priv->chip_family < CHIP_R200 ? RADEON_ZBLOCK16 : 0)); + (dev_priv->microcode_version == + UCODE_R100 ? RADEON_ZBLOCK16 : 0)); dev_priv->depth_clear.rb3d_zstencilcntl = (dev_priv->depth_fmt | @@ -1031,9 +1291,9 @@ #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) { - drm_core_ioremap(dev_priv->cp_ring, dev); - drm_core_ioremap(dev_priv->ring_rptr, dev); - drm_core_ioremap(dev->agp_buffer_map, dev); + drm_core_ioremap_wc(dev_priv->cp_ring, dev); + drm_core_ioremap_wc(dev_priv->ring_rptr, dev); + drm_core_ioremap_wc(dev->agp_buffer_map, dev); if (!dev_priv->cp_ring->handle || !dev_priv->ring_rptr->handle || !dev->agp_buffer_map->handle) { @@ -1044,11 +1304,12 @@ } else #endif { - dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; + dev_priv->cp_ring->handle = + (void *)(unsigned long)dev_priv->cp_ring->offset; dev_priv->ring_rptr->handle = - (void *)dev_priv->ring_rptr->offset; + (void *)(unsigned long)dev_priv->ring_rptr->offset; dev->agp_buffer_map->handle = - (void *)dev->agp_buffer_map->offset; + (void *)(unsigned long)dev->agp_buffer_map->offset; DRM_DEBUG("dev_priv->cp_ring->handle %p\n", dev_priv->cp_ring->handle); @@ -1144,7 +1405,6 @@ dev_priv->ring.fetch_size = /* init->fetch_size */ 32; dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16); - dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; @@ -1156,6 +1416,9 @@ } else #endif { + u32 sctrl; + int ret; + dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); /* if we have an offset set from userspace */ if (dev_priv->pcigart_offset_set) { @@ -1197,21 +1460,37 @@ } } - if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { + sctrl = RADEON_READ(RADEON_SURFACE_CNTL); + RADEON_WRITE(RADEON_SURFACE_CNTL, 0); + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + ret = r600_page_table_init(dev); + else + ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info); + RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl); + + if (!ret) { DRM_ERROR("failed to init PCI GART!\n"); radeon_do_cleanup_cp(dev); return -ENOMEM; } + ret = radeon_setup_pcigart_surface(dev_priv); + if (ret) { + DRM_ERROR("failed to setup GART surface!\n"); + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + r600_page_table_cleanup(dev, &dev_priv->gart_info); + else + drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); + radeon_do_cleanup_cp(dev); + return ret; + } + /* Turn on PCI GART */ radeon_set_pcigart(dev_priv, 1); } - /* Start with assuming that writeback doesn't work */ - dev_priv->writeback_works = 0; - radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); dev_priv->last_buf = 0; @@ -1254,8 +1533,12 @@ if (dev_priv->gart_info.bus_addr) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); - if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) - DRM_ERROR("failed to cleanup PCI GART!\n"); + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + r600_page_table_cleanup(dev, &dev_priv->gart_info); + else { + if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) + DRM_ERROR("failed to cleanup PCI GART!\n"); + } } if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) @@ -1277,7 +1560,7 @@ * * Charl P. Botha */ -static int radeon_do_resume_cp(struct drm_device * dev) +static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -1300,7 +1583,7 @@ } radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); radeon_do_engine_reset(dev); radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); @@ -1312,6 +1595,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { + drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_init_t *init = data; LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -1323,9 +1607,14 @@ case RADEON_INIT_CP: case RADEON_INIT_R200_CP: case RADEON_INIT_R300_CP: - return radeon_do_init_cp(dev, init); + return radeon_do_init_cp(dev, init, file_priv); + case RADEON_INIT_R600_CP: + return r600_do_init_cp(dev, init, file_priv); case RADEON_CLEANUP_CP: - return radeon_do_cleanup_cp(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_cleanup_cp(dev); + else + return radeon_do_cleanup_cp(dev); } return -EINVAL; @@ -1348,7 +1637,10 @@ return 0; } - radeon_do_cp_start(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_cp_start(dev_priv); + else + radeon_do_cp_start(dev_priv); return 0; } @@ -1379,7 +1671,10 @@ * code so that the DRM ioctl wrapper can try again. */ if (stop->idle) { - ret = radeon_do_cp_idle(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + ret = r600_do_cp_idle(dev_priv); + else + ret = radeon_do_cp_idle(dev_priv); if (ret) return ret; } @@ -1388,10 +1683,16 @@ * we will get some dropped triangles as they won't be fully * rendered before the CP is shut down. */ - radeon_do_cp_stop(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_cp_stop(dev_priv); + else + radeon_do_cp_stop(dev_priv); /* Reset the engine */ - radeon_do_engine_reset(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_engine_reset(dev); + else + radeon_do_engine_reset(dev); return 0; } @@ -1404,34 +1705,53 @@ if (dev_priv) { if (dev_priv->cp_running) { /* Stop the cp */ - while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { - DRM_DEBUG("radeon_do_cp_idle %d\n", ret); + if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) { + while ((ret = r600_do_cp_idle(dev_priv)) != 0) { + DRM_DEBUG("radeon_do_cp_idle %d\n", ret); #ifdef __linux__ - schedule(); + schedule(); +#elsif defined(__FreeBSD__) + mtx_sleep(&ret, &dev->dev_lock, 0, + "rdnrel", 1); #else -#if defined(__FreeBSD__) && __FreeBSD_version > 500000 - mtx_sleep(&ret, &dev->dev_lock, PZERO, "rdnrel", - 1); + tsleep(&ret, PZERO, "rdnrel", 1); +#endif + } + } else { + while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { + DRM_DEBUG("radeon_do_cp_idle %d\n", ret); +#ifdef __linux__ + schedule(); +#elsif defined(__FreeBSD__) + mtx_sleep(&ret, &dev->dev_lock, 0, + "rdnrel", 1); #else - tsleep(&ret, PZERO, "rdnrel", 1); + tsleep(&ret, PZERO, "rdnrel", 1); #endif -#endif + } } - radeon_do_cp_stop(dev_priv); - radeon_do_engine_reset(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + r600_do_cp_stop(dev_priv); + r600_do_engine_reset(dev); + } else { + radeon_do_cp_stop(dev_priv); + radeon_do_engine_reset(dev); + } } - /* Disable *all* interrupts */ - if (dev_priv->mmio) /* remove this after permanent addmaps */ - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); + if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) { + /* Disable *all* interrupts */ + if (dev_priv->mmio) /* remove this after permanent addmaps */ + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - if (dev_priv->mmio) { /* remove all surfaces */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + - 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + - 16 * i, 0); + if (dev_priv->mmio) { /* remove all surfaces */ + for (i = 0; i < RADEON_MAX_SURFACES; i++) { + RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); + RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + + 16 * i, 0); + RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + + 16 * i, 0); + } } } @@ -1440,7 +1760,10 @@ radeon_mem_takedown(&(dev_priv->fb_heap)); /* deallocate kernel resources */ - radeon_do_cleanup_cp(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_cleanup_cp(dev); + else + radeon_do_cleanup_cp(dev); } } @@ -1458,7 +1781,10 @@ return -EINVAL; } - radeon_do_cp_reset(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_cp_reset(dev_priv); + else + radeon_do_cp_reset(dev_priv); /* The CP is no longer running after an engine reset */ dev_priv->cp_running = 0; @@ -1473,24 +1799,36 @@ LOCK_TEST_WITH_RETURN(dev, file_priv); - return radeon_do_cp_idle(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_cp_idle(dev_priv); + else + return radeon_do_cp_idle(dev_priv); } /* Added by Charl P. Botha to call radeon_do_resume_cp(). */ int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) { + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); - return radeon_do_resume_cp(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_resume_cp(dev, file_priv); + else + return radeon_do_resume_cp(dev, file_priv); } int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) { + drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); LOCK_TEST_WITH_RETURN(dev, file_priv); - return radeon_do_engine_reset(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_engine_reset(dev); + else + return radeon_do_engine_reset(dev); } /* ================================================================ @@ -1540,7 +1878,7 @@ start = dev_priv->last_buf; for (t = 0; t < dev_priv->usec_timeout; t++) { - u32 done_age = GET_SCRATCH(1); + u32 done_age = GET_SCRATCH(dev_priv, 1); DRM_DEBUG("done_age = %d\n", done_age); for (i = start; i < dma->buf_count; i++) { buf = dma->buflist[i]; @@ -1574,8 +1912,9 @@ struct drm_buf *buf; int i, t; int start; - u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); + u32 done_age; + done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); if (++dev_priv->last_buf >= dma->buf_count) dev_priv->last_buf = 0; @@ -1743,7 +2082,6 @@ break; } - dev_priv->chip_family = flags & RADEON_FAMILY_MASK; if (drm_device_is_agp(dev)) dev_priv->flags |= RADEON_IS_AGP; else if (drm_device_is_pcie(dev)) @@ -1751,6 +2089,12 @@ else dev_priv->flags |= RADEON_IS_PCI; + ret = drm_addmap(dev, drm_get_resource_start(dev, 2), + drm_get_resource_len(dev, 2), _DRM_REGISTERS, + _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); + if (ret != 0) + return ret; + ret = drm_vblank_init(dev, 2); if (ret) { radeon_driver_unload(dev); @@ -1773,12 +2117,6 @@ dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - ret = drm_addmap(dev, drm_get_resource_start(dev, 2), - drm_get_resource_len(dev, 2), _DRM_REGISTERS, - _DRM_READ_ONLY, &dev_priv->mmio); - if (ret != 0) - return ret; - dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); ret = drm_addmap(dev, dev_priv->fb_aper_offset, drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, @@ -1794,8 +2132,49 @@ drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); + + drm_rmmap(dev, dev_priv->mmio); + drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; return 0; } + +void radeon_commit_ring(drm_radeon_private_t *dev_priv) +{ + int i; + u32 *ring; + int tail_aligned; + + /* check if the ring is padded out to 16-dword alignment */ + + tail_aligned = dev_priv->ring.tail & 0xf; + if (tail_aligned) { + int num_p2 = 16 - tail_aligned; + + ring = dev_priv->ring.start; + /* pad with some CP_PACKET2 */ + for (i = 0; i < num_p2; i++) + ring[dev_priv->ring.tail + i] = CP_PACKET2(); + + dev_priv->ring.tail += i; + + dev_priv->ring.space -= num_p2 * sizeof(u32); + } + + dev_priv->ring.tail &= dev_priv->ring.tail_mask; + + DRM_MEMORYBARRIER(); + GET_RING_HEAD( dev_priv ); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); + /* read from PCI bus to ensure correct posting */ + RADEON_READ(R600_CP_RB_RPTR); + } else { + RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); + /* read from PCI bus to ensure correct posting */ + RADEON_READ(RADEON_CP_RB_RPTR); + } +} Index: dev/drm/drm_pciids.h =================================================================== --- dev/drm/drm_pciids.h (revision 189388) +++ dev/drm/drm_pciids.h (working copy) @@ -240,12 +240,123 @@ {0x1002, 0x7297, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \ {0x1002, 0x7834, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon RS350 9000/9100 IGP"}, \ {0x1002, 0x7835, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon RS350 Mobility IGP"}, \ + {0x1002, 0x793f, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon X1200"}, \ + {0x1002, 0x7941, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon X1200"}, \ + {0x1002, 0x7942, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon X1200"}, \ {0x1002, 0x791e, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS690 X1250 IGP"}, \ {0x1002, 0x791f, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS690 X1270 IGP"}, \ {0x1002, 0x796c, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \ {0x1002, 0x796d, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \ {0x1002, 0x796e, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \ {0x1002, 0x796f, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \ + {0x1002, 0x9400, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 XT"}, \ + {0x1002, 0x9401, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 XT"}, \ + {0x1002, 0x9402, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 XT"}, \ + {0x1002, 0x9403, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 Pro"}, \ + {0x1002, 0x9405, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 GT"}, \ + {0x1002, 0x940A, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V8650"}, \ + {0x1002, 0x940B, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V8600"}, \ + {0x1002, 0x940F, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V7600"}, \ + {0x1002, 0x94C0, CHIP_RV610|RADEON_NEW_MEMMAP, "RV610"}, \ + {0x1002, 0x94C1, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 XT"}, \ + {0x1002, 0x94C3, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 Pro"}, \ + {0x1002, 0x94C4, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 PRO AGP"}, \ + {0x1002, 0x94C5, CHIP_RV610|RADEON_NEW_MEMMAP, "FireGL V4000"}, \ + {0x1002, 0x94C6, CHIP_RV610|RADEON_NEW_MEMMAP, "RV610"}, \ + {0x1002, 0x94C7, CHIP_RV610|RADEON_NEW_MEMMAP, "ATI Radeon HD 2350"}, \ + {0x1002, 0x94C8, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2400 XT"}, \ + {0x1002, 0x94C9, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2400"}, \ + {0x1002, 0x94CB, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI RADEON E2400"}, \ + {0x1002, 0x94CC, CHIP_RV610|RADEON_NEW_MEMMAP, "ATI RV610"}, \ + {0x1002, 0x94CD, CHIP_RV610|RADEON_NEW_MEMMAP, "ATI FireMV 2260"}, \ + {0x1002, 0x9500, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI RV670"}, \ + {0x1002, 0x9501, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3870"}, \ + {0x1002, 0x9504, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3850"}, \ + {0x1002, 0x9505, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3850"}, \ + {0x1002, 0x9506, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3850 X2"}, \ + {0x1002, 0x9507, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI RV670"}, \ + {0x1002, 0x9508, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3870"}, \ + {0x1002, 0x9509, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3870 X2"}, \ + {0x1002, 0x950F, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3870 X2"}, \ + {0x1002, 0x9511, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI FireGL V7700"}, \ + {0x1002, 0x9515, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3850"}, \ + {0x1002, 0x9517, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3690"}, \ + {0x1002, 0x9519, CHIP_RV670|RADEON_NEW_MEMMAP, "AMD Firestream 9170"}, \ + {0x1002, 0x9580, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI RV630"}, \ + {0x1002, 0x9581, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2600"}, \ + {0x1002, 0x9583, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2600 XT"}, \ + {0x1002, 0x9586, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 XT AGP"}, \ + {0x1002, 0x9587, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 Pro AGP"}, \ + {0x1002, 0x9588, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 XT"}, \ + {0x1002, 0x9589, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 Pro"}, \ + {0x1002, 0x958A, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Gemini RV630"}, \ + {0x1002, 0x958B, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Gemini Mobility Radeon HD 2600 XT"}, \ + {0x1002, 0x958C, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI FireGL V5600"}, \ + {0x1002, 0x958D, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI FireGL V3600"}, \ + {0x1002, 0x958E, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 LE"}, \ + {0x1002, 0x958F, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL Graphics Processor"}, \ + {0x1002, 0x95C0, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3470"}, \ + {0x1002, 0x95C5, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3450"}, \ + {0x1002, 0x95C6, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3450"}, \ + {0x1002, 0x95C7, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3430"}, \ + {0x1002, 0x95C9, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3450"}, \ + {0x1002, 0x95C2, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3430"}, \ + {0x1002, 0x95C4, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3400 Series"}, \ + {0x1002, 0x95CC, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FirePro V3700"}, \ + {0x1002, 0x95CD, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FireMV 2450"}, \ + {0x1002, 0x95CE, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FireMV 2260"}, \ + {0x1002, 0x95CF, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FireMV 2260"}, \ + {0x1002, 0x9590, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 Series"}, \ + {0x1002, 0x9596, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3650 AGP"}, \ + {0x1002, 0x9597, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 PRO"}, \ + {0x1002, 0x9598, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 XT"}, \ + {0x1002, 0x9599, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 PRO"}, \ + {0x1002, 0x9591, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3650"}, \ + {0x1002, 0x9593, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3670"}, \ + {0x1002, 0x9595, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5700"}, \ + {0x1002, 0x959B, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5725"}, \ + {0x1002, 0x9610, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon HD 3200 Graphics"}, \ + {0x1002, 0x9611, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3100 Graphics"}, \ + {0x1002, 0x9612, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon HD 3200 Graphics"}, \ + {0x1002, 0x9613, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3100 Graphics"}, \ + {0x1002, 0x9614, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3300 Graphics"}, \ + {0x1002, 0x9440, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ + {0x1002, 0x9441, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4870 X2"}, \ + {0x1002, 0x9442, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ + {0x1002, 0x944C, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \ + {0x1002, 0x9450, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9270"}, \ + {0x1002, 0x9452, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9250"}, \ + {0x1002, 0x9444, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro V8750 (FireGL)"}, \ + {0x1002, 0x9446, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro V7760 (FireGL)"}, \ + {0x1002, 0x9456, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro V8700 (FireGL)"}, \ + {0x1002, 0x944E, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro RV770"}, \ + {0x1002, 0x944A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4850"}, \ + {0x1002, 0x944B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4850 X2"}, \ + {0x1002, 0x945A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4870"}, \ + {0x1002, 0x945B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon M98"}, \ + {0x1002, 0x946A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M7750"}, \ + {0x1002, 0x946B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M98"}, \ + {0x1002, 0x947A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M98"}, \ + {0x1002, 0x947B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M98"}, \ + {0x1002, 0x9487, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon RV730 (AGP)"}, \ + {0x1002, 0x948F, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon RV730 (AGP)"}, \ + {0x1002, 0x9490, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4670"}, \ + {0x1002, 0x9498, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4650"}, \ + {0x1002, 0x9480, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4650"}, \ + {0x1002, 0x9488, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4670"}, \ + {0x1002, 0x9489, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M5750"}, \ + {0x1002, 0x9491, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI RADEON E4600"}, \ + {0x1002, 0x949C, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI FirePro V7750 (FireGL)"}, \ + {0x1002, 0x949E, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI FirePro V5700 (FireGL)"}, \ + {0x1002, 0x949F, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI FirePro V3750 (FireGL)"}, \ + {0x1002, 0x9540, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon HD 4550"}, \ + {0x1002, 0x9541, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon RV710"}, \ + {0x1002, 0x9542, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon RV710"}, \ + {0x1002, 0x954E, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon RV710"}, \ + {0x1002, 0x954F, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon HD 4350"}, \ + {0x1002, 0x9552, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4300 Series"}, \ + {0x1002, 0x9553, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4500 Series"}, \ + {0x1002, 0x9555, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4500 Series"}, \ {0, 0, 0, NULL} #define r128_PCI_IDS \ Index: dev/drm/radeon_drv.h =================================================================== --- dev/drm/radeon_drv.h (revision 189388) +++ dev/drm/radeon_drv.h (working copy) @@ -41,7 +41,7 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20080613" +#define DRIVER_DATE "20080528" /* Interface history: * @@ -103,7 +103,6 @@ * 1.28- Add support for VBL on CRTC2 * 1.29- R500 3D cmd buffer support */ - #define DRIVER_MAJOR 1 #define DRIVER_MINOR 29 #define DRIVER_PATCHLEVEL 0 @@ -130,6 +129,7 @@ CHIP_RV410, CHIP_RS400, CHIP_RS480, + CHIP_RS600, CHIP_RS690, CHIP_RS740, CHIP_RV515, @@ -138,9 +138,25 @@ CHIP_RV560, CHIP_RV570, CHIP_R580, + CHIP_R600, + CHIP_RV610, + CHIP_RV630, + CHIP_RV620, + CHIP_RV635, + CHIP_RV670, + CHIP_RS780, + CHIP_RV770, + CHIP_RV730, + CHIP_RV710, CHIP_LAST, }; +enum radeon_cp_microcode_version { + UCODE_R100, + UCODE_R200, + UCODE_R300, +}; + /* * Chip flags */ @@ -158,10 +174,6 @@ RADEON_IS_IGPGART = 0x01000000UL, }; -#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ - DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR)) -#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) - typedef struct drm_radeon_freelist { unsigned int age; struct drm_buf *buf; @@ -172,8 +184,8 @@ typedef struct drm_radeon_ring_buffer { u32 *start; u32 *end; - int size; /* Double Words */ - int size_l2qw; /* log2 Quad Words */ + int size; + int size_l2qw; int rptr_update; /* Double Words */ int rptr_update_l2qw; /* log2 Quad Words */ @@ -219,13 +231,13 @@ u32 upper; u32 flags; struct drm_file *file_priv; +#define PCIGART_FILE_PRIV ((void *) -1L) }; -#define RADEON_FLUSH_EMITED (1 < 0) -#define RADEON_PURGE_EMITED (1 < 1) +#define RADEON_FLUSH_EMITED (1 << 0) +#define RADEON_PURGE_EMITED (1 << 1) typedef struct drm_radeon_private { - drm_radeon_ring_buffer_t ring; drm_radeon_sarea_t *sarea_priv; @@ -243,11 +255,12 @@ drm_radeon_freelist_t *head; drm_radeon_freelist_t *tail; int last_buf; - volatile u32 *scratch; int writeback_works; int usec_timeout; + int microcode_version; + struct { u32 boxes; int freelist_timeouts; @@ -284,7 +297,6 @@ unsigned long gart_textures_offset; drm_local_map_t *sarea; - drm_local_map_t *mmio; drm_local_map_t *cp_ring; drm_local_map_t *ring_rptr; drm_local_map_t *gart_textures; @@ -309,16 +321,33 @@ u32 scratch_ages[5]; - unsigned int crtc_last_cnt; - unsigned int crtc2_last_cnt; - /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ unsigned long fb_aper_offset; int num_gb_pipes; int track_flush; - uint32_t chip_family; /* extract from flags */ + drm_local_map_t *mmio; + + /* r6xx/r7xx pipe/shader config */ + int r600_max_pipes; + int r600_max_tile_pipes; + int r600_max_simds; + int r600_max_backends; + int r600_max_gprs; + int r600_max_threads; + int r600_max_stack_entries; + int r600_max_hw_contexts; + int r600_max_gs_threads; + int r600_sx_max_export_size; + int r600_sx_max_export_pos_size; + int r600_sx_max_export_smx_size; + int r600_sq_num_cf_insts; + int r700_sx_num_of_sets; + int r700_sc_prim_fifo_size; + int r700_sc_hiz_tile_fifo_size; + int r700_sc_earlyz_tile_fifo_fize; + } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -336,6 +365,12 @@ extern struct drm_ioctl_desc radeon_ioctls[]; extern int radeon_max_ioctl; +extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv); +extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val); + +#define GET_RING_HEAD(dev_priv) radeon_get_ring_head(dev_priv) +#define SET_RING_HEAD(dev_priv, val) radeon_set_ring_head(dev_priv, val) + /* Check whether the given hardware address is inside the framebuffer or the * GART area. */ @@ -362,6 +397,9 @@ extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv); +extern void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc); +extern void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base); +extern u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr); extern void radeon_freelist_reset(struct drm_device * dev); extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); @@ -370,6 +408,10 @@ extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); +extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags); +extern int radeon_presetup(struct drm_device *dev); +extern int radeon_driver_postcleanup(struct drm_device *dev); + extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -377,6 +419,10 @@ extern void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap); +extern void radeon_enable_bm(struct drm_radeon_private *dev_priv); +extern u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off); +extern void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val); + /* radeon_irq.c */ extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state); extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -388,23 +434,24 @@ extern void radeon_disable_vblank(struct drm_device *dev, int crtc); extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); extern void radeon_driver_irq_preinstall(struct drm_device * dev); -extern int radeon_driver_irq_postinstall(struct drm_device * dev); +extern int radeon_driver_irq_postinstall(struct drm_device *dev); extern void radeon_driver_irq_uninstall(struct drm_device * dev); +extern void radeon_enable_interrupt(struct drm_device *dev); extern int radeon_vblank_crtc_get(struct drm_device *dev); extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); extern int radeon_driver_unload(struct drm_device *dev); extern int radeon_driver_firstopen(struct drm_device *dev); -extern void radeon_driver_preclose(struct drm_device * dev, +extern void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); -extern void radeon_driver_postclose(struct drm_device * dev, +extern void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv); extern void radeon_driver_lastclose(struct drm_device * dev); -extern int radeon_driver_open(struct drm_device * dev, - struct drm_file * file_priv); +extern int radeon_driver_open(struct drm_device *dev, + struct drm_file *file_priv); extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); + unsigned long arg); /* r300_cmdbuf.c */ extern void r300_init_reg_flags(struct drm_device *dev); @@ -413,6 +460,21 @@ struct drm_file *file_priv, drm_radeon_kcmd_buffer_t *cmdbuf); +/* r600_cp.c */ +extern int r600_do_engine_reset(struct drm_device *dev); +extern int r600_do_cleanup_cp(struct drm_device *dev); +extern int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, + struct drm_file *file_priv); +extern int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv); +extern int r600_do_cp_idle(drm_radeon_private_t *dev_priv); +extern void r600_do_cp_start(drm_radeon_private_t *dev_priv); +extern void r600_do_cp_reset(drm_radeon_private_t *dev_priv); +extern void r600_do_cp_stop(drm_radeon_private_t *dev_priv); +extern int r600_cp_dispatch_indirect(struct drm_device *dev, + struct drm_buf *buf, int start, int end); +extern int r600_page_table_init(struct drm_device *dev); +extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); + /* Flags for stats.boxes */ #define RADEON_BOX_DMA_IDLE 0x1 @@ -424,9 +486,12 @@ /* Register definitions, register access macros and drmAddMap constants * for Radeon kernel driver. */ +#define RADEON_MM_INDEX 0x0000 +#define RADEON_MM_DATA 0x0004 + #define RADEON_AGP_COMMAND 0x0f60 -#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ -# define RADEON_AGP_ENABLE (1<<8) +#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ +# define RADEON_AGP_ENABLE (1<<8) #define RADEON_AUX_SCISSOR_CNTL 0x26f0 # define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24) # define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25) @@ -447,7 +512,7 @@ /* rs600/rs690/rs740 */ # define RS600_BUS_MASTER_DIS (1 << 14) # define RS600_MSI_REARM (1 << 20) -/* see RS480_MSI_REARM in AIC_CNTL for rs480 */ +/* see RS400_MSI_REARM in AIC_CNTL for rs480 */ #define RADEON_BUS_CNTL1 0x0034 # define RADEON_PMI_BM_DIS (1 << 2) @@ -465,7 +530,7 @@ # define RADEON_PLL_WR_EN (1 << 7) #define RADEON_CLOCK_CNTL_INDEX 0x0008 #define RADEON_CONFIG_APER_SIZE 0x0108 -#define RADEON_CONFIG_MEMSIZE 0x00f8 +#define RADEON_CONFIG_MEMSIZE 0x00f8 #define RADEON_CRTC_OFFSET 0x0224 #define RADEON_CRTC_OFFSET_CNTL 0x0228 # define RADEON_CRTC_TILE_EN (1 << 15) @@ -545,6 +610,56 @@ #define RS690_MC_AGP_BASE 0x102 #define RS690_MC_AGP_BASE_2 0x103 +#define RS600_MC_INDEX 0x70 +# define RS600_MC_ADDR_MASK 0xffff +# define RS600_MC_IND_SEQ_RBS_0 (1 << 16) +# define RS600_MC_IND_SEQ_RBS_1 (1 << 17) +# define RS600_MC_IND_SEQ_RBS_2 (1 << 18) +# define RS600_MC_IND_SEQ_RBS_3 (1 << 19) +# define RS600_MC_IND_AIC_RBS (1 << 20) +# define RS600_MC_IND_CITF_ARB0 (1 << 21) +# define RS600_MC_IND_CITF_ARB1 (1 << 22) +# define RS600_MC_IND_WR_EN (1 << 23) +#define RS600_MC_DATA 0x74 + +#define RS600_MC_STATUS 0x0 +# define RS600_MC_IDLE (1 << 1) +#define RS600_MC_FB_LOCATION 0x4 +#define RS600_MC_AGP_LOCATION 0x5 +#define RS600_AGP_BASE 0x6 +#define RS600_AGP_BASE_2 0x7 +#define RS600_MC_CNTL1 0x9 +# define RS600_ENABLE_PAGE_TABLES (1 << 26) +#define RS600_MC_PT0_CNTL 0x100 +# define RS600_ENABLE_PT (1 << 0) +# define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15) +# define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21) +# define RS600_INVALIDATE_ALL_L1_TLBS (1 << 28) +# define RS600_INVALIDATE_L2_CACHE (1 << 29) +#define RS600_MC_PT0_CONTEXT0_CNTL 0x102 +# define RS600_ENABLE_PAGE_TABLE (1 << 0) +# define RS600_PAGE_TABLE_TYPE_FLAT (0 << 1) +#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x112 +#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x114 +#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c +#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x12c +#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x13c +#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x14c +#define RS600_MC_PT0_CLIENT0_CNTL 0x16c +# define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE (1 << 0) +# define RS600_TRANSLATION_MODE_OVERRIDE (1 << 1) +# define RS600_SYSTEM_ACCESS_MODE_MASK (3 << 8) +# define RS600_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 8) +# define RS600_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 8) +# define RS600_SYSTEM_ACCESS_MODE_IN_SYS (2 << 8) +# define RS600_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 8) +# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH (0 << 10) +# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 10) +# define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11) +# define RS600_ENABLE_FRAGMENT_PROCESSING (1 << 14) +# define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) +# define RS600_INVALIDATE_L1_TLB (1 << 20) + #define R520_MC_IND_INDEX 0x70 #define R520_MC_IND_WR_EN (1 << 24) #define R520_MC_IND_DATA 0x74 @@ -628,16 +743,23 @@ #define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) -#define GET_SCRATCH( x ) (dev_priv->writeback_works \ - ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ - : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) +extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); -#define RADEON_CRTC_CRNT_FRAME 0x0214 -#define RADEON_CRTC2_CRNT_FRAME 0x0314 +#define GET_SCRATCH(dev_priv, x) radeon_get_scratch(dev_priv, x) -#define RADEON_CRTC_STATUS 0x005c -#define RADEON_CRTC2_STATUS 0x03fc +#define R600_SCRATCH_REG0 0x8500 +#define R600_SCRATCH_REG1 0x8504 +#define R600_SCRATCH_REG2 0x8508 +#define R600_SCRATCH_REG3 0x850c +#define R600_SCRATCH_REG4 0x8510 +#define R600_SCRATCH_REG5 0x8514 +#define R600_SCRATCH_REG6 0x8518 +#define R600_SCRATCH_REG7 0x851c +#define R600_SCRATCH_UMSK 0x8540 +#define R600_SCRATCH_ADDR 0x8544 +#define R600_SCRATCHOFF(x) (R600_SCRATCH_REG_OFFSET + 4*(x)) + #define RADEON_GEN_INT_CNTL 0x0040 # define RADEON_CRTC_VBLANK_MASK (1 << 0) # define RADEON_CRTC2_VBLANK_MASK (1 << 9) @@ -655,7 +777,6 @@ # define RADEON_SW_INT_FIRE (1 << 26) # define R500_DISPLAY_INT_STATUS (1 << 0) - #define RADEON_HOST_PATH_CNTL 0x0130 # define RADEON_HDP_SOFT_RESET (1 << 26) # define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) @@ -730,7 +851,7 @@ # define R300_ZC_FLUSH (1 << 0) # define R300_ZC_FREE (1 << 1) # define R300_ZC_BUSY (1 << 31) -#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c +#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c # define RADEON_RB3D_DC_FLUSH (3 << 0) # define RADEON_RB3D_DC_FREE (3 << 2) # define RADEON_RB3D_DC_FLUSH_ALL 0xf @@ -742,15 +863,15 @@ #define RADEON_RB3D_ZSTENCILCNTL 0x1c2c # define RADEON_Z_TEST_MASK (7 << 4) # define RADEON_Z_TEST_ALWAYS (7 << 4) -# define RADEON_Z_HIERARCHY_ENABLE (1 << 8) +# define RADEON_Z_HIERARCHY_ENABLE (1 << 8) # define RADEON_STENCIL_TEST_ALWAYS (7 << 12) # define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) # define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) # define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) -# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) -# define RADEON_FORCE_Z_DIRTY (1 << 29) +# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) +# define RADEON_FORCE_Z_DIRTY (1 << 29) # define RADEON_Z_WRITE_ENABLE (1 << 30) -# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31) +# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31) #define RADEON_RBBM_SOFT_RESET 0x00f0 # define RADEON_SOFT_RESET_CP (1 << 0) # define RADEON_SOFT_RESET_HI (1 << 1) @@ -918,6 +1039,7 @@ #define RADEON_CP_RB_CNTL 0x0704 # define RADEON_BUF_SWAP_32BIT (2 << 16) # define RADEON_RB_NO_UPDATE (1 << 27) +# define RADEON_RB_RPTR_WR_ENA (1 << 31) #define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_WPTR 0x0714 @@ -957,7 +1079,7 @@ # define RADEON_CP_NEXT_CHAR 0x00001900 # define RADEON_CP_PLY_NEXTSCAN 0x00001D00 # define RADEON_CP_SET_SCISSORS 0x00001E00 - /* GEN_INDX_PRIM is unsupported starting with R300 */ + /* GEN_INDX_PRIM is unsupported starting with R300 */ # define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 # define RADEON_WAIT_FOR_IDLE 0x00002600 # define RADEON_3D_DRAW_VBUF 0x00002800 @@ -979,6 +1101,14 @@ # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 # define RADEON_CNTL_SET_SCISSORS 0xC0001E00 +# define R600_IT_INDIRECT_BUFFER 0x00003200 +# define R600_IT_ME_INITIALIZE 0x00004400 +# define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) +# define R600_IT_EVENT_WRITE 0x00004600 +# define R600_IT_SET_CONFIG_REG 0x00006800 +# define R600_SET_CONFIG_REG_OFFSET 0x00008000 +# define R600_SET_CONFIG_REG_END 0x0000ac00 + #define RADEON_CP_PACKET_MASK 0xC0000000 #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 #define RADEON_CP_PACKET0_REG_MASK 0x000007ff @@ -1142,41 +1272,16 @@ #define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4 -#define R200_PP_TRI_PERF 0x2cf8 +#define R200_PP_TRI_PERF 0x2cf8 #define R200_PP_AFS_0 0x2f80 -#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ +#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ #define R200_VAP_PVS_CNTL_1 0x22D0 -/* MPEG settings from VHA code */ -#define RADEON_VHA_SETTO16_1 0x2694 -#define RADEON_VHA_SETTO16_2 0x2680 -#define RADEON_VHA_SETTO0_1 0x1840 -#define RADEON_VHA_FB_OFFSET 0x19e4 -#define RADEON_VHA_SETTO1AND70S 0x19d8 -#define RADEON_VHA_DST_PITCH 0x1408 +#define RADEON_CRTC_CRNT_FRAME 0x0214 +#define RADEON_CRTC2_CRNT_FRAME 0x0314 -// set as reference header -#define RADEON_VHA_BACKFRAME0_OFF_Y 0x1840 -#define RADEON_VHA_BACKFRAME1_OFF_PITCH_Y 0x1844 -#define RADEON_VHA_BACKFRAME0_OFF_U 0x1848 -#define RADEON_VHA_BACKFRAME1_OFF_PITCH_U 0x184c -#define RADOEN_VHA_BACKFRAME0_OFF_V 0x1850 -#define RADEON_VHA_BACKFRAME1_OFF_PITCH_V 0x1854 -#define RADEON_VHA_FORWFRAME0_OFF_Y 0x1858 -#define RADEON_VHA_FORWFRAME1_OFF_PITCH_Y 0x185c -#define RADEON_VHA_FORWFRAME0_OFF_U 0x1860 -#define RADEON_VHA_FORWFRAME1_OFF_PITCH_U 0x1864 -#define RADEON_VHA_FORWFRAME0_OFF_V 0x1868 -#define RADEON_VHA_FORWFRAME0_OFF_PITCH_V 0x1880 -#define RADEON_VHA_BACKFRAME0_OFF_Y_2 0x1884 -#define RADEON_VHA_BACKFRAME1_OFF_PITCH_Y_2 0x1888 -#define RADEON_VHA_BACKFRAME0_OFF_U_2 0x188c -#define RADEON_VHA_BACKFRAME1_OFF_PITCH_U_2 0x1890 -#define RADEON_VHA_BACKFRAME0_OFF_V_2 0x1894 -#define RADEON_VHA_BACKFRAME1_OFF_PITCH_V_2 0x1898 - #define R500_D1CRTC_STATUS 0x609c #define R500_D2CRTC_STATUS 0x689c #define R500_CRTC_V_BLANK (1<<0) @@ -1202,6 +1307,422 @@ #define R500_D1_VBLANK_INTERRUPT (1 << 4) #define R500_D2_VBLANK_INTERRUPT (1 << 5) +/* R6xx/R7xx registers */ +#define R600_MC_VM_FB_LOCATION 0x2180 +#define R600_MC_VM_AGP_TOP 0x2184 +#define R600_MC_VM_AGP_BOT 0x2188 +#define R600_MC_VM_AGP_BASE 0x218c +#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 +#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 +#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 + +#define R700_MC_VM_FB_LOCATION 0x2024 +#define R700_MC_VM_AGP_TOP 0x2028 +#define R700_MC_VM_AGP_BOT 0x202c +#define R700_MC_VM_AGP_BASE 0x2030 +#define R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 +#define R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 +#define R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203c + +#define R600_MCD_RD_A_CNTL 0x219c +#define R600_MCD_RD_B_CNTL 0x21a0 + +#define R600_MCD_WR_A_CNTL 0x21a4 +#define R600_MCD_WR_B_CNTL 0x21a8 + +#define R600_MCD_RD_SYS_CNTL 0x2200 +#define R600_MCD_WR_SYS_CNTL 0x2214 + +#define R600_MCD_RD_GFX_CNTL 0x21fc +#define R600_MCD_RD_HDP_CNTL 0x2204 +#define R600_MCD_RD_PDMA_CNTL 0x2208 +#define R600_MCD_RD_SEM_CNTL 0x220c +#define R600_MCD_WR_GFX_CNTL 0x2210 +#define R600_MCD_WR_HDP_CNTL 0x2218 +#define R600_MCD_WR_PDMA_CNTL 0x221c +#define R600_MCD_WR_SEM_CNTL 0x2220 + +# define R600_MCD_L1_TLB (1 << 0) +# define R600_MCD_L1_FRAG_PROC (1 << 1) +# define R600_MCD_L1_STRICT_ORDERING (1 << 2) + +# define R600_MCD_SYSTEM_ACCESS_MODE_MASK (3 << 6) +# define R600_MCD_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6) +# define R600_MCD_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6) +# define R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS (2 << 6) +# define R600_MCD_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6) + +# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8) +# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8) + +# define R600_MCD_SEMAPHORE_MODE (1 << 10) +# define R600_MCD_WAIT_L2_QUERY (1 << 11) +# define R600_MCD_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 12) +# define R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) + +#define R700_MC_VM_MD_L1_TLB0_CNTL 0x2654 +#define R700_MC_VM_MD_L1_TLB1_CNTL 0x2658 +#define R700_MC_VM_MD_L1_TLB2_CNTL 0x265c + +#define R700_MC_VM_MB_L1_TLB0_CNTL 0x2234 +#define R700_MC_VM_MB_L1_TLB1_CNTL 0x2238 +#define R700_MC_VM_MB_L1_TLB2_CNTL 0x223c +#define R700_MC_VM_MB_L1_TLB3_CNTL 0x2240 + +# define R700_ENABLE_L1_TLB (1 << 0) +# define R700_ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) +# define R700_SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) +# define R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) +# define R700_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 15) +# define R700_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 18) + +#define R700_MC_ARB_RAMCFG 0x2760 +# define R700_NOOFBANK_SHIFT 0 +# define R700_NOOFBANK_MASK 0x3 +# define R700_NOOFRANK_SHIFT 2 +# define R700_NOOFRANK_MASK 0x1 +# define R700_NOOFROWS_SHIFT 3 +# define R700_NOOFROWS_MASK 0x7 +# define R700_NOOFCOLS_SHIFT 6 +# define R700_NOOFCOLS_MASK 0x3 +# define R700_CHANSIZE_SHIFT 8 +# define R700_CHANSIZE_MASK 0x1 +# define R700_BURSTLENGTH_SHIFT 9 +# define R700_BURSTLENGTH_MASK 0x1 +#define R600_RAMCFG 0x2408 +# define R600_NOOFBANK_SHIFT 0 +# define R600_NOOFBANK_MASK 0x1 +# define R600_NOOFRANK_SHIFT 1 +# define R600_NOOFRANK_MASK 0x1 +# define R600_NOOFROWS_SHIFT 2 +# define R600_NOOFROWS_MASK 0x7 +# define R600_NOOFCOLS_SHIFT 5 +# define R600_NOOFCOLS_MASK 0x3 +# define R600_CHANSIZE_SHIFT 7 +# define R600_CHANSIZE_MASK 0x1 +# define R600_BURSTLENGTH_SHIFT 8 +# define R600_BURSTLENGTH_MASK 0x1 + +#define R600_VM_L2_CNTL 0x1400 +# define R600_VM_L2_CACHE_EN (1 << 0) +# define R600_VM_L2_FRAG_PROC (1 << 1) +# define R600_VM_ENABLE_PTE_CACHE_LRU_W (1 << 9) +# define R600_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 13) +# define R700_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 14) + +#define R600_VM_L2_CNTL2 0x1404 +# define R600_VM_L2_CNTL2_INVALIDATE_ALL_L1_TLBS (1 << 0) +# define R600_VM_L2_CNTL2_INVALIDATE_L2_CACHE (1 << 1) +#define R600_VM_L2_CNTL3 0x1408 +# define R600_VM_L2_CNTL3_BANK_SELECT_0(x) ((x) << 0) +# define R600_VM_L2_CNTL3_BANK_SELECT_1(x) ((x) << 5) +# define R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 10) +# define R700_VM_L2_CNTL3_BANK_SELECT(x) ((x) << 0) +# define R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 6) + +#define R600_VM_L2_STATUS 0x140c + +#define R600_VM_CONTEXT0_CNTL 0x1410 +# define R600_VM_ENABLE_CONTEXT (1 << 0) +# define R600_VM_PAGE_TABLE_DEPTH_FLAT (0 << 1) + +#define R600_VM_CONTEXT0_CNTL2 0x1430 +#define R600_VM_CONTEXT0_REQUEST_RESPONSE 0x1470 +#define R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490 +#define R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14b0 +#define R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574 +#define R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594 +#define R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15b4 + +#define R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153c +#define R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155c +#define R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157c + +#define R600_HDP_HOST_PATH_CNTL 0x2c00 + +#define R600_GRBM_CNTL 0x8000 +# define R600_GRBM_READ_TIMEOUT(x) ((x) << 0) + +#define R600_GRBM_STATUS 0x8010 +# define R600_CMDFIFO_AVAIL_MASK 0x1f +# define R700_CMDFIFO_AVAIL_MASK 0xf +# define R600_GUI_ACTIVE (1 << 31) +#define R600_GRBM_STATUS2 0x8014 +#define R600_GRBM_SOFT_RESET 0x8020 +# define R600_SOFT_RESET_CP (1 << 0) +#define R600_WAIT_UNTIL 0x8040 + +#define R600_CP_SEM_WAIT_TIMER 0x85bc +#define R600_CP_ME_CNTL 0x86d8 +# define R600_CP_ME_HALT (1 << 28) +#define R600_CP_QUEUE_THRESHOLDS 0x8760 +# define R600_ROQ_IB1_START(x) ((x) << 0) +# define R600_ROQ_IB2_START(x) ((x) << 8) +#define R600_CP_MEQ_THRESHOLDS 0x8764 +# define R700_STQ_SPLIT(x) ((x) << 0) +# define R600_MEQ_END(x) ((x) << 16) +# define R600_ROQ_END(x) ((x) << 24) +#define R600_CP_PERFMON_CNTL 0x87fc +#define R600_CP_RB_BASE 0xc100 +#define R600_CP_RB_CNTL 0xc104 +# define R600_RB_BUFSZ(x) ((x) << 0) +# define R600_RB_BLKSZ(x) ((x) << 8) +# define R600_RB_NO_UPDATE (1 << 27) +# define R600_RB_RPTR_WR_ENA (1 << 31) +#define R600_CP_RB_RPTR_WR 0xc108 +#define R600_CP_RB_RPTR_ADDR 0xc10c +#define R600_CP_RB_RPTR_ADDR_HI 0xc110 +#define R600_CP_RB_WPTR 0xc114 +#define R600_CP_RB_WPTR_ADDR 0xc118 +#define R600_CP_RB_WPTR_ADDR_HI 0xc11c +#define R600_CP_RB_RPTR 0x8700 +#define R600_CP_RB_WPTR_DELAY 0x8704 +#define R600_CP_PFP_UCODE_ADDR 0xc150 +#define R600_CP_PFP_UCODE_DATA 0xc154 +#define R600_CP_ME_RAM_RADDR 0xc158 +#define R600_CP_ME_RAM_WADDR 0xc15c +#define R600_CP_ME_RAM_DATA 0xc160 +#define R600_CP_DEBUG 0xc1fc + +#define R600_PA_CL_ENHANCE 0x8a14 +# define R600_CLIP_VTX_REORDER_ENA (1 << 0) +# define R600_NUM_CLIP_SEQ(x) ((x) << 1) +#define R600_PA_SC_LINE_STIPPLE_STATE 0x8b10 +#define R600_PA_SC_MULTI_CHIP_CNTL 0x8b20 +#define R700_PA_SC_FORCE_EOV_MAX_CNTS 0x8b24 +# define R700_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) +# define R700_FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) +#define R600_PA_SC_AA_SAMPLE_LOCS_2S 0x8b40 +#define R600_PA_SC_AA_SAMPLE_LOCS_4S 0x8b44 +#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8b48 +#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8b4c +# define R600_S0_X(x) ((x) << 0) +# define R600_S0_Y(x) ((x) << 4) +# define R600_S1_X(x) ((x) << 8) +# define R600_S1_Y(x) ((x) << 12) +# define R600_S2_X(x) ((x) << 16) +# define R600_S2_Y(x) ((x) << 20) +# define R600_S3_X(x) ((x) << 24) +# define R600_S3_Y(x) ((x) << 28) +# define R600_S4_X(x) ((x) << 0) +# define R600_S4_Y(x) ((x) << 4) +# define R600_S5_X(x) ((x) << 8) +# define R600_S5_Y(x) ((x) << 12) +# define R600_S6_X(x) ((x) << 16) +# define R600_S6_Y(x) ((x) << 20) +# define R600_S7_X(x) ((x) << 24) +# define R600_S7_Y(x) ((x) << 28) +#define R600_PA_SC_FIFO_SIZE 0x8bd0 +# define R600_SC_PRIM_FIFO_SIZE(x) ((x) << 0) +# define R600_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 8) +# define R600_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 16) +#define R700_PA_SC_FIFO_SIZE_R7XX 0x8bcc +# define R700_SC_PRIM_FIFO_SIZE(x) ((x) << 0) +# define R700_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) +# define R700_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) +#define R600_PA_SC_ENHANCE 0x8bf0 +# define R600_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) +# define R600_FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12) +#define R600_PA_SC_CLIPRECT_RULE 0x2820c +#define R700_PA_SC_EDGERULE 0x28230 +#define R600_PA_SC_LINE_STIPPLE 0x28a0c +#define R600_PA_SC_MODE_CNTL 0x28a4c +#define R600_PA_SC_AA_CONFIG 0x28c04 + +#define R600_SX_EXPORT_BUFFER_SIZES 0x900c +# define R600_COLOR_BUFFER_SIZE(x) ((x) << 0) +# define R600_POSITION_BUFFER_SIZE(x) ((x) << 8) +# define R600_SMX_BUFFER_SIZE(x) ((x) << 16) +#define R600_SX_DEBUG_1 0x9054 +# define R600_SMX_EVENT_RELEASE (1 << 0) +# define R600_ENABLE_NEW_SMX_ADDRESS (1 << 16) +#define R700_SX_DEBUG_1 0x9058 +# define R700_ENABLE_NEW_SMX_ADDRESS (1 << 16) +#define R600_SX_MISC 0x28350 + +#define R600_DB_DEBUG 0x9830 +# define R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) +#define R600_DB_WATERMARKS 0x9838 +# define R600_DEPTH_FREE(x) ((x) << 0) +# define R600_DEPTH_FLUSH(x) ((x) << 5) +# define R600_DEPTH_PENDING_FREE(x) ((x) << 15) +# define R600_DEPTH_CACHELINE_FREE(x) ((x) << 20) +#define R700_DB_DEBUG3 0x98b0 +# define R700_DB_CLK_OFF_DELAY(x) ((x) << 11) +#define RV700_DB_DEBUG4 0x9b8c +# define RV700_DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6) + +#define R600_VGT_CACHE_INVALIDATION 0x88c4 +# define R600_CACHE_INVALIDATION(x) ((x) << 0) +# define R600_VC_ONLY 0 +# define R600_TC_ONLY 1 +# define R600_VC_AND_TC 2 +# define R700_AUTO_INVLD_EN(x) ((x) << 6) +# define R700_NO_AUTO 0 +# define R700_ES_AUTO 1 +# define R700_GS_AUTO 2 +# define R700_ES_AND_GS_AUTO 3 +#define R600_VGT_GS_PER_ES 0x88c8 +#define R600_VGT_ES_PER_GS 0x88cc +#define R600_VGT_GS_PER_VS 0x88e8 +#define R600_VGT_GS_VERTEX_REUSE 0x88d4 +#define R600_VGT_NUM_INSTANCES 0x8974 +#define R600_VGT_STRMOUT_EN 0x28ab0 +#define R600_VGT_EVENT_INITIATOR 0x28a90 +# define R600_CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) +#define R600_VGT_VERTEX_REUSE_BLOCK_CNTL 0x28c58 +# define R600_VTX_REUSE_DEPTH_MASK 0xff +#define R600_VGT_OUT_DEALLOC_CNTL 0x28c5c +# define R600_DEALLOC_DIST_MASK 0x7f + +#define R600_CB_COLOR0_BASE 0x28040 +#define R600_CB_COLOR1_BASE 0x28044 +#define R600_CB_COLOR2_BASE 0x28048 +#define R600_CB_COLOR3_BASE 0x2804c +#define R600_CB_COLOR4_BASE 0x28050 +#define R600_CB_COLOR5_BASE 0x28054 +#define R600_CB_COLOR6_BASE 0x28058 +#define R600_CB_COLOR7_BASE 0x2805c +#define R600_CB_COLOR7_FRAG 0x280fc + +#define R600_TC_CNTL 0x9608 +# define R600_TC_L2_SIZE(x) ((x) << 5) +# define R600_L2_DISABLE_LATE_HIT (1 << 9) + +#define R600_ARB_POP 0x2418 +# define R600_ENABLE_TC128 (1 << 30) +#define R600_ARB_GDEC_RD_CNTL 0x246c + +#define R600_TA_CNTL_AUX 0x9508 +# define R600_DISABLE_CUBE_WRAP (1 << 0) +# define R600_DISABLE_CUBE_ANISO (1 << 1) +# define R700_GETLOD_SELECT(x) ((x) << 2) +# define R600_SYNC_GRADIENT (1 << 24) +# define R600_SYNC_WALKER (1 << 25) +# define R600_SYNC_ALIGNER (1 << 26) +# define R600_BILINEAR_PRECISION_6_BIT (0 << 31) +# define R600_BILINEAR_PRECISION_8_BIT (1 << 31) + +#define R700_TCP_CNTL 0x9610 + +#define R600_SMX_DC_CTL0 0xa020 +# define R700_USE_HASH_FUNCTION (1 << 0) +# define R700_CACHE_DEPTH(x) ((x) << 1) +# define R700_FLUSH_ALL_ON_EVENT (1 << 10) +# define R700_STALL_ON_EVENT (1 << 11) +#define R700_SMX_EVENT_CTL 0xa02c +# define R700_ES_FLUSH_CTL(x) ((x) << 0) +# define R700_GS_FLUSH_CTL(x) ((x) << 3) +# define R700_ACK_FLUSH_CTL(x) ((x) << 6) +# define R700_SYNC_FLUSH_CTL (1 << 8) + +#define R600_SQ_CONFIG 0x8c00 +# define R600_VC_ENABLE (1 << 0) +# define R600_EXPORT_SRC_C (1 << 1) +# define R600_DX9_CONSTS (1 << 2) +# define R600_ALU_INST_PREFER_VECTOR (1 << 3) +# define R600_DX10_CLAMP (1 << 4) +# define R600_CLAUSE_SEQ_PRIO(x) ((x) << 8) +# define R600_PS_PRIO(x) ((x) << 24) +# define R600_VS_PRIO(x) ((x) << 26) +# define R600_GS_PRIO(x) ((x) << 28) +# define R600_ES_PRIO(x) ((x) << 30) +#define R600_SQ_GPR_RESOURCE_MGMT_1 0x8c04 +# define R600_NUM_PS_GPRS(x) ((x) << 0) +# define R600_NUM_VS_GPRS(x) ((x) << 16) +# define R700_DYN_GPR_ENABLE (1 << 27) +# define R600_NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) +#define R600_SQ_GPR_RESOURCE_MGMT_2 0x8c08 +# define R600_NUM_GS_GPRS(x) ((x) << 0) +# define R600_NUM_ES_GPRS(x) ((x) << 16) +#define R600_SQ_THREAD_RESOURCE_MGMT 0x8c0c +# define R600_NUM_PS_THREADS(x) ((x) << 0) +# define R600_NUM_VS_THREADS(x) ((x) << 8) +# define R600_NUM_GS_THREADS(x) ((x) << 16) +# define R600_NUM_ES_THREADS(x) ((x) << 24) +#define R600_SQ_STACK_RESOURCE_MGMT_1 0x8c10 +# define R600_NUM_PS_STACK_ENTRIES(x) ((x) << 0) +# define R600_NUM_VS_STACK_ENTRIES(x) ((x) << 16) +#define R600_SQ_STACK_RESOURCE_MGMT_2 0x8c14 +# define R600_NUM_GS_STACK_ENTRIES(x) ((x) << 0) +# define R600_NUM_ES_STACK_ENTRIES(x) ((x) << 16) +#define R600_SQ_MS_FIFO_SIZES 0x8cf0 +# define R600_CACHE_FIFO_SIZE(x) ((x) << 0) +# define R600_FETCH_FIFO_HIWATER(x) ((x) << 8) +# define R600_DONE_FIFO_HIWATER(x) ((x) << 16) +# define R600_ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8db0 +# define R700_SIMDA_RING0(x) ((x) << 0) +# define R700_SIMDA_RING1(x) ((x) << 8) +# define R700_SIMDB_RING0(x) ((x) << 16) +# define R700_SIMDB_RING1(x) ((x) << 24) +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8db4 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8db8 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8dbc +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8dc0 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8dc4 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8dc8 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8dcc + +#define R600_SPI_PS_IN_CONTROL_0 0x286cc +# define R600_NUM_INTERP(x) ((x) << 0) +# define R600_POSITION_ENA (1 << 8) +# define R600_POSITION_CENTROID (1 << 9) +# define R600_POSITION_ADDR(x) ((x) << 10) +# define R600_PARAM_GEN(x) ((x) << 15) +# define R600_PARAM_GEN_ADDR(x) ((x) << 19) +# define R600_BARYC_SAMPLE_CNTL(x) ((x) << 26) +# define R600_PERSP_GRADIENT_ENA (1 << 28) +# define R600_LINEAR_GRADIENT_ENA (1 << 29) +# define R600_POSITION_SAMPLE (1 << 30) +# define R600_BARYC_AT_SAMPLE_ENA (1 << 31) +#define R600_SPI_PS_IN_CONTROL_1 0x286d0 +# define R600_GEN_INDEX_PIX (1 << 0) +# define R600_GEN_INDEX_PIX_ADDR(x) ((x) << 1) +# define R600_FRONT_FACE_ENA (1 << 8) +# define R600_FRONT_FACE_CHAN(x) ((x) << 9) +# define R600_FRONT_FACE_ALL_BITS (1 << 11) +# define R600_FRONT_FACE_ADDR(x) ((x) << 12) +# define R600_FOG_ADDR(x) ((x) << 17) +# define R600_FIXED_PT_POSITION_ENA (1 << 24) +# define R600_FIXED_PT_POSITION_ADDR(x) ((x) << 25) +# define R700_POSITION_ULC (1 << 30) +#define R600_SPI_INPUT_Z 0x286d8 + +#define R600_SPI_CONFIG_CNTL 0x9100 +# define R600_GPR_WRITE_PRIORITY(x) ((x) << 0) +# define R600_DISABLE_INTERP_1 (1 << 5) +#define R600_SPI_CONFIG_CNTL_1 0x913c +# define R600_VTX_DONE_DELAY(x) ((x) << 0) +# define R600_INTERP_ONE_PRIM_PER_ROW (1 << 4) + +#define R600_GB_TILING_CONFIG 0x98f0 +# define R600_PIPE_TILING(x) ((x) << 1) +# define R600_BANK_TILING(x) ((x) << 4) +# define R600_GROUP_SIZE(x) ((x) << 6) +# define R600_ROW_TILING(x) ((x) << 8) +# define R600_BANK_SWAPS(x) ((x) << 11) +# define R600_SAMPLE_SPLIT(x) ((x) << 14) +# define R600_BACKEND_MAP(x) ((x) << 16) +#define R600_DCP_TILING_CONFIG 0x6ca0 +#define R600_HDP_TILING_CONFIG 0x2f3c + +#define R600_CC_RB_BACKEND_DISABLE 0x98f4 +#define R700_CC_SYS_RB_BACKEND_DISABLE 0x3f88 +# define R600_BACKEND_DISABLE(x) ((x) << 16) + +#define R600_CC_GC_SHADER_PIPE_CONFIG 0x8950 +#define R600_GC_USER_SHADER_PIPE_CONFIG 0x8954 +# define R600_INACTIVE_QD_PIPES(x) ((x) << 8) +# define R600_INACTIVE_QD_PIPES_MASK (0xff << 8) +# define R600_INACTIVE_SIMDS(x) ((x) << 16) +# define R600_INACTIVE_SIMDS_MASK (0xff << 16) + +#define R700_CGTS_SYS_TCC_DISABLE 0x3f90 +#define R700_CGTS_USER_SYS_TCC_DISABLE 0x3f94 +#define R700_CGTS_TCC_DISABLE 0x9148 +#define R700_CGTS_USER_TCC_DISABLE 0x914c + /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ @@ -1211,6 +1732,11 @@ #define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3 #define RADEON_LAST_DISPATCH 1 +#define R600_LAST_FRAME_REG R600_SCRATCH_REG0 +#define R600_LAST_DISPATCH_REG R600_SCRATCH_REG1 +#define R600_LAST_CLEAR_REG R600_SCRATCH_REG2 +#define R600_LAST_SWI_REG R600_SCRATCH_REG3 + #define RADEON_MAX_VB_AGE 0x7fffffff #define RADEON_MAX_VB_VERTS (0xffff) @@ -1218,54 +1744,70 @@ #define RADEON_PCIGART_TABLE_SIZE (32*1024) -#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) -#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) +#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) +#define RADEON_WRITE(reg, val) \ +do { \ + if (reg < 0x10000) { \ + DRM_WRITE32(dev_priv->mmio, (reg), (val)); \ + } else { \ + DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, (reg)); \ + DRM_WRITE32(dev_priv->mmio, RADEON_MM_DATA, (val)); \ + } \ +} while (0) #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) #define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) -#define RADEON_WRITE_PLL( addr, val ) \ +#define RADEON_WRITE_PLL(addr, val) \ do { \ - RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \ + RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \ ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \ - RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ + RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \ } while (0) -#define RADEON_WRITE_PCIE( addr, val ) \ +#define RADEON_WRITE_PCIE(addr, val) \ do { \ - RADEON_WRITE8( RADEON_PCIE_INDEX, \ + RADEON_WRITE8(RADEON_PCIE_INDEX, \ ((addr) & 0xff)); \ - RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \ + RADEON_WRITE(RADEON_PCIE_DATA, (val)); \ } while (0) -#define R500_WRITE_MCIND( addr, val ) \ +#define R500_WRITE_MCIND(addr, val) \ do { \ RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff)); \ RADEON_WRITE(R520_MC_IND_DATA, (val)); \ RADEON_WRITE(R520_MC_IND_INDEX, 0); \ } while (0) -#define RS480_WRITE_MCIND( addr, val ) \ +#define RS480_WRITE_MCIND(addr, val) \ do { \ - RADEON_WRITE( RS480_NB_MC_INDEX, \ + RADEON_WRITE(RS480_NB_MC_INDEX, \ ((addr) & 0xff) | RS480_NB_MC_IND_WR_EN); \ - RADEON_WRITE( RS480_NB_MC_DATA, (val) ); \ - RADEON_WRITE( RS480_NB_MC_INDEX, 0xff ); \ + RADEON_WRITE(RS480_NB_MC_DATA, (val)); \ + RADEON_WRITE(RS480_NB_MC_INDEX, 0xff); \ } while (0) -#define RS690_WRITE_MCIND( addr, val ) \ +#define RS690_WRITE_MCIND(addr, val) \ do { \ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \ RADEON_WRITE(RS690_MC_DATA, val); \ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ } while (0) -#define IGP_WRITE_MCIND( addr, val ) \ +#define RS600_WRITE_MCIND(addr, val) \ +do { \ + RADEON_WRITE(RS600_MC_INDEX, RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | ((addr) & RS600_MC_ADDR_MASK)); \ + RADEON_WRITE(RS600_MC_DATA, val); \ +} while (0) + +#define IGP_WRITE_MCIND(addr, val) \ do { \ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ - RS690_WRITE_MCIND( addr, val ); \ - else \ - RS480_WRITE_MCIND( addr, val ); \ + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ + RS690_WRITE_MCIND(addr, val); \ + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) \ + RS600_WRITE_MCIND(addr, val); \ + else \ + RS480_WRITE_MCIND(addr, val); \ } while (0) #define CP_PACKET0( reg, n ) \ @@ -1309,42 +1851,42 @@ #define RADEON_FLUSH_CACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH); \ } else { \ - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_RB3D_DC_FLUSH); \ - } \ + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(R300_RB3D_DC_FLUSH); \ + } \ } while (0) #define RADEON_PURGE_CACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \ } else { \ - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE ); \ - } \ + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); \ + } \ } while (0) #define RADEON_FLUSH_ZCACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_ZC_FLUSH); \ } else { \ - OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( R300_ZC_FLUSH ); \ - } \ + OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(R300_ZC_FLUSH); \ + } \ } while (0) #define RADEON_PURGE_ZCACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \ } else { \ - OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \ - } \ + OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \ + } \ } while (0) /* ================================================================ @@ -1363,10 +1905,14 @@ } while (0) #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ -do { \ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ +do { \ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ - int __ret = radeon_do_cp_idle( dev_priv ); \ + int __ret; \ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) \ + __ret = r600_do_cp_idle(dev_priv); \ + else \ + __ret = radeon_do_cp_idle(dev_priv); \ if ( __ret ) return __ret; \ sarea_priv->last_dispatch = 0; \ radeon_freelist_reset( dev ); \ @@ -1388,21 +1934,40 @@ OUT_RING( age ); \ } while (0) +#define R600_DISPATCH_AGE(age) do { \ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ + OUT_RING((R600_LAST_DISPATCH_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ + OUT_RING(age); \ +} while (0) + +#define R600_FRAME_AGE(age) do { \ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ + OUT_RING((R600_LAST_FRAME_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ + OUT_RING(age); \ +} while (0) + +#define R600_CLEAR_AGE(age) do { \ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ + OUT_RING((R600_LAST_CLEAR_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ + OUT_RING(age); \ +} while (0) + /* ================================================================ * Ring control */ #define RADEON_VERBOSE 0 -#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; +#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; #define BEGIN_RING( n ) do { \ if ( RADEON_VERBOSE ) { \ DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ } \ - if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ - COMMIT_RING(); \ - radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ + _align_nr = (n + 0xf) & ~0xf; \ + if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ + COMMIT_RING(); \ + radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \ } \ _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ @@ -1419,19 +1984,16 @@ DRM_ERROR( \ "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ ((dev_priv->ring.tail + _nr) & mask), \ - write, __LINE__); \ + write, __LINE__); \ } else \ dev_priv->ring.tail = write; \ } while (0) +extern void radeon_commit_ring(drm_radeon_private_t *dev_priv); + #define COMMIT_RING() do { \ - /* Flush writes to ring */ \ - DRM_MEMORYBARRIER(); \ - GET_RING_HEAD( dev_priv ); \ - RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ - /* read from PCI bus to ensure correct posting */ \ - RADEON_READ( RADEON_CP_RB_RPTR ); \ -} while (0) + radeon_commit_ring(dev_priv); \ + } while(0) #define OUT_RING( x ) do { \ if ( RADEON_VERBOSE ) { \ @@ -1447,14 +2009,14 @@ OUT_RING( val ); \ } while (0) -#define OUT_RING_TABLE( tab, sz ) do { \ +#define OUT_RING_TABLE( tab, sz ) do { \ int _size = (sz); \ int *_tab = (int *)(tab); \ \ if (write + _size > mask) { \ int _i = (mask+1) - write; \ _size -= _i; \ - while (_i > 0) { \ + while (_i > 0 ) { \ *(int *)(ring + write) = *_tab++; \ write++; \ _i--; \ Index: dev/drm/radeon_state.c =================================================================== --- dev/drm/radeon_state.c (revision 189388) +++ dev/drm/radeon_state.c (working copy) @@ -1,4 +1,3 @@ -/* radeon_state.c -- State support for Radeon -*- linux-c -*- */ /*- * Copyright 2000 VA Linux Systems, Inc., Fremont, California. * All Rights Reserved. @@ -43,7 +42,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * dev_priv, struct drm_file *file_priv, - u32 * offset) + u32 *offset) { u64 off = *offset; u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1; @@ -308,9 +307,8 @@ case RADEON_CP_3D_DRAW_INDX_2: case RADEON_3D_CLEAR_HIZ: /* safe but r200 only */ - if ((dev_priv->chip_family < CHIP_R200) || - (dev_priv->chip_family > CHIP_RV280)) { - DRM_ERROR("Invalid 3d packet for non r200-class chip\n"); + if (dev_priv->microcode_version != UCODE_R200) { + DRM_ERROR("Invalid 3d packet for r100-class chip\n"); return -EINVAL; } break; @@ -363,8 +361,8 @@ break; case RADEON_3D_RNDR_GEN_INDX_PRIM: - if (dev_priv->chip_family > CHIP_RS200) { - DRM_ERROR("Invalid 3d packet for non-r100-class chip\n"); + if (dev_priv->microcode_version != UCODE_R100) { + DRM_ERROR("Invalid 3d packet for r200-class chip\n"); return -EINVAL; } if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) { @@ -374,10 +372,8 @@ break; case RADEON_CP_INDX_BUFFER: - /* safe but r200 only */ - if ((dev_priv->chip_family < CHIP_R200) || - (dev_priv->chip_family > CHIP_RV280)) { - DRM_ERROR("Invalid 3d packet for non-r200-class chip\n"); + if (dev_priv->microcode_version != UCODE_R200) { + DRM_ERROR("Invalid 3d packet for r100-class chip\n"); return -EINVAL; } if ((cmd[1] & 0x8000ffff) != 0x80000810) { @@ -796,7 +792,7 @@ ADVANCE_RING(); } -static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) +static void radeon_cp_performance_boxes(drm_radeon_private_t *dev_priv) { /* Collapse various things into a wait flag -- trying to * guess if userspase slept -- better just to have them tell us. @@ -870,7 +866,7 @@ dev_priv->stats.clears++; - if (dev_priv->sarea_priv->pfCurrentPage == 1) { + if (sarea_priv->pfCurrentPage == 1) { unsigned int tmp = flags; flags &= ~(RADEON_FRONT | RADEON_BACK); @@ -896,7 +892,7 @@ /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; for (i = 0; i < nbox; i++) { int x = pbox[i].x1; @@ -973,7 +969,7 @@ /* Make sure we restore the 3D state next time. * we haven't touched any "normal" state - still need this? */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; if ((dev_priv->flags & RADEON_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) { @@ -1021,7 +1017,7 @@ int tileoffset, nrtilesx, nrtilesy, j; /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */ if ((dev_priv->flags & RADEON_HAS_HIERZ) - && (dev_priv->chip_family < CHIP_R200)) { + && !(dev_priv->microcode_version == UCODE_R200)) { /* FIXME : figure this out for r200 (when hierz is enabled). Or maybe r200 actually doesn't need to put the low-res z value into the tile cache like r100, but just needs to clear the hi-level z-buffer? @@ -1050,8 +1046,7 @@ ADVANCE_RING(); tileoffset += depthpixperline >> 6; } - } else if ((dev_priv->chip_family >= CHIP_R200) && - (dev_priv->chip_family <= CHIP_RV280)) { + } else if (dev_priv->microcode_version == UCODE_R200) { /* works for rv250. */ /* find first macro tile (8x2 4x4 z-pixels on rv250) */ tileoffset = @@ -1106,8 +1101,7 @@ /* TODO don't always clear all hi-level z tiles */ if ((dev_priv->flags & RADEON_HAS_HIERZ) - && ((dev_priv->chip_family >= CHIP_R200) && - (dev_priv->chip_family <= CHIP_RV280)) + && (dev_priv->microcode_version == UCODE_R200) && (flags & RADEON_USE_HIERZ)) /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ /* FIXME : the mask supposedly contains low-res z values. So can't set @@ -1127,9 +1121,8 @@ * rendering a quad into just those buffers. Thus, we have to * make sure the 3D engine is configured correctly. */ - else if ((dev_priv->chip_family >= CHIP_R200) && - (dev_priv->chip_family <= CHIP_RV280) && - (flags & (RADEON_DEPTH | RADEON_STENCIL))) { + else if ((dev_priv->microcode_version == UCODE_R200) && + (flags & (RADEON_DEPTH | RADEON_STENCIL))) { int tempPP_CNTL; int tempRE_CNTL; @@ -1223,7 +1216,7 @@ /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; for (i = 0; i < nbox; i++) { @@ -1294,7 +1287,7 @@ /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; for (i = 0; i < nbox; i++) { @@ -1337,17 +1330,17 @@ * wait on this value before performing the clear ioctl. We * need this because the card's so damned fast... */ - dev_priv->sarea_priv->last_clear++; + sarea_priv->last_clear++; BEGIN_RING(4); - RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear); + RADEON_CLEAR_AGE(sarea_priv->last_clear); RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); } -static void radeon_cp_dispatch_swap(struct drm_device * dev) +static void radeon_cp_dispatch_swap(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -1394,7 +1387,7 @@ /* Make this work even if front & back are flipped: */ OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); - if (dev_priv->sarea_priv->pfCurrentPage == 0) { + if (sarea_priv->pfCurrentPage == 0) { OUT_RING(dev_priv->back_pitch_offset); OUT_RING(dev_priv->front_pitch_offset); } else { @@ -1414,20 +1407,20 @@ * throttle the framerate by waiting for this value before * performing the swapbuffer ioctl. */ - dev_priv->sarea_priv->last_frame++; + sarea_priv->last_frame++; BEGIN_RING(4); - RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame); + RADEON_FRAME_AGE(sarea_priv->last_frame); RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING(); } -static void radeon_cp_dispatch_flip(struct drm_device * dev) +static void radeon_cp_dispatch_flip(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle; + struct drm_sarea *sarea = (struct drm_sarea *)dev_priv->sarea->handle; int offset = (dev_priv->sarea_priv->pfCurrentPage == 1) ? dev_priv->front_offset : dev_priv->back_offset; RING_LOCALS; @@ -1548,7 +1541,7 @@ } while (i < nbox); } -static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf) +static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_buf *buf) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; @@ -1557,9 +1550,15 @@ buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ - BEGIN_RING(2); - RADEON_DISPATCH_AGE(buf_priv->age); - ADVANCE_RING(); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + BEGIN_RING(3); + R600_DISPATCH_AGE(buf_priv->age); + ADVANCE_RING(); + } else { + BEGIN_RING(2); + RADEON_DISPATCH_AGE(buf_priv->age); + ADVANCE_RING(); + } buf->pending = 1; buf->used = 0; @@ -1599,7 +1598,7 @@ } } -static void radeon_cp_dispatch_indices(struct drm_device * dev, +static void radeon_cp_dispatch_indices(struct drm_device *dev, struct drm_buf * elt_buf, drm_radeon_tcl_prim_t * prim) { @@ -2099,11 +2098,6 @@ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_surface_alloc_t *alloc = data; - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - if (alloc_surface(alloc, dev_priv, file_priv) == -1) return -EINVAL; else @@ -2115,11 +2109,6 @@ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_surface_free_t *memfree = data; - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - if (free_surface(file_priv, dev_priv, memfree->address)) return -EINVAL; else @@ -2153,7 +2142,7 @@ /* Not sure why this isn't set all the time: */ -static int radeon_do_init_pageflip(struct drm_device * dev) +static int radeon_do_init_pageflip(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -2203,6 +2192,7 @@ { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + DRM_DEBUG("\n"); LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -2213,7 +2203,7 @@ sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; radeon_cp_dispatch_swap(dev); - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; COMMIT_RING(); return 0; @@ -2230,11 +2220,6 @@ LOCK_TEST_WITH_RETURN(dev, file_priv); - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - sarea_priv = dev_priv->sarea_priv; DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", @@ -2289,7 +2274,7 @@ prim.finish = vertex->count; /* unused */ prim.prim = vertex->prim; prim.numverts = vertex->count; - prim.vc_format = dev_priv->sarea_priv->vc_format; + prim.vc_format = sarea_priv->vc_format; radeon_cp_dispatch_vertex(dev, buf, &prim); } @@ -2314,10 +2299,6 @@ LOCK_TEST_WITH_RETURN(dev, file_priv); - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } sarea_priv = dev_priv->sarea_priv; DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n", @@ -2385,7 +2366,7 @@ prim.prim = elts->prim; prim.offset = 0; /* offset from start of dma buffers */ prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - prim.vc_format = dev_priv->sarea_priv->vc_format; + prim.vc_format = sarea_priv->vc_format; radeon_cp_dispatch_indices(dev, buf, &prim); if (elts->discard) { @@ -2490,24 +2471,25 @@ buf->used = indirect->end; - /* Wait for the 3D stream to idle before the indirect buffer - * containing 2D acceleration commands is processed. - */ - BEGIN_RING(2); - - RADEON_WAIT_UNTIL_3D_IDLE(); - - ADVANCE_RING(); - /* Dispatch the indirect buffer full of commands from the * X server. This is insecure and is thus only available to * privileged clients. */ - radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); - if (indirect->discard) { - radeon_cp_discard_buffer(dev, buf); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); + else { + /* Wait for the 3D stream to idle before the indirect buffer + * containing 2D acceleration commands is processed. + */ + BEGIN_RING(2); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); + radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); } + if (indirect->discard) + radeon_cp_discard_buffer(dev, buf); + COMMIT_RING(); return 0; } @@ -2524,11 +2506,6 @@ LOCK_TEST_WITH_RETURN(dev, file_priv); - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - sarea_priv = dev_priv->sarea_priv; DRM_DEBUG("pid=%d index=%d discard=%d\n", @@ -2719,10 +2696,10 @@ int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8); RING_LOCALS; - if (!sz) - return 0; - if (sz * 4 > cmdbuf->bufsz) - return -EINVAL; + if (!sz) + return 0; + if (sz * 4 > cmdbuf->bufsz) + return -EINVAL; BEGIN_RING(5 + sz); OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); @@ -2867,11 +2844,6 @@ LOCK_TEST_WITH_RETURN(dev, file_priv); - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); @@ -2898,7 +2870,7 @@ orig_nbox = cmdbuf->nbox; - if (dev_priv->chip_family >= CHIP_R300) { + if (dev_priv->microcode_version == UCODE_R300) { int temp; temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); @@ -3028,11 +3000,6 @@ drm_radeon_getparam_t *param = data; int value; - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); switch (param->param) { @@ -3041,14 +3008,14 @@ break; case RADEON_PARAM_LAST_FRAME: dev_priv->stats.last_frame_reads++; - value = GET_SCRATCH(0); + value = GET_SCRATCH(dev_priv, 0); break; case RADEON_PARAM_LAST_DISPATCH: - value = GET_SCRATCH(1); + value = GET_SCRATCH(dev_priv, 1); break; case RADEON_PARAM_LAST_CLEAR: dev_priv->stats.last_clear_reads++; - value = GET_SCRATCH(2); + value = GET_SCRATCH(dev_priv, 2); break; case RADEON_PARAM_IRQ_NR: value = dev->irq; @@ -3083,9 +3050,11 @@ case RADEON_PARAM_SCRATCH_OFFSET: if (!dev_priv->writeback_works) return -EINVAL; - value = RADEON_SCRATCH_REG_OFFSET; + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + value = R600_SCRATCH_REG_OFFSET; + else + value = RADEON_SCRATCH_REG_OFFSET; break; - case RADEON_PARAM_CARD_TYPE: if (dev_priv->flags & RADEON_IS_PCIE) value = RADEON_CARD_PCIE; @@ -3104,7 +3073,7 @@ value = dev_priv->num_gb_pipes; break; default: - DRM_DEBUG( "Invalid parameter %d\n", param->param ); + DRM_DEBUG("Invalid parameter %d\n", param->param); return -EINVAL; } @@ -3122,11 +3091,6 @@ drm_radeon_setparam_t *sp = data; struct drm_radeon_driver_file_fields *radeon_priv; - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - switch (sp->param) { case RADEON_SETPARAM_FB_LOCATION: radeon_priv = file_priv->driver_priv; @@ -3178,8 +3142,7 @@ * * DRM infrastructure takes care of reclaiming dma buffers. */ -void radeon_driver_preclose(struct drm_device *dev, - struct drm_file *file_priv) +void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) { if (dev->dev_private) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -3192,14 +3155,7 @@ void radeon_driver_lastclose(struct drm_device *dev) { - if (dev->dev_private) { - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (dev_priv->sarea_priv && - dev_priv->sarea_priv->pfCurrentPage != 0) - radeon_cp_dispatch_flip(dev); - } - + radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private); radeon_do_release(dev); } @@ -3248,7 +3204,7 @@ DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), Index: dev/drm/radeon_drm.h =================================================================== --- dev/drm/radeon_drm.h (revision 189388) +++ dev/drm/radeon_drm.h (working copy) @@ -306,6 +306,7 @@ #define RADEON_INDEX_PRIM_OFFSET 20 #define RADEON_SCRATCH_REG_OFFSET 32 +#define R600_SCRATCH_REG_OFFSET 256 #define RADEON_NR_SAREA_CLIPRECTS 12 @@ -529,7 +530,8 @@ RADEON_INIT_CP = 0x01, RADEON_CLEANUP_CP = 0x02, RADEON_INIT_R200_CP = 0x03, - RADEON_INIT_R300_CP = 0x04 + RADEON_INIT_R300_CP = 0x04, + RADEON_INIT_R600_CP = 0x05, } func; unsigned long sarea_priv_offset; int is_pci; /* for overriding only */ @@ -655,6 +657,9 @@ int discard; } drm_radeon_indirect_t; +#define RADEON_INDIRECT_DISCARD (1 << 0) +#define RADEON_INDIRECT_NOFLUSH (1 << 1) + /* enum for card type parameters */ #define RADEON_CARD_PCI 0 #define RADEON_CARD_AGP 1