diff --git a/drivers/video/drm/include/pci.h b/drivers/video/drm/include/pci.h index 7731a72e52..4466e7905d 100644 --- a/drivers/video/drm/include/pci.h +++ b/drivers/video/drm/include/pci.h @@ -554,6 +554,10 @@ int enum_pci_devices(void); struct pci_device_id* find_pci_device(dev_t* pdev, struct pci_device_id *idlist); +#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) + +int pci_set_dma_mask(struct pci_dev *dev, u64 mask); + #define pci_name(x) "radeon" diff --git a/drivers/video/drm/include/types.h b/drivers/video/drm/include/types.h index a9f5683155..f3d17ca123 100644 --- a/drivers/video/drm/include/types.h +++ b/drivers/video/drm/include/types.h @@ -193,7 +193,12 @@ struct drm_file; #define DRM_MEMORYBARRIER() __asm__ __volatile__("lock; addl $0,0(%esp)") +#define mb() __asm__ __volatile__("lock; addl $0,0(%esp)") +#define PAGE_SIZE 4096 +#define PAGE_SHIFT 12 + +#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16)) #endif //__TYPES_H__ diff --git a/drivers/video/drm/radeon/atom.c b/drivers/video/drm/radeon/atom.c index 80b6ed5cd2..6e2dd7480d 100644 --- a/drivers/video/drm/radeon/atom.c +++ b/drivers/video/drm/radeon/atom.c @@ -26,6 +26,7 @@ //#include #include +#include #define ATOM_DEBUG @@ -607,10 +608,10 @@ static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg) { uint8_t count = U8((*ptr)++); SDEBUG(" count: %d\n", count); - // if (arg == ATOM_UNIT_MICROSEC) - // schedule_timeout_uninterruptible(usecs_to_jiffies(count)); - // else - // schedule_timeout_uninterruptible(msecs_to_jiffies(count)); + if (arg == ATOM_UNIT_MICROSEC) + udelay(count); + else + mdelay(count); } static void atom_op_div(atom_exec_context *ctx, int *ptr, int arg) diff --git a/drivers/video/drm/radeon/pci.c b/drivers/video/drm/radeon/pci.c index 2d6226d875..bd2b4bd8dd 100644 --- a/drivers/video/drm/radeon/pci.c +++ b/drivers/video/drm/radeon/pci.c @@ -793,3 +793,15 @@ void *pci_map_rom(struct pci_dev *pdev, size_t *size) return rom; } + +int +pci_set_dma_mask(struct pci_dev *dev, u64 mask) +{ +// if (!pci_dma_supported(dev, mask)) +// return -EIO; + + dev->dma_mask = mask; + + return 0; +} + diff --git a/drivers/video/drm/radeon/r100.c b/drivers/video/drm/radeon/r100.c index fc23e6217a..c2d553a5a2 100644 --- a/drivers/video/drm/radeon/r100.c +++ b/drivers/video/drm/radeon/r100.c @@ -30,7 +30,6 @@ //#include "drm.h" #include "radeon_drm.h" #include "radeon_microcode.h" - #include "radeon_reg.h" #include "radeon.h" @@ -487,7 +486,6 @@ static void r100_cp_load_microcode(struct radeon_device *rdev) } } - int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) { unsigned rb_bufsz; @@ -1168,7 +1166,6 @@ void r100_gpu_init(struct radeon_device *rdev) r100_hdp_reset(rdev); } - void r100_hdp_reset(struct radeon_device *rdev) { uint32_t tmp; @@ -1185,7 +1182,6 @@ void r100_hdp_reset(struct radeon_device *rdev) (void)RREG32(RADEON_HOST_PATH_CNTL); } - int r100_rb2d_reset(struct radeon_device *rdev) { uint32_t tmp; @@ -1307,6 +1303,7 @@ void r100_vram_info(struct radeon_device *rdev) rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); } +#endif /* * Indirect registers accessor @@ -1364,8 +1361,6 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) r100_pll_errata_after_data(rdev); } -#endif - uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) { if (reg < 0x10000) @@ -1376,7 +1371,6 @@ uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) } } - void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) { if (reg < 0x10000) diff --git a/drivers/video/drm/radeon/r520.c b/drivers/video/drm/radeon/r520.c index 74f919ea06..7cdac7ed94 100644 --- a/drivers/video/drm/radeon/r520.c +++ b/drivers/video/drm/radeon/r520.c @@ -47,7 +47,6 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev); void r520_gpu_init(struct radeon_device *rdev); int r520_mc_wait_for_idle(struct radeon_device *rdev); -#if 0 /* * MC */ @@ -56,15 +55,17 @@ int r520_mc_init(struct radeon_device *rdev) uint32_t tmp; int r; - if (r100_debugfs_rbbm_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for RBBM !\n"); - } - if (rv515_debugfs_pipes_info_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for pipes !\n"); - } - if (rv515_debugfs_ga_info_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for pipes !\n"); - } + dbgprintf("%s\n",__FUNCTION__); + +// if (r100_debugfs_rbbm_init(rdev)) { +// DRM_ERROR("Failed to register debugfs file for RBBM !\n"); +// } +// if (rv515_debugfs_pipes_info_init(rdev)) { +// DRM_ERROR("Failed to register debugfs file for pipes !\n"); +// } +// if (rv515_debugfs_ga_info_init(rdev)) { +// DRM_ERROR("Failed to register debugfs file for pipes !\n"); +// } r520_gpu_init(rdev); rv370_pcie_gart_disable(rdev); @@ -88,9 +89,9 @@ int r520_mc_init(struct radeon_device *rdev) } /* Program GPU memory space */ - rs600_mc_disable_clients(rdev); - if (r520_mc_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait MC idle while " + rs600_mc_disable_clients(rdev); + if (r520_mc_wait_for_idle(rdev)) { + printk(KERN_WARNING "Failed to wait MC idle while " "programming pipes. Bad things might happen.\n"); } /* Write VRAM size in case we are limiting it */ @@ -113,6 +114,9 @@ int r520_mc_init(struct radeon_device *rdev) WREG32_MC(R520_MC_AGP_BASE, 0); WREG32_MC(R520_MC_AGP_BASE_2, 0); } + + dbgprintf("done: %s\n",__FUNCTION__); + return 0; } @@ -123,7 +127,6 @@ void r520_mc_fini(struct radeon_device *rdev) radeon_gart_fini(rdev); } -#endif /* * Global GPU functions @@ -133,7 +136,6 @@ void r520_errata(struct radeon_device *rdev) rdev->pll_errata = 0; } -#if 0 int r520_mc_wait_for_idle(struct radeon_device *rdev) { unsigned i; @@ -153,6 +155,7 @@ int r520_mc_wait_for_idle(struct radeon_device *rdev) void r520_gpu_init(struct radeon_device *rdev) { unsigned pipe_select_current, gb_pipe_select, tmp; + dbgprintf("%s\n\r",__FUNCTION__); r100_hdp_reset(rdev); rs600_disable_vga(rdev); @@ -194,8 +197,6 @@ void r520_gpu_init(struct radeon_device *rdev) } } -#endif - /* * VRAM info @@ -203,6 +204,7 @@ void r520_gpu_init(struct radeon_device *rdev) static void r520_vram_get_type(struct radeon_device *rdev) { uint32_t tmp; + dbgprintf("%s\n\r",__FUNCTION__); rdev->mc.vram_width = 128; rdev->mc.vram_is_ddr = true; @@ -237,3 +239,551 @@ void r520_vram_info(struct radeon_device *rdev) rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); } +/* + * Global GPU functions + */ +void rs600_disable_vga(struct radeon_device *rdev) +{ + unsigned tmp; + dbgprintf("%s\n\r",__FUNCTION__); + + WREG32(0x330, 0); + WREG32(0x338, 0); + tmp = RREG32(0x300); + tmp &= ~(3 << 16); + WREG32(0x300, tmp); + WREG32(0x308, (1 << 8)); + WREG32(0x310, rdev->mc.vram_location); + WREG32(0x594, 0); +} + + +void r420_pipes_init(struct radeon_device *rdev) +{ + unsigned tmp; + unsigned gb_pipe_select; + unsigned num_pipes; + + dbgprintf("%s\n\r",__FUNCTION__); + + /* GA_ENHANCE workaround TCL deadlock issue */ + WREG32(0x4274, (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); + /* get max number of pipes */ + gb_pipe_select = RREG32(0x402C); + num_pipes = ((gb_pipe_select >> 12) & 3) + 1; + rdev->num_gb_pipes = num_pipes; + tmp = 0; + switch (num_pipes) { + default: + /* force to 1 pipe */ + num_pipes = 1; + case 1: + tmp = (0 << 1); + break; + case 2: + tmp = (3 << 1); + break; + case 3: + tmp = (6 << 1); + break; + case 4: + tmp = (7 << 1); + break; + } + WREG32(0x42C8, (1 << num_pipes) - 1); + /* Sub pixel 1/12 so we can have 4K rendering according to doc */ + tmp |= (1 << 4) | (1 << 0); + WREG32(0x4018, tmp); + if (r100_gui_wait_for_idle(rdev)) { + printk(KERN_WARNING "Failed to wait GUI idle while " + "programming pipes. Bad things might happen.\n"); + } + + tmp = RREG32(0x170C); + WREG32(0x170C, tmp | (1 << 31)); + + WREG32(R300_RB2D_DSTCACHE_MODE, + RREG32(R300_RB2D_DSTCACHE_MODE) | + R300_DC_AUTOFLUSH_ENABLE | + R300_DC_DC_DISABLE_IGNORE_PE); + + if (r100_gui_wait_for_idle(rdev)) { + printk(KERN_WARNING "Failed to wait GUI idle while " + "programming pipes. Bad things might happen.\n"); + } + DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes); +} + +void rv370_pcie_gart_disable(struct radeon_device *rdev) +{ + uint32_t tmp; + dbgprintf("%s\n\r",__FUNCTION__); + + tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); + tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; + WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); + if (rdev->gart.table.vram.robj) { +// radeon_object_kunmap(rdev->gart.table.vram.robj); +// radeon_object_unpin(rdev->gart.table.vram.robj); + } +} + +void radeon_gart_table_vram_free(struct radeon_device *rdev) +{ + if (rdev->gart.table.vram.robj == NULL) { + return; + } +// radeon_object_kunmap(rdev->gart.table.vram.robj); +// radeon_object_unpin(rdev->gart.table.vram.robj); +// radeon_object_unref(&rdev->gart.table.vram.robj); +} + +/* + * Common gart functions. + */ +void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, + int pages) +{ + unsigned t; + unsigned p; + int i, j; + dbgprintf("%s\n\r",__FUNCTION__); + + if (!rdev->gart.ready) { + dbgprintf("trying to unbind memory to unitialized GART !\n"); + return; + } + t = offset / 4096; + p = t / (PAGE_SIZE / 4096); + for (i = 0; i < pages; i++, p++) { + if (rdev->gart.pages[p]) { +// pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], +// PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + rdev->gart.pages[p] = NULL; + rdev->gart.pages_addr[p] = 0; + for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) { + radeon_gart_set_page(rdev, t, 0); + } + } + } + mb(); + radeon_gart_tlb_flush(rdev); +} + + + +void radeon_gart_fini(struct radeon_device *rdev) +{ + if (rdev->gart.pages && rdev->gart.pages_addr && rdev->gart.ready) { + /* unbind pages */ + radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); + } + rdev->gart.ready = false; +// kfree(rdev->gart.pages); +// kfree(rdev->gart.pages_addr); + rdev->gart.pages = NULL; + rdev->gart.pages_addr = NULL; +} + + + +int radeon_agp_init(struct radeon_device *rdev) +{ + + dbgprintf("%s\n\r",__FUNCTION__); + +#if __OS_HAS_AGP + struct radeon_agpmode_quirk *p = radeon_agpmode_quirk_list; + struct drm_agp_mode mode; + struct drm_agp_info info; + uint32_t agp_status; + int default_mode; + bool is_v3; + int ret; + + /* Acquire AGP. */ + if (!rdev->ddev->agp->acquired) { + ret = drm_agp_acquire(rdev->ddev); + if (ret) { + DRM_ERROR("Unable to acquire AGP: %d\n", ret); + return ret; + } + } + + ret = drm_agp_info(rdev->ddev, &info); + if (ret) { + DRM_ERROR("Unable to get AGP info: %d\n", ret); + return ret; + } + mode.mode = info.mode; + agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; + is_v3 = !!(agp_status & RADEON_AGPv3_MODE); + + if (is_v3) { + default_mode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4; + } else { + if (agp_status & RADEON_AGP_4X_MODE) { + default_mode = 4; + } else if (agp_status & RADEON_AGP_2X_MODE) { + default_mode = 2; + } else { + default_mode = 1; + } + } + + /* Apply AGPMode Quirks */ + while (p && p->chip_device != 0) { + if (info.id_vendor == p->hostbridge_vendor && + info.id_device == p->hostbridge_device && + rdev->pdev->vendor == p->chip_vendor && + rdev->pdev->device == p->chip_device && + rdev->pdev->subsystem_vendor == p->subsys_vendor && + rdev->pdev->subsystem_device == p->subsys_device) { + default_mode = p->default_mode; + } + ++p; + } + + if (radeon_agpmode > 0) { + if ((radeon_agpmode < (is_v3 ? 4 : 1)) || + (radeon_agpmode > (is_v3 ? 8 : 4)) || + (radeon_agpmode & (radeon_agpmode - 1))) { + DRM_ERROR("Illegal AGP Mode: %d (valid %s), leaving at %d\n", + radeon_agpmode, is_v3 ? "4, 8" : "1, 2, 4", + default_mode); + radeon_agpmode = default_mode; + } else { + DRM_INFO("AGP mode requested: %d\n", radeon_agpmode); + } + } else { + radeon_agpmode = default_mode; + } + + mode.mode &= ~RADEON_AGP_MODE_MASK; + if (is_v3) { + switch (radeon_agpmode) { + case 8: + mode.mode |= RADEON_AGPv3_8X_MODE; + break; + case 4: + default: + mode.mode |= RADEON_AGPv3_4X_MODE; + break; + } + } else { + switch (radeon_agpmode) { + case 4: + mode.mode |= RADEON_AGP_4X_MODE; + break; + case 2: + mode.mode |= RADEON_AGP_2X_MODE; + break; + case 1: + default: + mode.mode |= RADEON_AGP_1X_MODE; + break; + } + } + + mode.mode &= ~RADEON_AGP_FW_MODE; /* disable fw */ + ret = drm_agp_enable(rdev->ddev, mode); + if (ret) { + DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); + return ret; + } + + rdev->mc.agp_base = rdev->ddev->agp->agp_info.aper_base; + rdev->mc.gtt_size = rdev->ddev->agp->agp_info.aper_size << 20; + + /* workaround some hw issues */ + if (rdev->family < CHIP_R200) { + WREG32(RADEON_AGP_CNTL, RREG32(RADEON_AGP_CNTL) | 0x000e0000); + } + return 0; +#else + return 0; +#endif +} + + +void rs600_mc_disable_clients(struct radeon_device *rdev) +{ + unsigned tmp; + dbgprintf("%s\n",__FUNCTION__); + + if (r100_gui_wait_for_idle(rdev)) { + printk(KERN_WARNING "Failed to wait GUI idle while " + "programming pipes. Bad things might happen.\n"); + } + + tmp = RREG32(AVIVO_D1VGA_CONTROL); + WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE); + tmp = RREG32(AVIVO_D2VGA_CONTROL); + WREG32(AVIVO_D2VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE); + + tmp = RREG32(AVIVO_D1CRTC_CONTROL); + WREG32(AVIVO_D1CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN); + tmp = RREG32(AVIVO_D2CRTC_CONTROL); + WREG32(AVIVO_D2CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN); + + /* make sure all previous write got through */ + tmp = RREG32(AVIVO_D2CRTC_CONTROL); + + mdelay(1); + + dbgprintf("done\n"); + +} + +int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) +{ + void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; + + if (i < 0 || i > rdev->gart.num_gpu_pages) { + return -EINVAL; + } + addr = (((u32_t)addr) >> 8) | ((upper_32_bits(addr) & 0xff) << 4) | 0xC; + writel(cpu_to_le32(addr), ((void __iomem *)ptr) + (i * 4)); + return 0; +} + + +int radeon_gart_init(struct radeon_device *rdev) +{ + + dbgprintf("%s\n",__FUNCTION__); + + if (rdev->gart.pages) { + return 0; + } + /* We need PAGE_SIZE >= 4096 */ + if (PAGE_SIZE < 4096) { + DRM_ERROR("Page size is smaller than GPU page size!\n"); + return -EINVAL; + } + /* Compute table size */ + rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE; + rdev->gart.num_gpu_pages = rdev->mc.gtt_size / 4096; + DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", + rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); + /* Allocate pages table */ + rdev->gart.pages = kzalloc(sizeof(void *) * rdev->gart.num_cpu_pages, + GFP_KERNEL); + if (rdev->gart.pages == NULL) { +// radeon_gart_fini(rdev); + return -ENOMEM; + } + rdev->gart.pages_addr = kzalloc(sizeof(u32_t) * + rdev->gart.num_cpu_pages, GFP_KERNEL); + if (rdev->gart.pages_addr == NULL) { +// radeon_gart_fini(rdev); + return -ENOMEM; + } + return 0; +} + +int radeon_gart_table_vram_alloc(struct radeon_device *rdev) +{ + uint32_t gpu_addr; + int r; + +// if (rdev->gart.table.vram.robj == NULL) { +// r = radeon_object_create(rdev, NULL, +// rdev->gart.table_size, +// true, +// RADEON_GEM_DOMAIN_VRAM, +// false, &rdev->gart.table.vram.robj); +// if (r) { +// return r; +// } +// } +// r = radeon_object_pin(rdev->gart.table.vram.robj, +// RADEON_GEM_DOMAIN_VRAM, &gpu_addr); +// if (r) { +// radeon_object_unref(&rdev->gart.table.vram.robj); +// return r; +// } +// r = radeon_object_kmap(rdev->gart.table.vram.robj, +// (void **)&rdev->gart.table.vram.ptr); +// if (r) { +// radeon_object_unpin(rdev->gart.table.vram.robj); +// radeon_object_unref(&rdev->gart.table.vram.robj); +// DRM_ERROR("radeon: failed to map gart vram table.\n"); +// return r; +// } + + gpu_addr = 0x800000; + + u32_t pci_addr = rdev->mc.aper_base + gpu_addr; + + rdev->gart.table.vram.ptr = (void*)MapIoMem(pci_addr, rdev->gart.table_size, PG_SW); + + rdev->gart.table_addr = gpu_addr; + + dbgprintf("alloc gart vram:\n gpu_base %x pci_base %x lin_addr %x", + gpu_addr, pci_addr, rdev->gart.table.vram.ptr); + + return 0; +} + +void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); + +int rv370_pcie_gart_enable(struct radeon_device *rdev) +{ + uint32_t table_addr; + uint32_t tmp; + int r; + + dbgprintf("%s\n",__FUNCTION__); + + /* Initialize common gart structure */ + r = radeon_gart_init(rdev); + if (r) { + return r; + } + // r = rv370_debugfs_pcie_gart_info_init(rdev); + // if (r) { + // DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); + // } + rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; + r = radeon_gart_table_vram_alloc(rdev); + if (r) { + return r; + } + /* discard memory request outside of configured range */ + tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; + WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); + WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location); + tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 4096; + WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp); + WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); + WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); + table_addr = rdev->gart.table_addr; + WREG32_PCIE(RADEON_PCIE_TX_GART_BASE, table_addr); + /* FIXME: setup default page */ + WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_location); + WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_HI, 0); + /* Clear error */ + WREG32_PCIE(0x18, 0); + tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); + tmp |= RADEON_PCIE_TX_GART_EN; + tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; + WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); + rv370_pcie_gart_tlb_flush(rdev); + DRM_INFO("PCIE GART of %uM enabled (table at 0x%08X).\n", + rdev->mc.gtt_size >> 20, table_addr); + rdev->gart.ready = true; + return 0; +} + +void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) +{ + uint32_t tmp; + int i; + + /* Workaround HW bug do flush 2 times */ + for (i = 0; i < 2; i++) { + tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); + WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp | RADEON_PCIE_TX_GART_INVALIDATE_TLB); + (void)RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); + WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); + mb(); + } +} + +int r300_gart_enable(struct radeon_device *rdev) +{ +#if __OS_HAS_AGP + if (rdev->flags & RADEON_IS_AGP) { + if (rdev->family > CHIP_RV350) { + rv370_pcie_gart_disable(rdev); + } else { + r100_pci_gart_disable(rdev); + } + return 0; + } +#endif + if (rdev->flags & RADEON_IS_PCIE) { + rdev->asic->gart_disable = &rv370_pcie_gart_disable; + rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; + rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; + return rv370_pcie_gart_enable(rdev); + } + // return r100_pci_gart_enable(rdev); +} + + + +int radeon_fence_driver_init(struct radeon_device *rdev) +{ + unsigned long irq_flags; + int r; + +// write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); + r = radeon_scratch_get(rdev, &rdev->fence_drv.scratch_reg); + if (r) { + DRM_ERROR("Fence failed to get a scratch register."); +// write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); + return r; + } + WREG32(rdev->fence_drv.scratch_reg, 0); +// atomic_set(&rdev->fence_drv.seq, 0); +// INIT_LIST_HEAD(&rdev->fence_drv.created); +// INIT_LIST_HEAD(&rdev->fence_drv.emited); +// INIT_LIST_HEAD(&rdev->fence_drv.signaled); + rdev->fence_drv.count_timeout = 0; +// init_waitqueue_head(&rdev->fence_drv.queue); +// write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); +// if (radeon_debugfs_fence_init(rdev)) { +// DRM_ERROR("Failed to register debugfs file for fence !\n"); +// } + return 0; +} + + +int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, + int pages, u32_t *pagelist) +{ + unsigned t; + unsigned p; + uint64_t page_base; + int i, j; + + dbgprintf("%s\n\r",__FUNCTION__); + + + if (!rdev->gart.ready) { + DRM_ERROR("trying to bind memory to unitialized GART !\n"); + return -EINVAL; + } + t = offset / 4096; + p = t / (PAGE_SIZE / 4096); + + for (i = 0; i < pages; i++, p++) { + /* we need to support large memory configurations */ + /* assume that unbind have already been call on the range */ + + rdev->gart.pages_addr[p] = pagelist[i] & ~4095; + + //if (pci_dma_mapping_error(rdev->pdev, rdev->gart.pages_addr[p])) { + // /* FIXME: failed to map page (return -ENOMEM?) */ + // radeon_gart_unbind(rdev, offset, pages); + // return -ENOMEM; + //} + rdev->gart.pages[p] = pagelist[i]; + page_base = (uint32_t)rdev->gart.pages_addr[p]; + for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) { + radeon_gart_set_page(rdev, t, page_base); + page_base += 4096; + } + } + mb(); + radeon_gart_tlb_flush(rdev); + + dbgprintf("done %s\n",__FUNCTION__); + + return 0; +} + + + diff --git a/drivers/video/drm/radeon/radeon.h b/drivers/video/drm/radeon/radeon.h index 8034ea9d76..228a129942 100644 --- a/drivers/video/drm/radeon/radeon.h +++ b/drivers/video/drm/radeon/radeon.h @@ -255,8 +255,8 @@ int radeon_gart_init(struct radeon_device *rdev); void radeon_gart_fini(struct radeon_device *rdev); void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, int pages); -int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, - int pages, struct page **pagelist); +//int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, +// int pages, struct page **pagelist); /* @@ -527,7 +527,7 @@ struct radeon_device { struct radeon_gart gart; struct radeon_mode_info mode_info; struct radeon_scratch scratch; -// struct radeon_mman mman; + // struct radeon_mman mman; struct radeon_fence_driver fence_drv; struct radeon_cp cp; struct radeon_ib_pool ib_pool; @@ -1066,6 +1066,8 @@ struct drm_device { void *dev_private; /**< device private data */ void *mm_private; +// struct address_space *dev_mapping; + struct drm_mode_config mode_config; /**< Current mode config */ }; diff --git a/drivers/video/drm/radeon/radeon_asic.h b/drivers/video/drm/radeon/radeon_asic.h index f197b50bd4..7133463722 100644 --- a/drivers/video/drm/radeon/radeon_asic.h +++ b/drivers/video/drm/radeon/radeon_asic.h @@ -401,18 +401,18 @@ static struct radeon_asic r520_asic = { .errata = &r520_errata, .vram_info = &r520_vram_info, .gpu_reset = &rv515_gpu_reset, -// .mc_init = &r520_mc_init, -// .mc_fini = &r520_mc_fini, + .mc_init = &r520_mc_init, + .mc_fini = &r520_mc_fini, // .wb_init = &r100_wb_init, // .wb_fini = &r100_wb_fini, -// .gart_enable = &r300_gart_enable, -// .gart_disable = &rv370_pcie_gart_disable, -// .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, -// .gart_set_page = &rv370_pcie_gart_set_page, -// .cp_init = &r100_cp_init, -// .cp_fini = &r100_cp_fini, + .gart_enable = &r300_gart_enable, + .gart_disable = &rv370_pcie_gart_disable, + .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, + .gart_set_page = &rv370_pcie_gart_set_page, + .cp_init = &r100_cp_init, +// .cp_fini = &r100_cp_fini, // .cp_disable = &r100_cp_disable, -// .ring_start = &rv515_ring_start, + .ring_start = &rv515_ring_start, // .irq_set = &r100_irq_set, // .irq_process = &r100_irq_process, // .fence_ring_emit = &r300_fence_ring_emit, diff --git a/drivers/video/drm/radeon/radeon_device.c b/drivers/video/drm/radeon/radeon_device.c index 5358bc4a29..d058aadac8 100644 --- a/drivers/video/drm/radeon/radeon_device.c +++ b/drivers/video/drm/radeon/radeon_device.c @@ -228,7 +228,6 @@ void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) BUG_ON(1); } - void radeon_register_accessor_init(struct radeon_device *rdev) { @@ -251,13 +250,13 @@ void radeon_register_accessor_init(struct radeon_device *rdev) // rdev->pcie_wreg = &rv370_pcie_wreg; } if (rdev->family >= CHIP_RV515) { -// rdev->pcie_rreg = &rv515_pcie_rreg; -// rdev->pcie_wreg = &rv515_pcie_wreg; + rdev->pcie_rreg = &rv515_pcie_rreg; + rdev->pcie_wreg = &rv515_pcie_wreg; } /* FIXME: not sure here */ if (rdev->family <= CHIP_R580) { -// rdev->pll_rreg = &r100_pll_rreg; -// rdev->pll_wreg = &r100_pll_wreg; + rdev->pll_rreg = &r100_pll_rreg; + rdev->pll_wreg = &r100_pll_wreg; } if (rdev->family >= CHIP_RV515) { rdev->mc_rreg = &rv515_mc_rreg; @@ -447,7 +446,7 @@ int radeon_atombios_init(struct radeon_device *rdev) void radeon_atombios_fini(struct radeon_device *rdev) { - free(rdev->mode_info.atom_context); + kfree(rdev->mode_info.atom_context); } int radeon_combios_init(struct radeon_device *rdev) @@ -463,7 +462,7 @@ void radeon_combios_fini(struct radeon_device *rdev) int radeon_modeset_init(struct radeon_device *rdev); void radeon_modeset_fini(struct radeon_device *rdev); - +void *ring_buffer; /* * Radeon device. */ @@ -493,6 +492,8 @@ int radeon_device_init(struct radeon_device *rdev, // mutex_init(&rdev->cp.mutex); // rwlock_init(&rdev->fence_drv.lock); + ring_buffer = CreateRingBuffer( 1024*1024, PG_SW ); + if (radeon_agpmode == -1) { rdev->flags &= ~RADEON_IS_AGP; if (rdev->family > CHIP_RV515 || @@ -521,10 +522,10 @@ int radeon_device_init(struct radeon_device *rdev, } /* Report DMA addressing limitation */ -// r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(32)); -// if (r) { -// printk(KERN_WARNING "radeon: No suitable DMA available.\n"); -// } + r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(32)); + if (r) { + printk(KERN_WARNING "radeon: No suitable DMA available.\n"); + } /* Registers mapping */ /* TODO: block userspace mapping of io register */ @@ -565,13 +566,10 @@ int radeon_device_init(struct radeon_device *rdev, return r; } } - - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ if (radeon_gpu_reset(rdev)) { /* FIXME: what do we want to do here ? */ } - /* check if cards are posted or not */ if (!radeon_card_posted(rdev) && rdev->bios) { DRM_INFO("GPU not posted. posting now...\n"); @@ -605,45 +603,47 @@ int radeon_device_init(struct radeon_device *rdev, return r; } -#if 0 - /* Initialize memory controller (also test AGP) */ r = radeon_mc_init(rdev); if (r) { return r; - } + }; + + /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) { - return r; - } - r = radeon_irq_kms_init(rdev); - if (r) { - return r; - } +// r = radeon_fence_driver_init(rdev); +// if (r) { +// return r; +// } +// r = radeon_irq_kms_init(rdev); +// if (r) { +// return r; +// } /* Memory manager */ - r = radeon_object_init(rdev); - if (r) { - return r; - } +// r = radeon_object_init(rdev); +// if (r) { +// return r; +// } /* Initialize GART (initialize after TTM so we can allocate * memory through TTM but finalize after TTM) */ r = radeon_gart_enable(rdev); - if (!r) { - r = radeon_gem_init(rdev); - } +// if (!r) { +// r = radeon_gem_init(rdev); +// } /* 1M ring buffer */ if (!r) { r = radeon_cp_init(rdev, 1024 * 1024); } - if (!r) { - r = radeon_wb_init(rdev); - if (r) { - DRM_ERROR("radeon: failled initializing WB (%d).\n", r); - return r; - } - } +// if (!r) { +// r = radeon_wb_init(rdev); +// if (r) { +// DRM_ERROR("radeon: failled initializing WB (%d).\n", r); +// return r; +// } +// } + +#if 0 if (!r) { r = radeon_ib_pool_init(rdev); if (r) { diff --git a/drivers/video/drm/radeon/radeon_ring.c b/drivers/video/drm/radeon/radeon_ring.c index 271a065843..5335bc9f62 100644 --- a/drivers/video/drm/radeon/radeon_ring.c +++ b/drivers/video/drm/radeon/radeon_ring.c @@ -32,6 +32,8 @@ #include "radeon.h" #include "atom.h" +extern void * ring_buffer; + #if 0 int radeon_debugfs_ib_init(struct radeon_device *rdev); @@ -287,7 +289,6 @@ int radeon_ib_test(struct radeon_device *rdev) #endif - /* * Ring. */ @@ -360,7 +361,7 @@ int radeon_ring_test(struct radeon_device *rdev) unsigned i; int r; - dbgprintf("%s\n\r",__FUNCTION__); + dbgprintf("%s\n",__FUNCTION__); r = radeon_scratch_get(rdev, &scratch); if (r) { @@ -377,14 +378,14 @@ int radeon_ring_test(struct radeon_device *rdev) radeon_ring_write(rdev, PACKET0(scratch, 0)); radeon_ring_write(rdev, 0xDEADBEEF); radeon_ring_unlock_commit(rdev); - for (i = 0; i < rdev->usec_timeout; i++) { + for (i = 0; i < 100000; i++) { tmp = RREG32(scratch); if (tmp == 0xDEADBEEF) { break; } - DRM_UDELAY(1); + DRM_UDELAY(1); } - if (i < rdev->usec_timeout) { + if (i < 100000) { DRM_INFO("ring test succeeded in %d usecs\n", i); } else { DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n", @@ -392,15 +393,23 @@ int radeon_ring_test(struct radeon_device *rdev) r = -EINVAL; } radeon_scratch_free(rdev, scratch); + + dbgprintf("done %s\n",__FUNCTION__); return r; } +int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, + int pages, u32_t *pagelist); + +#define page_tabs 0xFDC00000 + + int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) { int r; - dbgprintf("%s\n\r",__FUNCTION__); + dbgprintf("%s\n",__FUNCTION__); rdev->cp.ring_size = ring_size; @@ -435,10 +444,27 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) } #endif - rdev->cp.ring = CreateRingBuffer( ring_size, PG_SW); - rdev->cp.gpu_addr = GetPgAddr(rdev->cp.ring); + dbgprintf("ring size %x\n", ring_size); + + dbgprintf("ring buffer %x\n", rdev->cp.ring ); + + rdev->cp.ring = ring_buffer; //CreateRingBuffer( ring_size, PG_SW ); + + dbgprintf("ring buffer %x\n", rdev->cp.ring ); + + rdev->cp.gpu_addr = rdev->mc.gtt_location; + + u32_t *pagelist = &((u32_t*)page_tabs)[(u32_t)rdev->cp.ring >> 12]; + + dbgprintf("pagelist %x\n", pagelist); + + radeon_gart_bind(rdev, 0, ring_size / 4096, pagelist); + rdev->cp.ptr_mask = (rdev->cp.ring_size / 4) - 1; rdev->cp.ring_free_dw = rdev->cp.ring_size / 4; + + dbgprintf("done %s\n",__FUNCTION__); + return 0; } diff --git a/drivers/video/drm/radeon/rv515.c b/drivers/video/drm/radeon/rv515.c index f5809dae30..3f9f39cb70 100644 --- a/drivers/video/drm/radeon/rv515.c +++ b/drivers/video/drm/radeon/rv515.c @@ -130,6 +130,7 @@ void rv515_mc_fini(struct radeon_device *rdev) radeon_gart_fini(rdev); } +#endif /* * Global GPU functions @@ -139,6 +140,7 @@ void rv515_ring_start(struct radeon_device *rdev) unsigned gb_tile_config; int r; + dbgprintf("%s\n\r",__FUNCTION__); /* Sub pixel 1/12 so we can have 4K rendering according to doc */ gb_tile_config = R300_ENABLE_TILING | R300_TILE_SIZE_16; switch (rdev->num_gb_pipes) { @@ -228,6 +230,9 @@ void rv515_ring_start(struct radeon_device *rdev) radeon_ring_write(rdev, PACKET0(0x20C8, 0)); radeon_ring_write(rdev, 0); radeon_ring_unlock_commit(rdev); + + dbgprintf("done %s\n\r",__FUNCTION__); + } void rv515_errata(struct radeon_device *rdev) @@ -251,6 +256,7 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev) return -1; } +#if 0 void rv515_gpu_init(struct radeon_device *rdev) { unsigned pipe_select_current, gb_pipe_select, tmp; @@ -340,7 +346,6 @@ int rv515_ga_reset(struct radeon_device *rdev) return -1; } - int rv515_gpu_reset(struct radeon_device *rdev) { uint32_t status; @@ -374,7 +379,6 @@ int rv515_gpu_reset(struct radeon_device *rdev) return 0; } -#if 0 /* * VRAM info @@ -409,7 +413,6 @@ void rv515_vram_info(struct radeon_device *rdev) rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); } -#endif /* * Indirect registers accessor