r600_cp.c revision 189558
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: head/sys/dev/drm/r600_cp.c 189558 2009-03-09 07:33:35Z rnoland $"); 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 ret = -EINVAL; 178189499Srnoland goto done; 179189499Srnoland } 180189499Srnoland#endif 181189499Srnoland entry_addr = entry->busaddr[i]; 182189499Srnoland for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { 183189499Srnoland page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK; 184189499Srnoland page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; 185189499Srnoland page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE; 186189499Srnoland 187189499Srnoland *pci_gart = page_base; 188189499Srnoland 189189499Srnoland if ((i % 128) == 0) 190189499Srnoland DRM_DEBUG("page entry %d: 0x%016llx\n", 191189499Srnoland i, (unsigned long long)page_base); 192189499Srnoland pci_gart++; 193189499Srnoland entry_addr += ATI_PCIGART_PAGE_SIZE; 194189499Srnoland } 195189499Srnoland } 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{ 285189499Srnoland int i; 286189499Srnoland 287189499Srnoland r600_do_cp_stop(dev_priv); 288189499Srnoland 289189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 290189499Srnoland R600_RB_NO_UPDATE | 291189499Srnoland R600_RB_BLKSZ(15) | 292189499Srnoland R600_RB_BUFSZ(3)); 293189499Srnoland 294189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); 295189499Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 296189499Srnoland DRM_UDELAY(15000); 297189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 298189499Srnoland 299189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 300189499Srnoland 301189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) { 302189499Srnoland DRM_INFO("Loading R600 CP Microcode\n"); 303189499Srnoland for (i = 0; i < PM4_UCODE_SIZE; i++) { 304189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 305189499Srnoland R600_cp_microcode[i][0]); 306189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 307189499Srnoland R600_cp_microcode[i][1]); 308189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 309189499Srnoland R600_cp_microcode[i][2]); 310189499Srnoland } 311189499Srnoland 312189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 313189499Srnoland DRM_INFO("Loading R600 PFP Microcode\n"); 314189499Srnoland for (i = 0; i < PFP_UCODE_SIZE; i++) 315189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]); 316189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) { 317189499Srnoland DRM_INFO("Loading RV610 CP Microcode\n"); 318189499Srnoland for (i = 0; i < PM4_UCODE_SIZE; i++) { 319189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 320189499Srnoland RV610_cp_microcode[i][0]); 321189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 322189499Srnoland RV610_cp_microcode[i][1]); 323189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 324189499Srnoland RV610_cp_microcode[i][2]); 325189499Srnoland } 326189499Srnoland 327189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 328189499Srnoland DRM_INFO("Loading RV610 PFP Microcode\n"); 329189499Srnoland for (i = 0; i < PFP_UCODE_SIZE; i++) 330189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]); 331189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { 332189499Srnoland DRM_INFO("Loading RV630 CP Microcode\n"); 333189499Srnoland for (i = 0; i < PM4_UCODE_SIZE; i++) { 334189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 335189499Srnoland RV630_cp_microcode[i][0]); 336189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 337189499Srnoland RV630_cp_microcode[i][1]); 338189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 339189499Srnoland RV630_cp_microcode[i][2]); 340189499Srnoland } 341189499Srnoland 342189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 343189499Srnoland DRM_INFO("Loading RV630 PFP Microcode\n"); 344189499Srnoland for (i = 0; i < PFP_UCODE_SIZE; i++) 345189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]); 346189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) { 347189499Srnoland DRM_INFO("Loading RV620 CP Microcode\n"); 348189499Srnoland for (i = 0; i < PM4_UCODE_SIZE; i++) { 349189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 350189499Srnoland RV620_cp_microcode[i][0]); 351189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 352189499Srnoland RV620_cp_microcode[i][1]); 353189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 354189499Srnoland RV620_cp_microcode[i][2]); 355189499Srnoland } 356189499Srnoland 357189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 358189499Srnoland DRM_INFO("Loading RV620 PFP Microcode\n"); 359189499Srnoland for (i = 0; i < PFP_UCODE_SIZE; i++) 360189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]); 361189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { 362189499Srnoland DRM_INFO("Loading RV635 CP Microcode\n"); 363189499Srnoland for (i = 0; i < PM4_UCODE_SIZE; i++) { 364189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 365189499Srnoland RV635_cp_microcode[i][0]); 366189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 367189499Srnoland RV635_cp_microcode[i][1]); 368189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 369189499Srnoland RV635_cp_microcode[i][2]); 370189499Srnoland } 371189499Srnoland 372189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 373189499Srnoland DRM_INFO("Loading RV635 PFP Microcode\n"); 374189499Srnoland for (i = 0; i < PFP_UCODE_SIZE; i++) 375189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]); 376189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) { 377189499Srnoland DRM_INFO("Loading RV670 CP Microcode\n"); 378189499Srnoland for (i = 0; i < PM4_UCODE_SIZE; i++) { 379189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 380189499Srnoland RV670_cp_microcode[i][0]); 381189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 382189499Srnoland RV670_cp_microcode[i][1]); 383189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 384189499Srnoland RV670_cp_microcode[i][2]); 385189499Srnoland } 386189499Srnoland 387189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 388189499Srnoland DRM_INFO("Loading RV670 PFP Microcode\n"); 389189499Srnoland for (i = 0; i < PFP_UCODE_SIZE; i++) 390189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); 391189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { 392189499Srnoland DRM_INFO("Loading RS780 CP Microcode\n"); 393189499Srnoland for (i = 0; i < PM4_UCODE_SIZE; i++) { 394189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 395189499Srnoland RV670_cp_microcode[i][0]); 396189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 397189499Srnoland RV670_cp_microcode[i][1]); 398189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, 399189499Srnoland RV670_cp_microcode[i][2]); 400189499Srnoland } 401189499Srnoland 402189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 403189499Srnoland DRM_INFO("Loading RS780 PFP Microcode\n"); 404189499Srnoland for (i = 0; i < PFP_UCODE_SIZE; i++) 405189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); 406189499Srnoland } 407189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 408189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 409189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); 410189499Srnoland 411189499Srnoland} 412189499Srnoland 413189499Srnolandstatic void r700_vm_init(struct drm_device *dev) 414189499Srnoland{ 415189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 416189499Srnoland /* initialise the VM to use the page table we constructed up there */ 417189499Srnoland u32 vm_c0, i; 418189499Srnoland u32 mc_vm_md_l1; 419189499Srnoland u32 vm_l2_cntl, vm_l2_cntl3; 420189499Srnoland /* okay set up the PCIE aperture type thingo */ 421189499Srnoland RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); 422189499Srnoland RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); 423189499Srnoland RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); 424189499Srnoland 425189499Srnoland mc_vm_md_l1 = R700_ENABLE_L1_TLB | 426189499Srnoland R700_ENABLE_L1_FRAGMENT_PROCESSING | 427189499Srnoland R700_SYSTEM_ACCESS_MODE_IN_SYS | 428189499Srnoland R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | 429189499Srnoland R700_EFFECTIVE_L1_TLB_SIZE(5) | 430189499Srnoland R700_EFFECTIVE_L1_QUEUE_SIZE(5); 431189499Srnoland 432189499Srnoland RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1); 433189499Srnoland RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1); 434189499Srnoland RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1); 435189499Srnoland RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1); 436189499Srnoland RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1); 437189499Srnoland RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1); 438189499Srnoland RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1); 439189499Srnoland 440189499Srnoland vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; 441189499Srnoland vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7); 442189499Srnoland RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); 443189499Srnoland 444189499Srnoland RADEON_WRITE(R600_VM_L2_CNTL2, 0); 445189499Srnoland vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2); 446189499Srnoland RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); 447189499Srnoland 448189499Srnoland vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; 449189499Srnoland 450189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); 451189499Srnoland 452189499Srnoland vm_c0 &= ~R600_VM_ENABLE_CONTEXT; 453189499Srnoland 454189499Srnoland /* disable all other contexts */ 455189499Srnoland for (i = 1; i < 8; i++) 456189499Srnoland RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); 457189499Srnoland 458189499Srnoland RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); 459189499Srnoland RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); 460189499Srnoland RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); 461189499Srnoland 462189499Srnoland r600_vm_flush_gart_range(dev); 463189499Srnoland} 464189499Srnoland 465189499Srnoland/* load r600 microcode */ 466189499Srnolandstatic void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) 467189499Srnoland{ 468189499Srnoland int i; 469189499Srnoland 470189499Srnoland r600_do_cp_stop(dev_priv); 471189499Srnoland 472189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 473189499Srnoland R600_RB_NO_UPDATE | 474189499Srnoland (15 << 8) | 475189499Srnoland (3 << 0)); 476189499Srnoland 477189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); 478189499Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 479189499Srnoland DRM_UDELAY(15000); 480189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 481189499Srnoland 482189499Srnoland 483189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) { 484189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 485189499Srnoland DRM_INFO("Loading RV770 PFP Microcode\n"); 486189499Srnoland for (i = 0; i < R700_PFP_UCODE_SIZE; i++) 487189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]); 488189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 489189499Srnoland 490189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 491189499Srnoland DRM_INFO("Loading RV770 CP Microcode\n"); 492189499Srnoland for (i = 0; i < R700_PM4_UCODE_SIZE; i++) 493189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]); 494189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 495189499Srnoland 496189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730)) { 497189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 498189499Srnoland DRM_INFO("Loading RV730 PFP Microcode\n"); 499189499Srnoland for (i = 0; i < R700_PFP_UCODE_SIZE; i++) 500189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]); 501189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 502189499Srnoland 503189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 504189499Srnoland DRM_INFO("Loading RV730 CP Microcode\n"); 505189499Srnoland for (i = 0; i < R700_PM4_UCODE_SIZE; i++) 506189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]); 507189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 508189499Srnoland 509189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) { 510189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 511189499Srnoland DRM_INFO("Loading RV710 PFP Microcode\n"); 512189499Srnoland for (i = 0; i < R700_PFP_UCODE_SIZE; i++) 513189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]); 514189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 515189499Srnoland 516189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 517189499Srnoland DRM_INFO("Loading RV710 CP Microcode\n"); 518189499Srnoland for (i = 0; i < R700_PM4_UCODE_SIZE; i++) 519189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]); 520189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 521189499Srnoland 522189499Srnoland } 523189499Srnoland RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 524189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 525189499Srnoland RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); 526189499Srnoland 527189499Srnoland} 528189499Srnoland 529189499Srnolandstatic void r600_test_writeback(drm_radeon_private_t *dev_priv) 530189499Srnoland{ 531189499Srnoland u32 tmp; 532189499Srnoland 533189499Srnoland /* Start with assuming that writeback doesn't work */ 534189499Srnoland dev_priv->writeback_works = 0; 535189499Srnoland 536189499Srnoland /* Writeback doesn't seem to work everywhere, test it here and possibly 537189499Srnoland * enable it if it appears to work 538189499Srnoland */ 539189499Srnoland radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); 540189499Srnoland 541189499Srnoland RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef); 542189499Srnoland 543189499Srnoland for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { 544189499Srnoland u32 val; 545189499Srnoland 546189499Srnoland val = radeon_read_ring_rptr(dev_priv, R600_SCRATCHOFF(1)); 547189499Srnoland if (val == 0xdeadbeef) 548189499Srnoland break; 549189499Srnoland DRM_UDELAY(1); 550189499Srnoland } 551189499Srnoland 552189499Srnoland if (tmp < dev_priv->usec_timeout) { 553189499Srnoland dev_priv->writeback_works = 1; 554189499Srnoland DRM_INFO("writeback test succeeded in %d usecs\n", tmp); 555189499Srnoland } else { 556189499Srnoland dev_priv->writeback_works = 0; 557189499Srnoland DRM_INFO("writeback test failed\n"); 558189499Srnoland } 559189499Srnoland if (radeon_no_wb == 1) { 560189499Srnoland dev_priv->writeback_works = 0; 561189499Srnoland DRM_INFO("writeback forced off\n"); 562189499Srnoland } 563189499Srnoland 564189499Srnoland if (!dev_priv->writeback_works) { 565189499Srnoland /* Disable writeback to avoid unnecessary bus master transfer */ 566189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) | 567189499Srnoland RADEON_RB_NO_UPDATE); 568189499Srnoland RADEON_WRITE(R600_SCRATCH_UMSK, 0); 569189499Srnoland } 570189499Srnoland} 571189499Srnoland 572189499Srnolandint r600_do_engine_reset(struct drm_device *dev) 573189499Srnoland{ 574189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 575189499Srnoland u32 cp_ptr, cp_me_cntl, cp_rb_cntl; 576189499Srnoland 577189499Srnoland DRM_INFO("Resetting GPU\n"); 578189499Srnoland 579189499Srnoland cp_ptr = RADEON_READ(R600_CP_RB_WPTR); 580189499Srnoland cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL); 581189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT); 582189499Srnoland 583189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff); 584189499Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 585189499Srnoland DRM_UDELAY(50); 586189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 587189499Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 588189499Srnoland 589189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); 590189499Srnoland cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); 591189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA); 592189499Srnoland 593189499Srnoland RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); 594189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); 595189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl); 596189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl); 597189499Srnoland 598189499Srnoland /* Reset the CP ring */ 599189499Srnoland r600_do_cp_reset(dev_priv); 600189499Srnoland 601189499Srnoland /* The CP is no longer running after an engine reset */ 602189499Srnoland dev_priv->cp_running = 0; 603189499Srnoland 604189499Srnoland /* Reset any pending vertex, indirect buffers */ 605189499Srnoland radeon_freelist_reset(dev); 606189499Srnoland 607189499Srnoland return 0; 608189499Srnoland 609189499Srnoland} 610189499Srnoland 611189499Srnolandstatic u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, 612189499Srnoland u32 num_backends, 613189499Srnoland u32 backend_disable_mask) 614189499Srnoland{ 615189499Srnoland u32 backend_map = 0; 616189499Srnoland u32 enabled_backends_mask; 617189499Srnoland u32 enabled_backends_count; 618189499Srnoland u32 cur_pipe; 619189499Srnoland u32 swizzle_pipe[R6XX_MAX_PIPES]; 620189499Srnoland u32 cur_backend; 621189499Srnoland u32 i; 622189499Srnoland 623189499Srnoland if (num_tile_pipes > R6XX_MAX_PIPES) 624189499Srnoland num_tile_pipes = R6XX_MAX_PIPES; 625189499Srnoland if (num_tile_pipes < 1) 626189499Srnoland num_tile_pipes = 1; 627189499Srnoland if (num_backends > R6XX_MAX_BACKENDS) 628189499Srnoland num_backends = R6XX_MAX_BACKENDS; 629189499Srnoland if (num_backends < 1) 630189499Srnoland num_backends = 1; 631189499Srnoland 632189499Srnoland enabled_backends_mask = 0; 633189499Srnoland enabled_backends_count = 0; 634189499Srnoland for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { 635189499Srnoland if (((backend_disable_mask >> i) & 1) == 0) { 636189499Srnoland enabled_backends_mask |= (1 << i); 637189499Srnoland ++enabled_backends_count; 638189499Srnoland } 639189499Srnoland if (enabled_backends_count == num_backends) 640189499Srnoland break; 641189499Srnoland } 642189499Srnoland 643189499Srnoland if (enabled_backends_count == 0) { 644189499Srnoland enabled_backends_mask = 1; 645189499Srnoland enabled_backends_count = 1; 646189499Srnoland } 647189499Srnoland 648189499Srnoland if (enabled_backends_count != num_backends) 649189499Srnoland num_backends = enabled_backends_count; 650189499Srnoland 651189499Srnoland memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); 652189499Srnoland switch (num_tile_pipes) { 653189499Srnoland case 1: 654189499Srnoland swizzle_pipe[0] = 0; 655189499Srnoland break; 656189499Srnoland case 2: 657189499Srnoland swizzle_pipe[0] = 0; 658189499Srnoland swizzle_pipe[1] = 1; 659189499Srnoland break; 660189499Srnoland case 3: 661189499Srnoland swizzle_pipe[0] = 0; 662189499Srnoland swizzle_pipe[1] = 1; 663189499Srnoland swizzle_pipe[2] = 2; 664189499Srnoland break; 665189499Srnoland case 4: 666189499Srnoland swizzle_pipe[0] = 0; 667189499Srnoland swizzle_pipe[1] = 1; 668189499Srnoland swizzle_pipe[2] = 2; 669189499Srnoland swizzle_pipe[3] = 3; 670189499Srnoland break; 671189499Srnoland case 5: 672189499Srnoland swizzle_pipe[0] = 0; 673189499Srnoland swizzle_pipe[1] = 1; 674189499Srnoland swizzle_pipe[2] = 2; 675189499Srnoland swizzle_pipe[3] = 3; 676189499Srnoland swizzle_pipe[4] = 4; 677189499Srnoland break; 678189499Srnoland case 6: 679189499Srnoland swizzle_pipe[0] = 0; 680189499Srnoland swizzle_pipe[1] = 2; 681189499Srnoland swizzle_pipe[2] = 4; 682189499Srnoland swizzle_pipe[3] = 5; 683189499Srnoland swizzle_pipe[4] = 1; 684189499Srnoland swizzle_pipe[5] = 3; 685189499Srnoland break; 686189499Srnoland case 7: 687189499Srnoland swizzle_pipe[0] = 0; 688189499Srnoland swizzle_pipe[1] = 2; 689189499Srnoland swizzle_pipe[2] = 4; 690189499Srnoland swizzle_pipe[3] = 6; 691189499Srnoland swizzle_pipe[4] = 1; 692189499Srnoland swizzle_pipe[5] = 3; 693189499Srnoland swizzle_pipe[6] = 5; 694189499Srnoland break; 695189499Srnoland case 8: 696189499Srnoland swizzle_pipe[0] = 0; 697189499Srnoland swizzle_pipe[1] = 2; 698189499Srnoland swizzle_pipe[2] = 4; 699189499Srnoland swizzle_pipe[3] = 6; 700189499Srnoland swizzle_pipe[4] = 1; 701189499Srnoland swizzle_pipe[5] = 3; 702189499Srnoland swizzle_pipe[6] = 5; 703189499Srnoland swizzle_pipe[7] = 7; 704189499Srnoland break; 705189499Srnoland } 706189499Srnoland 707189499Srnoland cur_backend = 0; 708189499Srnoland for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { 709189499Srnoland while (((1 << cur_backend) & enabled_backends_mask) == 0) 710189499Srnoland cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; 711189499Srnoland 712189499Srnoland backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); 713189499Srnoland 714189499Srnoland cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; 715189499Srnoland } 716189499Srnoland 717189499Srnoland return backend_map; 718189499Srnoland} 719189499Srnoland 720189499Srnolandstatic int r600_count_pipe_bits(uint32_t val) 721189499Srnoland{ 722189499Srnoland int i, ret = 0; 723189499Srnoland for (i = 0; i < 32; i++) { 724189499Srnoland ret += val & 1; 725189499Srnoland val >>= 1; 726189499Srnoland } 727189499Srnoland return ret; 728189499Srnoland} 729189499Srnoland 730189499Srnolandstatic void r600_gfx_init(struct drm_device *dev, 731189499Srnoland drm_radeon_private_t *dev_priv) 732189499Srnoland{ 733189499Srnoland int i, j, num_qd_pipes; 734189499Srnoland u32 sx_debug_1; 735189499Srnoland u32 tc_cntl; 736189499Srnoland u32 arb_pop; 737189499Srnoland u32 num_gs_verts_per_thread; 738189499Srnoland u32 vgt_gs_per_es; 739189499Srnoland u32 gs_prim_buffer_depth = 0; 740189499Srnoland u32 sq_ms_fifo_sizes; 741189499Srnoland u32 sq_config; 742189499Srnoland u32 sq_gpr_resource_mgmt_1 = 0; 743189499Srnoland u32 sq_gpr_resource_mgmt_2 = 0; 744189499Srnoland u32 sq_thread_resource_mgmt = 0; 745189499Srnoland u32 sq_stack_resource_mgmt_1 = 0; 746189499Srnoland u32 sq_stack_resource_mgmt_2 = 0; 747189499Srnoland u32 hdp_host_path_cntl; 748189499Srnoland u32 backend_map; 749189499Srnoland u32 gb_tiling_config = 0; 750189499Srnoland u32 cc_rb_backend_disable = 0; 751189499Srnoland u32 cc_gc_shader_pipe_config = 0; 752189499Srnoland u32 ramcfg; 753189499Srnoland 754189499Srnoland /* setup chip specs */ 755189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 756189499Srnoland case CHIP_R600: 757189499Srnoland dev_priv->r600_max_pipes = 4; 758189499Srnoland dev_priv->r600_max_tile_pipes = 8; 759189499Srnoland dev_priv->r600_max_simds = 4; 760189499Srnoland dev_priv->r600_max_backends = 4; 761189499Srnoland dev_priv->r600_max_gprs = 256; 762189499Srnoland dev_priv->r600_max_threads = 192; 763189499Srnoland dev_priv->r600_max_stack_entries = 256; 764189499Srnoland dev_priv->r600_max_hw_contexts = 8; 765189499Srnoland dev_priv->r600_max_gs_threads = 16; 766189499Srnoland dev_priv->r600_sx_max_export_size = 128; 767189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 768189499Srnoland dev_priv->r600_sx_max_export_smx_size = 128; 769189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 770189499Srnoland break; 771189499Srnoland case CHIP_RV630: 772189499Srnoland case CHIP_RV635: 773189499Srnoland dev_priv->r600_max_pipes = 2; 774189499Srnoland dev_priv->r600_max_tile_pipes = 2; 775189499Srnoland dev_priv->r600_max_simds = 3; 776189499Srnoland dev_priv->r600_max_backends = 1; 777189499Srnoland dev_priv->r600_max_gprs = 128; 778189499Srnoland dev_priv->r600_max_threads = 192; 779189499Srnoland dev_priv->r600_max_stack_entries = 128; 780189499Srnoland dev_priv->r600_max_hw_contexts = 8; 781189499Srnoland dev_priv->r600_max_gs_threads = 4; 782189499Srnoland dev_priv->r600_sx_max_export_size = 128; 783189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 784189499Srnoland dev_priv->r600_sx_max_export_smx_size = 128; 785189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 786189499Srnoland break; 787189499Srnoland case CHIP_RV610: 788189499Srnoland case CHIP_RS780: 789189499Srnoland case CHIP_RV620: 790189499Srnoland dev_priv->r600_max_pipes = 1; 791189499Srnoland dev_priv->r600_max_tile_pipes = 1; 792189499Srnoland dev_priv->r600_max_simds = 2; 793189499Srnoland dev_priv->r600_max_backends = 1; 794189499Srnoland dev_priv->r600_max_gprs = 128; 795189499Srnoland dev_priv->r600_max_threads = 192; 796189499Srnoland dev_priv->r600_max_stack_entries = 128; 797189499Srnoland dev_priv->r600_max_hw_contexts = 4; 798189499Srnoland dev_priv->r600_max_gs_threads = 4; 799189499Srnoland dev_priv->r600_sx_max_export_size = 128; 800189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 801189499Srnoland dev_priv->r600_sx_max_export_smx_size = 128; 802189499Srnoland dev_priv->r600_sq_num_cf_insts = 1; 803189499Srnoland break; 804189499Srnoland case CHIP_RV670: 805189499Srnoland dev_priv->r600_max_pipes = 4; 806189499Srnoland dev_priv->r600_max_tile_pipes = 4; 807189499Srnoland dev_priv->r600_max_simds = 4; 808189499Srnoland dev_priv->r600_max_backends = 4; 809189499Srnoland dev_priv->r600_max_gprs = 192; 810189499Srnoland dev_priv->r600_max_threads = 192; 811189499Srnoland dev_priv->r600_max_stack_entries = 256; 812189499Srnoland dev_priv->r600_max_hw_contexts = 8; 813189499Srnoland dev_priv->r600_max_gs_threads = 16; 814189499Srnoland dev_priv->r600_sx_max_export_size = 128; 815189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 816189499Srnoland dev_priv->r600_sx_max_export_smx_size = 128; 817189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 818189499Srnoland break; 819189499Srnoland default: 820189499Srnoland break; 821189499Srnoland } 822189499Srnoland 823189499Srnoland /* Initialize HDP */ 824189499Srnoland j = 0; 825189499Srnoland for (i = 0; i < 32; i++) { 826189499Srnoland RADEON_WRITE((0x2c14 + j), 0x00000000); 827189499Srnoland RADEON_WRITE((0x2c18 + j), 0x00000000); 828189499Srnoland RADEON_WRITE((0x2c1c + j), 0x00000000); 829189499Srnoland RADEON_WRITE((0x2c20 + j), 0x00000000); 830189499Srnoland RADEON_WRITE((0x2c24 + j), 0x00000000); 831189499Srnoland j += 0x18; 832189499Srnoland } 833189499Srnoland 834189499Srnoland RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); 835189499Srnoland 836189499Srnoland /* setup tiling, simd, pipe config */ 837189499Srnoland ramcfg = RADEON_READ(R600_RAMCFG); 838189499Srnoland 839189499Srnoland switch (dev_priv->r600_max_tile_pipes) { 840189499Srnoland case 1: 841189499Srnoland gb_tiling_config |= R600_PIPE_TILING(0); 842189499Srnoland break; 843189499Srnoland case 2: 844189499Srnoland gb_tiling_config |= R600_PIPE_TILING(1); 845189499Srnoland break; 846189499Srnoland case 4: 847189499Srnoland gb_tiling_config |= R600_PIPE_TILING(2); 848189499Srnoland break; 849189499Srnoland case 8: 850189499Srnoland gb_tiling_config |= R600_PIPE_TILING(3); 851189499Srnoland break; 852189499Srnoland default: 853189499Srnoland break; 854189499Srnoland } 855189499Srnoland 856189499Srnoland gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK); 857189499Srnoland 858189499Srnoland gb_tiling_config |= R600_GROUP_SIZE(0); 859189499Srnoland 860189499Srnoland if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) { 861189499Srnoland gb_tiling_config |= R600_ROW_TILING(3); 862189499Srnoland gb_tiling_config |= R600_SAMPLE_SPLIT(3); 863189499Srnoland } else { 864189499Srnoland gb_tiling_config |= 865189499Srnoland R600_ROW_TILING(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); 866189499Srnoland gb_tiling_config |= 867189499Srnoland R600_SAMPLE_SPLIT(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); 868189499Srnoland } 869189499Srnoland 870189499Srnoland gb_tiling_config |= R600_BANK_SWAPS(1); 871189499Srnoland 872189499Srnoland backend_map = r600_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, 873189499Srnoland dev_priv->r600_max_backends, 874189499Srnoland (0xff << dev_priv->r600_max_backends) & 0xff); 875189499Srnoland gb_tiling_config |= R600_BACKEND_MAP(backend_map); 876189499Srnoland 877189499Srnoland cc_gc_shader_pipe_config = 878189499Srnoland R600_INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R6XX_MAX_PIPES_MASK); 879189499Srnoland cc_gc_shader_pipe_config |= 880189499Srnoland R600_INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R6XX_MAX_SIMDS_MASK); 881189499Srnoland 882189499Srnoland cc_rb_backend_disable = 883189499Srnoland R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK); 884189499Srnoland 885189499Srnoland RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); 886189499Srnoland RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); 887189499Srnoland RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); 888189499Srnoland 889189499Srnoland RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); 890189499Srnoland RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); 891189499Srnoland RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); 892189499Srnoland 893189499Srnoland num_qd_pipes = 894189499Srnoland R6XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); 895189499Srnoland RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); 896189499Srnoland RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); 897189499Srnoland 898189499Srnoland /* set HW defaults for 3D engine */ 899189499Srnoland RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | 900189499Srnoland R600_ROQ_IB2_START(0x2b))); 901189499Srnoland 902189499Srnoland RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, (R600_MEQ_END(0x40) | 903189499Srnoland R600_ROQ_END(0x40))); 904189499Srnoland 905189499Srnoland RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | 906189499Srnoland R600_SYNC_GRADIENT | 907189499Srnoland R600_SYNC_WALKER | 908189499Srnoland R600_SYNC_ALIGNER)); 909189499Srnoland 910189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) 911189499Srnoland RADEON_WRITE(R600_ARB_GDEC_RD_CNTL, 0x00000021); 912189499Srnoland 913189499Srnoland sx_debug_1 = RADEON_READ(R600_SX_DEBUG_1); 914189499Srnoland sx_debug_1 |= R600_SMX_EVENT_RELEASE; 915189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600)) 916189499Srnoland sx_debug_1 |= R600_ENABLE_NEW_SMX_ADDRESS; 917189499Srnoland RADEON_WRITE(R600_SX_DEBUG_1, sx_debug_1); 918189499Srnoland 919189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || 920189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || 921189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || 922189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || 923189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) 924189499Srnoland RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE); 925189499Srnoland else 926189499Srnoland RADEON_WRITE(R600_DB_DEBUG, 0); 927189499Srnoland 928189499Srnoland RADEON_WRITE(R600_DB_WATERMARKS, (R600_DEPTH_FREE(4) | 929189499Srnoland R600_DEPTH_FLUSH(16) | 930189499Srnoland R600_DEPTH_PENDING_FREE(4) | 931189499Srnoland R600_DEPTH_CACHELINE_FREE(16))); 932189499Srnoland RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); 933189499Srnoland RADEON_WRITE(R600_VGT_NUM_INSTANCES, 0); 934189499Srnoland 935189499Srnoland RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); 936189499Srnoland RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(0)); 937189499Srnoland 938189499Srnoland sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES); 939189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || 940189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || 941189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { 942189499Srnoland sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) | 943189499Srnoland R600_FETCH_FIFO_HIWATER(0xa) | 944189499Srnoland R600_DONE_FIFO_HIWATER(0xe0) | 945189499Srnoland R600_ALU_UPDATE_FIFO_HIWATER(0x8)); 946189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || 947189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { 948189499Srnoland sq_ms_fifo_sizes &= ~R600_DONE_FIFO_HIWATER(0xff); 949189499Srnoland sq_ms_fifo_sizes |= R600_DONE_FIFO_HIWATER(0x4); 950189499Srnoland } 951189499Srnoland RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); 952189499Srnoland 953189499Srnoland /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT 954189499Srnoland * should be adjusted as needed by the 2D/3D drivers. This just sets default values 955189499Srnoland */ 956189499Srnoland sq_config = RADEON_READ(R600_SQ_CONFIG); 957189499Srnoland sq_config &= ~(R600_PS_PRIO(3) | 958189499Srnoland R600_VS_PRIO(3) | 959189499Srnoland R600_GS_PRIO(3) | 960189499Srnoland R600_ES_PRIO(3)); 961189499Srnoland sq_config |= (R600_DX9_CONSTS | 962189499Srnoland R600_VC_ENABLE | 963189499Srnoland R600_PS_PRIO(0) | 964189499Srnoland R600_VS_PRIO(1) | 965189499Srnoland R600_GS_PRIO(2) | 966189499Srnoland R600_ES_PRIO(3)); 967189499Srnoland 968189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) { 969189499Srnoland sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(124) | 970189499Srnoland R600_NUM_VS_GPRS(124) | 971189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(4)); 972189499Srnoland sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(0) | 973189499Srnoland R600_NUM_ES_GPRS(0)); 974189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(136) | 975189499Srnoland R600_NUM_VS_THREADS(48) | 976189499Srnoland R600_NUM_GS_THREADS(4) | 977189499Srnoland R600_NUM_ES_THREADS(4)); 978189499Srnoland sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(128) | 979189499Srnoland R600_NUM_VS_STACK_ENTRIES(128)); 980189499Srnoland sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(0) | 981189499Srnoland R600_NUM_ES_STACK_ENTRIES(0)); 982189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || 983189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || 984189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { 985189499Srnoland /* no vertex cache */ 986189499Srnoland sq_config &= ~R600_VC_ENABLE; 987189499Srnoland 988189499Srnoland sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | 989189499Srnoland R600_NUM_VS_GPRS(44) | 990189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(2)); 991189499Srnoland sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | 992189499Srnoland R600_NUM_ES_GPRS(17)); 993189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | 994189499Srnoland R600_NUM_VS_THREADS(78) | 995189499Srnoland R600_NUM_GS_THREADS(4) | 996189499Srnoland R600_NUM_ES_THREADS(31)); 997189499Srnoland sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | 998189499Srnoland R600_NUM_VS_STACK_ENTRIES(40)); 999189499Srnoland sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | 1000189499Srnoland R600_NUM_ES_STACK_ENTRIES(16)); 1001189499Srnoland } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || 1002189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { 1003189499Srnoland sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | 1004189499Srnoland R600_NUM_VS_GPRS(44) | 1005189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(2)); 1006189499Srnoland sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(18) | 1007189499Srnoland R600_NUM_ES_GPRS(18)); 1008189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | 1009189499Srnoland R600_NUM_VS_THREADS(78) | 1010189499Srnoland R600_NUM_GS_THREADS(4) | 1011189499Srnoland R600_NUM_ES_THREADS(31)); 1012189499Srnoland sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | 1013189499Srnoland R600_NUM_VS_STACK_ENTRIES(40)); 1014189499Srnoland sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | 1015189499Srnoland R600_NUM_ES_STACK_ENTRIES(16)); 1016189499Srnoland } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) { 1017189499Srnoland sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | 1018189499Srnoland R600_NUM_VS_GPRS(44) | 1019189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(2)); 1020189499Srnoland sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | 1021189499Srnoland R600_NUM_ES_GPRS(17)); 1022189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | 1023189499Srnoland R600_NUM_VS_THREADS(78) | 1024189499Srnoland R600_NUM_GS_THREADS(4) | 1025189499Srnoland R600_NUM_ES_THREADS(31)); 1026189499Srnoland sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(64) | 1027189499Srnoland R600_NUM_VS_STACK_ENTRIES(64)); 1028189499Srnoland sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(64) | 1029189499Srnoland R600_NUM_ES_STACK_ENTRIES(64)); 1030189499Srnoland } 1031189499Srnoland 1032189499Srnoland RADEON_WRITE(R600_SQ_CONFIG, sq_config); 1033189499Srnoland RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); 1034189499Srnoland RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); 1035189499Srnoland RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); 1036189499Srnoland RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); 1037189499Srnoland RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); 1038189499Srnoland 1039189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || 1040189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || 1041189499Srnoland ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) 1042189499Srnoland RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY)); 1043189499Srnoland else 1044189499Srnoland RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC)); 1045189499Srnoland 1046189499Srnoland RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_2S, (R600_S0_X(0xc) | 1047189499Srnoland R600_S0_Y(0x4) | 1048189499Srnoland R600_S1_X(0x4) | 1049189499Srnoland R600_S1_Y(0xc))); 1050189499Srnoland RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_4S, (R600_S0_X(0xe) | 1051189499Srnoland R600_S0_Y(0xe) | 1052189499Srnoland R600_S1_X(0x2) | 1053189499Srnoland R600_S1_Y(0x2) | 1054189499Srnoland R600_S2_X(0xa) | 1055189499Srnoland R600_S2_Y(0x6) | 1056189499Srnoland R600_S3_X(0x6) | 1057189499Srnoland R600_S3_Y(0xa))); 1058189499Srnoland RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0, (R600_S0_X(0xe) | 1059189499Srnoland R600_S0_Y(0xb) | 1060189499Srnoland R600_S1_X(0x4) | 1061189499Srnoland R600_S1_Y(0xc) | 1062189499Srnoland R600_S2_X(0x1) | 1063189499Srnoland R600_S2_Y(0x6) | 1064189499Srnoland R600_S3_X(0xa) | 1065189499Srnoland R600_S3_Y(0xe))); 1066189499Srnoland RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1, (R600_S4_X(0x6) | 1067189499Srnoland R600_S4_Y(0x1) | 1068189499Srnoland R600_S5_X(0x0) | 1069189499Srnoland R600_S5_Y(0x0) | 1070189499Srnoland R600_S6_X(0xb) | 1071189499Srnoland R600_S6_Y(0x4) | 1072189499Srnoland R600_S7_X(0x7) | 1073189499Srnoland R600_S7_Y(0x8))); 1074189499Srnoland 1075189499Srnoland 1076189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1077189499Srnoland case CHIP_R600: 1078189499Srnoland case CHIP_RV630: 1079189499Srnoland case CHIP_RV635: 1080189499Srnoland gs_prim_buffer_depth = 0; 1081189499Srnoland break; 1082189499Srnoland case CHIP_RV610: 1083189499Srnoland case CHIP_RS780: 1084189499Srnoland case CHIP_RV620: 1085189499Srnoland gs_prim_buffer_depth = 32; 1086189499Srnoland break; 1087189499Srnoland case CHIP_RV670: 1088189499Srnoland gs_prim_buffer_depth = 128; 1089189499Srnoland break; 1090189499Srnoland default: 1091189499Srnoland break; 1092189499Srnoland } 1093189499Srnoland 1094189499Srnoland num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; 1095189499Srnoland vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; 1096189499Srnoland /* Max value for this is 256 */ 1097189499Srnoland if (vgt_gs_per_es > 256) 1098189499Srnoland vgt_gs_per_es = 256; 1099189499Srnoland 1100189499Srnoland RADEON_WRITE(R600_VGT_ES_PER_GS, 128); 1101189499Srnoland RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); 1102189499Srnoland RADEON_WRITE(R600_VGT_GS_PER_VS, 2); 1103189499Srnoland RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); 1104189499Srnoland 1105189499Srnoland /* more default values. 2D/3D driver should adjust as needed */ 1106189499Srnoland RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); 1107189499Srnoland RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); 1108189499Srnoland RADEON_WRITE(R600_SX_MISC, 0); 1109189499Srnoland RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); 1110189499Srnoland RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); 1111189499Srnoland RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); 1112189499Srnoland RADEON_WRITE(R600_SPI_INPUT_Z, 0); 1113189499Srnoland RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); 1114189499Srnoland RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); 1115189499Srnoland 1116189499Srnoland /* clear render buffer base addresses */ 1117189499Srnoland RADEON_WRITE(R600_CB_COLOR0_BASE, 0); 1118189499Srnoland RADEON_WRITE(R600_CB_COLOR1_BASE, 0); 1119189499Srnoland RADEON_WRITE(R600_CB_COLOR2_BASE, 0); 1120189499Srnoland RADEON_WRITE(R600_CB_COLOR3_BASE, 0); 1121189499Srnoland RADEON_WRITE(R600_CB_COLOR4_BASE, 0); 1122189499Srnoland RADEON_WRITE(R600_CB_COLOR5_BASE, 0); 1123189499Srnoland RADEON_WRITE(R600_CB_COLOR6_BASE, 0); 1124189499Srnoland RADEON_WRITE(R600_CB_COLOR7_BASE, 0); 1125189499Srnoland 1126189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1127189499Srnoland case CHIP_RV610: 1128189499Srnoland case CHIP_RS780: 1129189499Srnoland case CHIP_RV620: 1130189499Srnoland tc_cntl = R600_TC_L2_SIZE(8); 1131189499Srnoland break; 1132189499Srnoland case CHIP_RV630: 1133189499Srnoland case CHIP_RV635: 1134189499Srnoland tc_cntl = R600_TC_L2_SIZE(4); 1135189499Srnoland break; 1136189499Srnoland case CHIP_R600: 1137189499Srnoland tc_cntl = R600_TC_L2_SIZE(0) | R600_L2_DISABLE_LATE_HIT; 1138189499Srnoland break; 1139189499Srnoland default: 1140189499Srnoland tc_cntl = R600_TC_L2_SIZE(0); 1141189499Srnoland break; 1142189499Srnoland } 1143189499Srnoland 1144189499Srnoland RADEON_WRITE(R600_TC_CNTL, tc_cntl); 1145189499Srnoland 1146189499Srnoland hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); 1147189499Srnoland RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); 1148189499Srnoland 1149189499Srnoland arb_pop = RADEON_READ(R600_ARB_POP); 1150189499Srnoland arb_pop |= R600_ENABLE_TC128; 1151189499Srnoland RADEON_WRITE(R600_ARB_POP, arb_pop); 1152189499Srnoland 1153189499Srnoland RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); 1154189499Srnoland RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | 1155189499Srnoland R600_NUM_CLIP_SEQ(3))); 1156189499Srnoland RADEON_WRITE(R600_PA_SC_ENHANCE, R600_FORCE_EOV_MAX_CLK_CNT(4095)); 1157189499Srnoland 1158189499Srnoland} 1159189499Srnoland 1160189499Srnolandstatic u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, 1161189499Srnoland u32 num_backends, 1162189499Srnoland u32 backend_disable_mask) 1163189499Srnoland{ 1164189499Srnoland u32 backend_map = 0; 1165189499Srnoland u32 enabled_backends_mask; 1166189499Srnoland u32 enabled_backends_count; 1167189499Srnoland u32 cur_pipe; 1168189499Srnoland u32 swizzle_pipe[R7XX_MAX_PIPES]; 1169189499Srnoland u32 cur_backend; 1170189499Srnoland u32 i; 1171189499Srnoland 1172189499Srnoland if (num_tile_pipes > R7XX_MAX_PIPES) 1173189499Srnoland num_tile_pipes = R7XX_MAX_PIPES; 1174189499Srnoland if (num_tile_pipes < 1) 1175189499Srnoland num_tile_pipes = 1; 1176189499Srnoland if (num_backends > R7XX_MAX_BACKENDS) 1177189499Srnoland num_backends = R7XX_MAX_BACKENDS; 1178189499Srnoland if (num_backends < 1) 1179189499Srnoland num_backends = 1; 1180189499Srnoland 1181189499Srnoland enabled_backends_mask = 0; 1182189499Srnoland enabled_backends_count = 0; 1183189499Srnoland for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { 1184189499Srnoland if (((backend_disable_mask >> i) & 1) == 0) { 1185189499Srnoland enabled_backends_mask |= (1 << i); 1186189499Srnoland ++enabled_backends_count; 1187189499Srnoland } 1188189499Srnoland if (enabled_backends_count == num_backends) 1189189499Srnoland break; 1190189499Srnoland } 1191189499Srnoland 1192189499Srnoland if (enabled_backends_count == 0) { 1193189499Srnoland enabled_backends_mask = 1; 1194189499Srnoland enabled_backends_count = 1; 1195189499Srnoland } 1196189499Srnoland 1197189499Srnoland if (enabled_backends_count != num_backends) 1198189499Srnoland num_backends = enabled_backends_count; 1199189499Srnoland 1200189499Srnoland memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); 1201189499Srnoland switch (num_tile_pipes) { 1202189499Srnoland case 1: 1203189499Srnoland swizzle_pipe[0] = 0; 1204189499Srnoland break; 1205189499Srnoland case 2: 1206189499Srnoland swizzle_pipe[0] = 0; 1207189499Srnoland swizzle_pipe[1] = 1; 1208189499Srnoland break; 1209189499Srnoland case 3: 1210189499Srnoland swizzle_pipe[0] = 0; 1211189499Srnoland swizzle_pipe[1] = 2; 1212189499Srnoland swizzle_pipe[2] = 1; 1213189499Srnoland break; 1214189499Srnoland case 4: 1215189499Srnoland swizzle_pipe[0] = 0; 1216189499Srnoland swizzle_pipe[1] = 2; 1217189499Srnoland swizzle_pipe[2] = 3; 1218189499Srnoland swizzle_pipe[3] = 1; 1219189499Srnoland break; 1220189499Srnoland case 5: 1221189499Srnoland swizzle_pipe[0] = 0; 1222189499Srnoland swizzle_pipe[1] = 2; 1223189499Srnoland swizzle_pipe[2] = 4; 1224189499Srnoland swizzle_pipe[3] = 1; 1225189499Srnoland swizzle_pipe[4] = 3; 1226189499Srnoland break; 1227189499Srnoland case 6: 1228189499Srnoland swizzle_pipe[0] = 0; 1229189499Srnoland swizzle_pipe[1] = 2; 1230189499Srnoland swizzle_pipe[2] = 4; 1231189499Srnoland swizzle_pipe[3] = 5; 1232189499Srnoland swizzle_pipe[4] = 3; 1233189499Srnoland swizzle_pipe[5] = 1; 1234189499Srnoland break; 1235189499Srnoland case 7: 1236189499Srnoland swizzle_pipe[0] = 0; 1237189499Srnoland swizzle_pipe[1] = 2; 1238189499Srnoland swizzle_pipe[2] = 4; 1239189499Srnoland swizzle_pipe[3] = 6; 1240189499Srnoland swizzle_pipe[4] = 3; 1241189499Srnoland swizzle_pipe[5] = 1; 1242189499Srnoland swizzle_pipe[6] = 5; 1243189499Srnoland break; 1244189499Srnoland case 8: 1245189499Srnoland swizzle_pipe[0] = 0; 1246189499Srnoland swizzle_pipe[1] = 2; 1247189499Srnoland swizzle_pipe[2] = 4; 1248189499Srnoland swizzle_pipe[3] = 6; 1249189499Srnoland swizzle_pipe[4] = 3; 1250189499Srnoland swizzle_pipe[5] = 1; 1251189499Srnoland swizzle_pipe[6] = 7; 1252189499Srnoland swizzle_pipe[7] = 5; 1253189499Srnoland break; 1254189499Srnoland } 1255189499Srnoland 1256189499Srnoland cur_backend = 0; 1257189499Srnoland for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { 1258189499Srnoland while (((1 << cur_backend) & enabled_backends_mask) == 0) 1259189499Srnoland cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; 1260189499Srnoland 1261189499Srnoland backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); 1262189499Srnoland 1263189499Srnoland cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; 1264189499Srnoland } 1265189499Srnoland 1266189499Srnoland return backend_map; 1267189499Srnoland} 1268189499Srnoland 1269189499Srnolandstatic void r700_gfx_init(struct drm_device *dev, 1270189499Srnoland drm_radeon_private_t *dev_priv) 1271189499Srnoland{ 1272189499Srnoland int i, j, num_qd_pipes; 1273189499Srnoland u32 sx_debug_1; 1274189499Srnoland u32 smx_dc_ctl0; 1275189499Srnoland u32 num_gs_verts_per_thread; 1276189499Srnoland u32 vgt_gs_per_es; 1277189499Srnoland u32 gs_prim_buffer_depth = 0; 1278189499Srnoland u32 sq_ms_fifo_sizes; 1279189499Srnoland u32 sq_config; 1280189499Srnoland u32 sq_thread_resource_mgmt; 1281189499Srnoland u32 hdp_host_path_cntl; 1282189499Srnoland u32 sq_dyn_gpr_size_simd_ab_0; 1283189499Srnoland u32 backend_map; 1284189499Srnoland u32 gb_tiling_config = 0; 1285189499Srnoland u32 cc_rb_backend_disable = 0; 1286189499Srnoland u32 cc_gc_shader_pipe_config = 0; 1287189499Srnoland u32 mc_arb_ramcfg; 1288189499Srnoland u32 db_debug4; 1289189499Srnoland 1290189499Srnoland /* setup chip specs */ 1291189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1292189499Srnoland case CHIP_RV770: 1293189499Srnoland dev_priv->r600_max_pipes = 4; 1294189499Srnoland dev_priv->r600_max_tile_pipes = 8; 1295189499Srnoland dev_priv->r600_max_simds = 10; 1296189499Srnoland dev_priv->r600_max_backends = 4; 1297189499Srnoland dev_priv->r600_max_gprs = 256; 1298189499Srnoland dev_priv->r600_max_threads = 248; 1299189499Srnoland dev_priv->r600_max_stack_entries = 512; 1300189499Srnoland dev_priv->r600_max_hw_contexts = 8; 1301189499Srnoland dev_priv->r600_max_gs_threads = 16 * 2; 1302189499Srnoland dev_priv->r600_sx_max_export_size = 128; 1303189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 1304189499Srnoland dev_priv->r600_sx_max_export_smx_size = 112; 1305189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 1306189499Srnoland 1307189499Srnoland dev_priv->r700_sx_num_of_sets = 7; 1308189499Srnoland dev_priv->r700_sc_prim_fifo_size = 0xF9; 1309189499Srnoland dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; 1310189499Srnoland dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; 1311189499Srnoland break; 1312189499Srnoland case CHIP_RV730: 1313189499Srnoland dev_priv->r600_max_pipes = 2; 1314189499Srnoland dev_priv->r600_max_tile_pipes = 4; 1315189499Srnoland dev_priv->r600_max_simds = 8; 1316189499Srnoland dev_priv->r600_max_backends = 2; 1317189499Srnoland dev_priv->r600_max_gprs = 128; 1318189499Srnoland dev_priv->r600_max_threads = 248; 1319189499Srnoland dev_priv->r600_max_stack_entries = 256; 1320189499Srnoland dev_priv->r600_max_hw_contexts = 8; 1321189499Srnoland dev_priv->r600_max_gs_threads = 16 * 2; 1322189499Srnoland dev_priv->r600_sx_max_export_size = 256; 1323189499Srnoland dev_priv->r600_sx_max_export_pos_size = 32; 1324189499Srnoland dev_priv->r600_sx_max_export_smx_size = 224; 1325189499Srnoland dev_priv->r600_sq_num_cf_insts = 2; 1326189499Srnoland 1327189499Srnoland dev_priv->r700_sx_num_of_sets = 7; 1328189499Srnoland dev_priv->r700_sc_prim_fifo_size = 0xf9; 1329189499Srnoland dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; 1330189499Srnoland dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; 1331189499Srnoland break; 1332189499Srnoland case CHIP_RV710: 1333189499Srnoland dev_priv->r600_max_pipes = 2; 1334189499Srnoland dev_priv->r600_max_tile_pipes = 2; 1335189499Srnoland dev_priv->r600_max_simds = 2; 1336189499Srnoland dev_priv->r600_max_backends = 1; 1337189499Srnoland dev_priv->r600_max_gprs = 256; 1338189499Srnoland dev_priv->r600_max_threads = 192; 1339189499Srnoland dev_priv->r600_max_stack_entries = 256; 1340189499Srnoland dev_priv->r600_max_hw_contexts = 4; 1341189499Srnoland dev_priv->r600_max_gs_threads = 8 * 2; 1342189499Srnoland dev_priv->r600_sx_max_export_size = 128; 1343189499Srnoland dev_priv->r600_sx_max_export_pos_size = 16; 1344189499Srnoland dev_priv->r600_sx_max_export_smx_size = 112; 1345189499Srnoland dev_priv->r600_sq_num_cf_insts = 1; 1346189499Srnoland 1347189499Srnoland dev_priv->r700_sx_num_of_sets = 7; 1348189499Srnoland dev_priv->r700_sc_prim_fifo_size = 0x40; 1349189499Srnoland dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; 1350189499Srnoland dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; 1351189499Srnoland break; 1352189499Srnoland default: 1353189499Srnoland break; 1354189499Srnoland } 1355189499Srnoland 1356189499Srnoland /* Initialize HDP */ 1357189499Srnoland j = 0; 1358189499Srnoland for (i = 0; i < 32; i++) { 1359189499Srnoland RADEON_WRITE((0x2c14 + j), 0x00000000); 1360189499Srnoland RADEON_WRITE((0x2c18 + j), 0x00000000); 1361189499Srnoland RADEON_WRITE((0x2c1c + j), 0x00000000); 1362189499Srnoland RADEON_WRITE((0x2c20 + j), 0x00000000); 1363189499Srnoland RADEON_WRITE((0x2c24 + j), 0x00000000); 1364189499Srnoland j += 0x18; 1365189499Srnoland } 1366189499Srnoland 1367189499Srnoland RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); 1368189499Srnoland 1369189499Srnoland /* setup tiling, simd, pipe config */ 1370189499Srnoland mc_arb_ramcfg = RADEON_READ(R700_MC_ARB_RAMCFG); 1371189499Srnoland 1372189499Srnoland switch (dev_priv->r600_max_tile_pipes) { 1373189499Srnoland case 1: 1374189499Srnoland gb_tiling_config |= R600_PIPE_TILING(0); 1375189499Srnoland break; 1376189499Srnoland case 2: 1377189499Srnoland gb_tiling_config |= R600_PIPE_TILING(1); 1378189499Srnoland break; 1379189499Srnoland case 4: 1380189499Srnoland gb_tiling_config |= R600_PIPE_TILING(2); 1381189499Srnoland break; 1382189499Srnoland case 8: 1383189499Srnoland gb_tiling_config |= R600_PIPE_TILING(3); 1384189499Srnoland break; 1385189499Srnoland default: 1386189499Srnoland break; 1387189499Srnoland } 1388189499Srnoland 1389189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) 1390189499Srnoland gb_tiling_config |= R600_BANK_TILING(1); 1391189499Srnoland else 1392189499Srnoland gb_tiling_config |= R600_BANK_TILING((mc_arb_ramcfg >> R700_NOOFBANK_SHIFT) & R700_NOOFBANK_MASK); 1393189499Srnoland 1394189499Srnoland gb_tiling_config |= R600_GROUP_SIZE(0); 1395189499Srnoland 1396189499Srnoland if (((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK) > 3) { 1397189499Srnoland gb_tiling_config |= R600_ROW_TILING(3); 1398189499Srnoland gb_tiling_config |= R600_SAMPLE_SPLIT(3); 1399189499Srnoland } else { 1400189499Srnoland gb_tiling_config |= 1401189499Srnoland R600_ROW_TILING(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); 1402189499Srnoland gb_tiling_config |= 1403189499Srnoland R600_SAMPLE_SPLIT(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); 1404189499Srnoland } 1405189499Srnoland 1406189499Srnoland gb_tiling_config |= R600_BANK_SWAPS(1); 1407189499Srnoland 1408189499Srnoland backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, 1409189499Srnoland dev_priv->r600_max_backends, 1410189499Srnoland (0xff << dev_priv->r600_max_backends) & 0xff); 1411189499Srnoland gb_tiling_config |= R600_BACKEND_MAP(backend_map); 1412189499Srnoland 1413189499Srnoland cc_gc_shader_pipe_config = 1414189499Srnoland R600_INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R7XX_MAX_PIPES_MASK); 1415189499Srnoland cc_gc_shader_pipe_config |= 1416189499Srnoland R600_INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R7XX_MAX_SIMDS_MASK); 1417189499Srnoland 1418189499Srnoland cc_rb_backend_disable = 1419189499Srnoland R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK); 1420189499Srnoland 1421189499Srnoland RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); 1422189499Srnoland RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); 1423189499Srnoland RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); 1424189499Srnoland 1425189499Srnoland RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); 1426189499Srnoland RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); 1427189499Srnoland RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); 1428189499Srnoland 1429189499Srnoland RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); 1430189499Srnoland RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0); 1431189499Srnoland RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0); 1432189499Srnoland RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0); 1433189499Srnoland RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0); 1434189499Srnoland 1435189499Srnoland num_qd_pipes = 1436189499Srnoland R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); 1437189499Srnoland RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); 1438189499Srnoland RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); 1439189499Srnoland 1440189499Srnoland /* set HW defaults for 3D engine */ 1441189499Srnoland RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | 1442189499Srnoland R600_ROQ_IB2_START(0x2b))); 1443189499Srnoland 1444189499Srnoland RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, R700_STQ_SPLIT(0x30)); 1445189499Srnoland 1446189499Srnoland RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | 1447189499Srnoland R600_SYNC_GRADIENT | 1448189499Srnoland R600_SYNC_WALKER | 1449189499Srnoland R600_SYNC_ALIGNER)); 1450189499Srnoland 1451189499Srnoland sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1); 1452189499Srnoland sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS; 1453189499Srnoland RADEON_WRITE(R700_SX_DEBUG_1, sx_debug_1); 1454189499Srnoland 1455189499Srnoland smx_dc_ctl0 = RADEON_READ(R600_SMX_DC_CTL0); 1456189499Srnoland smx_dc_ctl0 &= ~R700_CACHE_DEPTH(0x1ff); 1457189499Srnoland smx_dc_ctl0 |= R700_CACHE_DEPTH((dev_priv->r700_sx_num_of_sets * 64) - 1); 1458189499Srnoland RADEON_WRITE(R600_SMX_DC_CTL0, smx_dc_ctl0); 1459189499Srnoland 1460189499Srnoland RADEON_WRITE(R700_SMX_EVENT_CTL, (R700_ES_FLUSH_CTL(4) | 1461189499Srnoland R700_GS_FLUSH_CTL(4) | 1462189499Srnoland R700_ACK_FLUSH_CTL(3) | 1463189499Srnoland R700_SYNC_FLUSH_CTL)); 1464189499Srnoland 1465189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) 1466189499Srnoland RADEON_WRITE(R700_DB_DEBUG3, R700_DB_CLK_OFF_DELAY(0x1f)); 1467189499Srnoland else { 1468189499Srnoland db_debug4 = RADEON_READ(RV700_DB_DEBUG4); 1469189499Srnoland db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER; 1470189499Srnoland RADEON_WRITE(RV700_DB_DEBUG4, db_debug4); 1471189499Srnoland } 1472189499Srnoland 1473189499Srnoland RADEON_WRITE(R600_SX_EXPORT_BUFFER_SIZES, (R600_COLOR_BUFFER_SIZE((dev_priv->r600_sx_max_export_size / 4) - 1) | 1474189499Srnoland R600_POSITION_BUFFER_SIZE((dev_priv->r600_sx_max_export_pos_size / 4) - 1) | 1475189499Srnoland R600_SMX_BUFFER_SIZE((dev_priv->r600_sx_max_export_smx_size / 4) - 1))); 1476189499Srnoland 1477189499Srnoland RADEON_WRITE(R700_PA_SC_FIFO_SIZE_R7XX, (R700_SC_PRIM_FIFO_SIZE(dev_priv->r700_sc_prim_fifo_size) | 1478189499Srnoland R700_SC_HIZ_TILE_FIFO_SIZE(dev_priv->r700_sc_hiz_tile_fifo_size) | 1479189499Srnoland R700_SC_EARLYZ_TILE_FIFO_SIZE(dev_priv->r700_sc_earlyz_tile_fifo_fize))); 1480189499Srnoland 1481189499Srnoland RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); 1482189499Srnoland 1483189499Srnoland RADEON_WRITE(R600_VGT_NUM_INSTANCES, 1); 1484189499Srnoland 1485189499Srnoland RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); 1486189499Srnoland 1487189499Srnoland RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(4)); 1488189499Srnoland 1489189499Srnoland RADEON_WRITE(R600_CP_PERFMON_CNTL, 0); 1490189499Srnoland 1491189499Srnoland sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(16 * dev_priv->r600_sq_num_cf_insts) | 1492189499Srnoland R600_DONE_FIFO_HIWATER(0xe0) | 1493189499Srnoland R600_ALU_UPDATE_FIFO_HIWATER(0x8)); 1494189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1495189499Srnoland case CHIP_RV770: 1496189499Srnoland sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1); 1497189499Srnoland break; 1498189499Srnoland case CHIP_RV730: 1499189499Srnoland case CHIP_RV710: 1500189499Srnoland default: 1501189499Srnoland sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4); 1502189499Srnoland break; 1503189499Srnoland } 1504189499Srnoland RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); 1505189499Srnoland 1506189499Srnoland /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT 1507189499Srnoland * should be adjusted as needed by the 2D/3D drivers. This just sets default values 1508189499Srnoland */ 1509189499Srnoland sq_config = RADEON_READ(R600_SQ_CONFIG); 1510189499Srnoland sq_config &= ~(R600_PS_PRIO(3) | 1511189499Srnoland R600_VS_PRIO(3) | 1512189499Srnoland R600_GS_PRIO(3) | 1513189499Srnoland R600_ES_PRIO(3)); 1514189499Srnoland sq_config |= (R600_DX9_CONSTS | 1515189499Srnoland R600_VC_ENABLE | 1516189499Srnoland R600_EXPORT_SRC_C | 1517189499Srnoland R600_PS_PRIO(0) | 1518189499Srnoland R600_VS_PRIO(1) | 1519189499Srnoland R600_GS_PRIO(2) | 1520189499Srnoland R600_ES_PRIO(3)); 1521189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) 1522189499Srnoland /* no vertex cache */ 1523189499Srnoland sq_config &= ~R600_VC_ENABLE; 1524189499Srnoland 1525189499Srnoland RADEON_WRITE(R600_SQ_CONFIG, sq_config); 1526189499Srnoland 1527189499Srnoland RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, (R600_NUM_PS_GPRS((dev_priv->r600_max_gprs * 24)/64) | 1528189499Srnoland R600_NUM_VS_GPRS((dev_priv->r600_max_gprs * 24)/64) | 1529189499Srnoland R600_NUM_CLAUSE_TEMP_GPRS(((dev_priv->r600_max_gprs * 24)/64)/2))); 1530189499Srnoland 1531189499Srnoland RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, (R600_NUM_GS_GPRS((dev_priv->r600_max_gprs * 7)/64) | 1532189499Srnoland R600_NUM_ES_GPRS((dev_priv->r600_max_gprs * 7)/64))); 1533189499Srnoland 1534189499Srnoland sq_thread_resource_mgmt = (R600_NUM_PS_THREADS((dev_priv->r600_max_threads * 4)/8) | 1535189499Srnoland R600_NUM_VS_THREADS((dev_priv->r600_max_threads * 2)/8) | 1536189499Srnoland R600_NUM_ES_THREADS((dev_priv->r600_max_threads * 1)/8)); 1537189499Srnoland if (((dev_priv->r600_max_threads * 1) / 8) > dev_priv->r600_max_gs_threads) 1538189499Srnoland sq_thread_resource_mgmt |= R600_NUM_GS_THREADS(dev_priv->r600_max_gs_threads); 1539189499Srnoland else 1540189499Srnoland sq_thread_resource_mgmt |= R600_NUM_GS_THREADS((dev_priv->r600_max_gs_threads * 1)/8); 1541189499Srnoland RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); 1542189499Srnoland 1543189499Srnoland RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, (R600_NUM_PS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | 1544189499Srnoland R600_NUM_VS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); 1545189499Srnoland 1546189499Srnoland RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, (R600_NUM_GS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | 1547189499Srnoland R600_NUM_ES_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); 1548189499Srnoland 1549189499Srnoland sq_dyn_gpr_size_simd_ab_0 = (R700_SIMDA_RING0((dev_priv->r600_max_gprs * 38)/64) | 1550189499Srnoland R700_SIMDA_RING1((dev_priv->r600_max_gprs * 38)/64) | 1551189499Srnoland R700_SIMDB_RING0((dev_priv->r600_max_gprs * 38)/64) | 1552189499Srnoland R700_SIMDB_RING1((dev_priv->r600_max_gprs * 38)/64)); 1553189499Srnoland 1554189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0); 1555189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0); 1556189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0); 1557189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0); 1558189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0); 1559189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0); 1560189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0); 1561189499Srnoland RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0); 1562189499Srnoland 1563189499Srnoland RADEON_WRITE(R700_PA_SC_FORCE_EOV_MAX_CNTS, (R700_FORCE_EOV_MAX_CLK_CNT(4095) | 1564189499Srnoland R700_FORCE_EOV_MAX_REZ_CNT(255))); 1565189499Srnoland 1566189499Srnoland if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) 1567189499Srnoland RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_TC_ONLY) | 1568189499Srnoland R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); 1569189499Srnoland else 1570189499Srnoland RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_VC_AND_TC) | 1571189499Srnoland R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); 1572189499Srnoland 1573189499Srnoland switch (dev_priv->flags & RADEON_FAMILY_MASK) { 1574189499Srnoland case CHIP_RV770: 1575189499Srnoland case CHIP_RV730: 1576189499Srnoland gs_prim_buffer_depth = 384; 1577189499Srnoland break; 1578189499Srnoland case CHIP_RV710: 1579189499Srnoland gs_prim_buffer_depth = 128; 1580189499Srnoland break; 1581189499Srnoland default: 1582189499Srnoland break; 1583189499Srnoland } 1584189499Srnoland 1585189499Srnoland num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; 1586189499Srnoland vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; 1587189499Srnoland /* Max value for this is 256 */ 1588189499Srnoland if (vgt_gs_per_es > 256) 1589189499Srnoland vgt_gs_per_es = 256; 1590189499Srnoland 1591189499Srnoland RADEON_WRITE(R600_VGT_ES_PER_GS, 128); 1592189499Srnoland RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); 1593189499Srnoland RADEON_WRITE(R600_VGT_GS_PER_VS, 2); 1594189499Srnoland 1595189499Srnoland /* more default values. 2D/3D driver should adjust as needed */ 1596189499Srnoland RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); 1597189499Srnoland RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); 1598189499Srnoland RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); 1599189499Srnoland RADEON_WRITE(R600_SX_MISC, 0); 1600189499Srnoland RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); 1601189499Srnoland RADEON_WRITE(R700_PA_SC_EDGERULE, 0xaaaaaaaa); 1602189499Srnoland RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); 1603189499Srnoland RADEON_WRITE(R600_PA_SC_CLIPRECT_RULE, 0xffff); 1604189499Srnoland RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); 1605189499Srnoland RADEON_WRITE(R600_SPI_INPUT_Z, 0); 1606189499Srnoland RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); 1607189499Srnoland RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); 1608189499Srnoland 1609189499Srnoland /* clear render buffer base addresses */ 1610189499Srnoland RADEON_WRITE(R600_CB_COLOR0_BASE, 0); 1611189499Srnoland RADEON_WRITE(R600_CB_COLOR1_BASE, 0); 1612189499Srnoland RADEON_WRITE(R600_CB_COLOR2_BASE, 0); 1613189499Srnoland RADEON_WRITE(R600_CB_COLOR3_BASE, 0); 1614189499Srnoland RADEON_WRITE(R600_CB_COLOR4_BASE, 0); 1615189499Srnoland RADEON_WRITE(R600_CB_COLOR5_BASE, 0); 1616189499Srnoland RADEON_WRITE(R600_CB_COLOR6_BASE, 0); 1617189499Srnoland RADEON_WRITE(R600_CB_COLOR7_BASE, 0); 1618189499Srnoland 1619189499Srnoland RADEON_WRITE(R700_TCP_CNTL, 0); 1620189499Srnoland 1621189499Srnoland hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); 1622189499Srnoland RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); 1623189499Srnoland 1624189499Srnoland RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); 1625189499Srnoland 1626189499Srnoland RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | 1627189499Srnoland R600_NUM_CLIP_SEQ(3))); 1628189499Srnoland 1629189499Srnoland} 1630189499Srnoland 1631189499Srnolandstatic void r600_cp_init_ring_buffer(struct drm_device *dev, 1632189499Srnoland drm_radeon_private_t *dev_priv, 1633189499Srnoland struct drm_file *file_priv) 1634189499Srnoland{ 1635189499Srnoland u32 ring_start; 1636189558Srnoland u64 rptr_addr; 1637189499Srnoland 1638189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) 1639189499Srnoland r700_gfx_init(dev, dev_priv); 1640189499Srnoland else 1641189499Srnoland r600_gfx_init(dev, dev_priv); 1642189499Srnoland 1643189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); 1644189499Srnoland RADEON_READ(R600_GRBM_SOFT_RESET); 1645189499Srnoland DRM_UDELAY(15000); 1646189499Srnoland RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 1647189499Srnoland 1648189499Srnoland 1649189499Srnoland /* Set ring buffer size */ 1650189499Srnoland#ifdef __BIG_ENDIAN 1651189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1652189499Srnoland RADEON_BUF_SWAP_32BIT | 1653189499Srnoland RADEON_RB_NO_UPDATE | 1654189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1655189499Srnoland dev_priv->ring.size_l2qw); 1656189499Srnoland#else 1657189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1658189499Srnoland RADEON_RB_NO_UPDATE | 1659189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1660189499Srnoland dev_priv->ring.size_l2qw); 1661189499Srnoland#endif 1662189499Srnoland 1663189499Srnoland RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x4); 1664189499Srnoland 1665189499Srnoland /* Set the write pointer delay */ 1666189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); 1667189499Srnoland 1668189499Srnoland#ifdef __BIG_ENDIAN 1669189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1670189499Srnoland RADEON_BUF_SWAP_32BIT | 1671189499Srnoland RADEON_RB_NO_UPDATE | 1672189499Srnoland RADEON_RB_RPTR_WR_ENA | 1673189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1674189499Srnoland dev_priv->ring.size_l2qw); 1675189499Srnoland#else 1676189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1677189499Srnoland RADEON_RB_NO_UPDATE | 1678189499Srnoland RADEON_RB_RPTR_WR_ENA | 1679189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1680189499Srnoland dev_priv->ring.size_l2qw); 1681189499Srnoland#endif 1682189499Srnoland 1683189499Srnoland /* Initialize the ring buffer's read and write pointers */ 1684189499Srnoland RADEON_WRITE(R600_CP_RB_RPTR_WR, 0); 1685189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR, 0); 1686189499Srnoland SET_RING_HEAD(dev_priv, 0); 1687189499Srnoland dev_priv->ring.tail = 0; 1688189499Srnoland 1689189499Srnoland#if __OS_HAS_AGP 1690189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1691189558Srnoland rptr_addr = dev_priv->ring_rptr->offset 1692189558Srnoland - dev->agp->base + 1693189558Srnoland dev_priv->gart_vm_start; 1694189499Srnoland } else 1695189499Srnoland#endif 1696189499Srnoland { 1697189558Srnoland rptr_addr = dev_priv->ring_rptr->offset 1698189558Srnoland - ((unsigned long) dev->sg->virtual) 1699189558Srnoland + dev_priv->gart_vm_start; 1700189499Srnoland } 1701189558Srnoland RADEON_WRITE(R600_CP_RB_RPTR_ADDR, 1702189558Srnoland rptr_addr & 0xffffffff); 1703189558Srnoland RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, 1704189558Srnoland upper_32_bits(rptr_addr)); 1705189499Srnoland 1706189499Srnoland#ifdef __BIG_ENDIAN 1707189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1708189499Srnoland RADEON_BUF_SWAP_32BIT | 1709189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1710189499Srnoland dev_priv->ring.size_l2qw); 1711189499Srnoland#else 1712189499Srnoland RADEON_WRITE(R600_CP_RB_CNTL, 1713189499Srnoland (dev_priv->ring.rptr_update_l2qw << 8) | 1714189499Srnoland dev_priv->ring.size_l2qw); 1715189499Srnoland#endif 1716189499Srnoland 1717189499Srnoland#if __OS_HAS_AGP 1718189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1719189499Srnoland /* XXX */ 1720189499Srnoland radeon_write_agp_base(dev_priv, dev->agp->base); 1721189499Srnoland 1722189499Srnoland /* XXX */ 1723189499Srnoland radeon_write_agp_location(dev_priv, 1724189499Srnoland (((dev_priv->gart_vm_start - 1 + 1725189499Srnoland dev_priv->gart_size) & 0xffff0000) | 1726189499Srnoland (dev_priv->gart_vm_start >> 16))); 1727189499Srnoland 1728189499Srnoland ring_start = (dev_priv->cp_ring->offset 1729189499Srnoland - dev->agp->base 1730189499Srnoland + dev_priv->gart_vm_start); 1731189499Srnoland } else 1732189499Srnoland#endif 1733189499Srnoland ring_start = (dev_priv->cp_ring->offset 1734189499Srnoland - (unsigned long)dev->sg->virtual 1735189499Srnoland + dev_priv->gart_vm_start); 1736189499Srnoland 1737189499Srnoland RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8); 1738189499Srnoland 1739189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, 0xff); 1740189499Srnoland 1741189499Srnoland RADEON_WRITE(R600_CP_DEBUG, (1 << 27) | (1 << 28)); 1742189499Srnoland 1743189499Srnoland /* Start with assuming that writeback doesn't work */ 1744189499Srnoland dev_priv->writeback_works = 0; 1745189499Srnoland 1746189499Srnoland /* Initialize the scratch register pointer. This will cause 1747189499Srnoland * the scratch register values to be written out to memory 1748189499Srnoland * whenever they are updated. 1749189499Srnoland * 1750189499Srnoland * We simply put this behind the ring read pointer, this works 1751189499Srnoland * with PCI GART as well as (whatever kind of) AGP GART 1752189499Srnoland */ 1753189558Srnoland { 1754189558Srnoland u64 scratch_addr; 1755189499Srnoland 1756189558Srnoland scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR); 1757189558Srnoland scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; 1758189558Srnoland scratch_addr += R600_SCRATCH_REG_OFFSET; 1759189558Srnoland scratch_addr >>= 8; 1760189558Srnoland scratch_addr &= 0xffffffff; 1761189558Srnoland 1762189558Srnoland RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr); 1763189558Srnoland } 1764189558Srnoland 1765189499Srnoland RADEON_WRITE(R600_SCRATCH_UMSK, 0x7); 1766189499Srnoland 1767189499Srnoland /* Turn on bus mastering */ 1768189499Srnoland radeon_enable_bm(dev_priv); 1769189499Srnoland 1770189499Srnoland radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0); 1771189499Srnoland RADEON_WRITE(R600_LAST_FRAME_REG, 0); 1772189499Srnoland 1773189499Srnoland radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); 1774189499Srnoland RADEON_WRITE(R600_LAST_DISPATCH_REG, 0); 1775189499Srnoland 1776189499Srnoland radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0); 1777189499Srnoland RADEON_WRITE(R600_LAST_CLEAR_REG, 0); 1778189499Srnoland 1779189499Srnoland /* reset sarea copies of these */ 1780189499Srnoland if (dev_priv->sarea_priv) { 1781189499Srnoland dev_priv->sarea_priv->last_frame = 0; 1782189499Srnoland dev_priv->sarea_priv->last_dispatch = 0; 1783189499Srnoland dev_priv->sarea_priv->last_clear = 0; 1784189499Srnoland } 1785189499Srnoland 1786189499Srnoland r600_do_wait_for_idle(dev_priv); 1787189499Srnoland 1788189499Srnoland} 1789189499Srnoland 1790189499Srnolandint r600_do_cleanup_cp(struct drm_device *dev) 1791189499Srnoland{ 1792189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1793189499Srnoland DRM_DEBUG("\n"); 1794189499Srnoland 1795189499Srnoland /* Make sure interrupts are disabled here because the uninstall ioctl 1796189499Srnoland * may not have been called from userspace and after dev_private 1797189499Srnoland * is freed, it's too late. 1798189499Srnoland */ 1799189499Srnoland if (dev->irq_enabled) 1800189499Srnoland drm_irq_uninstall(dev); 1801189499Srnoland 1802189499Srnoland#if __OS_HAS_AGP 1803189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1804189499Srnoland if (dev_priv->cp_ring != NULL) { 1805189499Srnoland drm_core_ioremapfree(dev_priv->cp_ring, dev); 1806189499Srnoland dev_priv->cp_ring = NULL; 1807189499Srnoland } 1808189499Srnoland if (dev_priv->ring_rptr != NULL) { 1809189499Srnoland drm_core_ioremapfree(dev_priv->ring_rptr, dev); 1810189499Srnoland dev_priv->ring_rptr = NULL; 1811189499Srnoland } 1812189499Srnoland if (dev->agp_buffer_map != NULL) { 1813189499Srnoland drm_core_ioremapfree(dev->agp_buffer_map, dev); 1814189499Srnoland dev->agp_buffer_map = NULL; 1815189499Srnoland } 1816189499Srnoland } else 1817189499Srnoland#endif 1818189499Srnoland { 1819189499Srnoland 1820189499Srnoland if (dev_priv->gart_info.bus_addr) 1821189499Srnoland r600_page_table_cleanup(dev, &dev_priv->gart_info); 1822189499Srnoland 1823189499Srnoland if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { 1824189499Srnoland drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); 1825189499Srnoland dev_priv->gart_info.addr = 0; 1826189499Srnoland } 1827189499Srnoland } 1828189499Srnoland /* only clear to the start of flags */ 1829189499Srnoland memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); 1830189499Srnoland 1831189499Srnoland return 0; 1832189499Srnoland} 1833189499Srnoland 1834189499Srnolandint r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, 1835189499Srnoland struct drm_file *file_priv) 1836189499Srnoland{ 1837189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 1838189499Srnoland 1839189499Srnoland DRM_DEBUG("\n"); 1840189499Srnoland 1841189499Srnoland /* if we require new memory map but we don't have it fail */ 1842189499Srnoland if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { 1843189499Srnoland DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); 1844189499Srnoland r600_do_cleanup_cp(dev); 1845189499Srnoland return -EINVAL; 1846189499Srnoland } 1847189499Srnoland 1848189499Srnoland if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { 1849189499Srnoland DRM_DEBUG("Forcing AGP card to PCI mode\n"); 1850189499Srnoland dev_priv->flags &= ~RADEON_IS_AGP; 1851189499Srnoland /* The writeback test succeeds, but when writeback is enabled, 1852189499Srnoland * the ring buffer read ptr update fails after first 128 bytes. 1853189499Srnoland */ 1854189499Srnoland radeon_no_wb = 1; 1855189499Srnoland } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) 1856189499Srnoland && !init->is_pci) { 1857189499Srnoland DRM_DEBUG("Restoring AGP flag\n"); 1858189499Srnoland dev_priv->flags |= RADEON_IS_AGP; 1859189499Srnoland } 1860189499Srnoland 1861189499Srnoland dev_priv->usec_timeout = init->usec_timeout; 1862189499Srnoland if (dev_priv->usec_timeout < 1 || 1863189499Srnoland dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { 1864189499Srnoland DRM_DEBUG("TIMEOUT problem!\n"); 1865189499Srnoland r600_do_cleanup_cp(dev); 1866189499Srnoland return -EINVAL; 1867189499Srnoland } 1868189499Srnoland 1869189499Srnoland /* Enable vblank on CRTC1 for older X servers 1870189499Srnoland */ 1871189499Srnoland dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; 1872189499Srnoland 1873189499Srnoland dev_priv->cp_mode = init->cp_mode; 1874189499Srnoland 1875189499Srnoland /* We don't support anything other than bus-mastering ring mode, 1876189499Srnoland * but the ring can be in either AGP or PCI space for the ring 1877189499Srnoland * read pointer. 1878189499Srnoland */ 1879189499Srnoland if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && 1880189499Srnoland (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { 1881189499Srnoland DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); 1882189499Srnoland r600_do_cleanup_cp(dev); 1883189499Srnoland return -EINVAL; 1884189499Srnoland } 1885189499Srnoland 1886189499Srnoland switch (init->fb_bpp) { 1887189499Srnoland case 16: 1888189499Srnoland dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; 1889189499Srnoland break; 1890189499Srnoland case 32: 1891189499Srnoland default: 1892189499Srnoland dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; 1893189499Srnoland break; 1894189499Srnoland } 1895189499Srnoland dev_priv->front_offset = init->front_offset; 1896189499Srnoland dev_priv->front_pitch = init->front_pitch; 1897189499Srnoland dev_priv->back_offset = init->back_offset; 1898189499Srnoland dev_priv->back_pitch = init->back_pitch; 1899189499Srnoland 1900189499Srnoland dev_priv->ring_offset = init->ring_offset; 1901189499Srnoland dev_priv->ring_rptr_offset = init->ring_rptr_offset; 1902189499Srnoland dev_priv->buffers_offset = init->buffers_offset; 1903189499Srnoland dev_priv->gart_textures_offset = init->gart_textures_offset; 1904189499Srnoland 1905189499Srnoland dev_priv->sarea = drm_getsarea(dev); 1906189499Srnoland if (!dev_priv->sarea) { 1907189499Srnoland DRM_ERROR("could not find sarea!\n"); 1908189499Srnoland r600_do_cleanup_cp(dev); 1909189499Srnoland return -EINVAL; 1910189499Srnoland } 1911189499Srnoland 1912189499Srnoland dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); 1913189499Srnoland if (!dev_priv->cp_ring) { 1914189499Srnoland DRM_ERROR("could not find cp ring region!\n"); 1915189499Srnoland r600_do_cleanup_cp(dev); 1916189499Srnoland return -EINVAL; 1917189499Srnoland } 1918189499Srnoland dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); 1919189499Srnoland if (!dev_priv->ring_rptr) { 1920189499Srnoland DRM_ERROR("could not find ring read pointer!\n"); 1921189499Srnoland r600_do_cleanup_cp(dev); 1922189499Srnoland return -EINVAL; 1923189499Srnoland } 1924189499Srnoland dev->agp_buffer_token = init->buffers_offset; 1925189499Srnoland dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 1926189499Srnoland if (!dev->agp_buffer_map) { 1927189499Srnoland DRM_ERROR("could not find dma buffer region!\n"); 1928189499Srnoland r600_do_cleanup_cp(dev); 1929189499Srnoland return -EINVAL; 1930189499Srnoland } 1931189499Srnoland 1932189499Srnoland if (init->gart_textures_offset) { 1933189499Srnoland dev_priv->gart_textures = 1934189499Srnoland drm_core_findmap(dev, init->gart_textures_offset); 1935189499Srnoland if (!dev_priv->gart_textures) { 1936189499Srnoland DRM_ERROR("could not find GART texture region!\n"); 1937189499Srnoland r600_do_cleanup_cp(dev); 1938189499Srnoland return -EINVAL; 1939189499Srnoland } 1940189499Srnoland } 1941189499Srnoland 1942189499Srnoland dev_priv->sarea_priv = 1943189499Srnoland (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle + 1944189499Srnoland init->sarea_priv_offset); 1945189499Srnoland 1946189499Srnoland#if __OS_HAS_AGP 1947189499Srnoland /* XXX */ 1948189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 1949189499Srnoland drm_core_ioremap_wc(dev_priv->cp_ring, dev); 1950189499Srnoland drm_core_ioremap_wc(dev_priv->ring_rptr, dev); 1951189499Srnoland drm_core_ioremap_wc(dev->agp_buffer_map, dev); 1952189499Srnoland if (!dev_priv->cp_ring->handle || 1953189499Srnoland !dev_priv->ring_rptr->handle || 1954189499Srnoland !dev->agp_buffer_map->handle) { 1955189499Srnoland DRM_ERROR("could not find ioremap agp regions!\n"); 1956189499Srnoland r600_do_cleanup_cp(dev); 1957189499Srnoland return -EINVAL; 1958189499Srnoland } 1959189499Srnoland } else 1960189499Srnoland#endif 1961189499Srnoland { 1962189499Srnoland dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; 1963189499Srnoland dev_priv->ring_rptr->handle = 1964189499Srnoland (void *)dev_priv->ring_rptr->offset; 1965189499Srnoland dev->agp_buffer_map->handle = 1966189499Srnoland (void *)dev->agp_buffer_map->offset; 1967189499Srnoland 1968189499Srnoland DRM_DEBUG("dev_priv->cp_ring->handle %p\n", 1969189499Srnoland dev_priv->cp_ring->handle); 1970189499Srnoland DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", 1971189499Srnoland dev_priv->ring_rptr->handle); 1972189499Srnoland DRM_DEBUG("dev->agp_buffer_map->handle %p\n", 1973189499Srnoland dev->agp_buffer_map->handle); 1974189499Srnoland } 1975189499Srnoland 1976189499Srnoland dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24; 1977189499Srnoland dev_priv->fb_size = 1978189499Srnoland (((radeon_read_fb_location(dev_priv) & 0xffff0000u) << 8) + 0x1000000) 1979189499Srnoland - dev_priv->fb_location; 1980189499Srnoland 1981189499Srnoland dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | 1982189499Srnoland ((dev_priv->front_offset 1983189499Srnoland + dev_priv->fb_location) >> 10)); 1984189499Srnoland 1985189499Srnoland dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | 1986189499Srnoland ((dev_priv->back_offset 1987189499Srnoland + dev_priv->fb_location) >> 10)); 1988189499Srnoland 1989189499Srnoland dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | 1990189499Srnoland ((dev_priv->depth_offset 1991189499Srnoland + dev_priv->fb_location) >> 10)); 1992189499Srnoland 1993189499Srnoland dev_priv->gart_size = init->gart_size; 1994189499Srnoland 1995189499Srnoland /* New let's set the memory map ... */ 1996189499Srnoland if (dev_priv->new_memmap) { 1997189499Srnoland u32 base = 0; 1998189499Srnoland 1999189499Srnoland DRM_INFO("Setting GART location based on new memory map\n"); 2000189499Srnoland 2001189499Srnoland /* If using AGP, try to locate the AGP aperture at the same 2002189499Srnoland * location in the card and on the bus, though we have to 2003189499Srnoland * align it down. 2004189499Srnoland */ 2005189499Srnoland#if __OS_HAS_AGP 2006189499Srnoland /* XXX */ 2007189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 2008189499Srnoland base = dev->agp->base; 2009189499Srnoland /* Check if valid */ 2010189499Srnoland if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && 2011189499Srnoland base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { 2012189499Srnoland DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", 2013189499Srnoland dev->agp->base); 2014189499Srnoland base = 0; 2015189499Srnoland } 2016189499Srnoland } 2017189499Srnoland#endif 2018189499Srnoland /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ 2019189499Srnoland if (base == 0) { 2020189499Srnoland base = dev_priv->fb_location + dev_priv->fb_size; 2021189499Srnoland if (base < dev_priv->fb_location || 2022189499Srnoland ((base + dev_priv->gart_size) & 0xfffffffful) < base) 2023189499Srnoland base = dev_priv->fb_location 2024189499Srnoland - dev_priv->gart_size; 2025189499Srnoland } 2026189499Srnoland dev_priv->gart_vm_start = base & 0xffc00000u; 2027189499Srnoland if (dev_priv->gart_vm_start != base) 2028189499Srnoland DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", 2029189499Srnoland base, dev_priv->gart_vm_start); 2030189499Srnoland } 2031189499Srnoland 2032189499Srnoland#if __OS_HAS_AGP 2033189499Srnoland /* XXX */ 2034189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) 2035189499Srnoland dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset 2036189499Srnoland - dev->agp->base 2037189499Srnoland + dev_priv->gart_vm_start); 2038189499Srnoland else 2039189499Srnoland#endif 2040189499Srnoland dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset 2041189499Srnoland - (unsigned long)dev->sg->virtual 2042189499Srnoland + dev_priv->gart_vm_start); 2043189499Srnoland 2044189499Srnoland DRM_DEBUG("fb 0x%08x size %d\n", 2045189499Srnoland (unsigned int) dev_priv->fb_location, 2046189499Srnoland (unsigned int) dev_priv->fb_size); 2047189499Srnoland DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); 2048189499Srnoland DRM_DEBUG("dev_priv->gart_vm_start 0x%08x\n", 2049189499Srnoland (unsigned int) dev_priv->gart_vm_start); 2050189499Srnoland DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n", 2051189499Srnoland dev_priv->gart_buffers_offset); 2052189499Srnoland 2053189499Srnoland dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; 2054189499Srnoland dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle 2055189499Srnoland + init->ring_size / sizeof(u32)); 2056189499Srnoland dev_priv->ring.size = init->ring_size; 2057189499Srnoland dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); 2058189499Srnoland 2059189499Srnoland dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; 2060189499Srnoland dev_priv->ring.rptr_update_l2qw = drm_order(/* init->rptr_update */ 4096 / 8); 2061189499Srnoland 2062189499Srnoland dev_priv->ring.fetch_size = /* init->fetch_size */ 32; 2063189499Srnoland dev_priv->ring.fetch_size_l2ow = drm_order(/* init->fetch_size */ 32 / 16); 2064189499Srnoland 2065189499Srnoland dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; 2066189499Srnoland 2067189499Srnoland dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; 2068189499Srnoland 2069189499Srnoland#if __OS_HAS_AGP 2070189499Srnoland if (dev_priv->flags & RADEON_IS_AGP) { 2071189499Srnoland /* XXX turn off pcie gart */ 2072189499Srnoland } else 2073189499Srnoland#endif 2074189499Srnoland { 2075189499Srnoland dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); 2076189499Srnoland /* if we have an offset set from userspace */ 2077189499Srnoland if (!dev_priv->pcigart_offset_set) { 2078189499Srnoland DRM_ERROR("Need gart offset from userspace\n"); 2079189499Srnoland r600_do_cleanup_cp(dev); 2080189499Srnoland return -EINVAL; 2081189499Srnoland } 2082189499Srnoland 2083189499Srnoland DRM_DEBUG("Using gart offset 0x%08lx\n", dev_priv->pcigart_offset); 2084189499Srnoland 2085189499Srnoland dev_priv->gart_info.bus_addr = 2086189499Srnoland dev_priv->pcigart_offset + dev_priv->fb_location; 2087189499Srnoland dev_priv->gart_info.mapping.offset = 2088189499Srnoland dev_priv->pcigart_offset + dev_priv->fb_aper_offset; 2089189499Srnoland dev_priv->gart_info.mapping.size = 2090189499Srnoland dev_priv->gart_info.table_size; 2091189499Srnoland 2092189499Srnoland drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); 2093189499Srnoland if (!dev_priv->gart_info.mapping.handle) { 2094189499Srnoland DRM_ERROR("ioremap failed.\n"); 2095189499Srnoland r600_do_cleanup_cp(dev); 2096189499Srnoland return -EINVAL; 2097189499Srnoland } 2098189499Srnoland 2099189499Srnoland dev_priv->gart_info.addr = 2100189499Srnoland dev_priv->gart_info.mapping.handle; 2101189499Srnoland 2102189499Srnoland DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", 2103189499Srnoland dev_priv->gart_info.addr, 2104189499Srnoland dev_priv->pcigart_offset); 2105189499Srnoland 2106189499Srnoland if (r600_page_table_init(dev)) { 2107189499Srnoland DRM_ERROR("Failed to init GART table\n"); 2108189499Srnoland r600_do_cleanup_cp(dev); 2109189499Srnoland return -EINVAL; 2110189499Srnoland } 2111189499Srnoland 2112189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) 2113189499Srnoland r700_vm_init(dev); 2114189499Srnoland else 2115189499Srnoland r600_vm_init(dev); 2116189499Srnoland } 2117189499Srnoland 2118189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) 2119189499Srnoland r700_cp_load_microcode(dev_priv); 2120189499Srnoland else 2121189499Srnoland r600_cp_load_microcode(dev_priv); 2122189499Srnoland 2123189499Srnoland r600_cp_init_ring_buffer(dev, dev_priv, file_priv); 2124189499Srnoland 2125189499Srnoland dev_priv->last_buf = 0; 2126189499Srnoland 2127189499Srnoland r600_do_engine_reset(dev); 2128189499Srnoland r600_test_writeback(dev_priv); 2129189499Srnoland 2130189499Srnoland return 0; 2131189499Srnoland} 2132189499Srnoland 2133189499Srnolandint r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) 2134189499Srnoland{ 2135189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 2136189499Srnoland 2137189499Srnoland DRM_DEBUG("\n"); 2138189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) { 2139189499Srnoland r700_vm_init(dev); 2140189499Srnoland r700_cp_load_microcode(dev_priv); 2141189499Srnoland } else { 2142189499Srnoland r600_vm_init(dev); 2143189499Srnoland r600_cp_load_microcode(dev_priv); 2144189499Srnoland } 2145189499Srnoland r600_cp_init_ring_buffer(dev, dev_priv, file_priv); 2146189499Srnoland r600_do_engine_reset(dev); 2147189499Srnoland 2148189499Srnoland return 0; 2149189499Srnoland} 2150189499Srnoland 2151189499Srnoland/* Wait for the CP to go idle. 2152189499Srnoland */ 2153189499Srnolandint r600_do_cp_idle(drm_radeon_private_t *dev_priv) 2154189499Srnoland{ 2155189499Srnoland RING_LOCALS; 2156189499Srnoland DRM_DEBUG("\n"); 2157189499Srnoland 2158189499Srnoland BEGIN_RING(5); 2159189499Srnoland OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); 2160189499Srnoland OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); 2161189499Srnoland /* wait for 3D idle clean */ 2162189499Srnoland OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); 2163189499Srnoland OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); 2164189499Srnoland OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); 2165189499Srnoland 2166189499Srnoland ADVANCE_RING(); 2167189499Srnoland COMMIT_RING(); 2168189499Srnoland 2169189499Srnoland return r600_do_wait_for_idle(dev_priv); 2170189499Srnoland} 2171189499Srnoland 2172189499Srnoland/* Start the Command Processor. 2173189499Srnoland */ 2174189499Srnolandvoid r600_do_cp_start(drm_radeon_private_t *dev_priv) 2175189499Srnoland{ 2176189499Srnoland u32 cp_me; 2177189499Srnoland RING_LOCALS; 2178189499Srnoland DRM_DEBUG("\n"); 2179189499Srnoland 2180189499Srnoland BEGIN_RING(7); 2181189499Srnoland OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5)); 2182189499Srnoland OUT_RING(0x00000001); 2183189499Srnoland if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) 2184189499Srnoland OUT_RING(0x00000003); 2185189499Srnoland else 2186189499Srnoland OUT_RING(0x00000000); 2187189499Srnoland OUT_RING((dev_priv->r600_max_hw_contexts - 1)); 2188189499Srnoland OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1)); 2189189499Srnoland OUT_RING(0x00000000); 2190189499Srnoland OUT_RING(0x00000000); 2191189499Srnoland ADVANCE_RING(); 2192189499Srnoland COMMIT_RING(); 2193189499Srnoland 2194189499Srnoland /* set the mux and reset the halt bit */ 2195189499Srnoland cp_me = 0xff; 2196189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, cp_me); 2197189499Srnoland 2198189499Srnoland dev_priv->cp_running = 1; 2199189499Srnoland 2200189499Srnoland} 2201189499Srnoland 2202189499Srnolandvoid r600_do_cp_reset(drm_radeon_private_t *dev_priv) 2203189499Srnoland{ 2204189499Srnoland u32 cur_read_ptr; 2205189499Srnoland DRM_DEBUG("\n"); 2206189499Srnoland 2207189499Srnoland cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR); 2208189499Srnoland RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr); 2209189499Srnoland SET_RING_HEAD(dev_priv, cur_read_ptr); 2210189499Srnoland dev_priv->ring.tail = cur_read_ptr; 2211189499Srnoland} 2212189499Srnoland 2213189499Srnolandvoid r600_do_cp_stop(drm_radeon_private_t *dev_priv) 2214189499Srnoland{ 2215189499Srnoland uint32_t cp_me; 2216189499Srnoland 2217189499Srnoland DRM_DEBUG("\n"); 2218189499Srnoland 2219189499Srnoland cp_me = 0xff | R600_CP_ME_HALT; 2220189499Srnoland 2221189499Srnoland RADEON_WRITE(R600_CP_ME_CNTL, cp_me); 2222189499Srnoland 2223189499Srnoland dev_priv->cp_running = 0; 2224189499Srnoland} 2225189499Srnoland 2226189499Srnolandint r600_cp_dispatch_indirect(struct drm_device *dev, 2227189499Srnoland struct drm_buf *buf, int start, int end) 2228189499Srnoland{ 2229189499Srnoland drm_radeon_private_t *dev_priv = dev->dev_private; 2230189499Srnoland RING_LOCALS; 2231189499Srnoland 2232189499Srnoland if (start != end) { 2233189499Srnoland unsigned long offset = (dev_priv->gart_buffers_offset 2234189499Srnoland + buf->offset + start); 2235189499Srnoland int dwords = (end - start + 3) / sizeof(u32); 2236189499Srnoland 2237189499Srnoland DRM_DEBUG("dwords:%d\n", dwords); 2238189499Srnoland DRM_DEBUG("offset 0x%lx\n", offset); 2239189499Srnoland 2240189499Srnoland 2241189499Srnoland /* Indirect buffer data must be a multiple of 16 dwords. 2242189499Srnoland * pad the data with a Type-2 CP packet. 2243189499Srnoland */ 2244189499Srnoland while (dwords & 0xf) { 2245189499Srnoland u32 *data = (u32 *) 2246189499Srnoland ((char *)dev->agp_buffer_map->handle 2247189499Srnoland + buf->offset + start); 2248189499Srnoland data[dwords++] = RADEON_CP_PACKET2; 2249189499Srnoland } 2250189499Srnoland 2251189499Srnoland /* Fire off the indirect buffer */ 2252189499Srnoland BEGIN_RING(4); 2253189499Srnoland OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2)); 2254189499Srnoland OUT_RING((offset & 0xfffffffc)); 2255189499Srnoland OUT_RING((upper_32_bits(offset) & 0xff)); 2256189499Srnoland OUT_RING(dwords); 2257189499Srnoland ADVANCE_RING(); 2258189499Srnoland } 2259189499Srnoland 2260189499Srnoland return 0; 2261189499Srnoland} 2262