root/drivers/gpu/drm/msm/adreno/a2xx_gpu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. a2xx_me_init
  2. a2xx_hw_init
  3. a2xx_recover
  4. a2xx_destroy
  5. a2xx_idle
  6. a2xx_irq
  7. a2xx_dump
  8. a2xx_gpu_state_get
  9. a2xx_gpu_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright (c) 2018 The Linux Foundation. All rights reserved. */
   3 
   4 #include "a2xx_gpu.h"
   5 #include "msm_gem.h"
   6 #include "msm_mmu.h"
   7 
   8 extern bool hang_debug;
   9 
  10 static void a2xx_dump(struct msm_gpu *gpu);
  11 static bool a2xx_idle(struct msm_gpu *gpu);
  12 
  13 static bool a2xx_me_init(struct msm_gpu *gpu)
  14 {
  15         struct msm_ringbuffer *ring = gpu->rb[0];
  16 
  17         OUT_PKT3(ring, CP_ME_INIT, 18);
  18 
  19         /* All fields present (bits 9:0) */
  20         OUT_RING(ring, 0x000003ff);
  21         /* Disable/Enable Real-Time Stream processing (present but ignored) */
  22         OUT_RING(ring, 0x00000000);
  23         /* Enable (2D <-> 3D) implicit synchronization (present but ignored) */
  24         OUT_RING(ring, 0x00000000);
  25 
  26         OUT_RING(ring, REG_A2XX_RB_SURFACE_INFO - 0x2000);
  27         OUT_RING(ring, REG_A2XX_PA_SC_WINDOW_OFFSET - 0x2000);
  28         OUT_RING(ring, REG_A2XX_VGT_MAX_VTX_INDX - 0x2000);
  29         OUT_RING(ring, REG_A2XX_SQ_PROGRAM_CNTL - 0x2000);
  30         OUT_RING(ring, REG_A2XX_RB_DEPTHCONTROL - 0x2000);
  31         OUT_RING(ring, REG_A2XX_PA_SU_POINT_SIZE - 0x2000);
  32         OUT_RING(ring, REG_A2XX_PA_SC_LINE_CNTL - 0x2000);
  33         OUT_RING(ring, REG_A2XX_PA_SU_POLY_OFFSET_FRONT_SCALE - 0x2000);
  34 
  35         /* Vertex and Pixel Shader Start Addresses in instructions
  36          * (3 DWORDS per instruction) */
  37         OUT_RING(ring, 0x80000180);
  38         /* Maximum Contexts */
  39         OUT_RING(ring, 0x00000001);
  40         /* Write Confirm Interval and The CP will wait the
  41          * wait_interval * 16 clocks between polling  */
  42         OUT_RING(ring, 0x00000000);
  43         /* NQ and External Memory Swap */
  44         OUT_RING(ring, 0x00000000);
  45         /* protected mode error checking (0x1f2 is REG_AXXX_CP_INT_CNTL) */
  46         OUT_RING(ring, 0x200001f2);
  47         /* Disable header dumping and Header dump address */
  48         OUT_RING(ring, 0x00000000);
  49         /* Header dump size */
  50         OUT_RING(ring, 0x00000000);
  51 
  52         /* enable protected mode */
  53         OUT_PKT3(ring, CP_SET_PROTECTED_MODE, 1);
  54         OUT_RING(ring, 1);
  55 
  56         gpu->funcs->flush(gpu, ring);
  57         return a2xx_idle(gpu);
  58 }
  59 
  60 static int a2xx_hw_init(struct msm_gpu *gpu)
  61 {
  62         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
  63         dma_addr_t pt_base, tran_error;
  64         uint32_t *ptr, len;
  65         int i, ret;
  66 
  67         msm_gpummu_params(gpu->aspace->mmu, &pt_base, &tran_error);
  68 
  69         DBG("%s", gpu->name);
  70 
  71         /* halt ME to avoid ucode upload issues on a20x */
  72         gpu_write(gpu, REG_AXXX_CP_ME_CNTL, AXXX_CP_ME_CNTL_HALT);
  73 
  74         gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE1, 0xfffffffe);
  75         gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE2, 0xffffffff);
  76 
  77         /* note: kgsl uses 0x00000001 after first reset on a22x */
  78         gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 0xffffffff);
  79         msleep(30);
  80         gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 0x00000000);
  81 
  82         if (adreno_is_a225(adreno_gpu))
  83                 gpu_write(gpu, REG_A2XX_SQ_FLOW_CONTROL, 0x18000000);
  84 
  85         /* note: kgsl uses 0x0000ffff for a20x */
  86         gpu_write(gpu, REG_A2XX_RBBM_CNTL, 0x00004442);
  87 
  88         /* MPU: physical range */
  89         gpu_write(gpu, REG_A2XX_MH_MMU_MPU_BASE, 0x00000000);
  90         gpu_write(gpu, REG_A2XX_MH_MMU_MPU_END, 0xfffff000);
  91 
  92         gpu_write(gpu, REG_A2XX_MH_MMU_CONFIG, A2XX_MH_MMU_CONFIG_MMU_ENABLE |
  93                 A2XX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
  94                 A2XX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
  95                 A2XX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
  96                 A2XX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
  97                 A2XX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
  98                 A2XX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
  99                 A2XX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
 100                 A2XX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
 101                 A2XX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
 102                 A2XX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
 103                 A2XX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(BEH_TRAN_RNG));
 104 
 105         /* same as parameters in adreno_gpu */
 106         gpu_write(gpu, REG_A2XX_MH_MMU_VA_RANGE, SZ_16M |
 107                 A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS(0xfff));
 108 
 109         gpu_write(gpu, REG_A2XX_MH_MMU_PT_BASE, pt_base);
 110         gpu_write(gpu, REG_A2XX_MH_MMU_TRAN_ERROR, tran_error);
 111 
 112         gpu_write(gpu, REG_A2XX_MH_MMU_INVALIDATE,
 113                 A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL |
 114                 A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC);
 115 
 116         gpu_write(gpu, REG_A2XX_MH_ARBITER_CONFIG,
 117                 A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT(16) |
 118                 A2XX_MH_ARBITER_CONFIG_L1_ARB_ENABLE |
 119                 A2XX_MH_ARBITER_CONFIG_L1_ARB_HOLD_ENABLE |
 120                 A2XX_MH_ARBITER_CONFIG_PAGE_SIZE(1) |
 121                 A2XX_MH_ARBITER_CONFIG_TC_REORDER_ENABLE |
 122                 A2XX_MH_ARBITER_CONFIG_TC_ARB_HOLD_ENABLE |
 123                 A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT_ENABLE |
 124                 A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT(8) |
 125                 A2XX_MH_ARBITER_CONFIG_CP_CLNT_ENABLE |
 126                 A2XX_MH_ARBITER_CONFIG_VGT_CLNT_ENABLE |
 127                 A2XX_MH_ARBITER_CONFIG_TC_CLNT_ENABLE |
 128                 A2XX_MH_ARBITER_CONFIG_RB_CLNT_ENABLE |
 129                 A2XX_MH_ARBITER_CONFIG_PA_CLNT_ENABLE);
 130         if (!adreno_is_a20x(adreno_gpu))
 131                 gpu_write(gpu, REG_A2XX_MH_CLNT_INTF_CTRL_CONFIG1, 0x00032f07);
 132 
 133         gpu_write(gpu, REG_A2XX_SQ_VS_PROGRAM, 0x00000000);
 134         gpu_write(gpu, REG_A2XX_SQ_PS_PROGRAM, 0x00000000);
 135 
 136         gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE1, 0); /* 0x200 for msm8960? */
 137         gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE2, 0); /* 0x80/0x1a0 for a22x? */
 138 
 139         /* note: gsl doesn't set this */
 140         gpu_write(gpu, REG_A2XX_RBBM_DEBUG, 0x00080000);
 141 
 142         gpu_write(gpu, REG_A2XX_RBBM_INT_CNTL,
 143                 A2XX_RBBM_INT_CNTL_RDERR_INT_MASK);
 144         gpu_write(gpu, REG_AXXX_CP_INT_CNTL,
 145                 AXXX_CP_INT_CNTL_T0_PACKET_IN_IB_MASK |
 146                 AXXX_CP_INT_CNTL_OPCODE_ERROR_MASK |
 147                 AXXX_CP_INT_CNTL_PROTECTED_MODE_ERROR_MASK |
 148                 AXXX_CP_INT_CNTL_RESERVED_BIT_ERROR_MASK |
 149                 AXXX_CP_INT_CNTL_IB_ERROR_MASK |
 150                 AXXX_CP_INT_CNTL_IB1_INT_MASK |
 151                 AXXX_CP_INT_CNTL_RB_INT_MASK);
 152         gpu_write(gpu, REG_A2XX_SQ_INT_CNTL, 0);
 153         gpu_write(gpu, REG_A2XX_MH_INTERRUPT_MASK,
 154                 A2XX_MH_INTERRUPT_MASK_AXI_READ_ERROR |
 155                 A2XX_MH_INTERRUPT_MASK_AXI_WRITE_ERROR |
 156                 A2XX_MH_INTERRUPT_MASK_MMU_PAGE_FAULT);
 157 
 158         for (i = 3; i <= 5; i++)
 159                 if ((SZ_16K << i) == adreno_gpu->gmem)
 160                         break;
 161         gpu_write(gpu, REG_A2XX_RB_EDRAM_INFO, i);
 162 
 163         ret = adreno_hw_init(gpu);
 164         if (ret)
 165                 return ret;
 166 
 167         /* NOTE: PM4/micro-engine firmware registers look to be the same
 168          * for a2xx and a3xx.. we could possibly push that part down to
 169          * adreno_gpu base class.  Or push both PM4 and PFP but
 170          * parameterize the pfp ucode addr/data registers..
 171          */
 172 
 173         /* Load PM4: */
 174         ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);
 175         len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
 176         DBG("loading PM4 ucode version: %x", ptr[1]);
 177 
 178         gpu_write(gpu, REG_AXXX_CP_DEBUG,
 179                         AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE);
 180         gpu_write(gpu, REG_AXXX_CP_ME_RAM_WADDR, 0);
 181         for (i = 1; i < len; i++)
 182                 gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]);
 183 
 184         /* Load PFP: */
 185         ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data);
 186         len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4;
 187         DBG("loading PFP ucode version: %x", ptr[5]);
 188 
 189         gpu_write(gpu, REG_A2XX_CP_PFP_UCODE_ADDR, 0);
 190         for (i = 1; i < len; i++)
 191                 gpu_write(gpu, REG_A2XX_CP_PFP_UCODE_DATA, ptr[i]);
 192 
 193         gpu_write(gpu, REG_AXXX_CP_QUEUE_THRESHOLDS, 0x000C0804);
 194 
 195         /* clear ME_HALT to start micro engine */
 196         gpu_write(gpu, REG_AXXX_CP_ME_CNTL, 0);
 197 
 198         return a2xx_me_init(gpu) ? 0 : -EINVAL;
 199 }
 200 
 201 static void a2xx_recover(struct msm_gpu *gpu)
 202 {
 203         int i;
 204 
 205         adreno_dump_info(gpu);
 206 
 207         for (i = 0; i < 8; i++) {
 208                 printk("CP_SCRATCH_REG%d: %u\n", i,
 209                         gpu_read(gpu, REG_AXXX_CP_SCRATCH_REG0 + i));
 210         }
 211 
 212         /* dump registers before resetting gpu, if enabled: */
 213         if (hang_debug)
 214                 a2xx_dump(gpu);
 215 
 216         gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 1);
 217         gpu_read(gpu, REG_A2XX_RBBM_SOFT_RESET);
 218         gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 0);
 219         adreno_recover(gpu);
 220 }
 221 
 222 static void a2xx_destroy(struct msm_gpu *gpu)
 223 {
 224         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 225         struct a2xx_gpu *a2xx_gpu = to_a2xx_gpu(adreno_gpu);
 226 
 227         DBG("%s", gpu->name);
 228 
 229         adreno_gpu_cleanup(adreno_gpu);
 230 
 231         kfree(a2xx_gpu);
 232 }
 233 
 234 static bool a2xx_idle(struct msm_gpu *gpu)
 235 {
 236         /* wait for ringbuffer to drain: */
 237         if (!adreno_idle(gpu, gpu->rb[0]))
 238                 return false;
 239 
 240         /* then wait for GPU to finish: */
 241         if (spin_until(!(gpu_read(gpu, REG_A2XX_RBBM_STATUS) &
 242                         A2XX_RBBM_STATUS_GUI_ACTIVE))) {
 243                 DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
 244 
 245                 /* TODO maybe we need to reset GPU here to recover from hang? */
 246                 return false;
 247         }
 248 
 249         return true;
 250 }
 251 
 252 static irqreturn_t a2xx_irq(struct msm_gpu *gpu)
 253 {
 254         uint32_t mstatus, status;
 255 
 256         mstatus = gpu_read(gpu, REG_A2XX_MASTER_INT_SIGNAL);
 257 
 258         if (mstatus & A2XX_MASTER_INT_SIGNAL_MH_INT_STAT) {
 259                 status = gpu_read(gpu, REG_A2XX_MH_INTERRUPT_STATUS);
 260 
 261                 dev_warn(gpu->dev->dev, "MH_INT: %08X\n", status);
 262                 dev_warn(gpu->dev->dev, "MMU_PAGE_FAULT: %08X\n",
 263                         gpu_read(gpu, REG_A2XX_MH_MMU_PAGE_FAULT));
 264 
 265                 gpu_write(gpu, REG_A2XX_MH_INTERRUPT_CLEAR, status);
 266         }
 267 
 268         if (mstatus & A2XX_MASTER_INT_SIGNAL_CP_INT_STAT) {
 269                 status = gpu_read(gpu, REG_AXXX_CP_INT_STATUS);
 270 
 271                 /* only RB_INT is expected */
 272                 if (status & ~AXXX_CP_INT_CNTL_RB_INT_MASK)
 273                         dev_warn(gpu->dev->dev, "CP_INT: %08X\n", status);
 274 
 275                 gpu_write(gpu, REG_AXXX_CP_INT_ACK, status);
 276         }
 277 
 278         if (mstatus & A2XX_MASTER_INT_SIGNAL_RBBM_INT_STAT) {
 279                 status = gpu_read(gpu, REG_A2XX_RBBM_INT_STATUS);
 280 
 281                 dev_warn(gpu->dev->dev, "RBBM_INT: %08X\n", status);
 282 
 283                 gpu_write(gpu, REG_A2XX_RBBM_INT_ACK, status);
 284         }
 285 
 286         msm_gpu_retire(gpu);
 287 
 288         return IRQ_HANDLED;
 289 }
 290 
 291 static const unsigned int a200_registers[] = {
 292         0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
 293         0x0046, 0x0047, 0x01C0, 0x01C1, 0x01C3, 0x01C8, 0x01D5, 0x01D9,
 294         0x01DC, 0x01DD, 0x01EA, 0x01EA, 0x01EE, 0x01F3, 0x01F6, 0x01F7,
 295         0x01FC, 0x01FF, 0x0391, 0x0392, 0x039B, 0x039E, 0x03B2, 0x03B5,
 296         0x03B7, 0x03B7, 0x03F8, 0x03FB, 0x0440, 0x0440, 0x0443, 0x0444,
 297         0x044B, 0x044B, 0x044D, 0x044F, 0x0452, 0x0452, 0x0454, 0x045B,
 298         0x047F, 0x047F, 0x0578, 0x0587, 0x05C9, 0x05C9, 0x05D0, 0x05D0,
 299         0x0601, 0x0604, 0x0606, 0x0609, 0x060B, 0x060E, 0x0613, 0x0614,
 300         0x0A29, 0x0A2B, 0x0A2F, 0x0A31, 0x0A40, 0x0A43, 0x0A45, 0x0A45,
 301         0x0A4E, 0x0A4F, 0x0C2C, 0x0C2C, 0x0C30, 0x0C30, 0x0C38, 0x0C3C,
 302         0x0C40, 0x0C40, 0x0C44, 0x0C44, 0x0C80, 0x0C86, 0x0C88, 0x0C94,
 303         0x0C99, 0x0C9A, 0x0CA4, 0x0CA5, 0x0D00, 0x0D03, 0x0D06, 0x0D06,
 304         0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, 0x0DC8, 0x0DD4,
 305         0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, 0x0E17, 0x0E1E,
 306         0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, 0x0ED4, 0x0ED7,
 307         0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x0F0C, 0x0F0C, 0x0F0E, 0x0F12,
 308         0x0F26, 0x0F2A, 0x0F2C, 0x0F2C, 0x2000, 0x2002, 0x2006, 0x200F,
 309         0x2080, 0x2082, 0x2100, 0x2109, 0x210C, 0x2114, 0x2180, 0x2184,
 310         0x21F5, 0x21F7, 0x2200, 0x2208, 0x2280, 0x2283, 0x2293, 0x2294,
 311         0x2300, 0x2308, 0x2312, 0x2312, 0x2316, 0x231D, 0x2324, 0x2326,
 312         0x2380, 0x2383, 0x2400, 0x2402, 0x2406, 0x240F, 0x2480, 0x2482,
 313         0x2500, 0x2509, 0x250C, 0x2514, 0x2580, 0x2584, 0x25F5, 0x25F7,
 314         0x2600, 0x2608, 0x2680, 0x2683, 0x2693, 0x2694, 0x2700, 0x2708,
 315         0x2712, 0x2712, 0x2716, 0x271D, 0x2724, 0x2726, 0x2780, 0x2783,
 316         0x4000, 0x4003, 0x4800, 0x4805, 0x4900, 0x4900, 0x4908, 0x4908,
 317         ~0   /* sentinel */
 318 };
 319 
 320 static const unsigned int a220_registers[] = {
 321         0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
 322         0x0046, 0x0047, 0x01C0, 0x01C1, 0x01C3, 0x01C8, 0x01D5, 0x01D9,
 323         0x01DC, 0x01DD, 0x01EA, 0x01EA, 0x01EE, 0x01F3, 0x01F6, 0x01F7,
 324         0x01FC, 0x01FF, 0x0391, 0x0392, 0x039B, 0x039E, 0x03B2, 0x03B5,
 325         0x03B7, 0x03B7, 0x03F8, 0x03FB, 0x0440, 0x0440, 0x0443, 0x0444,
 326         0x044B, 0x044B, 0x044D, 0x044F, 0x0452, 0x0452, 0x0454, 0x045B,
 327         0x047F, 0x047F, 0x0578, 0x0587, 0x05C9, 0x05C9, 0x05D0, 0x05D0,
 328         0x0601, 0x0604, 0x0606, 0x0609, 0x060B, 0x060E, 0x0613, 0x0614,
 329         0x0A29, 0x0A2B, 0x0A2F, 0x0A31, 0x0A40, 0x0A40, 0x0A42, 0x0A43,
 330         0x0A45, 0x0A45, 0x0A4E, 0x0A4F, 0x0C30, 0x0C30, 0x0C38, 0x0C39,
 331         0x0C3C, 0x0C3C, 0x0C80, 0x0C81, 0x0C88, 0x0C93, 0x0D00, 0x0D03,
 332         0x0D05, 0x0D06, 0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1,
 333         0x0DC8, 0x0DD4, 0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04,
 334         0x0E17, 0x0E1E, 0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0,
 335         0x0ED4, 0x0ED7, 0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x2000, 0x2002,
 336         0x2006, 0x200F, 0x2080, 0x2082, 0x2100, 0x2102, 0x2104, 0x2109,
 337         0x210C, 0x2114, 0x2180, 0x2184, 0x21F5, 0x21F7, 0x2200, 0x2202,
 338         0x2204, 0x2204, 0x2208, 0x2208, 0x2280, 0x2282, 0x2294, 0x2294,
 339         0x2300, 0x2308, 0x2309, 0x230A, 0x2312, 0x2312, 0x2316, 0x2316,
 340         0x2318, 0x231D, 0x2324, 0x2326, 0x2380, 0x2383, 0x2400, 0x2402,
 341         0x2406, 0x240F, 0x2480, 0x2482, 0x2500, 0x2502, 0x2504, 0x2509,
 342         0x250C, 0x2514, 0x2580, 0x2584, 0x25F5, 0x25F7, 0x2600, 0x2602,
 343         0x2604, 0x2606, 0x2608, 0x2608, 0x2680, 0x2682, 0x2694, 0x2694,
 344         0x2700, 0x2708, 0x2712, 0x2712, 0x2716, 0x2716, 0x2718, 0x271D,
 345         0x2724, 0x2726, 0x2780, 0x2783, 0x4000, 0x4003, 0x4800, 0x4805,
 346         0x4900, 0x4900, 0x4908, 0x4908,
 347         ~0   /* sentinel */
 348 };
 349 
 350 static const unsigned int a225_registers[] = {
 351         0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
 352         0x0046, 0x0047, 0x013C, 0x013C, 0x0140, 0x014F, 0x01C0, 0x01C1,
 353         0x01C3, 0x01C8, 0x01D5, 0x01D9, 0x01DC, 0x01DD, 0x01EA, 0x01EA,
 354         0x01EE, 0x01F3, 0x01F6, 0x01F7, 0x01FC, 0x01FF, 0x0391, 0x0392,
 355         0x039B, 0x039E, 0x03B2, 0x03B5, 0x03B7, 0x03B7, 0x03F8, 0x03FB,
 356         0x0440, 0x0440, 0x0443, 0x0444, 0x044B, 0x044B, 0x044D, 0x044F,
 357         0x0452, 0x0452, 0x0454, 0x045B, 0x047F, 0x047F, 0x0578, 0x0587,
 358         0x05C9, 0x05C9, 0x05D0, 0x05D0, 0x0601, 0x0604, 0x0606, 0x0609,
 359         0x060B, 0x060E, 0x0613, 0x0614, 0x0A29, 0x0A2B, 0x0A2F, 0x0A31,
 360         0x0A40, 0x0A40, 0x0A42, 0x0A43, 0x0A45, 0x0A45, 0x0A4E, 0x0A4F,
 361         0x0C01, 0x0C1D, 0x0C30, 0x0C30, 0x0C38, 0x0C39, 0x0C3C, 0x0C3C,
 362         0x0C80, 0x0C81, 0x0C88, 0x0C93, 0x0D00, 0x0D03, 0x0D05, 0x0D06,
 363         0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, 0x0DC8, 0x0DD4,
 364         0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, 0x0E17, 0x0E1E,
 365         0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, 0x0ED4, 0x0ED7,
 366         0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x2000, 0x200F, 0x2080, 0x2082,
 367         0x2100, 0x2109, 0x210C, 0x2114, 0x2180, 0x2184, 0x21F5, 0x21F7,
 368         0x2200, 0x2202, 0x2204, 0x2206, 0x2208, 0x2210, 0x2220, 0x2222,
 369         0x2280, 0x2282, 0x2294, 0x2294, 0x2297, 0x2297, 0x2300, 0x230A,
 370         0x2312, 0x2312, 0x2315, 0x2316, 0x2318, 0x231D, 0x2324, 0x2326,
 371         0x2340, 0x2357, 0x2360, 0x2360, 0x2380, 0x2383, 0x2400, 0x240F,
 372         0x2480, 0x2482, 0x2500, 0x2509, 0x250C, 0x2514, 0x2580, 0x2584,
 373         0x25F5, 0x25F7, 0x2600, 0x2602, 0x2604, 0x2606, 0x2608, 0x2610,
 374         0x2620, 0x2622, 0x2680, 0x2682, 0x2694, 0x2694, 0x2697, 0x2697,
 375         0x2700, 0x270A, 0x2712, 0x2712, 0x2715, 0x2716, 0x2718, 0x271D,
 376         0x2724, 0x2726, 0x2740, 0x2757, 0x2760, 0x2760, 0x2780, 0x2783,
 377         0x4000, 0x4003, 0x4800, 0x4806, 0x4808, 0x4808, 0x4900, 0x4900,
 378         0x4908, 0x4908,
 379         ~0   /* sentinel */
 380 };
 381 
 382 /* would be nice to not have to duplicate the _show() stuff with printk(): */
 383 static void a2xx_dump(struct msm_gpu *gpu)
 384 {
 385         printk("status:   %08x\n",
 386                         gpu_read(gpu, REG_A2XX_RBBM_STATUS));
 387         adreno_dump(gpu);
 388 }
 389 
 390 static struct msm_gpu_state *a2xx_gpu_state_get(struct msm_gpu *gpu)
 391 {
 392         struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
 393 
 394         if (!state)
 395                 return ERR_PTR(-ENOMEM);
 396 
 397         adreno_gpu_state_get(gpu, state);
 398 
 399         state->rbbm_status = gpu_read(gpu, REG_A2XX_RBBM_STATUS);
 400 
 401         return state;
 402 }
 403 
 404 /* Register offset defines for A2XX - copy of A3XX */
 405 static const unsigned int a2xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
 406         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE),
 407         REG_ADRENO_SKIP(REG_ADRENO_CP_RB_BASE_HI),
 408         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_AXXX_CP_RB_RPTR_ADDR),
 409         REG_ADRENO_SKIP(REG_ADRENO_CP_RB_RPTR_ADDR_HI),
 410         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_AXXX_CP_RB_RPTR),
 411         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_AXXX_CP_RB_WPTR),
 412         REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_AXXX_CP_RB_CNTL),
 413 };
 414 
 415 static const struct adreno_gpu_funcs funcs = {
 416         .base = {
 417                 .get_param = adreno_get_param,
 418                 .hw_init = a2xx_hw_init,
 419                 .pm_suspend = msm_gpu_pm_suspend,
 420                 .pm_resume = msm_gpu_pm_resume,
 421                 .recover = a2xx_recover,
 422                 .submit = adreno_submit,
 423                 .flush = adreno_flush,
 424                 .active_ring = adreno_active_ring,
 425                 .irq = a2xx_irq,
 426                 .destroy = a2xx_destroy,
 427 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
 428                 .show = adreno_show,
 429 #endif
 430                 .gpu_state_get = a2xx_gpu_state_get,
 431                 .gpu_state_put = adreno_gpu_state_put,
 432         },
 433 };
 434 
 435 static const struct msm_gpu_perfcntr perfcntrs[] = {
 436 /* TODO */
 437 };
 438 
 439 struct msm_gpu *a2xx_gpu_init(struct drm_device *dev)
 440 {
 441         struct a2xx_gpu *a2xx_gpu = NULL;
 442         struct adreno_gpu *adreno_gpu;
 443         struct msm_gpu *gpu;
 444         struct msm_drm_private *priv = dev->dev_private;
 445         struct platform_device *pdev = priv->gpu_pdev;
 446         int ret;
 447 
 448         if (!pdev) {
 449                 dev_err(dev->dev, "no a2xx device\n");
 450                 ret = -ENXIO;
 451                 goto fail;
 452         }
 453 
 454         a2xx_gpu = kzalloc(sizeof(*a2xx_gpu), GFP_KERNEL);
 455         if (!a2xx_gpu) {
 456                 ret = -ENOMEM;
 457                 goto fail;
 458         }
 459 
 460         adreno_gpu = &a2xx_gpu->base;
 461         gpu = &adreno_gpu->base;
 462 
 463         gpu->perfcntrs = perfcntrs;
 464         gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
 465 
 466         if (adreno_is_a20x(adreno_gpu))
 467                 adreno_gpu->registers = a200_registers;
 468         else if (adreno_is_a225(adreno_gpu))
 469                 adreno_gpu->registers = a225_registers;
 470         else
 471                 adreno_gpu->registers = a220_registers;
 472 
 473         adreno_gpu->reg_offsets = a2xx_register_offsets;
 474 
 475         ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
 476         if (ret)
 477                 goto fail;
 478 
 479         if (!gpu->aspace) {
 480                 dev_err(dev->dev, "No memory protection without MMU\n");
 481                 ret = -ENXIO;
 482                 goto fail;
 483         }
 484 
 485         return gpu;
 486 
 487 fail:
 488         if (a2xx_gpu)
 489                 a2xx_destroy(&a2xx_gpu->base.base);
 490 
 491         return ERR_PTR(ret);
 492 }

/* [<][>][^][v][top][bottom][index][help] */