1189499Srnoland/*- 2189499Srnoland * Copyright 2008-2009 Advanced Micro Devices, Inc. 3189499Srnoland * Copyright 2008 Red Hat Inc. 4189499Srnoland * 5189499Srnoland * Permission is hereby granted, free of charge, to any person obtaining a 6189499Srnoland * copy of this software and associated documentation files (the "Software"), 7189499Srnoland * to deal in the Software without restriction, including without limitation 8189499Srnoland * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9189499Srnoland * and/or sell copies of the Software, and to permit persons to whom the 10189499Srnoland * Software is furnished to do so, subject to the following conditions: 11189499Srnoland * 12189499Srnoland * The above copyright notice and this permission notice (including the next 13189499Srnoland * paragraph) shall be included in all copies or substantial portions of the 14189499Srnoland * Software. 15189499Srnoland * 16189499Srnoland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17189499Srnoland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18189499Srnoland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19189499Srnoland * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20189499Srnoland * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21189499Srnoland * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22189499Srnoland * DEALINGS IN THE SOFTWARE. 23189499Srnoland * 24189499Srnoland * Authors: 25189499Srnoland * Dave Airlie <airlied@redhat.com> 26189499Srnoland * Alex Deucher <alexander.deucher@amd.com> 27189499Srnoland */ 28189499Srnoland 29189499Srnoland#include <sys/cdefs.h> 30189499Srnoland__FBSDID("$FreeBSD$"); 31189499Srnoland 32189499Srnoland#include "dev/drm/drmP.h" 33189499Srnoland#include "dev/drm/drm.h" 34189499Srnoland#include "dev/drm/radeon_drm.h" 35189499Srnoland#include "dev/drm/radeon_drv.h" 36189499Srnoland 37189499Srnoland#include "dev/drm/r600_microcode.h" 38189499Srnoland 39189499Srnoland# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ 40189499Srnoland# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) 41189499Srnoland 42189499Srnoland#define R600_PTE_VALID (1 << 0) 43189499Srnoland#define R600_PTE_SYSTEM (1 << 1) 44189499Srnoland#define R600_PTE_SNOOPED (1 << 2) 45189499Srnoland#define R600_PTE_READABLE (1 << 5) 46189499Srnoland#define R600_PTE_WRITEABLE (1 << 6) 47189499Srnoland 48189499Srnoland/* MAX values used for gfx init */ 49189499Srnoland#define R6XX_MAX_SH_GPRS 256 50189499Srnoland#define R6XX_MAX_TEMP_GPRS 16 51189499Srnoland#define R6XX_MAX_SH_THREADS 256 52189499Srnoland#define R6XX_MAX_SH_STACK_ENTRIES 4096 53189499Srnoland#define R6XX_MAX_BACKENDS 8 54189499Srnoland#define R6XX_MAX_BACKENDS_MASK 0xff 55189499Srnoland#define R6XX_MAX_SIMDS 8 56189499Srnoland#define R6XX_MAX_SIMDS_MASK 0xff 57189499Srnoland#define R6XX_MAX_PIPES 8 58189499Srnoland#define R6XX_MAX_PIPES_MASK 0xff 59189499Srnoland 60189499Srnoland#define R7XX_MAX_SH_GPRS 256 61189499Srnoland#define R7XX_MAX_TEMP_GPRS 16 62189499Srnoland#define R7XX_MAX_SH_THREADS 256 63189499Srnoland#define R7XX_MAX_SH_STACK_ENTRIES 4096 64189499Srnoland#define R7XX_MAX_BACKENDS 8 65189499Srnoland#define R7XX_MAX_BACKENDS_MASK 0xff 66189499Srnoland#define R7XX_MAX_SIMDS 16 67189499Srnoland#define R7XX_MAX_SIMDS_MASK 0xffff 68189499Srnoland#define R7XX_MAX_PIPES 8 69189499Srnoland#define R7XX_MAX_PIPES_MASK 0xff 70189499Srnoland 71189499Srnolandstatic int r600_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries) 72189499Srnoland{ 73189499Srnoland int i; 74189499Srnoland 75189499Srnoland dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 76189499Srnoland 77189499Srnoland for (i = 0; i < dev_priv->usec_timeout; i++) { 78189499Srnoland int slots; 79189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) 80189499Srnoland slots = (RADEON_READ(R600_GRBM_STATUS) 81189499Srnoland & R700_CMDFIFO_AVAIL_MASK); 82189499Srnoland else 83189499Srnoland slots = (RADEON_READ(R600_GRBM_STATUS) 84189499Srnoland & R600_CMDFIFO_AVAIL_MASK); 85189499Srnoland if (slots >= entries) 86189499Srnoland return 0; 87189499Srnoland DRM_UDELAY(1); 88189499Srnoland } 89189499Srnoland DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n", 90189499Srnoland RADEON_READ(R600_GRBM_STATUS), 91189499Srnoland RADEON_READ(R600_GRBM_STATUS2)); 92189499Srnoland 93189499Srnoland return -EBUSY; 94189499Srnoland} 95189499Srnoland 96189499Srnolandstatic int r600_do_wait_for_idle(drm_radeon_private_t *dev_priv) 97189499Srnoland{ 98189499Srnoland int i, ret; 99189499Srnoland 100189499Srnoland dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 101189499Srnoland 102189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) 103189499Srnoland ret = r600_do_wait_for_fifo(dev_priv, 8); 104189499Srnoland else 105189499Srnoland ret = r600_do_wait_for_fifo(dev_priv, 16); 106189499Srnoland if (ret) 107189499Srnoland return ret; 108189499Srnoland for (i = 0; i < dev_priv->usec_timeout; i++) { 109189499Srnoland if (!(RADEON_READ(R600_GRBM_STATUS) & R600_GUI_ACTIVE)) 110189499Srnoland return 0; 111189499Srnoland DRM_UDELAY(1); 112189499Srnoland } 113189499Srnoland DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n", 114189499Srnoland RADEON_READ(R600_GRBM_STATUS), 115189499Srnoland RADEON_READ(R600_GRBM_STATUS2)); 116189499Srnoland 117189499Srnoland return -EBUSY; 118189499Srnoland} 119189499Srnoland 120189499Srnolandvoid r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) 121189499Srnoland{ 122189499Srnoland#ifdef __linux__ 123189499Srnoland struct drm_sg_mem *entry = dev->sg; 124189499Srnoland int max_pages; 125189499Srnoland int pages; 126189499Srnoland int i; 127189499Srnoland#endif 128189499Srnoland if (gart_info->bus_addr) { 129189499Srnoland#ifdef __linux__ 130189499Srnoland max_pages = (gart_info->table_size / sizeof(u32)); 131189499Srnoland pages = (entry->pages <= max_pages) 132189499Srnoland ? entry->pages : max_pages; 133189499Srnoland 134189499Srnoland for (i = 0; i < pages; i++) { 135189499Srnoland if (!entry->busaddr[i]) 136189499Srnoland break; 137189499Srnoland pci_unmap_single(dev->pdev, entry->busaddr[i], 138189499Srnoland PAGE_SIZE, PCI_DMA_TODEVICE); 139189499Srnoland } 140189499Srnoland#endif 141189499Srnoland if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) 142189499Srnoland gart_info->bus_addr = 0; 143189499Srnoland } 144189499Srnoland} 145189499Srnoland 146189499Srnoland/* R600 has page table setup */ 147189499Srnolandint r600_page_table_init(struct drm_device *dev) 148189499Srnoland{ 149189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 150189499Srnoland struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; 151189499Srnoland struct drm_sg_mem *entry = dev->sg; 152189499Srnoland int ret = 0; 153189499Srnoland int i, j; 154189499Srnoland int max_pages, pages; 155189499Srnoland u64 *pci_gart, page_base; 156189499Srnoland dma_addr_t entry_addr; 157189499Srnoland 158189499Srnoland /* okay page table is available - lets rock */ 159189499Srnoland 160189499Srnoland /* PTEs are 64-bits */ 161189499Srnoland pci_gart = (u64 *)gart_info->addr; 162189499Srnoland 163189499Srnoland max_pages = (gart_info->table_size / sizeof(u64)); 164189499Srnoland pages = (entry->pages <= max_pages) ? entry->pages : max_pages; 165189499Srnoland 166189499Srnoland memset(pci_gart, 0, max_pages * sizeof(u64)); 167189499Srnoland 168189499Srnoland for (i = 0; i < pages; i++) { 169189499Srnoland#ifdef __linux__ 170189499Srnoland entry->busaddr[i] = pci_map_single(dev->pdev, 171189499Srnoland page_address(entry-> 172189499Srnoland pagelist[i]), 173189499Srnoland PAGE_SIZE, PCI_DMA_TODEVICE); 174189499Srnoland if (entry->busaddr[i] == 0) { 175189499Srnoland DRM_ERROR("unable to map PCIGART pages!\n"); 176189499Srnoland r600_page_table_cleanup(dev, gart_info); 177189499Srnoland goto done; 178189499Srnoland } 179189499Srnoland#endif 180189499Srnoland entry_addr = entry->busaddr[i]; 181189499Srnoland for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { 182189499Srnoland page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK; 183207069Srnoland page_base |= R600_PTE_VALID | R600_PTE_SYSTEM; 184189499Srnoland page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE; 185189499Srnoland 186189499Srnoland *pci_gart = page_base; 187189499Srnoland 188189499Srnoland if ((i % 128) == 0) 189189499Srnoland DRM_DEBUG("page entry %d: 0x%016llx\n", 190189499Srnoland i, (unsigned long long)page_base); 191189499Srnoland pci_gart++; 192189499Srnoland entry_addr += ATI_PCIGART_PAGE_SIZE; 193189499Srnoland } 194189499Srnoland } 195189909Srnoland ret = 1; 196189499Srnoland#ifdef __linux__ 197189499Srnolanddone: 198189499Srnoland#endif 199189499Srnoland return ret; 200189499Srnoland} 201189499Srnoland 202189499Srnolandstatic void r600_vm_flush_gart_range(struct drm_device *dev) 203189499Srnoland{ 204189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 205189499Srnoland u32 resp, countdown = 1000; 206189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR, dev_priv->gart_vm_start >> 12); 207189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); 208189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_REQUEST_RESPONSE, 2); 209189499Srnoland 210189499Srnoland do { 211189499Srnoland resp = RADEON_READ(R600_VM_CONTEXT0_REQUEST_RESPONSE); 212189499Srnoland countdown--; 213189499Srnoland DRM_UDELAY(1); 214189499Srnoland } while (((resp & 0xf0) == 0) && countdown); 215189499Srnoland} 216189499Srnoland 217189499Srnolandstatic void r600_vm_init(struct drm_device *dev) 218189499Srnoland{ 219189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 220189499Srnoland /* initialise the VM to use the page table we constructed up there */ 221189499Srnoland u32 vm_c0, i; 222189499Srnoland u32 mc_rd_a; 223189499Srnoland u32 vm_l2_cntl, vm_l2_cntl3; 224189499Srnoland /* okay set up the PCIE aperture type thingo */ 225189499Srnoland RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); 226189499Srnoland RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); 227189499Srnoland RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); 228189499Srnoland 229189499Srnoland /* setup MC RD a */ 230189499Srnoland mc_rd_a = R600_MCD_L1_TLB | R600_MCD_L1_FRAG_PROC | R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS | 231189499Srnoland R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | R600_MCD_EFFECTIVE_L1_TLB_SIZE(5) | 232189499Srnoland R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(5) | R600_MCD_WAIT_L2_QUERY; 233189499Srnoland 234189499Srnoland RADEON_WRITE(R600_MCD_RD_A_CNTL, mc_rd_a); 235189499Srnoland RADEON_WRITE(R600_MCD_RD_B_CNTL, mc_rd_a); 236189499Srnoland 237189499Srnoland RADEON_WRITE(R600_MCD_WR_A_CNTL, mc_rd_a); 238189499Srnoland RADEON_WRITE(R600_MCD_WR_B_CNTL, mc_rd_a); 239189499Srnoland 240189499Srnoland RADEON_WRITE(R600_MCD_RD_GFX_CNTL, mc_rd_a); 241189499Srnoland RADEON_WRITE(R600_MCD_WR_GFX_CNTL, mc_rd_a); 242189499Srnoland 243189499Srnoland RADEON_WRITE(R600_MCD_RD_SYS_CNTL, mc_rd_a); 244189499Srnoland RADEON_WRITE(R600_MCD_WR_SYS_CNTL, mc_rd_a); 245189499Srnoland 246189499Srnoland RADEON_WRITE(R600_MCD_RD_HDP_CNTL, mc_rd_a | R600_MCD_L1_STRICT_ORDERING); 247189499Srnoland RADEON_WRITE(R600_MCD_WR_HDP_CNTL, mc_rd_a /*| R600_MCD_L1_STRICT_ORDERING*/); 248189499Srnoland 249189499Srnoland RADEON_WRITE(R600_MCD_RD_PDMA_CNTL, mc_rd_a); 250189499Srnoland RADEON_WRITE(R600_MCD_WR_PDMA_CNTL, mc_rd_a); 251189499Srnoland 252189499Srnoland RADEON_WRITE(R600_MCD_RD_SEM_CNTL, mc_rd_a | R600_MCD_SEMAPHORE_MODE); 253189499Srnoland RADEON_WRITE(R600_MCD_WR_SEM_CNTL, mc_rd_a); 254189499Srnoland 255189499Srnoland vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; 256189499Srnoland vm_l2_cntl |= R600_VM_L2_CNTL_QUEUE_SIZE(7); 257189499Srnoland RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); 258189499Srnoland 259189499Srnoland RADEON_WRITE(R600_VM_L2_CNTL2, 0); 260189499Srnoland vm_l2_cntl3 = (R600_VM_L2_CNTL3_BANK_SELECT_0(0) | 261189499Srnoland R600_VM_L2_CNTL3_BANK_SELECT_1(1) | 262189499Srnoland R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(2)); 263189499Srnoland RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); 264189499Srnoland 265189499Srnoland vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; 266189499Srnoland 267189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); 268189499Srnoland 269189499Srnoland vm_c0 &= ~R600_VM_ENABLE_CONTEXT; 270189499Srnoland 271189499Srnoland /* disable all other contexts */ 272189499Srnoland for (i = 1; i < 8; i++) 273189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); 274189499Srnoland 275189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); 276189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); 277189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); 278189499Srnoland 279189499Srnoland r600_vm_flush_gart_range(dev); 280189499Srnoland} 281189499Srnoland 282189499Srnoland/* load r600 microcode */ 283189499Srnolandstatic void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) 284189499Srnoland{ 285190595Srnoland const u32 (*cp)[3]; 286190595Srnoland const u32 *pfp; 287189499Srnoland int i; 288189499Srnoland 289190595Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 290190595Srnoland case CHIP_R600: 291190595Srnoland DRM_INFO("Loading R600 Microcode\n"); 292190595Srnoland cp = R600_cp_microcode; 293190595Srnoland pfp = R600_pfp_microcode; 294190595Srnoland break; 295190595Srnoland case CHIP_RV610: 296190595Srnoland DRM_INFO("Loading RV610 Microcode\n"); 297190595Srnoland cp = RV610_cp_microcode; 298190595Srnoland pfp = RV610_pfp_microcode; 299190595Srnoland break; 300190595Srnoland case CHIP_RV630: 301190595Srnoland DRM_INFO("Loading RV630 Microcode\n"); 302190595Srnoland cp = RV630_cp_microcode; 303190595Srnoland pfp = RV630_pfp_microcode; 304190595Srnoland break; 305190595Srnoland case CHIP_RV620: 306190595Srnoland DRM_INFO("Loading RV620 Microcode\n"); 307190595Srnoland cp = RV620_cp_microcode; 308190595Srnoland pfp = RV620_pfp_microcode; 309190595Srnoland break; 310190595Srnoland case CHIP_RV635: 311190595Srnoland DRM_INFO("Loading RV635 Microcode\n"); 312190595Srnoland cp = RV635_cp_microcode; 313190595Srnoland pfp = RV635_pfp_microcode; 314190595Srnoland break; 315190595Srnoland case CHIP_RV670: 316190595Srnoland DRM_INFO("Loading RV670 Microcode\n"); 317190595Srnoland cp = RV670_cp_microcode; 318190595Srnoland pfp = RV670_pfp_microcode; 319190595Srnoland break; 320190595Srnoland case CHIP_RS780: 321196142Srnoland case CHIP_RS880: 322196142Srnoland DRM_INFO("Loading RS780/RS880 Microcode\n"); 323190595Srnoland cp = RS780_cp_microcode; 324190595Srnoland pfp = RS780_pfp_microcode; 325190595Srnoland break; 326190595Srnoland default: 327190674Srnoland return; 328190595Srnoland } 329189499Srnoland 330190674Srnoland r600_do_cp_stop(dev_priv); 331190674Srnoland 332190674Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 333190674Srnoland R600_RB_NO_UPDATE | 334190674Srnoland R600_RB_BLKSZ(15) | 335190674Srnoland R600_RB_BUFSZ(3)); 336190674Srnoland 337190674Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); 338190674Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 339190674Srnoland DRM_UDELAY(15000); 340190674Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 341190674Srnoland 342190674Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 343190674Srnoland 344190674Srnoland for (i = 0; i < PM4_UCODE_SIZE; i++) { 345190595Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, cp[i][0]); 346190595Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, cp[i][1]); 347190595Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, cp[i][2]); 348190595Srnoland } 349189499Srnoland 350190595Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 351190674Srnoland for (i = 0; i < PFP_UCODE_SIZE; i++) 352190595Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, pfp[i]); 353189499Srnoland 354189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 355189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 356189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); 357189499Srnoland} 358189499Srnoland 359189499Srnolandstatic void r700_vm_init(struct drm_device *dev) 360189499Srnoland{ 361189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 362189499Srnoland /* initialise the VM to use the page table we constructed up there */ 363189499Srnoland u32 vm_c0, i; 364189499Srnoland u32 mc_vm_md_l1; 365189499Srnoland u32 vm_l2_cntl, vm_l2_cntl3; 366189499Srnoland /* okay set up the PCIE aperture type thingo */ 367189499Srnoland RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); 368189499Srnoland RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); 369189499Srnoland RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); 370189499Srnoland 371189499Srnoland mc_vm_md_l1 = R700_ENABLE_L1_TLB | 372189499Srnoland R700_ENABLE_L1_FRAGMENT_PROCESSING | 373189499Srnoland R700_SYSTEM_ACCESS_MODE_IN_SYS | 374189499Srnoland R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | 375189499Srnoland R700_EFFECTIVE_L1_TLB_SIZE(5) | 376189499Srnoland R700_EFFECTIVE_L1_QUEUE_SIZE(5); 377189499Srnoland 378189499Srnoland RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1); 379189499Srnoland RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1); 380189499Srnoland RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1); 381189499Srnoland RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1); 382189499Srnoland RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1); 383189499Srnoland RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1); 384189499Srnoland RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1); 385189499Srnoland 386189499Srnoland vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; 387189499Srnoland vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7); 388189499Srnoland RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); 389189499Srnoland 390189499Srnoland RADEON_WRITE(R600_VM_L2_CNTL2, 0); 391189499Srnoland vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2); 392189499Srnoland RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); 393189499Srnoland 394189499Srnoland vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; 395189499Srnoland 396189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); 397189499Srnoland 398189499Srnoland vm_c0 &= ~R600_VM_ENABLE_CONTEXT; 399189499Srnoland 400189499Srnoland /* disable all other contexts */ 401189499Srnoland for (i = 1; i < 8; i++) 402189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); 403189499Srnoland 404189499Srnoland RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); 405189499Srnoland RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); 406189499Srnoland RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); 407189499Srnoland 408189499Srnoland r600_vm_flush_gart_range(dev); 409189499Srnoland} 410189499Srnoland 411189499Srnoland/* load r600 microcode */ 412189499Srnolandstatic void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) 413189499Srnoland{ 414190595Srnoland const u32 *pfp; 415190595Srnoland const u32 *cp; 416189499Srnoland int i; 417189499Srnoland 418190595Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 419190595Srnoland case CHIP_RV770: 420190674Srnoland DRM_INFO("Loading RV770/RV790 Microcode\n"); 421190595Srnoland pfp = RV770_pfp_microcode; 422190595Srnoland cp = RV770_cp_microcode; 423190595Srnoland break; 424190595Srnoland case CHIP_RV730: 425195501Srnoland case CHIP_RV740: 426195501Srnoland DRM_INFO("Loading RV730/RV740 Microcode\n"); 427190595Srnoland pfp = RV730_pfp_microcode; 428190595Srnoland cp = RV730_cp_microcode; 429190595Srnoland break; 430190595Srnoland case CHIP_RV710: 431190595Srnoland DRM_INFO("Loading RV710 Microcode\n"); 432190595Srnoland pfp = RV710_pfp_microcode; 433190595Srnoland cp = RV710_cp_microcode; 434190595Srnoland break; 435190595Srnoland default: 436190674Srnoland return; 437190595Srnoland } 438189499Srnoland 439190674Srnoland r600_do_cp_stop(dev_priv); 440190674Srnoland 441190674Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 442190674Srnoland R600_RB_NO_UPDATE | 443190674Srnoland (15 << 8) | 444190674Srnoland (3 << 0)); 445190674Srnoland 446190674Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); 447190674Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 448190674Srnoland DRM_UDELAY(15000); 449190674Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 450190674Srnoland 451190595Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 452190674Srnoland for (i = 0; i < R700_PFP_UCODE_SIZE; i++) 453190595Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, pfp[i]); 454190595Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 455189499Srnoland 456190595Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 457190674Srnoland for (i = 0; i < R700_PM4_UCODE_SIZE; i++) 458190595Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, cp[i]); 459190595Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 460189499Srnoland 461189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 462189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 463189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); 464189499Srnoland} 465189499Srnoland 466189499Srnolandstatic void r600_test_writeback(drm_radeon_private_t *dev_priv) 467189499Srnoland{ 468189499Srnoland u32 tmp; 469189499Srnoland 470189499Srnoland /* Start with assuming that writeback doesn't work */ 471189499Srnoland dev_priv->writeback_works = 0; 472189499Srnoland 473189499Srnoland /* Writeback doesn't seem to work everywhere, test it here and possibly 474189499Srnoland * enable it if it appears to work 475189499Srnoland */ 476189499Srnoland radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); 477189499Srnoland 478189499Srnoland RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef); 479189499Srnoland 480189499Srnoland for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { 481189499Srnoland u32 val; 482189499Srnoland 483189499Srnoland val = radeon_read_ring_rptr(dev_priv, R600_SCRATCHOFF(1)); 484189499Srnoland if (val == 0xdeadbeef) 485189499Srnoland break; 486189499Srnoland DRM_UDELAY(1); 487189499Srnoland } 488189499Srnoland 489189499Srnoland if (tmp < dev_priv->usec_timeout) { 490189499Srnoland dev_priv->writeback_works = 1; 491189499Srnoland DRM_INFO("writeback test succeeded in %d usecs\n", tmp); 492189499Srnoland } else { 493189499Srnoland dev_priv->writeback_works = 0; 494189499Srnoland DRM_INFO("writeback test failed\n"); 495189499Srnoland } 496189499Srnoland if (radeon_no_wb == 1) { 497189499Srnoland dev_priv->writeback_works = 0; 498189499Srnoland DRM_INFO("writeback forced off\n"); 499189499Srnoland } 500189499Srnoland 501189499Srnoland if (!dev_priv->writeback_works) { 502189499Srnoland /* Disable writeback to avoid unnecessary bus master transfer */ 503189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) | 504189499Srnoland RADEON_RB_NO_UPDATE); 505189499Srnoland RADEON_WRITE(R600_SCRATCH_UMSK, 0); 506189499Srnoland } 507189499Srnoland} 508189499Srnoland 509189499Srnolandint r600_do_engine_reset(struct drm_device *dev) 510189499Srnoland{ 511189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 512189499Srnoland u32 cp_ptr, cp_me_cntl, cp_rb_cntl; 513189499Srnoland 514189499Srnoland DRM_INFO("Resetting GPU\n"); 515189499Srnoland 516189499Srnoland cp_ptr = RADEON_READ(R600_CP_RB_WPTR); 517189499Srnoland cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL); 518189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT); 519189499Srnoland 520189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff); 521189499Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 522189499Srnoland DRM_UDELAY(50); 523189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 524189499Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 525189499Srnoland 526189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); 527189499Srnoland cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); 528189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA); 529189499Srnoland 530189499Srnoland RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); 531189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); 532189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl); 533189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl); 534189499Srnoland 535189499Srnoland /* Reset the CP ring */ 536189499Srnoland r600_do_cp_reset(dev_priv); 537189499Srnoland 538189499Srnoland /* The CP is no longer running after an engine reset */ 539189499Srnoland dev_priv->cp_running = 0; 540189499Srnoland 541189499Srnoland /* Reset any pending vertex, indirect buffers */ 542189499Srnoland radeon_freelist_reset(dev); 543189499Srnoland 544189499Srnoland return 0; 545189499Srnoland 546189499Srnoland} 547189499Srnoland 548189499Srnolandstatic u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, 549189499Srnoland u32 num_backends, 550189499Srnoland u32 backend_disable_mask) 551189499Srnoland{ 552189499Srnoland u32 backend_map = 0; 553189499Srnoland u32 enabled_backends_mask; 554189499Srnoland u32 enabled_backends_count; 555189499Srnoland u32 cur_pipe; 556189499Srnoland u32 swizzle_pipe[R6XX_MAX_PIPES]; 557189499Srnoland u32 cur_backend; 558189499Srnoland u32 i; 559189499Srnoland 560189499Srnoland if (num_tile_pipes > R6XX_MAX_PIPES) 561189499Srnoland num_tile_pipes = R6XX_MAX_PIPES; 562189499Srnoland if (num_tile_pipes < 1) 563189499Srnoland num_tile_pipes = 1; 564189499Srnoland if (num_backends > R6XX_MAX_BACKENDS) 565189499Srnoland num_backends = R6XX_MAX_BACKENDS; 566189499Srnoland if (num_backends < 1) 567189499Srnoland num_backends = 1; 568189499Srnoland 569189499Srnoland enabled_backends_mask = 0; 570189499Srnoland enabled_backends_count = 0; 571189499Srnoland for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { 572189499Srnoland if (((backend_disable_mask >> i) & 1) == 0) { 573189499Srnoland enabled_backends_mask |= (1 << i); 574189499Srnoland ++enabled_backends_count; 575189499Srnoland } 576189499Srnoland if (enabled_backends_count == num_backends) 577189499Srnoland break; 578189499Srnoland } 579189499Srnoland 580189499Srnoland if (enabled_backends_count == 0) { 581189499Srnoland enabled_backends_mask = 1; 582189499Srnoland enabled_backends_count = 1; 583189499Srnoland } 584189499Srnoland 585189499Srnoland if (enabled_backends_count != num_backends) 586189499Srnoland num_backends = enabled_backends_count; 587189499Srnoland 588189499Srnoland memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); 589189499Srnoland switch (num_tile_pipes) { 590189499Srnoland case 1: 591189499Srnoland swizzle_pipe[0] = 0; 592189499Srnoland break; 593189499Srnoland case 2: 594189499Srnoland swizzle_pipe[0] = 0; 595189499Srnoland swizzle_pipe[1] = 1; 596189499Srnoland break; 597189499Srnoland case 3: 598189499Srnoland swizzle_pipe[0] = 0; 599189499Srnoland swizzle_pipe[1] = 1; 600189499Srnoland swizzle_pipe[2] = 2; 601189499Srnoland break; 602189499Srnoland case 4: 603189499Srnoland swizzle_pipe[0] = 0; 604189499Srnoland swizzle_pipe[1] = 1; 605189499Srnoland swizzle_pipe[2] = 2; 606189499Srnoland swizzle_pipe[3] = 3; 607189499Srnoland break; 608189499Srnoland case 5: 609189499Srnoland swizzle_pipe[0] = 0; 610189499Srnoland swizzle_pipe[1] = 1; 611189499Srnoland swizzle_pipe[2] = 2; 612189499Srnoland swizzle_pipe[3] = 3; 613189499Srnoland swizzle_pipe[4] = 4; 614189499Srnoland break; 615189499Srnoland case 6: 616189499Srnoland swizzle_pipe[0] = 0; 617189499Srnoland swizzle_pipe[1] = 2; 618189499Srnoland swizzle_pipe[2] = 4; 619189499Srnoland swizzle_pipe[3] = 5; 620189499Srnoland swizzle_pipe[4] = 1; 621189499Srnoland swizzle_pipe[5] = 3; 622189499Srnoland break; 623189499Srnoland case 7: 624189499Srnoland swizzle_pipe[0] = 0; 625189499Srnoland swizzle_pipe[1] = 2; 626189499Srnoland swizzle_pipe[2] = 4; 627189499Srnoland swizzle_pipe[3] = 6; 628189499Srnoland swizzle_pipe[4] = 1; 629189499Srnoland swizzle_pipe[5] = 3; 630189499Srnoland swizzle_pipe[6] = 5; 631189499Srnoland break; 632189499Srnoland case 8: 633189499Srnoland swizzle_pipe[0] = 0; 634189499Srnoland swizzle_pipe[1] = 2; 635189499Srnoland swizzle_pipe[2] = 4; 636189499Srnoland swizzle_pipe[3] = 6; 637189499Srnoland swizzle_pipe[4] = 1; 638189499Srnoland swizzle_pipe[5] = 3; 639189499Srnoland swizzle_pipe[6] = 5; 640189499Srnoland swizzle_pipe[7] = 7; 641189499Srnoland break; 642189499Srnoland } 643189499Srnoland 644189499Srnoland cur_backend = 0; 645189499Srnoland for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { 646189499Srnoland while (((1 << cur_backend) & enabled_backends_mask) == 0) 647189499Srnoland cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; 648189499Srnoland 649189499Srnoland backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); 650189499Srnoland 651189499Srnoland cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; 652189499Srnoland } 653189499Srnoland 654189499Srnoland return backend_map; 655189499Srnoland} 656189499Srnoland 657189499Srnolandstatic int r600_count_pipe_bits(uint32_t val) 658189499Srnoland{ 659189499Srnoland int i, ret = 0; 660189499Srnoland for (i = 0; i < 32; i++) { 661189499Srnoland ret += val & 1; 662189499Srnoland val >>= 1; 663189499Srnoland } 664189499Srnoland return ret; 665189499Srnoland} 666189499Srnoland 667189499Srnolandstatic void r600_gfx_init(struct drm_device *dev, 668189499Srnoland drm_radeon_private_t *dev_priv) 669189499Srnoland{ 670189499Srnoland int i, j, num_qd_pipes; 671189499Srnoland u32 sx_debug_1; 672189499Srnoland u32 tc_cntl; 673189499Srnoland u32 arb_pop; 674189499Srnoland u32 num_gs_verts_per_thread; 675189499Srnoland u32 vgt_gs_per_es; 676189499Srnoland u32 gs_prim_buffer_depth = 0; 677189499Srnoland u32 sq_ms_fifo_sizes; 678189499Srnoland u32 sq_config; 679189499Srnoland u32 sq_gpr_resource_mgmt_1 = 0; 680189499Srnoland u32 sq_gpr_resource_mgmt_2 = 0; 681189499Srnoland u32 sq_thread_resource_mgmt = 0; 682189499Srnoland u32 sq_stack_resource_mgmt_1 = 0; 683189499Srnoland u32 sq_stack_resource_mgmt_2 = 0; 684189499Srnoland u32 hdp_host_path_cntl; 685189499Srnoland u32 backend_map; 686189499Srnoland u32 gb_tiling_config = 0; 687189499Srnoland u32 cc_rb_backend_disable = 0; 688189499Srnoland u32 cc_gc_shader_pipe_config = 0; 689189499Srnoland u32 ramcfg; 690189499Srnoland 691189499Srnoland /* setup chip specs */ 692189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 693189499Srnoland case CHIP_R600: 694189499Srnoland dev_priv->r600_max_pipes = 4; 695189499Srnoland dev_priv->r600_max_tile_pipes = 8; 696189499Srnoland dev_priv->r600_max_simds = 4; 697189499Srnoland dev_priv->r600_max_backends = 4; 698189499Srnoland dev_priv->r600_max_gprs = 256; 699189499Srnoland dev_priv->r600_max_threads = 192; 700189499Srnoland dev_priv->r600_max_stack_entries = 256; 701189499Srnoland dev_priv->r600_max_hw_contexts = 8; 702189499Srnoland dev_priv->r600_max_gs_threads = 16; 703189499Srnoland dev_priv->r600_sx_max_export_size = 128; 704189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 705189499Srnoland dev_priv->r600_sx_max_export_smx_size = 128; 706189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 707189499Srnoland break; 708189499Srnoland case CHIP_RV630: 709189499Srnoland case CHIP_RV635: 710189499Srnoland dev_priv->r600_max_pipes = 2; 711189499Srnoland dev_priv->r600_max_tile_pipes = 2; 712189499Srnoland dev_priv->r600_max_simds = 3; 713189499Srnoland dev_priv->r600_max_backends = 1; 714189499Srnoland dev_priv->r600_max_gprs = 128; 715189499Srnoland dev_priv->r600_max_threads = 192; 716189499Srnoland dev_priv->r600_max_stack_entries = 128; 717189499Srnoland dev_priv->r600_max_hw_contexts = 8; 718189499Srnoland dev_priv->r600_max_gs_threads = 4; 719189499Srnoland dev_priv->r600_sx_max_export_size = 128; 720189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 721189499Srnoland dev_priv->r600_sx_max_export_smx_size = 128; 722189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 723189499Srnoland break; 724189499Srnoland case CHIP_RV610: 725189499Srnoland case CHIP_RS780: 726196142Srnoland case CHIP_RS880: 727189499Srnoland case CHIP_RV620: 728189499Srnoland dev_priv->r600_max_pipes = 1; 729189499Srnoland dev_priv->r600_max_tile_pipes = 1; 730189499Srnoland dev_priv->r600_max_simds = 2; 731189499Srnoland dev_priv->r600_max_backends = 1; 732189499Srnoland dev_priv->r600_max_gprs = 128; 733189499Srnoland dev_priv->r600_max_threads = 192; 734189499Srnoland dev_priv->r600_max_stack_entries = 128; 735189499Srnoland dev_priv->r600_max_hw_contexts = 4; 736189499Srnoland dev_priv->r600_max_gs_threads = 4; 737189499Srnoland dev_priv->r600_sx_max_export_size = 128; 738189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 739189499Srnoland dev_priv->r600_sx_max_export_smx_size = 128; 740189499Srnoland dev_priv->r600_sq_num_cf_insts = 1; 741189499Srnoland break; 742189499Srnoland case CHIP_RV670: 743189499Srnoland dev_priv->r600_max_pipes = 4; 744189499Srnoland dev_priv->r600_max_tile_pipes = 4; 745189499Srnoland dev_priv->r600_max_simds = 4; 746189499Srnoland dev_priv->r600_max_backends = 4; 747189499Srnoland dev_priv->r600_max_gprs = 192; 748189499Srnoland dev_priv->r600_max_threads = 192; 749189499Srnoland dev_priv->r600_max_stack_entries = 256; 750189499Srnoland dev_priv->r600_max_hw_contexts = 8; 751189499Srnoland dev_priv->r600_max_gs_threads = 16; 752189499Srnoland dev_priv->r600_sx_max_export_size = 128; 753189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 754189499Srnoland dev_priv->r600_sx_max_export_smx_size = 128; 755189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 756189499Srnoland break; 757189499Srnoland default: 758189499Srnoland break; 759189499Srnoland } 760189499Srnoland 761189499Srnoland /* Initialize HDP */ 762189499Srnoland j = 0; 763189499Srnoland for (i = 0; i < 32; i++) { 764189499Srnoland RADEON_WRITE((0x2c14 + j), 0x00000000); 765189499Srnoland RADEON_WRITE((0x2c18 + j), 0x00000000); 766189499Srnoland RADEON_WRITE((0x2c1c + j), 0x00000000); 767189499Srnoland RADEON_WRITE((0x2c20 + j), 0x00000000); 768189499Srnoland RADEON_WRITE((0x2c24 + j), 0x00000000); 769189499Srnoland j += 0x18; 770189499Srnoland } 771189499Srnoland 772189499Srnoland RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); 773189499Srnoland 774189499Srnoland /* setup tiling, simd, pipe config */ 775189499Srnoland ramcfg = RADEON_READ(R600_RAMCFG); 776189499Srnoland 777189499Srnoland switch (dev_priv->r600_max_tile_pipes) { 778189499Srnoland case 1: 779189499Srnoland gb_tiling_config |= R600_PIPE_TILING(0); 780189499Srnoland break; 781189499Srnoland case 2: 782189499Srnoland gb_tiling_config |= R600_PIPE_TILING(1); 783189499Srnoland break; 784189499Srnoland case 4: 785189499Srnoland gb_tiling_config |= R600_PIPE_TILING(2); 786189499Srnoland break; 787189499Srnoland case 8: 788189499Srnoland gb_tiling_config |= R600_PIPE_TILING(3); 789189499Srnoland break; 790189499Srnoland default: 791189499Srnoland break; 792189499Srnoland } 793189499Srnoland 794189499Srnoland gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK); 795189499Srnoland 796189499Srnoland gb_tiling_config |= R600_GROUP_SIZE(0); 797189499Srnoland 798189499Srnoland if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) { 799189499Srnoland gb_tiling_config |= R600_ROW_TILING(3); 800189499Srnoland gb_tiling_config |= R600_SAMPLE_SPLIT(3); 801189499Srnoland } else { 802189499Srnoland gb_tiling_config |= 803189499Srnoland R600_ROW_TILING(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); 804189499Srnoland gb_tiling_config |= 805189499Srnoland R600_SAMPLE_SPLIT(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); 806189499Srnoland } 807189499Srnoland 808189499Srnoland gb_tiling_config |= R600_BANK_SWAPS(1); 809189499Srnoland 810189499Srnoland backend_map = r600_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, 811189499Srnoland dev_priv->r600_max_backends, 812189499Srnoland (0xff << dev_priv->r600_max_backends) & 0xff); 813189499Srnoland gb_tiling_config |= R600_BACKEND_MAP(backend_map); 814189499Srnoland 815189499Srnoland cc_gc_shader_pipe_config = 816189499Srnoland R600_INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R6XX_MAX_PIPES_MASK); 817189499Srnoland cc_gc_shader_pipe_config |= 818189499Srnoland R600_INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R6XX_MAX_SIMDS_MASK); 819189499Srnoland 820189499Srnoland cc_rb_backend_disable = 821189499Srnoland R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK); 822189499Srnoland 823189499Srnoland RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); 824189499Srnoland RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); 825189499Srnoland RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); 826189499Srnoland 827189499Srnoland RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); 828189499Srnoland RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); 829189499Srnoland RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); 830189499Srnoland 831189499Srnoland num_qd_pipes = 832189499Srnoland R6XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); 833189499Srnoland RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); 834189499Srnoland RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); 835189499Srnoland 836189499Srnoland /* set HW defaults for 3D engine */ 837189499Srnoland RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | 838189499Srnoland R600_ROQ_IB2_START(0x2b))); 839189499Srnoland 840189499Srnoland RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, (R600_MEQ_END(0x40) | 841189499Srnoland R600_ROQ_END(0x40))); 842189499Srnoland 843189499Srnoland RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | 844189499Srnoland R600_SYNC_GRADIENT | 845189499Srnoland R600_SYNC_WALKER | 846189499Srnoland R600_SYNC_ALIGNER)); 847189499Srnoland 848189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) 849189499Srnoland RADEON_WRITE(R600_ARB_GDEC_RD_CNTL, 0x00000021); 850189499Srnoland 851189499Srnoland sx_debug_1 = RADEON_READ(R600_SX_DEBUG_1); 852189499Srnoland sx_debug_1 |= R600_SMX_EVENT_RELEASE; 853189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600)) 854189499Srnoland sx_debug_1 |= R600_ENABLE_NEW_SMX_ADDRESS; 855189499Srnoland RADEON_WRITE(R600_SX_DEBUG_1, sx_debug_1); 856189499Srnoland 857189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || 858189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || 859189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || 860189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || 861196142Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || 862196142Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) 863189499Srnoland RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE); 864189499Srnoland else 865189499Srnoland RADEON_WRITE(R600_DB_DEBUG, 0); 866189499Srnoland 867189499Srnoland RADEON_WRITE(R600_DB_WATERMARKS, (R600_DEPTH_FREE(4) | 868189499Srnoland R600_DEPTH_FLUSH(16) | 869189499Srnoland R600_DEPTH_PENDING_FREE(4) | 870189499Srnoland R600_DEPTH_CACHELINE_FREE(16))); 871189499Srnoland RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); 872189499Srnoland RADEON_WRITE(R600_VGT_NUM_INSTANCES, 0); 873189499Srnoland 874189499Srnoland RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); 875189499Srnoland RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(0)); 876189499Srnoland 877189499Srnoland sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES); 878189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || 879189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || 880196142Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || 881196142Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { 882189499Srnoland sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) | 883189499Srnoland R600_FETCH_FIFO_HIWATER(0xa) | 884189499Srnoland R600_DONE_FIFO_HIWATER(0xe0) | 885189499Srnoland R600_ALU_UPDATE_FIFO_HIWATER(0x8)); 886189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || 887189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { 888189499Srnoland sq_ms_fifo_sizes &= ~R600_DONE_FIFO_HIWATER(0xff); 889189499Srnoland sq_ms_fifo_sizes |= R600_DONE_FIFO_HIWATER(0x4); 890189499Srnoland } 891189499Srnoland RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); 892189499Srnoland 893189499Srnoland /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT 894189499Srnoland * should be adjusted as needed by the 2D/3D drivers. This just sets default values 895189499Srnoland */ 896189499Srnoland sq_config = RADEON_READ(R600_SQ_CONFIG); 897189499Srnoland sq_config &= ~(R600_PS_PRIO(3) | 898189499Srnoland R600_VS_PRIO(3) | 899189499Srnoland R600_GS_PRIO(3) | 900189499Srnoland R600_ES_PRIO(3)); 901189499Srnoland sq_config |= (R600_DX9_CONSTS | 902189499Srnoland R600_VC_ENABLE | 903189499Srnoland R600_PS_PRIO(0) | 904189499Srnoland R600_VS_PRIO(1) | 905189499Srnoland R600_GS_PRIO(2) | 906189499Srnoland R600_ES_PRIO(3)); 907189499Srnoland 908189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) { 909189499Srnoland sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(124) | 910189499Srnoland R600_NUM_VS_GPRS(124) | 911189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(4)); 912189499Srnoland sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(0) | 913189499Srnoland R600_NUM_ES_GPRS(0)); 914189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(136) | 915189499Srnoland R600_NUM_VS_THREADS(48) | 916189499Srnoland R600_NUM_GS_THREADS(4) | 917189499Srnoland R600_NUM_ES_THREADS(4)); 918189499Srnoland sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(128) | 919189499Srnoland R600_NUM_VS_STACK_ENTRIES(128)); 920189499Srnoland sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(0) | 921189499Srnoland R600_NUM_ES_STACK_ENTRIES(0)); 922189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || 923189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || 924196142Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || 925196142Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { 926189499Srnoland /* no vertex cache */ 927189499Srnoland sq_config &= ~R600_VC_ENABLE; 928189499Srnoland 929189499Srnoland sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | 930189499Srnoland R600_NUM_VS_GPRS(44) | 931189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(2)); 932189499Srnoland sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | 933189499Srnoland R600_NUM_ES_GPRS(17)); 934189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | 935189499Srnoland R600_NUM_VS_THREADS(78) | 936189499Srnoland R600_NUM_GS_THREADS(4) | 937189499Srnoland R600_NUM_ES_THREADS(31)); 938189499Srnoland sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | 939189499Srnoland R600_NUM_VS_STACK_ENTRIES(40)); 940189499Srnoland sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | 941189499Srnoland R600_NUM_ES_STACK_ENTRIES(16)); 942189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || 943189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { 944189499Srnoland sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | 945189499Srnoland R600_NUM_VS_GPRS(44) | 946189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(2)); 947189499Srnoland sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(18) | 948189499Srnoland R600_NUM_ES_GPRS(18)); 949189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | 950189499Srnoland R600_NUM_VS_THREADS(78) | 951189499Srnoland R600_NUM_GS_THREADS(4) | 952189499Srnoland R600_NUM_ES_THREADS(31)); 953189499Srnoland sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | 954189499Srnoland R600_NUM_VS_STACK_ENTRIES(40)); 955189499Srnoland sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | 956189499Srnoland R600_NUM_ES_STACK_ENTRIES(16)); 957189499Srnoland } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) { 958189499Srnoland sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | 959189499Srnoland R600_NUM_VS_GPRS(44) | 960189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(2)); 961189499Srnoland sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | 962189499Srnoland R600_NUM_ES_GPRS(17)); 963189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | 964189499Srnoland R600_NUM_VS_THREADS(78) | 965189499Srnoland R600_NUM_GS_THREADS(4) | 966189499Srnoland R600_NUM_ES_THREADS(31)); 967189499Srnoland sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(64) | 968189499Srnoland R600_NUM_VS_STACK_ENTRIES(64)); 969189499Srnoland sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(64) | 970189499Srnoland R600_NUM_ES_STACK_ENTRIES(64)); 971189499Srnoland } 972189499Srnoland 973189499Srnoland RADEON_WRITE(R600_SQ_CONFIG, sq_config); 974189499Srnoland RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); 975189499Srnoland RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); 976189499Srnoland RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); 977189499Srnoland RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); 978189499Srnoland RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); 979189499Srnoland 980189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || 981189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || 982196142Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || 983196142Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) 984189499Srnoland RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY)); 985189499Srnoland else 986189499Srnoland RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC)); 987189499Srnoland 988189499Srnoland RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_2S, (R600_S0_X(0xc) | 989189499Srnoland R600_S0_Y(0x4) | 990189499Srnoland R600_S1_X(0x4) | 991189499Srnoland R600_S1_Y(0xc))); 992189499Srnoland RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_4S, (R600_S0_X(0xe) | 993189499Srnoland R600_S0_Y(0xe) | 994189499Srnoland R600_S1_X(0x2) | 995189499Srnoland R600_S1_Y(0x2) | 996189499Srnoland R600_S2_X(0xa) | 997189499Srnoland R600_S2_Y(0x6) | 998189499Srnoland R600_S3_X(0x6) | 999189499Srnoland R600_S3_Y(0xa))); 1000189499Srnoland RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0, (R600_S0_X(0xe) | 1001189499Srnoland R600_S0_Y(0xb) | 1002189499Srnoland R600_S1_X(0x4) | 1003189499Srnoland R600_S1_Y(0xc) | 1004189499Srnoland R600_S2_X(0x1) | 1005189499Srnoland R600_S2_Y(0x6) | 1006189499Srnoland R600_S3_X(0xa) | 1007189499Srnoland R600_S3_Y(0xe))); 1008189499Srnoland RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1, (R600_S4_X(0x6) | 1009189499Srnoland R600_S4_Y(0x1) | 1010189499Srnoland R600_S5_X(0x0) | 1011189499Srnoland R600_S5_Y(0x0) | 1012189499Srnoland R600_S6_X(0xb) | 1013189499Srnoland R600_S6_Y(0x4) | 1014189499Srnoland R600_S7_X(0x7) | 1015189499Srnoland R600_S7_Y(0x8))); 1016189499Srnoland 1017189499Srnoland 1018189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1019189499Srnoland case CHIP_R600: 1020189499Srnoland case CHIP_RV630: 1021189499Srnoland case CHIP_RV635: 1022189499Srnoland gs_prim_buffer_depth = 0; 1023189499Srnoland break; 1024189499Srnoland case CHIP_RV610: 1025189499Srnoland case CHIP_RS780: 1026196142Srnoland case CHIP_RS880: 1027189499Srnoland case CHIP_RV620: 1028189499Srnoland gs_prim_buffer_depth = 32; 1029189499Srnoland break; 1030189499Srnoland case CHIP_RV670: 1031189499Srnoland gs_prim_buffer_depth = 128; 1032189499Srnoland break; 1033189499Srnoland default: 1034189499Srnoland break; 1035189499Srnoland } 1036189499Srnoland 1037189499Srnoland num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; 1038189499Srnoland vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; 1039189499Srnoland /* Max value for this is 256 */ 1040189499Srnoland if (vgt_gs_per_es > 256) 1041189499Srnoland vgt_gs_per_es = 256; 1042189499Srnoland 1043189499Srnoland RADEON_WRITE(R600_VGT_ES_PER_GS, 128); 1044189499Srnoland RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); 1045189499Srnoland RADEON_WRITE(R600_VGT_GS_PER_VS, 2); 1046189499Srnoland RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); 1047189499Srnoland 1048189499Srnoland /* more default values. 2D/3D driver should adjust as needed */ 1049189499Srnoland RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); 1050189499Srnoland RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); 1051189499Srnoland RADEON_WRITE(R600_SX_MISC, 0); 1052189499Srnoland RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); 1053189499Srnoland RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); 1054189499Srnoland RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); 1055189499Srnoland RADEON_WRITE(R600_SPI_INPUT_Z, 0); 1056189499Srnoland RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); 1057189499Srnoland RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); 1058189499Srnoland 1059189499Srnoland /* clear render buffer base addresses */ 1060189499Srnoland RADEON_WRITE(R600_CB_COLOR0_BASE, 0); 1061189499Srnoland RADEON_WRITE(R600_CB_COLOR1_BASE, 0); 1062189499Srnoland RADEON_WRITE(R600_CB_COLOR2_BASE, 0); 1063189499Srnoland RADEON_WRITE(R600_CB_COLOR3_BASE, 0); 1064189499Srnoland RADEON_WRITE(R600_CB_COLOR4_BASE, 0); 1065189499Srnoland RADEON_WRITE(R600_CB_COLOR5_BASE, 0); 1066189499Srnoland RADEON_WRITE(R600_CB_COLOR6_BASE, 0); 1067189499Srnoland RADEON_WRITE(R600_CB_COLOR7_BASE, 0); 1068189499Srnoland 1069189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1070189499Srnoland case CHIP_RV610: 1071189499Srnoland case CHIP_RS780: 1072196142Srnoland case CHIP_RS880: 1073189499Srnoland case CHIP_RV620: 1074189499Srnoland tc_cntl = R600_TC_L2_SIZE(8); 1075189499Srnoland break; 1076189499Srnoland case CHIP_RV630: 1077189499Srnoland case CHIP_RV635: 1078189499Srnoland tc_cntl = R600_TC_L2_SIZE(4); 1079189499Srnoland break; 1080189499Srnoland case CHIP_R600: 1081189499Srnoland tc_cntl = R600_TC_L2_SIZE(0) | R600_L2_DISABLE_LATE_HIT; 1082189499Srnoland break; 1083189499Srnoland default: 1084189499Srnoland tc_cntl = R600_TC_L2_SIZE(0); 1085189499Srnoland break; 1086189499Srnoland } 1087189499Srnoland 1088189499Srnoland RADEON_WRITE(R600_TC_CNTL, tc_cntl); 1089189499Srnoland 1090189499Srnoland hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); 1091189499Srnoland RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); 1092189499Srnoland 1093189499Srnoland arb_pop = RADEON_READ(R600_ARB_POP); 1094189499Srnoland arb_pop |= R600_ENABLE_TC128; 1095189499Srnoland RADEON_WRITE(R600_ARB_POP, arb_pop); 1096189499Srnoland 1097189499Srnoland RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); 1098189499Srnoland RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | 1099189499Srnoland R600_NUM_CLIP_SEQ(3))); 1100189499Srnoland RADEON_WRITE(R600_PA_SC_ENHANCE, R600_FORCE_EOV_MAX_CLK_CNT(4095)); 1101189499Srnoland 1102189499Srnoland} 1103189499Srnoland 1104189499Srnolandstatic u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, 1105189499Srnoland u32 num_backends, 1106189499Srnoland u32 backend_disable_mask) 1107189499Srnoland{ 1108189499Srnoland u32 backend_map = 0; 1109189499Srnoland u32 enabled_backends_mask; 1110189499Srnoland u32 enabled_backends_count; 1111189499Srnoland u32 cur_pipe; 1112189499Srnoland u32 swizzle_pipe[R7XX_MAX_PIPES]; 1113189499Srnoland u32 cur_backend; 1114189499Srnoland u32 i; 1115189499Srnoland 1116189499Srnoland if (num_tile_pipes > R7XX_MAX_PIPES) 1117189499Srnoland num_tile_pipes = R7XX_MAX_PIPES; 1118189499Srnoland if (num_tile_pipes < 1) 1119189499Srnoland num_tile_pipes = 1; 1120189499Srnoland if (num_backends > R7XX_MAX_BACKENDS) 1121189499Srnoland num_backends = R7XX_MAX_BACKENDS; 1122189499Srnoland if (num_backends < 1) 1123189499Srnoland num_backends = 1; 1124189499Srnoland 1125189499Srnoland enabled_backends_mask = 0; 1126189499Srnoland enabled_backends_count = 0; 1127189499Srnoland for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { 1128189499Srnoland if (((backend_disable_mask >> i) & 1) == 0) { 1129189499Srnoland enabled_backends_mask |= (1 << i); 1130189499Srnoland ++enabled_backends_count; 1131189499Srnoland } 1132189499Srnoland if (enabled_backends_count == num_backends) 1133189499Srnoland break; 1134189499Srnoland } 1135189499Srnoland 1136189499Srnoland if (enabled_backends_count == 0) { 1137189499Srnoland enabled_backends_mask = 1; 1138189499Srnoland enabled_backends_count = 1; 1139189499Srnoland } 1140189499Srnoland 1141189499Srnoland if (enabled_backends_count != num_backends) 1142189499Srnoland num_backends = enabled_backends_count; 1143189499Srnoland 1144189499Srnoland memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); 1145189499Srnoland switch (num_tile_pipes) { 1146189499Srnoland case 1: 1147189499Srnoland swizzle_pipe[0] = 0; 1148189499Srnoland break; 1149189499Srnoland case 2: 1150189499Srnoland swizzle_pipe[0] = 0; 1151189499Srnoland swizzle_pipe[1] = 1; 1152189499Srnoland break; 1153189499Srnoland case 3: 1154189499Srnoland swizzle_pipe[0] = 0; 1155189499Srnoland swizzle_pipe[1] = 2; 1156189499Srnoland swizzle_pipe[2] = 1; 1157189499Srnoland break; 1158189499Srnoland case 4: 1159189499Srnoland swizzle_pipe[0] = 0; 1160189499Srnoland swizzle_pipe[1] = 2; 1161189499Srnoland swizzle_pipe[2] = 3; 1162189499Srnoland swizzle_pipe[3] = 1; 1163189499Srnoland break; 1164189499Srnoland case 5: 1165189499Srnoland swizzle_pipe[0] = 0; 1166189499Srnoland swizzle_pipe[1] = 2; 1167189499Srnoland swizzle_pipe[2] = 4; 1168189499Srnoland swizzle_pipe[3] = 1; 1169189499Srnoland swizzle_pipe[4] = 3; 1170189499Srnoland break; 1171189499Srnoland case 6: 1172189499Srnoland swizzle_pipe[0] = 0; 1173189499Srnoland swizzle_pipe[1] = 2; 1174189499Srnoland swizzle_pipe[2] = 4; 1175189499Srnoland swizzle_pipe[3] = 5; 1176189499Srnoland swizzle_pipe[4] = 3; 1177189499Srnoland swizzle_pipe[5] = 1; 1178189499Srnoland break; 1179189499Srnoland case 7: 1180189499Srnoland swizzle_pipe[0] = 0; 1181189499Srnoland swizzle_pipe[1] = 2; 1182189499Srnoland swizzle_pipe[2] = 4; 1183189499Srnoland swizzle_pipe[3] = 6; 1184189499Srnoland swizzle_pipe[4] = 3; 1185189499Srnoland swizzle_pipe[5] = 1; 1186189499Srnoland swizzle_pipe[6] = 5; 1187189499Srnoland break; 1188189499Srnoland case 8: 1189189499Srnoland swizzle_pipe[0] = 0; 1190189499Srnoland swizzle_pipe[1] = 2; 1191189499Srnoland swizzle_pipe[2] = 4; 1192189499Srnoland swizzle_pipe[3] = 6; 1193189499Srnoland swizzle_pipe[4] = 3; 1194189499Srnoland swizzle_pipe[5] = 1; 1195189499Srnoland swizzle_pipe[6] = 7; 1196189499Srnoland swizzle_pipe[7] = 5; 1197189499Srnoland break; 1198189499Srnoland } 1199189499Srnoland 1200189499Srnoland cur_backend = 0; 1201189499Srnoland for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { 1202189499Srnoland while (((1 << cur_backend) & enabled_backends_mask) == 0) 1203189499Srnoland cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; 1204189499Srnoland 1205189499Srnoland backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); 1206189499Srnoland 1207189499Srnoland cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; 1208189499Srnoland } 1209189499Srnoland 1210189499Srnoland return backend_map; 1211189499Srnoland} 1212189499Srnoland 1213189499Srnolandstatic void r700_gfx_init(struct drm_device *dev, 1214189499Srnoland drm_radeon_private_t *dev_priv) 1215189499Srnoland{ 1216189499Srnoland int i, j, num_qd_pipes; 1217189499Srnoland u32 sx_debug_1; 1218189499Srnoland u32 smx_dc_ctl0; 1219189499Srnoland u32 num_gs_verts_per_thread; 1220189499Srnoland u32 vgt_gs_per_es; 1221189499Srnoland u32 gs_prim_buffer_depth = 0; 1222189499Srnoland u32 sq_ms_fifo_sizes; 1223189499Srnoland u32 sq_config; 1224189499Srnoland u32 sq_thread_resource_mgmt; 1225189499Srnoland u32 hdp_host_path_cntl; 1226189499Srnoland u32 sq_dyn_gpr_size_simd_ab_0; 1227189499Srnoland u32 backend_map; 1228189499Srnoland u32 gb_tiling_config = 0; 1229189499Srnoland u32 cc_rb_backend_disable = 0; 1230189499Srnoland u32 cc_gc_shader_pipe_config = 0; 1231189499Srnoland u32 mc_arb_ramcfg; 1232189499Srnoland u32 db_debug4; 1233189499Srnoland 1234189499Srnoland /* setup chip specs */ 1235189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1236189499Srnoland case CHIP_RV770: 1237189499Srnoland dev_priv->r600_max_pipes = 4; 1238189499Srnoland dev_priv->r600_max_tile_pipes = 8; 1239189499Srnoland dev_priv->r600_max_simds = 10; 1240189499Srnoland dev_priv->r600_max_backends = 4; 1241189499Srnoland dev_priv->r600_max_gprs = 256; 1242189499Srnoland dev_priv->r600_max_threads = 248; 1243189499Srnoland dev_priv->r600_max_stack_entries = 512; 1244189499Srnoland dev_priv->r600_max_hw_contexts = 8; 1245189499Srnoland dev_priv->r600_max_gs_threads = 16 * 2; 1246189499Srnoland dev_priv->r600_sx_max_export_size = 128; 1247189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 1248189499Srnoland dev_priv->r600_sx_max_export_smx_size = 112; 1249189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 1250189499Srnoland 1251189499Srnoland dev_priv->r700_sx_num_of_sets = 7; 1252189499Srnoland dev_priv->r700_sc_prim_fifo_size = 0xF9; 1253189499Srnoland dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; 1254189499Srnoland dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; 1255189499Srnoland break; 1256195501Srnoland case CHIP_RV740: 1257195501Srnoland dev_priv->r600_max_pipes = 4; 1258195501Srnoland dev_priv->r600_max_tile_pipes = 4; 1259195501Srnoland dev_priv->r600_max_simds = 8; 1260195501Srnoland dev_priv->r600_max_backends = 4; 1261195501Srnoland dev_priv->r600_max_gprs = 256; 1262195501Srnoland dev_priv->r600_max_threads = 248; 1263195501Srnoland dev_priv->r600_max_stack_entries = 512; 1264195501Srnoland dev_priv->r600_max_hw_contexts = 8; 1265195501Srnoland dev_priv->r600_max_gs_threads = 16 * 2; 1266195501Srnoland dev_priv->r600_sx_max_export_size = 256; 1267195501Srnoland dev_priv->r600_sx_max_export_pos_size = 32; 1268195501Srnoland dev_priv->r600_sx_max_export_smx_size = 224; 1269195501Srnoland dev_priv->r600_sq_num_cf_insts = 2; 1270195501Srnoland 1271195501Srnoland dev_priv->r700_sx_num_of_sets = 7; 1272195501Srnoland dev_priv->r700_sc_prim_fifo_size = 0x100; 1273195501Srnoland dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; 1274195501Srnoland dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; 1275195501Srnoland 1276195501Srnoland if (dev_priv->r600_sx_max_export_pos_size > 16) { 1277195501Srnoland dev_priv->r600_sx_max_export_pos_size -= 16; 1278195501Srnoland dev_priv->r600_sx_max_export_smx_size += 16; 1279195501Srnoland } 1280195501Srnoland break; 1281189499Srnoland case CHIP_RV730: 1282189499Srnoland dev_priv->r600_max_pipes = 2; 1283189499Srnoland dev_priv->r600_max_tile_pipes = 4; 1284189499Srnoland dev_priv->r600_max_simds = 8; 1285189499Srnoland dev_priv->r600_max_backends = 2; 1286189499Srnoland dev_priv->r600_max_gprs = 128; 1287189499Srnoland dev_priv->r600_max_threads = 248; 1288189499Srnoland dev_priv->r600_max_stack_entries = 256; 1289189499Srnoland dev_priv->r600_max_hw_contexts = 8; 1290189499Srnoland dev_priv->r600_max_gs_threads = 16 * 2; 1291189499Srnoland dev_priv->r600_sx_max_export_size = 256; 1292189499Srnoland dev_priv->r600_sx_max_export_pos_size = 32; 1293189499Srnoland dev_priv->r600_sx_max_export_smx_size = 224; 1294189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 1295189499Srnoland 1296189499Srnoland dev_priv->r700_sx_num_of_sets = 7; 1297189499Srnoland dev_priv->r700_sc_prim_fifo_size = 0xf9; 1298189499Srnoland dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; 1299189499Srnoland dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; 1300195501Srnoland 1301195501Srnoland if (dev_priv->r600_sx_max_export_pos_size > 16) { 1302195501Srnoland dev_priv->r600_sx_max_export_pos_size -= 16; 1303195501Srnoland dev_priv->r600_sx_max_export_smx_size += 16; 1304195501Srnoland } 1305189499Srnoland break; 1306189499Srnoland case CHIP_RV710: 1307189499Srnoland dev_priv->r600_max_pipes = 2; 1308189499Srnoland dev_priv->r600_max_tile_pipes = 2; 1309189499Srnoland dev_priv->r600_max_simds = 2; 1310189499Srnoland dev_priv->r600_max_backends = 1; 1311189499Srnoland dev_priv->r600_max_gprs = 256; 1312189499Srnoland dev_priv->r600_max_threads = 192; 1313189499Srnoland dev_priv->r600_max_stack_entries = 256; 1314189499Srnoland dev_priv->r600_max_hw_contexts = 4; 1315189499Srnoland dev_priv->r600_max_gs_threads = 8 * 2; 1316189499Srnoland dev_priv->r600_sx_max_export_size = 128; 1317189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 1318189499Srnoland dev_priv->r600_sx_max_export_smx_size = 112; 1319189499Srnoland dev_priv->r600_sq_num_cf_insts = 1; 1320189499Srnoland 1321189499Srnoland dev_priv->r700_sx_num_of_sets = 7; 1322189499Srnoland dev_priv->r700_sc_prim_fifo_size = 0x40; 1323189499Srnoland dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; 1324189499Srnoland dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; 1325189499Srnoland break; 1326189499Srnoland default: 1327189499Srnoland break; 1328189499Srnoland } 1329189499Srnoland 1330189499Srnoland /* Initialize HDP */ 1331189499Srnoland j = 0; 1332189499Srnoland for (i = 0; i < 32; i++) { 1333189499Srnoland RADEON_WRITE((0x2c14 + j), 0x00000000); 1334189499Srnoland RADEON_WRITE((0x2c18 + j), 0x00000000); 1335189499Srnoland RADEON_WRITE((0x2c1c + j), 0x00000000); 1336189499Srnoland RADEON_WRITE((0x2c20 + j), 0x00000000); 1337189499Srnoland RADEON_WRITE((0x2c24 + j), 0x00000000); 1338189499Srnoland j += 0x18; 1339189499Srnoland } 1340189499Srnoland 1341189499Srnoland RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); 1342189499Srnoland 1343189499Srnoland /* setup tiling, simd, pipe config */ 1344189499Srnoland mc_arb_ramcfg = RADEON_READ(R700_MC_ARB_RAMCFG); 1345189499Srnoland 1346189499Srnoland switch (dev_priv->r600_max_tile_pipes) { 1347189499Srnoland case 1: 1348189499Srnoland gb_tiling_config |= R600_PIPE_TILING(0); 1349189499Srnoland break; 1350189499Srnoland case 2: 1351189499Srnoland gb_tiling_config |= R600_PIPE_TILING(1); 1352189499Srnoland break; 1353189499Srnoland case 4: 1354189499Srnoland gb_tiling_config |= R600_PIPE_TILING(2); 1355189499Srnoland break; 1356189499Srnoland case 8: 1357189499Srnoland gb_tiling_config |= R600_PIPE_TILING(3); 1358189499Srnoland break; 1359189499Srnoland default: 1360189499Srnoland break; 1361189499Srnoland } 1362189499Srnoland 1363189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) 1364189499Srnoland gb_tiling_config |= R600_BANK_TILING(1); 1365189499Srnoland else 1366189499Srnoland gb_tiling_config |= R600_BANK_TILING((mc_arb_ramcfg >> R700_NOOFBANK_SHIFT) & R700_NOOFBANK_MASK); 1367189499Srnoland 1368189499Srnoland gb_tiling_config |= R600_GROUP_SIZE(0); 1369189499Srnoland 1370189499Srnoland if (((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK) > 3) { 1371189499Srnoland gb_tiling_config |= R600_ROW_TILING(3); 1372189499Srnoland gb_tiling_config |= R600_SAMPLE_SPLIT(3); 1373189499Srnoland } else { 1374189499Srnoland gb_tiling_config |= 1375189499Srnoland R600_ROW_TILING(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); 1376189499Srnoland gb_tiling_config |= 1377189499Srnoland R600_SAMPLE_SPLIT(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); 1378189499Srnoland } 1379189499Srnoland 1380189499Srnoland gb_tiling_config |= R600_BANK_SWAPS(1); 1381189499Srnoland 1382189499Srnoland backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, 1383189499Srnoland dev_priv->r600_max_backends, 1384189499Srnoland (0xff << dev_priv->r600_max_backends) & 0xff); 1385189499Srnoland gb_tiling_config |= R600_BACKEND_MAP(backend_map); 1386189499Srnoland 1387189499Srnoland cc_gc_shader_pipe_config = 1388189499Srnoland R600_INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R7XX_MAX_PIPES_MASK); 1389189499Srnoland cc_gc_shader_pipe_config |= 1390189499Srnoland R600_INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R7XX_MAX_SIMDS_MASK); 1391189499Srnoland 1392189499Srnoland cc_rb_backend_disable = 1393189499Srnoland R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK); 1394189499Srnoland 1395189499Srnoland RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); 1396189499Srnoland RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); 1397189499Srnoland RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); 1398189499Srnoland 1399189499Srnoland RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); 1400189499Srnoland RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); 1401189499Srnoland RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); 1402189499Srnoland 1403189499Srnoland RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); 1404189499Srnoland RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0); 1405189499Srnoland RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0); 1406189499Srnoland RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0); 1407189499Srnoland RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0); 1408189499Srnoland 1409189499Srnoland num_qd_pipes = 1410189499Srnoland R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); 1411189499Srnoland RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); 1412189499Srnoland RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); 1413189499Srnoland 1414189499Srnoland /* set HW defaults for 3D engine */ 1415189499Srnoland RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | 1416189499Srnoland R600_ROQ_IB2_START(0x2b))); 1417189499Srnoland 1418189499Srnoland RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, R700_STQ_SPLIT(0x30)); 1419189499Srnoland 1420189499Srnoland RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | 1421189499Srnoland R600_SYNC_GRADIENT | 1422189499Srnoland R600_SYNC_WALKER | 1423189499Srnoland R600_SYNC_ALIGNER)); 1424189499Srnoland 1425189499Srnoland sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1); 1426189499Srnoland sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS; 1427189499Srnoland RADEON_WRITE(R700_SX_DEBUG_1, sx_debug_1); 1428189499Srnoland 1429189499Srnoland smx_dc_ctl0 = RADEON_READ(R600_SMX_DC_CTL0); 1430189499Srnoland smx_dc_ctl0 &= ~R700_CACHE_DEPTH(0x1ff); 1431189499Srnoland smx_dc_ctl0 |= R700_CACHE_DEPTH((dev_priv->r700_sx_num_of_sets * 64) - 1); 1432189499Srnoland RADEON_WRITE(R600_SMX_DC_CTL0, smx_dc_ctl0); 1433189499Srnoland 1434189499Srnoland RADEON_WRITE(R700_SMX_EVENT_CTL, (R700_ES_FLUSH_CTL(4) | 1435189499Srnoland R700_GS_FLUSH_CTL(4) | 1436189499Srnoland R700_ACK_FLUSH_CTL(3) | 1437189499Srnoland R700_SYNC_FLUSH_CTL)); 1438189499Srnoland 1439189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) 1440189499Srnoland RADEON_WRITE(R700_DB_DEBUG3, R700_DB_CLK_OFF_DELAY(0x1f)); 1441189499Srnoland else { 1442189499Srnoland db_debug4 = RADEON_READ(RV700_DB_DEBUG4); 1443189499Srnoland db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER; 1444189499Srnoland RADEON_WRITE(RV700_DB_DEBUG4, db_debug4); 1445189499Srnoland } 1446189499Srnoland 1447189499Srnoland RADEON_WRITE(R600_SX_EXPORT_BUFFER_SIZES, (R600_COLOR_BUFFER_SIZE((dev_priv->r600_sx_max_export_size / 4) - 1) | 1448189499Srnoland R600_POSITION_BUFFER_SIZE((dev_priv->r600_sx_max_export_pos_size / 4) - 1) | 1449189499Srnoland R600_SMX_BUFFER_SIZE((dev_priv->r600_sx_max_export_smx_size / 4) - 1))); 1450189499Srnoland 1451189499Srnoland RADEON_WRITE(R700_PA_SC_FIFO_SIZE_R7XX, (R700_SC_PRIM_FIFO_SIZE(dev_priv->r700_sc_prim_fifo_size) | 1452189499Srnoland R700_SC_HIZ_TILE_FIFO_SIZE(dev_priv->r700_sc_hiz_tile_fifo_size) | 1453189499Srnoland R700_SC_EARLYZ_TILE_FIFO_SIZE(dev_priv->r700_sc_earlyz_tile_fifo_fize))); 1454189499Srnoland 1455189499Srnoland RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); 1456189499Srnoland 1457189499Srnoland RADEON_WRITE(R600_VGT_NUM_INSTANCES, 1); 1458189499Srnoland 1459189499Srnoland RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); 1460189499Srnoland 1461189499Srnoland RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(4)); 1462189499Srnoland 1463189499Srnoland RADEON_WRITE(R600_CP_PERFMON_CNTL, 0); 1464189499Srnoland 1465189499Srnoland sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(16 * dev_priv->r600_sq_num_cf_insts) | 1466189499Srnoland R600_DONE_FIFO_HIWATER(0xe0) | 1467189499Srnoland R600_ALU_UPDATE_FIFO_HIWATER(0x8)); 1468189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1469189499Srnoland case CHIP_RV770: 1470189499Srnoland sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1); 1471189499Srnoland break; 1472195501Srnoland case CHIP_RV740: 1473189499Srnoland case CHIP_RV730: 1474189499Srnoland case CHIP_RV710: 1475189499Srnoland default: 1476189499Srnoland sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4); 1477189499Srnoland break; 1478189499Srnoland } 1479189499Srnoland RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); 1480189499Srnoland 1481189499Srnoland /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT 1482189499Srnoland * should be adjusted as needed by the 2D/3D drivers. This just sets default values 1483189499Srnoland */ 1484189499Srnoland sq_config = RADEON_READ(R600_SQ_CONFIG); 1485189499Srnoland sq_config &= ~(R600_PS_PRIO(3) | 1486189499Srnoland R600_VS_PRIO(3) | 1487189499Srnoland R600_GS_PRIO(3) | 1488189499Srnoland R600_ES_PRIO(3)); 1489189499Srnoland sq_config |= (R600_DX9_CONSTS | 1490189499Srnoland R600_VC_ENABLE | 1491189499Srnoland R600_EXPORT_SRC_C | 1492189499Srnoland R600_PS_PRIO(0) | 1493189499Srnoland R600_VS_PRIO(1) | 1494189499Srnoland R600_GS_PRIO(2) | 1495189499Srnoland R600_ES_PRIO(3)); 1496189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) 1497189499Srnoland /* no vertex cache */ 1498189499Srnoland sq_config &= ~R600_VC_ENABLE; 1499189499Srnoland 1500189499Srnoland RADEON_WRITE(R600_SQ_CONFIG, sq_config); 1501189499Srnoland 1502189499Srnoland RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, (R600_NUM_PS_GPRS((dev_priv->r600_max_gprs * 24)/64) | 1503189499Srnoland R600_NUM_VS_GPRS((dev_priv->r600_max_gprs * 24)/64) | 1504189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(((dev_priv->r600_max_gprs * 24)/64)/2))); 1505189499Srnoland 1506189499Srnoland RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, (R600_NUM_GS_GPRS((dev_priv->r600_max_gprs * 7)/64) | 1507189499Srnoland R600_NUM_ES_GPRS((dev_priv->r600_max_gprs * 7)/64))); 1508189499Srnoland 1509189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS((dev_priv->r600_max_threads * 4)/8) | 1510189499Srnoland R600_NUM_VS_THREADS((dev_priv->r600_max_threads * 2)/8) | 1511189499Srnoland R600_NUM_ES_THREADS((dev_priv->r600_max_threads * 1)/8)); 1512189499Srnoland if (((dev_priv->r600_max_threads * 1) / 8) > dev_priv->r600_max_gs_threads) 1513189499Srnoland sq_thread_resource_mgmt |= R600_NUM_GS_THREADS(dev_priv->r600_max_gs_threads); 1514189499Srnoland else 1515189499Srnoland sq_thread_resource_mgmt |= R600_NUM_GS_THREADS((dev_priv->r600_max_gs_threads * 1)/8); 1516189499Srnoland RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); 1517189499Srnoland 1518189499Srnoland RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, (R600_NUM_PS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | 1519189499Srnoland R600_NUM_VS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); 1520189499Srnoland 1521189499Srnoland RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, (R600_NUM_GS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | 1522189499Srnoland R600_NUM_ES_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); 1523189499Srnoland 1524189499Srnoland sq_dyn_gpr_size_simd_ab_0 = (R700_SIMDA_RING0((dev_priv->r600_max_gprs * 38)/64) | 1525189499Srnoland R700_SIMDA_RING1((dev_priv->r600_max_gprs * 38)/64) | 1526189499Srnoland R700_SIMDB_RING0((dev_priv->r600_max_gprs * 38)/64) | 1527189499Srnoland R700_SIMDB_RING1((dev_priv->r600_max_gprs * 38)/64)); 1528189499Srnoland 1529189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0); 1530189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0); 1531189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0); 1532189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0); 1533189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0); 1534189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0); 1535189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0); 1536189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0); 1537189499Srnoland 1538189499Srnoland RADEON_WRITE(R700_PA_SC_FORCE_EOV_MAX_CNTS, (R700_FORCE_EOV_MAX_CLK_CNT(4095) | 1539189499Srnoland R700_FORCE_EOV_MAX_REZ_CNT(255))); 1540189499Srnoland 1541189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) 1542189499Srnoland RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_TC_ONLY) | 1543189499Srnoland R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); 1544189499Srnoland else 1545189499Srnoland RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_VC_AND_TC) | 1546189499Srnoland R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); 1547189499Srnoland 1548189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1549189499Srnoland case CHIP_RV770: 1550195501Srnoland case CHIP_RV740: 1551189499Srnoland case CHIP_RV730: 1552189499Srnoland gs_prim_buffer_depth = 384; 1553189499Srnoland break; 1554189499Srnoland case CHIP_RV710: 1555189499Srnoland gs_prim_buffer_depth = 128; 1556189499Srnoland break; 1557189499Srnoland default: 1558189499Srnoland break; 1559189499Srnoland } 1560189499Srnoland 1561189499Srnoland num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; 1562189499Srnoland vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; 1563189499Srnoland /* Max value for this is 256 */ 1564189499Srnoland if (vgt_gs_per_es > 256) 1565189499Srnoland vgt_gs_per_es = 256; 1566189499Srnoland 1567189499Srnoland RADEON_WRITE(R600_VGT_ES_PER_GS, 128); 1568189499Srnoland RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); 1569189499Srnoland RADEON_WRITE(R600_VGT_GS_PER_VS, 2); 1570189499Srnoland 1571189499Srnoland /* more default values. 2D/3D driver should adjust as needed */ 1572189499Srnoland RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); 1573189499Srnoland RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); 1574189499Srnoland RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); 1575189499Srnoland RADEON_WRITE(R600_SX_MISC, 0); 1576189499Srnoland RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); 1577189499Srnoland RADEON_WRITE(R700_PA_SC_EDGERULE, 0xaaaaaaaa); 1578189499Srnoland RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); 1579189499Srnoland RADEON_WRITE(R600_PA_SC_CLIPRECT_RULE, 0xffff); 1580189499Srnoland RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); 1581189499Srnoland RADEON_WRITE(R600_SPI_INPUT_Z, 0); 1582189499Srnoland RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); 1583189499Srnoland RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); 1584189499Srnoland 1585189499Srnoland /* clear render buffer base addresses */ 1586189499Srnoland RADEON_WRITE(R600_CB_COLOR0_BASE, 0); 1587189499Srnoland RADEON_WRITE(R600_CB_COLOR1_BASE, 0); 1588189499Srnoland RADEON_WRITE(R600_CB_COLOR2_BASE, 0); 1589189499Srnoland RADEON_WRITE(R600_CB_COLOR3_BASE, 0); 1590189499Srnoland RADEON_WRITE(R600_CB_COLOR4_BASE, 0); 1591189499Srnoland RADEON_WRITE(R600_CB_COLOR5_BASE, 0); 1592189499Srnoland RADEON_WRITE(R600_CB_COLOR6_BASE, 0); 1593189499Srnoland RADEON_WRITE(R600_CB_COLOR7_BASE, 0); 1594189499Srnoland 1595189499Srnoland RADEON_WRITE(R700_TCP_CNTL, 0); 1596189499Srnoland 1597189499Srnoland hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); 1598189499Srnoland RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); 1599189499Srnoland 1600189499Srnoland RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); 1601189499Srnoland 1602189499Srnoland RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | 1603189499Srnoland R600_NUM_CLIP_SEQ(3))); 1604189499Srnoland 1605189499Srnoland} 1606189499Srnoland 1607189499Srnolandstatic void r600_cp_init_ring_buffer(struct drm_device *dev, 1608189499Srnoland drm_radeon_private_t *dev_priv, 1609189499Srnoland struct drm_file *file_priv) 1610189499Srnoland{ 1611189499Srnoland u32 ring_start; 1612189558Srnoland u64 rptr_addr; 1613189499Srnoland 1614189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) 1615189499Srnoland r700_gfx_init(dev, dev_priv); 1616189499Srnoland else 1617189499Srnoland r600_gfx_init(dev, dev_priv); 1618189499Srnoland 1619189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); 1620189499Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 1621189499Srnoland DRM_UDELAY(15000); 1622189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 1623189499Srnoland 1624189499Srnoland 1625189499Srnoland /* Set ring buffer size */ 1626189499Srnoland#ifdef __BIG_ENDIAN 1627189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1628189499Srnoland RADEON_BUF_SWAP_32BIT | 1629189499Srnoland RADEON_RB_NO_UPDATE | 1630189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1631189499Srnoland dev_priv->ring.size_l2qw); 1632189499Srnoland#else 1633189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1634189499Srnoland RADEON_RB_NO_UPDATE | 1635189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1636189499Srnoland dev_priv->ring.size_l2qw); 1637189499Srnoland#endif 1638189499Srnoland 1639189499Srnoland RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x4); 1640189499Srnoland 1641189499Srnoland /* Set the write pointer delay */ 1642189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); 1643189499Srnoland 1644189499Srnoland#ifdef __BIG_ENDIAN 1645189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1646189499Srnoland RADEON_BUF_SWAP_32BIT | 1647189499Srnoland RADEON_RB_NO_UPDATE | 1648189499Srnoland RADEON_RB_RPTR_WR_ENA | 1649189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1650189499Srnoland dev_priv->ring.size_l2qw); 1651189499Srnoland#else 1652189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1653189499Srnoland RADEON_RB_NO_UPDATE | 1654189499Srnoland RADEON_RB_RPTR_WR_ENA | 1655189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1656189499Srnoland dev_priv->ring.size_l2qw); 1657189499Srnoland#endif 1658189499Srnoland 1659189499Srnoland /* Initialize the ring buffer's read and write pointers */ 1660189499Srnoland RADEON_WRITE(R600_CP_RB_RPTR_WR, 0); 1661189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR, 0); 1662189499Srnoland SET_RING_HEAD(dev_priv, 0); 1663189499Srnoland dev_priv->ring.tail = 0; 1664189499Srnoland 1665189499Srnoland#if __OS_HAS_AGP 1666189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1667189558Srnoland rptr_addr = dev_priv->ring_rptr->offset 1668189558Srnoland - dev->agp->base + 1669189558Srnoland dev_priv->gart_vm_start; 1670189499Srnoland } else 1671189499Srnoland#endif 1672189499Srnoland { 1673207067Srnoland rptr_addr = dev_priv->ring_rptr->offset - dev->sg->vaddr + 1674207067Srnoland dev_priv->gart_vm_start; 1675189499Srnoland } 1676189558Srnoland RADEON_WRITE(R600_CP_RB_RPTR_ADDR, 1677189558Srnoland rptr_addr & 0xffffffff); 1678189558Srnoland RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, 1679189558Srnoland upper_32_bits(rptr_addr)); 1680189499Srnoland 1681189499Srnoland#ifdef __BIG_ENDIAN 1682189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1683189499Srnoland RADEON_BUF_SWAP_32BIT | 1684189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1685189499Srnoland dev_priv->ring.size_l2qw); 1686189499Srnoland#else 1687189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1688189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1689189499Srnoland dev_priv->ring.size_l2qw); 1690189499Srnoland#endif 1691189499Srnoland 1692189499Srnoland#if __OS_HAS_AGP 1693189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1694189499Srnoland /* XXX */ 1695189499Srnoland radeon_write_agp_base(dev_priv, dev->agp->base); 1696189499Srnoland 1697189499Srnoland /* XXX */ 1698189499Srnoland radeon_write_agp_location(dev_priv, 1699189499Srnoland (((dev_priv->gart_vm_start - 1 + 1700189499Srnoland dev_priv->gart_size) & 0xffff0000) | 1701189499Srnoland (dev_priv->gart_vm_start >> 16))); 1702189499Srnoland 1703189499Srnoland ring_start = (dev_priv->cp_ring->offset 1704189499Srnoland - dev->agp->base 1705189499Srnoland + dev_priv->gart_vm_start); 1706189499Srnoland } else 1707189499Srnoland#endif 1708207067Srnoland ring_start = dev_priv->cp_ring->offset - dev->sg->vaddr + 1709207067Srnoland dev_priv->gart_vm_start; 1710189499Srnoland 1711189499Srnoland RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8); 1712189499Srnoland 1713189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, 0xff); 1714189499Srnoland 1715189499Srnoland RADEON_WRITE(R600_CP_DEBUG, (1 << 27) | (1 << 28)); 1716189499Srnoland 1717189499Srnoland /* Initialize the scratch register pointer. This will cause 1718189499Srnoland * the scratch register values to be written out to memory 1719189499Srnoland * whenever they are updated. 1720189499Srnoland * 1721189499Srnoland * We simply put this behind the ring read pointer, this works 1722189499Srnoland * with PCI GART as well as (whatever kind of) AGP GART 1723189499Srnoland */ 1724189558Srnoland { 1725189558Srnoland u64 scratch_addr; 1726189499Srnoland 1727189558Srnoland scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR); 1728189558Srnoland scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; 1729189558Srnoland scratch_addr += R600_SCRATCH_REG_OFFSET; 1730189558Srnoland scratch_addr >>= 8; 1731189558Srnoland scratch_addr &= 0xffffffff; 1732189558Srnoland 1733189558Srnoland RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr); 1734189558Srnoland } 1735189558Srnoland 1736189499Srnoland RADEON_WRITE(R600_SCRATCH_UMSK, 0x7); 1737189499Srnoland 1738189499Srnoland /* Turn on bus mastering */ 1739189499Srnoland radeon_enable_bm(dev_priv); 1740189499Srnoland 1741189499Srnoland radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0); 1742189499Srnoland RADEON_WRITE(R600_LAST_FRAME_REG, 0); 1743189499Srnoland 1744189499Srnoland radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); 1745189499Srnoland RADEON_WRITE(R600_LAST_DISPATCH_REG, 0); 1746189499Srnoland 1747189499Srnoland radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0); 1748189499Srnoland RADEON_WRITE(R600_LAST_CLEAR_REG, 0); 1749189499Srnoland 1750189499Srnoland /* reset sarea copies of these */ 1751189499Srnoland if (dev_priv->sarea_priv) { 1752189499Srnoland dev_priv->sarea_priv->last_frame = 0; 1753189499Srnoland dev_priv->sarea_priv->last_dispatch = 0; 1754189499Srnoland dev_priv->sarea_priv->last_clear = 0; 1755189499Srnoland } 1756189499Srnoland 1757189499Srnoland r600_do_wait_for_idle(dev_priv); 1758189499Srnoland 1759189499Srnoland} 1760189499Srnoland 1761189499Srnolandint r600_do_cleanup_cp(struct drm_device *dev) 1762189499Srnoland{ 1763189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1764189499Srnoland DRM_DEBUG("\n"); 1765189499Srnoland 1766189499Srnoland /* Make sure interrupts are disabled here because the uninstall ioctl 1767189499Srnoland * may not have been called from userspace and after dev_private 1768189499Srnoland * is freed, it's too late. 1769189499Srnoland */ 1770189499Srnoland if (dev->irq_enabled) 1771189499Srnoland drm_irq_uninstall(dev); 1772189499Srnoland 1773189499Srnoland#if __OS_HAS_AGP 1774189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1775189499Srnoland if (dev_priv->cp_ring != NULL) { 1776189499Srnoland drm_core_ioremapfree(dev_priv->cp_ring, dev); 1777189499Srnoland dev_priv->cp_ring = NULL; 1778189499Srnoland } 1779189499Srnoland if (dev_priv->ring_rptr != NULL) { 1780189499Srnoland drm_core_ioremapfree(dev_priv->ring_rptr, dev); 1781189499Srnoland dev_priv->ring_rptr = NULL; 1782189499Srnoland } 1783189499Srnoland if (dev->agp_buffer_map != NULL) { 1784189499Srnoland drm_core_ioremapfree(dev->agp_buffer_map, dev); 1785189499Srnoland dev->agp_buffer_map = NULL; 1786189499Srnoland } 1787189499Srnoland } else 1788189499Srnoland#endif 1789189499Srnoland { 1790189499Srnoland 1791189499Srnoland if (dev_priv->gart_info.bus_addr) 1792189499Srnoland r600_page_table_cleanup(dev, &dev_priv->gart_info); 1793189499Srnoland 1794189499Srnoland if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { 1795189499Srnoland drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); 1796189499Srnoland dev_priv->gart_info.addr = 0; 1797189499Srnoland } 1798189499Srnoland } 1799189499Srnoland /* only clear to the start of flags */ 1800189499Srnoland memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); 1801189499Srnoland 1802189499Srnoland return 0; 1803189499Srnoland} 1804189499Srnoland 1805189499Srnolandint r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, 1806189499Srnoland struct drm_file *file_priv) 1807189499Srnoland{ 1808189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1809189499Srnoland 1810189499Srnoland DRM_DEBUG("\n"); 1811189499Srnoland 1812189499Srnoland /* if we require new memory map but we don't have it fail */ 1813189499Srnoland if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { 1814189499Srnoland DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); 1815189499Srnoland r600_do_cleanup_cp(dev); 1816189499Srnoland return -EINVAL; 1817189499Srnoland } 1818189499Srnoland 1819189499Srnoland if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { 1820189499Srnoland DRM_DEBUG("Forcing AGP card to PCI mode\n"); 1821189499Srnoland dev_priv->flags &= ~RADEON_IS_AGP; 1822189499Srnoland /* The writeback test succeeds, but when writeback is enabled, 1823189499Srnoland * the ring buffer read ptr update fails after first 128 bytes. 1824189499Srnoland */ 1825189499Srnoland radeon_no_wb = 1; 1826189499Srnoland } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) 1827189499Srnoland && !init->is_pci) { 1828189499Srnoland DRM_DEBUG("Restoring AGP flag\n"); 1829189499Srnoland dev_priv->flags |= RADEON_IS_AGP; 1830189499Srnoland } 1831189499Srnoland 1832189499Srnoland dev_priv->usec_timeout = init->usec_timeout; 1833189499Srnoland if (dev_priv->usec_timeout < 1 || 1834189499Srnoland dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { 1835189499Srnoland DRM_DEBUG("TIMEOUT problem!\n"); 1836189499Srnoland r600_do_cleanup_cp(dev); 1837189499Srnoland return -EINVAL; 1838189499Srnoland } 1839189499Srnoland 1840189499Srnoland /* Enable vblank on CRTC1 for older X servers 1841189499Srnoland */ 1842189499Srnoland dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; 1843189499Srnoland 1844196470Srnoland dev_priv->do_boxes = 0; 1845189499Srnoland dev_priv->cp_mode = init->cp_mode; 1846189499Srnoland 1847189499Srnoland /* We don't support anything other than bus-mastering ring mode, 1848189499Srnoland * but the ring can be in either AGP or PCI space for the ring 1849189499Srnoland * read pointer. 1850189499Srnoland */ 1851189499Srnoland if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && 1852189499Srnoland (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { 1853189499Srnoland DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); 1854189499Srnoland r600_do_cleanup_cp(dev); 1855189499Srnoland return -EINVAL; 1856189499Srnoland } 1857189499Srnoland 1858189499Srnoland switch (init->fb_bpp) { 1859189499Srnoland case 16: 1860189499Srnoland dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; 1861189499Srnoland break; 1862189499Srnoland case 32: 1863189499Srnoland default: 1864189499Srnoland dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; 1865189499Srnoland break; 1866189499Srnoland } 1867189499Srnoland dev_priv->front_offset = init->front_offset; 1868189499Srnoland dev_priv->front_pitch = init->front_pitch; 1869189499Srnoland dev_priv->back_offset = init->back_offset; 1870189499Srnoland dev_priv->back_pitch = init->back_pitch; 1871189499Srnoland 1872189499Srnoland dev_priv->ring_offset = init->ring_offset; 1873189499Srnoland dev_priv->ring_rptr_offset = init->ring_rptr_offset; 1874189499Srnoland dev_priv->buffers_offset = init->buffers_offset; 1875189499Srnoland dev_priv->gart_textures_offset = init->gart_textures_offset; 1876189499Srnoland 1877189499Srnoland dev_priv->sarea = drm_getsarea(dev); 1878189499Srnoland if (!dev_priv->sarea) { 1879189499Srnoland DRM_ERROR("could not find sarea!\n"); 1880189499Srnoland r600_do_cleanup_cp(dev); 1881189499Srnoland return -EINVAL; 1882189499Srnoland } 1883189499Srnoland 1884189499Srnoland dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); 1885189499Srnoland if (!dev_priv->cp_ring) { 1886189499Srnoland DRM_ERROR("could not find cp ring region!\n"); 1887189499Srnoland r600_do_cleanup_cp(dev); 1888189499Srnoland return -EINVAL; 1889189499Srnoland } 1890189499Srnoland dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); 1891189499Srnoland if (!dev_priv->ring_rptr) { 1892189499Srnoland DRM_ERROR("could not find ring read pointer!\n"); 1893189499Srnoland r600_do_cleanup_cp(dev); 1894189499Srnoland return -EINVAL; 1895189499Srnoland } 1896189499Srnoland dev->agp_buffer_token = init->buffers_offset; 1897189499Srnoland dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 1898189499Srnoland if (!dev->agp_buffer_map) { 1899189499Srnoland DRM_ERROR("could not find dma buffer region!\n"); 1900189499Srnoland r600_do_cleanup_cp(dev); 1901189499Srnoland return -EINVAL; 1902189499Srnoland } 1903189499Srnoland 1904189499Srnoland if (init->gart_textures_offset) { 1905189499Srnoland dev_priv->gart_textures = 1906189499Srnoland drm_core_findmap(dev, init->gart_textures_offset); 1907189499Srnoland if (!dev_priv->gart_textures) { 1908189499Srnoland DRM_ERROR("could not find GART texture region!\n"); 1909189499Srnoland r600_do_cleanup_cp(dev); 1910189499Srnoland return -EINVAL; 1911189499Srnoland } 1912189499Srnoland } 1913189499Srnoland 1914189499Srnoland dev_priv->sarea_priv = 1915207066Srnoland (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->virtual + 1916189499Srnoland init->sarea_priv_offset); 1917189499Srnoland 1918189499Srnoland#if __OS_HAS_AGP 1919189499Srnoland /* XXX */ 1920189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1921189499Srnoland drm_core_ioremap_wc(dev_priv->cp_ring, dev); 1922189499Srnoland drm_core_ioremap_wc(dev_priv->ring_rptr, dev); 1923189499Srnoland drm_core_ioremap_wc(dev->agp_buffer_map, dev); 1924207066Srnoland if (!dev_priv->cp_ring->virtual || 1925207066Srnoland !dev_priv->ring_rptr->virtual || 1926207066Srnoland !dev->agp_buffer_map->virtual) { 1927189499Srnoland DRM_ERROR("could not find ioremap agp regions!\n"); 1928189499Srnoland r600_do_cleanup_cp(dev); 1929189499Srnoland return -EINVAL; 1930189499Srnoland } 1931189499Srnoland } else 1932189499Srnoland#endif 1933189499Srnoland { 1934207066Srnoland dev_priv->cp_ring->virtual = 1935207066Srnoland (void *)dev_priv->cp_ring->offset; 1936207066Srnoland dev_priv->ring_rptr->virtual = 1937189499Srnoland (void *)dev_priv->ring_rptr->offset; 1938207066Srnoland dev->agp_buffer_map->virtual = 1939189499Srnoland (void *)dev->agp_buffer_map->offset; 1940189499Srnoland 1941207066Srnoland DRM_DEBUG("dev_priv->cp_ring->virtual %p\n", 1942207066Srnoland dev_priv->cp_ring->virtual); 1943207066Srnoland DRM_DEBUG("dev_priv->ring_rptr->virtual %p\n", 1944207066Srnoland dev_priv->ring_rptr->virtual); 1945207066Srnoland DRM_DEBUG("dev->agp_buffer_map->virtual %p\n", 1946207066Srnoland dev->agp_buffer_map->virtual); 1947189499Srnoland } 1948189499Srnoland 1949189499Srnoland dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24; 1950189499Srnoland dev_priv->fb_size = 1951189499Srnoland (((radeon_read_fb_location(dev_priv) & 0xffff0000u) << 8) + 0x1000000) 1952189499Srnoland - dev_priv->fb_location; 1953189499Srnoland 1954189499Srnoland dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | 1955189499Srnoland ((dev_priv->front_offset 1956189499Srnoland + dev_priv->fb_location) >> 10)); 1957189499Srnoland 1958189499Srnoland dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | 1959189499Srnoland ((dev_priv->back_offset 1960189499Srnoland + dev_priv->fb_location) >> 10)); 1961189499Srnoland 1962189499Srnoland dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | 1963189499Srnoland ((dev_priv->depth_offset 1964189499Srnoland + dev_priv->fb_location) >> 10)); 1965189499Srnoland 1966189499Srnoland dev_priv->gart_size = init->gart_size; 1967189499Srnoland 1968189499Srnoland /* New let's set the memory map ... */ 1969189499Srnoland if (dev_priv->new_memmap) { 1970189499Srnoland u32 base = 0; 1971189499Srnoland 1972189499Srnoland DRM_INFO("Setting GART location based on new memory map\n"); 1973189499Srnoland 1974189499Srnoland /* If using AGP, try to locate the AGP aperture at the same 1975189499Srnoland * location in the card and on the bus, though we have to 1976189499Srnoland * align it down. 1977189499Srnoland */ 1978189499Srnoland#if __OS_HAS_AGP 1979189499Srnoland /* XXX */ 1980189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1981189499Srnoland base = dev->agp->base; 1982189499Srnoland /* Check if valid */ 1983189499Srnoland if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && 1984189499Srnoland base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { 1985189499Srnoland DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", 1986189499Srnoland dev->agp->base); 1987189499Srnoland base = 0; 1988189499Srnoland } 1989189499Srnoland } 1990189499Srnoland#endif 1991189499Srnoland /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ 1992189499Srnoland if (base == 0) { 1993189499Srnoland base = dev_priv->fb_location + dev_priv->fb_size; 1994189499Srnoland if (base < dev_priv->fb_location || 1995189499Srnoland ((base + dev_priv->gart_size) & 0xfffffffful) < base) 1996189499Srnoland base = dev_priv->fb_location 1997189499Srnoland - dev_priv->gart_size; 1998189499Srnoland } 1999189499Srnoland dev_priv->gart_vm_start = base & 0xffc00000u; 2000189499Srnoland if (dev_priv->gart_vm_start != base) 2001189499Srnoland DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", 2002189499Srnoland base, dev_priv->gart_vm_start); 2003189499Srnoland } 2004189499Srnoland 2005189499Srnoland#if __OS_HAS_AGP 2006189499Srnoland /* XXX */ 2007189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) 2008189499Srnoland dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset 2009189499Srnoland - dev->agp->base 2010189499Srnoland + dev_priv->gart_vm_start); 2011189499Srnoland else 2012189499Srnoland#endif 2013207067Srnoland dev_priv->gart_buffers_offset = dev->agp_buffer_map->offset - 2014207067Srnoland dev->sg->vaddr + dev_priv->gart_vm_start; 2015189499Srnoland 2016189499Srnoland DRM_DEBUG("fb 0x%08x size %d\n", 2017189499Srnoland (unsigned int) dev_priv->fb_location, 2018189499Srnoland (unsigned int) dev_priv->fb_size); 2019189499Srnoland DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); 2020189499Srnoland DRM_DEBUG("dev_priv->gart_vm_start 0x%08x\n", 2021189499Srnoland (unsigned int) dev_priv->gart_vm_start); 2022189499Srnoland DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n", 2023189499Srnoland dev_priv->gart_buffers_offset); 2024189499Srnoland 2025207066Srnoland dev_priv->ring.start = (u32 *) dev_priv->cp_ring->virtual; 2026207066Srnoland dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->virtual 2027189499Srnoland + init->ring_size / sizeof(u32)); 2028189499Srnoland dev_priv->ring.size = init->ring_size; 2029189499Srnoland dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); 2030189499Srnoland 2031189499Srnoland dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; 2032189499Srnoland dev_priv->ring.rptr_update_l2qw = drm_order(/* init->rptr_update */ 4096 / 8); 2033189499Srnoland 2034189499Srnoland dev_priv->ring.fetch_size = /* init->fetch_size */ 32; 2035189499Srnoland dev_priv->ring.fetch_size_l2ow = drm_order(/* init->fetch_size */ 32 / 16); 2036189499Srnoland 2037189499Srnoland dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; 2038189499Srnoland 2039189499Srnoland dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; 2040189499Srnoland 2041189499Srnoland#if __OS_HAS_AGP 2042189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 2043189499Srnoland /* XXX turn off pcie gart */ 2044189499Srnoland } else 2045189499Srnoland#endif 2046189499Srnoland { 2047189499Srnoland dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); 2048189499Srnoland /* if we have an offset set from userspace */ 2049189499Srnoland if (!dev_priv->pcigart_offset_set) { 2050189499Srnoland DRM_ERROR("Need gart offset from userspace\n"); 2051189499Srnoland r600_do_cleanup_cp(dev); 2052189499Srnoland return -EINVAL; 2053189499Srnoland } 2054189499Srnoland 2055189499Srnoland DRM_DEBUG("Using gart offset 0x%08lx\n", dev_priv->pcigart_offset); 2056189499Srnoland 2057189499Srnoland dev_priv->gart_info.bus_addr = 2058189499Srnoland dev_priv->pcigart_offset + dev_priv->fb_location; 2059189499Srnoland dev_priv->gart_info.mapping.offset = 2060189499Srnoland dev_priv->pcigart_offset + dev_priv->fb_aper_offset; 2061189499Srnoland dev_priv->gart_info.mapping.size = 2062189499Srnoland dev_priv->gart_info.table_size; 2063189499Srnoland 2064189499Srnoland drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); 2065207066Srnoland if (!dev_priv->gart_info.mapping.virtual) { 2066189499Srnoland DRM_ERROR("ioremap failed.\n"); 2067189499Srnoland r600_do_cleanup_cp(dev); 2068189499Srnoland return -EINVAL; 2069189499Srnoland } 2070189499Srnoland 2071189499Srnoland dev_priv->gart_info.addr = 2072207066Srnoland dev_priv->gart_info.mapping.virtual; 2073189499Srnoland 2074189499Srnoland DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", 2075189499Srnoland dev_priv->gart_info.addr, 2076189499Srnoland dev_priv->pcigart_offset); 2077189499Srnoland 2078189909Srnoland if (!r600_page_table_init(dev)) { 2079189499Srnoland DRM_ERROR("Failed to init GART table\n"); 2080189499Srnoland r600_do_cleanup_cp(dev); 2081189499Srnoland return -EINVAL; 2082189499Srnoland } 2083189499Srnoland 2084189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) 2085189499Srnoland r700_vm_init(dev); 2086189499Srnoland else 2087189499Srnoland r600_vm_init(dev); 2088189499Srnoland } 2089189499Srnoland 2090189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) 2091189499Srnoland r700_cp_load_microcode(dev_priv); 2092189499Srnoland else 2093189499Srnoland r600_cp_load_microcode(dev_priv); 2094189499Srnoland 2095189499Srnoland r600_cp_init_ring_buffer(dev, dev_priv, file_priv); 2096189499Srnoland 2097189499Srnoland dev_priv->last_buf = 0; 2098189499Srnoland 2099189499Srnoland r600_do_engine_reset(dev); 2100189499Srnoland r600_test_writeback(dev_priv); 2101189499Srnoland 2102196470Srnoland r600_cs_init(dev); 2103196470Srnoland 2104189499Srnoland return 0; 2105189499Srnoland} 2106189499Srnoland 2107189499Srnolandint r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) 2108189499Srnoland{ 2109189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 2110189499Srnoland 2111189499Srnoland DRM_DEBUG("\n"); 2112189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) { 2113189499Srnoland r700_vm_init(dev); 2114189499Srnoland r700_cp_load_microcode(dev_priv); 2115189499Srnoland } else { 2116189499Srnoland r600_vm_init(dev); 2117189499Srnoland r600_cp_load_microcode(dev_priv); 2118189499Srnoland } 2119189499Srnoland r600_cp_init_ring_buffer(dev, dev_priv, file_priv); 2120189499Srnoland r600_do_engine_reset(dev); 2121189499Srnoland 2122189499Srnoland return 0; 2123189499Srnoland} 2124189499Srnoland 2125189499Srnoland/* Wait for the CP to go idle. 2126189499Srnoland */ 2127189499Srnolandint r600_do_cp_idle(drm_radeon_private_t *dev_priv) 2128189499Srnoland{ 2129189499Srnoland RING_LOCALS; 2130189499Srnoland DRM_DEBUG("\n"); 2131189499Srnoland 2132189499Srnoland BEGIN_RING(5); 2133189499Srnoland OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); 2134189499Srnoland OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); 2135189499Srnoland /* wait for 3D idle clean */ 2136189499Srnoland OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); 2137189499Srnoland OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); 2138189499Srnoland OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); 2139189499Srnoland 2140189499Srnoland ADVANCE_RING(); 2141189499Srnoland COMMIT_RING(); 2142189499Srnoland 2143189499Srnoland return r600_do_wait_for_idle(dev_priv); 2144189499Srnoland} 2145189499Srnoland 2146189499Srnoland/* Start the Command Processor. 2147189499Srnoland */ 2148189499Srnolandvoid r600_do_cp_start(drm_radeon_private_t *dev_priv) 2149189499Srnoland{ 2150189499Srnoland u32 cp_me; 2151189499Srnoland RING_LOCALS; 2152189499Srnoland DRM_DEBUG("\n"); 2153189499Srnoland 2154189499Srnoland BEGIN_RING(7); 2155189499Srnoland OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5)); 2156189499Srnoland OUT_RING(0x00000001); 2157189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) 2158189499Srnoland OUT_RING(0x00000003); 2159189499Srnoland else 2160189499Srnoland OUT_RING(0x00000000); 2161189499Srnoland OUT_RING((dev_priv->r600_max_hw_contexts - 1)); 2162189499Srnoland OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1)); 2163189499Srnoland OUT_RING(0x00000000); 2164189499Srnoland OUT_RING(0x00000000); 2165189499Srnoland ADVANCE_RING(); 2166189499Srnoland COMMIT_RING(); 2167189499Srnoland 2168189499Srnoland /* set the mux and reset the halt bit */ 2169189499Srnoland cp_me = 0xff; 2170189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, cp_me); 2171189499Srnoland 2172189499Srnoland dev_priv->cp_running = 1; 2173189499Srnoland 2174189499Srnoland} 2175189499Srnoland 2176189499Srnolandvoid r600_do_cp_reset(drm_radeon_private_t *dev_priv) 2177189499Srnoland{ 2178189499Srnoland u32 cur_read_ptr; 2179189499Srnoland DRM_DEBUG("\n"); 2180189499Srnoland 2181189499Srnoland cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR); 2182189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr); 2183189499Srnoland SET_RING_HEAD(dev_priv, cur_read_ptr); 2184189499Srnoland dev_priv->ring.tail = cur_read_ptr; 2185189499Srnoland} 2186189499Srnoland 2187189499Srnolandvoid r600_do_cp_stop(drm_radeon_private_t *dev_priv) 2188189499Srnoland{ 2189189499Srnoland uint32_t cp_me; 2190189499Srnoland 2191189499Srnoland DRM_DEBUG("\n"); 2192189499Srnoland 2193189499Srnoland cp_me = 0xff | R600_CP_ME_HALT; 2194189499Srnoland 2195189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, cp_me); 2196189499Srnoland 2197189499Srnoland dev_priv->cp_running = 0; 2198189499Srnoland} 2199189499Srnoland 2200189499Srnolandint r600_cp_dispatch_indirect(struct drm_device *dev, 2201189499Srnoland struct drm_buf *buf, int start, int end) 2202189499Srnoland{ 2203189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 2204189499Srnoland RING_LOCALS; 2205189499Srnoland 2206189499Srnoland if (start != end) { 2207189499Srnoland unsigned long offset = (dev_priv->gart_buffers_offset 2208189499Srnoland + buf->offset + start); 2209189499Srnoland int dwords = (end - start + 3) / sizeof(u32); 2210189499Srnoland 2211189499Srnoland DRM_DEBUG("dwords:%d\n", dwords); 2212189499Srnoland DRM_DEBUG("offset 0x%lx\n", offset); 2213189499Srnoland 2214189499Srnoland 2215189499Srnoland /* Indirect buffer data must be a multiple of 16 dwords. 2216189499Srnoland * pad the data with a Type-2 CP packet. 2217189499Srnoland */ 2218189499Srnoland while (dwords & 0xf) { 2219189499Srnoland u32 *data = (u32 *) 2220207066Srnoland ((char *)dev->agp_buffer_map->virtual 2221189499Srnoland + buf->offset + start); 2222189499Srnoland data[dwords++] = RADEON_CP_PACKET2; 2223189499Srnoland } 2224189499Srnoland 2225189499Srnoland /* Fire off the indirect buffer */ 2226189499Srnoland BEGIN_RING(4); 2227189499Srnoland OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2)); 2228189499Srnoland OUT_RING((offset & 0xfffffffc)); 2229189499Srnoland OUT_RING((upper_32_bits(offset) & 0xff)); 2230189499Srnoland OUT_RING(dwords); 2231189499Srnoland ADVANCE_RING(); 2232189499Srnoland } 2233189499Srnoland 2234189499Srnoland return 0; 2235189499Srnoland} 2236196470Srnoland 2237196470Srnolandvoid r600_cp_dispatch_swap(struct drm_device * dev) 2238196470Srnoland{ 2239196470Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 2240196470Srnoland drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; 2241196470Srnoland int nbox = sarea_priv->nbox; 2242196470Srnoland struct drm_clip_rect *pbox = sarea_priv->boxes; 2243196470Srnoland int i, cpp, src_pitch, dst_pitch; 2244196470Srnoland uint64_t src, dst; 2245196470Srnoland RING_LOCALS; 2246196470Srnoland DRM_DEBUG("\n"); 2247196470Srnoland 2248196470Srnoland if (dev_priv->color_fmt == RADEON_COLOR_FORMAT_ARGB8888) 2249196470Srnoland cpp = 4; 2250196470Srnoland else 2251196470Srnoland cpp = 2; 2252196470Srnoland 2253196470Srnoland if (dev_priv->sarea_priv->pfCurrentPage == 0) { 2254196470Srnoland src_pitch = dev_priv->back_pitch; 2255196470Srnoland dst_pitch = dev_priv->front_pitch; 2256196470Srnoland src = dev_priv->back_offset + dev_priv->fb_location; 2257196470Srnoland dst = dev_priv->front_offset + dev_priv->fb_location; 2258196470Srnoland } else { 2259196470Srnoland src_pitch = dev_priv->front_pitch; 2260196470Srnoland dst_pitch = dev_priv->back_pitch; 2261196470Srnoland src = dev_priv->front_offset + dev_priv->fb_location; 2262196470Srnoland dst = dev_priv->back_offset + dev_priv->fb_location; 2263196470Srnoland } 2264196470Srnoland 2265196470Srnoland if (r600_prepare_blit_copy(dev)) { 2266196470Srnoland DRM_ERROR("unable to allocate vertex buffer for swap buffer\n"); 2267196470Srnoland return; 2268196470Srnoland } 2269196470Srnoland for (i = 0; i < nbox; i++) { 2270196470Srnoland int x = pbox[i].x1; 2271196470Srnoland int y = pbox[i].y1; 2272196470Srnoland int w = pbox[i].x2 - x; 2273196470Srnoland int h = pbox[i].y2 - y; 2274196470Srnoland 2275196470Srnoland DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h); 2276196470Srnoland 2277196470Srnoland r600_blit_swap(dev, 2278196470Srnoland src, dst, 2279196470Srnoland x, y, x, y, w, h, 2280196470Srnoland src_pitch, dst_pitch, cpp); 2281196470Srnoland } 2282196470Srnoland r600_done_blit_copy(dev); 2283196470Srnoland 2284196470Srnoland /* Increment the frame counter. The client-side 3D driver must 2285196470Srnoland * throttle the framerate by waiting for this value before 2286196470Srnoland * performing the swapbuffer ioctl. 2287196470Srnoland */ 2288196470Srnoland dev_priv->sarea_priv->last_frame++; 2289196470Srnoland 2290196470Srnoland BEGIN_RING(3); 2291196470Srnoland R600_FRAME_AGE(dev_priv->sarea_priv->last_frame); 2292196470Srnoland ADVANCE_RING(); 2293196470Srnoland} 2294196470Srnoland 2295196470Srnolandint r600_cp_dispatch_texture(struct drm_device * dev, 2296196470Srnoland struct drm_file *file_priv, 2297196470Srnoland drm_radeon_texture_t * tex, 2298196470Srnoland drm_radeon_tex_image_t * image) 2299196470Srnoland{ 2300196470Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 2301196470Srnoland struct drm_buf *buf; 2302196470Srnoland u32 *buffer; 2303196470Srnoland const u8 __user *data; 2304196470Srnoland int size, pass_size; 2305196470Srnoland u64 src_offset, dst_offset; 2306196470Srnoland 2307196470Srnoland if (!radeon_check_offset(dev_priv, tex->offset)) { 2308196470Srnoland DRM_ERROR("Invalid destination offset\n"); 2309196470Srnoland return -EINVAL; 2310196470Srnoland } 2311196470Srnoland 2312196470Srnoland /* this might fail for zero-sized uploads - are those illegal? */ 2313196470Srnoland if (!radeon_check_offset(dev_priv, tex->offset + tex->height * tex->pitch - 1)) { 2314196470Srnoland DRM_ERROR("Invalid final destination offset\n"); 2315196470Srnoland return -EINVAL; 2316196470Srnoland } 2317196470Srnoland 2318196470Srnoland size = tex->height * tex->pitch; 2319196470Srnoland 2320196470Srnoland if (size == 0) 2321196470Srnoland return 0; 2322196470Srnoland 2323196470Srnoland dst_offset = tex->offset; 2324196470Srnoland 2325196470Srnoland r600_prepare_blit_copy(dev); 2326196470Srnoland do { 2327196470Srnoland data = (const u8 __user *)image->data; 2328196470Srnoland pass_size = size; 2329196470Srnoland 2330196470Srnoland buf = radeon_freelist_get(dev); 2331196470Srnoland if (!buf) { 2332196470Srnoland DRM_DEBUG("EAGAIN\n"); 2333196470Srnoland if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) 2334196470Srnoland return -EFAULT; 2335196470Srnoland return -EAGAIN; 2336196470Srnoland } 2337196470Srnoland 2338196470Srnoland if (pass_size > buf->total) 2339196470Srnoland pass_size = buf->total; 2340196470Srnoland 2341196470Srnoland /* Dispatch the indirect buffer. 2342196470Srnoland */ 2343196470Srnoland buffer = 2344207066Srnoland (u32 *) ((char *)dev->agp_buffer_map->virtual + 2345207066Srnoland buf->offset); 2346196470Srnoland 2347196470Srnoland if (DRM_COPY_FROM_USER(buffer, data, pass_size)) { 2348196470Srnoland DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size); 2349196470Srnoland return -EFAULT; 2350196470Srnoland } 2351196470Srnoland 2352196470Srnoland buf->file_priv = file_priv; 2353196470Srnoland buf->used = pass_size; 2354196470Srnoland src_offset = dev_priv->gart_buffers_offset + buf->offset; 2355196470Srnoland 2356196470Srnoland r600_blit_copy(dev, src_offset, dst_offset, pass_size); 2357196470Srnoland 2358196470Srnoland radeon_cp_discard_buffer(dev, buf); 2359196470Srnoland 2360196470Srnoland /* Update the input parameters for next time */ 2361196470Srnoland image->data = (const u8 __user *)image->data + pass_size; 2362196470Srnoland dst_offset += pass_size; 2363196470Srnoland size -= pass_size; 2364196470Srnoland } while (size > 0); 2365196470Srnoland r600_done_blit_copy(dev); 2366196470Srnoland 2367196470Srnoland return 0; 2368196470Srnoland} 2369