0001
0002
0003
0004
0005 #include "msm_gem.h"
0006 #include "msm_mmu.h"
0007 #include "msm_gpu_trace.h"
0008 #include "a6xx_gpu.h"
0009 #include "a6xx_gmu.xml.h"
0010
0011 #include <linux/bitfield.h>
0012 #include <linux/devfreq.h>
0013 #include <linux/soc/qcom/llcc-qcom.h>
0014
0015 #define GPU_PAS_ID 13
0016
0017 static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
0018 {
0019 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
0020 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
0021
0022
0023 if (!a6xx_gmu_isidle(&a6xx_gpu->gmu))
0024 return false;
0025
0026
0027 if (gpu_read(gpu, REG_A6XX_RBBM_STATUS) &
0028 ~A6XX_RBBM_STATUS_CP_AHB_BUSY_CX_MASTER)
0029 return false;
0030
0031 return !(gpu_read(gpu, REG_A6XX_RBBM_INT_0_STATUS) &
0032 A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT);
0033 }
0034
0035 static bool a6xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
0036 {
0037
0038 if (!adreno_idle(gpu, ring))
0039 return false;
0040
0041 if (spin_until(_a6xx_check_idle(gpu))) {
0042 DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X rptr/wptr %d/%d\n",
0043 gpu->name, __builtin_return_address(0),
0044 gpu_read(gpu, REG_A6XX_RBBM_STATUS),
0045 gpu_read(gpu, REG_A6XX_RBBM_INT_0_STATUS),
0046 gpu_read(gpu, REG_A6XX_CP_RB_RPTR),
0047 gpu_read(gpu, REG_A6XX_CP_RB_WPTR));
0048 return false;
0049 }
0050
0051 return true;
0052 }
0053
0054 static void update_shadow_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
0055 {
0056 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
0057 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
0058
0059
0060 if (a6xx_gpu->has_whereami && !adreno_gpu->base.hw_apriv) {
0061 OUT_PKT7(ring, CP_WHERE_AM_I, 2);
0062 OUT_RING(ring, lower_32_bits(shadowptr(a6xx_gpu, ring)));
0063 OUT_RING(ring, upper_32_bits(shadowptr(a6xx_gpu, ring)));
0064 }
0065 }
0066
0067 static void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
0068 {
0069 uint32_t wptr;
0070 unsigned long flags;
0071
0072 update_shadow_rptr(gpu, ring);
0073
0074 spin_lock_irqsave(&ring->preempt_lock, flags);
0075
0076
0077 ring->cur = ring->next;
0078
0079
0080 wptr = get_wptr(ring);
0081
0082 spin_unlock_irqrestore(&ring->preempt_lock, flags);
0083
0084
0085 mb();
0086
0087 gpu_write(gpu, REG_A6XX_CP_RB_WPTR, wptr);
0088 }
0089
0090 static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter,
0091 u64 iova)
0092 {
0093 OUT_PKT7(ring, CP_REG_TO_MEM, 3);
0094 OUT_RING(ring, CP_REG_TO_MEM_0_REG(counter) |
0095 CP_REG_TO_MEM_0_CNT(2) |
0096 CP_REG_TO_MEM_0_64B);
0097 OUT_RING(ring, lower_32_bits(iova));
0098 OUT_RING(ring, upper_32_bits(iova));
0099 }
0100
0101 static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
0102 struct msm_ringbuffer *ring, struct msm_file_private *ctx)
0103 {
0104 bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
0105 phys_addr_t ttbr;
0106 u32 asid;
0107 u64 memptr = rbmemptr(ring, ttbr0);
0108
0109 if (ctx->seqno == a6xx_gpu->base.base.cur_ctx_seqno)
0110 return;
0111
0112 if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
0113 return;
0114
0115 if (!sysprof) {
0116
0117 OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
0118 OUT_RING(ring, 0);
0119
0120 OUT_PKT4(ring, REG_A6XX_RBBM_PERFCTR_SRAM_INIT_CMD, 1);
0121 OUT_RING(ring, 1);
0122 }
0123
0124
0125 OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 4);
0126 OUT_RING(ring, CP_SMMU_TABLE_UPDATE_0_TTBR0_LO(lower_32_bits(ttbr)));
0127
0128 OUT_RING(ring,
0129 CP_SMMU_TABLE_UPDATE_1_TTBR0_HI(upper_32_bits(ttbr)) |
0130 CP_SMMU_TABLE_UPDATE_1_ASID(asid));
0131 OUT_RING(ring, CP_SMMU_TABLE_UPDATE_2_CONTEXTIDR(0));
0132 OUT_RING(ring, CP_SMMU_TABLE_UPDATE_3_CONTEXTBANK(0));
0133
0134
0135
0136
0137 OUT_PKT7(ring, CP_MEM_WRITE, 4);
0138 OUT_RING(ring, CP_MEM_WRITE_0_ADDR_LO(lower_32_bits(memptr)));
0139 OUT_RING(ring, CP_MEM_WRITE_1_ADDR_HI(upper_32_bits(memptr)));
0140 OUT_RING(ring, lower_32_bits(ttbr));
0141 OUT_RING(ring, (asid << 16) | upper_32_bits(ttbr));
0142
0143
0144
0145
0146
0147
0148 OUT_PKT7(ring, CP_EVENT_WRITE, 1);
0149 OUT_RING(ring, 0x31);
0150
0151 if (!sysprof) {
0152
0153
0154
0155
0156 OUT_PKT7(ring, CP_WAIT_REG_MEM, 6);
0157 OUT_RING(ring, CP_WAIT_REG_MEM_0_FUNCTION(WRITE_EQ));
0158 OUT_RING(ring, CP_WAIT_REG_MEM_1_POLL_ADDR_LO(
0159 REG_A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS));
0160 OUT_RING(ring, CP_WAIT_REG_MEM_2_POLL_ADDR_HI(0));
0161 OUT_RING(ring, CP_WAIT_REG_MEM_3_REF(0x1));
0162 OUT_RING(ring, CP_WAIT_REG_MEM_4_MASK(0x1));
0163 OUT_RING(ring, CP_WAIT_REG_MEM_5_DELAY_LOOP_CYCLES(0));
0164
0165
0166 OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
0167 OUT_RING(ring, 1);
0168 }
0169 }
0170
0171 static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
0172 {
0173 unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
0174 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
0175 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
0176 struct msm_ringbuffer *ring = submit->ring;
0177 unsigned int i, ibs = 0;
0178
0179 a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
0180
0181 get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
0182 rbmemptr_stats(ring, index, cpcycles_start));
0183
0184
0185
0186
0187
0188
0189 get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
0190 rbmemptr_stats(ring, index, alwayson_start));
0191
0192
0193 OUT_PKT7(ring, CP_EVENT_WRITE, 1);
0194 OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(PC_CCU_INVALIDATE_DEPTH));
0195
0196 OUT_PKT7(ring, CP_EVENT_WRITE, 1);
0197 OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(PC_CCU_INVALIDATE_COLOR));
0198
0199
0200 for (i = 0; i < submit->nr_cmds; i++) {
0201 switch (submit->cmd[i].type) {
0202 case MSM_SUBMIT_CMD_IB_TARGET_BUF:
0203 break;
0204 case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
0205 if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
0206 break;
0207 fallthrough;
0208 case MSM_SUBMIT_CMD_BUF:
0209 OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
0210 OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
0211 OUT_RING(ring, upper_32_bits(submit->cmd[i].iova));
0212 OUT_RING(ring, submit->cmd[i].size);
0213 ibs++;
0214 break;
0215 }
0216
0217
0218
0219
0220
0221
0222
0223
0224 if ((ibs % 32) == 0)
0225 update_shadow_rptr(gpu, ring);
0226 }
0227
0228 get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
0229 rbmemptr_stats(ring, index, cpcycles_end));
0230 get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
0231 rbmemptr_stats(ring, index, alwayson_end));
0232
0233
0234 OUT_PKT4(ring, REG_A6XX_CP_SCRATCH_REG(2), 1);
0235 OUT_RING(ring, submit->seqno);
0236
0237
0238
0239
0240
0241 OUT_PKT7(ring, CP_EVENT_WRITE, 4);
0242 OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(CACHE_FLUSH_TS) |
0243 CP_EVENT_WRITE_0_IRQ);
0244 OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
0245 OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
0246 OUT_RING(ring, submit->seqno);
0247
0248 trace_msm_gpu_submit_flush(submit,
0249 gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
0250 REG_A6XX_CP_ALWAYS_ON_COUNTER_HI));
0251
0252 a6xx_flush(gpu, ring);
0253 }
0254
0255
0256 const struct adreno_reglist a615_hwcg[] = {
0257 {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
0258 {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
0259 {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
0260 {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
0261 {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
0262 {REG_A6XX_RBBM_CLOCK_CNTL_TP1, 0x02222222},
0263 {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
0264 {REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
0265 {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
0266 {REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x22222222},
0267 {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
0268 {REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x00022222},
0269 {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
0270 {REG_A6XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
0271 {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
0272 {REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
0273 {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
0274 {REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x77777777},
0275 {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
0276 {REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x00077777},
0277 {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
0278 {REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
0279 {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
0280 {REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
0281 {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
0282 {REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x11111111},
0283 {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
0284 {REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x00011111},
0285 {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
0286 {REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
0287 {REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
0288 {REG_A6XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
0289 {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
0290 {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
0291 {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
0292 {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x00002222},
0293 {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002020},
0294 {REG_A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220},
0295 {REG_A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220},
0296 {REG_A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220},
0297 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
0298 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040F00},
0299 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040F00},
0300 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040F00},
0301 {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022},
0302 {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
0303 {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
0304 {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
0305 {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
0306 {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
0307 {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
0308 {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
0309 {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
0310 {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
0311 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
0312 {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
0313 {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
0314 {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
0315 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
0316 {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
0317 {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
0318 {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
0319 {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
0320 {},
0321 };
0322
0323 const struct adreno_reglist a630_hwcg[] = {
0324 {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
0325 {REG_A6XX_RBBM_CLOCK_CNTL_SP1, 0x22222222},
0326 {REG_A6XX_RBBM_CLOCK_CNTL_SP2, 0x22222222},
0327 {REG_A6XX_RBBM_CLOCK_CNTL_SP3, 0x22222222},
0328 {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022220},
0329 {REG_A6XX_RBBM_CLOCK_CNTL2_SP1, 0x02022220},
0330 {REG_A6XX_RBBM_CLOCK_CNTL2_SP2, 0x02022220},
0331 {REG_A6XX_RBBM_CLOCK_CNTL2_SP3, 0x02022220},
0332 {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
0333 {REG_A6XX_RBBM_CLOCK_DELAY_SP1, 0x00000080},
0334 {REG_A6XX_RBBM_CLOCK_DELAY_SP2, 0x00000080},
0335 {REG_A6XX_RBBM_CLOCK_DELAY_SP3, 0x00000080},
0336 {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf},
0337 {REG_A6XX_RBBM_CLOCK_HYST_SP1, 0x0000f3cf},
0338 {REG_A6XX_RBBM_CLOCK_HYST_SP2, 0x0000f3cf},
0339 {REG_A6XX_RBBM_CLOCK_HYST_SP3, 0x0000f3cf},
0340 {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
0341 {REG_A6XX_RBBM_CLOCK_CNTL_TP1, 0x02222222},
0342 {REG_A6XX_RBBM_CLOCK_CNTL_TP2, 0x02222222},
0343 {REG_A6XX_RBBM_CLOCK_CNTL_TP3, 0x02222222},
0344 {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
0345 {REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
0346 {REG_A6XX_RBBM_CLOCK_CNTL2_TP2, 0x22222222},
0347 {REG_A6XX_RBBM_CLOCK_CNTL2_TP3, 0x22222222},
0348 {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
0349 {REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x22222222},
0350 {REG_A6XX_RBBM_CLOCK_CNTL3_TP2, 0x22222222},
0351 {REG_A6XX_RBBM_CLOCK_CNTL3_TP3, 0x22222222},
0352 {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
0353 {REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x00022222},
0354 {REG_A6XX_RBBM_CLOCK_CNTL4_TP2, 0x00022222},
0355 {REG_A6XX_RBBM_CLOCK_CNTL4_TP3, 0x00022222},
0356 {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
0357 {REG_A6XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
0358 {REG_A6XX_RBBM_CLOCK_HYST_TP2, 0x77777777},
0359 {REG_A6XX_RBBM_CLOCK_HYST_TP3, 0x77777777},
0360 {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
0361 {REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
0362 {REG_A6XX_RBBM_CLOCK_HYST2_TP2, 0x77777777},
0363 {REG_A6XX_RBBM_CLOCK_HYST2_TP3, 0x77777777},
0364 {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
0365 {REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x77777777},
0366 {REG_A6XX_RBBM_CLOCK_HYST3_TP2, 0x77777777},
0367 {REG_A6XX_RBBM_CLOCK_HYST3_TP3, 0x77777777},
0368 {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
0369 {REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x00077777},
0370 {REG_A6XX_RBBM_CLOCK_HYST4_TP2, 0x00077777},
0371 {REG_A6XX_RBBM_CLOCK_HYST4_TP3, 0x00077777},
0372 {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
0373 {REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
0374 {REG_A6XX_RBBM_CLOCK_DELAY_TP2, 0x11111111},
0375 {REG_A6XX_RBBM_CLOCK_DELAY_TP3, 0x11111111},
0376 {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
0377 {REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
0378 {REG_A6XX_RBBM_CLOCK_DELAY2_TP2, 0x11111111},
0379 {REG_A6XX_RBBM_CLOCK_DELAY2_TP3, 0x11111111},
0380 {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
0381 {REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x11111111},
0382 {REG_A6XX_RBBM_CLOCK_DELAY3_TP2, 0x11111111},
0383 {REG_A6XX_RBBM_CLOCK_DELAY3_TP3, 0x11111111},
0384 {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
0385 {REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x00011111},
0386 {REG_A6XX_RBBM_CLOCK_DELAY4_TP2, 0x00011111},
0387 {REG_A6XX_RBBM_CLOCK_DELAY4_TP3, 0x00011111},
0388 {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
0389 {REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
0390 {REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
0391 {REG_A6XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
0392 {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
0393 {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
0394 {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
0395 {REG_A6XX_RBBM_CLOCK_CNTL_RB1, 0x22222222},
0396 {REG_A6XX_RBBM_CLOCK_CNTL_RB2, 0x22222222},
0397 {REG_A6XX_RBBM_CLOCK_CNTL_RB3, 0x22222222},
0398 {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x00002222},
0399 {REG_A6XX_RBBM_CLOCK_CNTL2_RB1, 0x00002222},
0400 {REG_A6XX_RBBM_CLOCK_CNTL2_RB2, 0x00002222},
0401 {REG_A6XX_RBBM_CLOCK_CNTL2_RB3, 0x00002222},
0402 {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
0403 {REG_A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220},
0404 {REG_A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220},
0405 {REG_A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220},
0406 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00},
0407 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040f00},
0408 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040f00},
0409 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040f00},
0410 {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022},
0411 {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
0412 {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
0413 {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
0414 {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
0415 {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
0416 {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
0417 {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
0418 {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
0419 {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
0420 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
0421 {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
0422 {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
0423 {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
0424 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
0425 {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
0426 {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
0427 {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
0428 {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
0429 {},
0430 };
0431
0432 const struct adreno_reglist a640_hwcg[] = {
0433 {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
0434 {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
0435 {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
0436 {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
0437 {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
0438 {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
0439 {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
0440 {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
0441 {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
0442 {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
0443 {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
0444 {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
0445 {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
0446 {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
0447 {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
0448 {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
0449 {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
0450 {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
0451 {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
0452 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
0453 {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05222022},
0454 {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
0455 {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
0456 {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
0457 {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
0458 {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
0459 {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
0460 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
0461 {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
0462 {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
0463 {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
0464 {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
0465 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
0466 {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
0467 {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
0468 {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
0469 {REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
0470 {REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
0471 {REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
0472 {REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
0473 {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
0474 {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
0475 {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
0476 {REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
0477 {REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
0478 {REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
0479 {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
0480 {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
0481 {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
0482 {},
0483 };
0484
0485 const struct adreno_reglist a650_hwcg[] = {
0486 {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
0487 {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
0488 {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
0489 {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
0490 {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
0491 {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
0492 {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
0493 {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
0494 {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
0495 {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
0496 {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
0497 {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
0498 {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
0499 {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
0500 {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
0501 {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
0502 {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
0503 {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
0504 {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
0505 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
0506 {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
0507 {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
0508 {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
0509 {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
0510 {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
0511 {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
0512 {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
0513 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
0514 {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
0515 {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
0516 {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
0517 {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
0518 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
0519 {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
0520 {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
0521 {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
0522 {REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
0523 {REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
0524 {REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
0525 {REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000777},
0526 {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
0527 {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
0528 {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
0529 {REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
0530 {REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
0531 {REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
0532 {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
0533 {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
0534 {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
0535 {},
0536 };
0537
0538 const struct adreno_reglist a660_hwcg[] = {
0539 {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
0540 {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
0541 {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
0542 {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
0543 {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
0544 {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
0545 {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
0546 {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
0547 {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
0548 {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
0549 {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
0550 {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
0551 {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
0552 {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
0553 {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
0554 {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
0555 {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
0556 {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
0557 {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
0558 {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
0559 {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
0560 {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
0561 {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
0562 {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
0563 {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
0564 {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
0565 {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
0566 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
0567 {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
0568 {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
0569 {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
0570 {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
0571 {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
0572 {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
0573 {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
0574 {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
0575 {REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
0576 {REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
0577 {REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
0578 {REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
0579 {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
0580 {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
0581 {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
0582 {REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
0583 {REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
0584 {REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
0585 {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
0586 {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
0587 {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
0588 {},
0589 };
0590
0591 static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
0592 {
0593 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
0594 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
0595 struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
0596 const struct adreno_reglist *reg;
0597 unsigned int i;
0598 u32 val, clock_cntl_on;
0599
0600 if (!adreno_gpu->info->hwcg)
0601 return;
0602
0603 if (adreno_is_a630(adreno_gpu))
0604 clock_cntl_on = 0x8aa8aa02;
0605 else
0606 clock_cntl_on = 0x8aa8aa82;
0607
0608 val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
0609
0610
0611 if ((!state && !val) || (state && (val == clock_cntl_on)))
0612 return;
0613
0614
0615 gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0);
0616
0617 for (i = 0; (reg = &adreno_gpu->info->hwcg[i], reg->offset); i++)
0618 gpu_write(gpu, reg->offset, state ? reg->value : 0);
0619
0620
0621 gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1);
0622
0623 gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0);
0624 }
0625
0626
0627 static const u32 a6xx_protect[] = {
0628 A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
0629 A6XX_PROTECT_RDONLY(0x00501, 0x0005),
0630 A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
0631 A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
0632 A6XX_PROTECT_NORDWR(0x00510, 0x0000),
0633 A6XX_PROTECT_NORDWR(0x00534, 0x0000),
0634 A6XX_PROTECT_NORDWR(0x00800, 0x0082),
0635 A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
0636 A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
0637 A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
0638 A6XX_PROTECT_NORDWR(0x00900, 0x004d),
0639 A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
0640 A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
0641 A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
0642 A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
0643 A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
0644 A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
0645 A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
0646 A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
0647 A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
0648 A6XX_PROTECT_NORDWR(0x09624, 0x01db),
0649 A6XX_PROTECT_NORDWR(0x09e70, 0x0001),
0650 A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
0651 A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
0652 A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
0653 A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
0654 A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
0655 A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
0656 A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
0657 A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
0658 A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
0659 A6XX_PROTECT_NORDWR(0x11c00, 0x0000),
0660 };
0661
0662
0663 static const u32 a650_protect[] = {
0664 A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
0665 A6XX_PROTECT_RDONLY(0x00501, 0x0005),
0666 A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
0667 A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
0668 A6XX_PROTECT_NORDWR(0x00510, 0x0000),
0669 A6XX_PROTECT_NORDWR(0x00534, 0x0000),
0670 A6XX_PROTECT_NORDWR(0x00800, 0x0082),
0671 A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
0672 A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
0673 A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
0674 A6XX_PROTECT_NORDWR(0x00900, 0x004d),
0675 A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
0676 A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
0677 A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
0678 A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
0679 A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
0680 A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
0681 A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
0682 A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
0683 A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
0684 A6XX_PROTECT_NORDWR(0x08e80, 0x027f),
0685 A6XX_PROTECT_NORDWR(0x09624, 0x01db),
0686 A6XX_PROTECT_NORDWR(0x09e60, 0x0011),
0687 A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
0688 A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
0689 A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
0690 A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
0691 A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
0692 A6XX_PROTECT_NORDWR(0x0b608, 0x0007),
0693 A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
0694 A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
0695 A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
0696 A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
0697 A6XX_PROTECT_NORDWR(0x18400, 0x1fff),
0698 A6XX_PROTECT_NORDWR(0x1a800, 0x1fff),
0699 A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
0700 A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
0701 A6XX_PROTECT_NORDWR(0x1f887, 0x001b),
0702 A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000),
0703 };
0704
0705
0706 static const u32 a660_protect[] = {
0707 A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
0708 A6XX_PROTECT_RDONLY(0x00501, 0x0005),
0709 A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
0710 A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
0711 A6XX_PROTECT_NORDWR(0x00510, 0x0000),
0712 A6XX_PROTECT_NORDWR(0x00534, 0x0000),
0713 A6XX_PROTECT_NORDWR(0x00800, 0x0082),
0714 A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
0715 A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
0716 A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
0717 A6XX_PROTECT_NORDWR(0x00900, 0x004d),
0718 A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
0719 A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
0720 A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
0721 A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
0722 A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
0723 A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
0724 A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
0725 A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
0726 A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
0727 A6XX_PROTECT_NORDWR(0x08e80, 0x027f),
0728 A6XX_PROTECT_NORDWR(0x09624, 0x01db),
0729 A6XX_PROTECT_NORDWR(0x09e60, 0x0011),
0730 A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
0731 A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
0732 A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
0733 A6XX_PROTECT_NORDWR(0x0ae50, 0x012f),
0734 A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
0735 A6XX_PROTECT_NORDWR(0x0b608, 0x0006),
0736 A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
0737 A6XX_PROTECT_NORDWR(0x0be20, 0x015f),
0738 A6XX_PROTECT_NORDWR(0x0d000, 0x05ff),
0739 A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
0740 A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
0741 A6XX_PROTECT_NORDWR(0x18400, 0x1fff),
0742 A6XX_PROTECT_NORDWR(0x1a400, 0x1fff),
0743 A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
0744 A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
0745 A6XX_PROTECT_NORDWR(0x1f860, 0x0000),
0746 A6XX_PROTECT_NORDWR(0x1f887, 0x001b),
0747 A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000),
0748 };
0749
0750 static void a6xx_set_cp_protect(struct msm_gpu *gpu)
0751 {
0752 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
0753 const u32 *regs = a6xx_protect;
0754 unsigned i, count, count_max;
0755
0756 if (adreno_is_a650(adreno_gpu)) {
0757 regs = a650_protect;
0758 count = ARRAY_SIZE(a650_protect);
0759 count_max = 48;
0760 BUILD_BUG_ON(ARRAY_SIZE(a650_protect) > 48);
0761 } else if (adreno_is_a660_family(adreno_gpu)) {
0762 regs = a660_protect;
0763 count = ARRAY_SIZE(a660_protect);
0764 count_max = 48;
0765 BUILD_BUG_ON(ARRAY_SIZE(a660_protect) > 48);
0766 } else {
0767 regs = a6xx_protect;
0768 count = ARRAY_SIZE(a6xx_protect);
0769 count_max = 32;
0770 BUILD_BUG_ON(ARRAY_SIZE(a6xx_protect) > 32);
0771 }
0772
0773
0774
0775
0776
0777
0778 gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, BIT(0) | BIT(1) | BIT(3));
0779
0780 for (i = 0; i < count - 1; i++)
0781 gpu_write(gpu, REG_A6XX_CP_PROTECT(i), regs[i]);
0782
0783 gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]);
0784 }
0785
0786 static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
0787 {
0788 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
0789 u32 lower_bit = 2;
0790 u32 amsbc = 0;
0791 u32 rgb565_predicator = 0;
0792 u32 uavflagprd_inv = 0;
0793
0794
0795 if (adreno_is_a618(adreno_gpu))
0796 return;
0797
0798 if (adreno_is_a640_family(adreno_gpu))
0799 amsbc = 1;
0800
0801 if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) {
0802
0803 lower_bit = 3;
0804 amsbc = 1;
0805 rgb565_predicator = 1;
0806 uavflagprd_inv = 2;
0807 }
0808
0809 if (adreno_is_7c3(adreno_gpu)) {
0810 lower_bit = 1;
0811 amsbc = 1;
0812 rgb565_predicator = 1;
0813 uavflagprd_inv = 2;
0814 }
0815
0816 gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL,
0817 rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1);
0818 gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1);
0819 gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL,
0820 uavflagprd_inv << 4 | lower_bit << 1);
0821 gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, lower_bit << 21);
0822 }
0823
0824 static int a6xx_cp_init(struct msm_gpu *gpu)
0825 {
0826 struct msm_ringbuffer *ring = gpu->rb[0];
0827
0828 OUT_PKT7(ring, CP_ME_INIT, 8);
0829
0830 OUT_RING(ring, 0x0000002f);
0831
0832
0833 OUT_RING(ring, 0x00000003);
0834
0835
0836 OUT_RING(ring, 0x20000000);
0837
0838
0839 OUT_RING(ring, 0x00000000);
0840 OUT_RING(ring, 0x00000000);
0841
0842
0843 OUT_RING(ring, 0x00000000);
0844
0845
0846 OUT_RING(ring, 0x00000000);
0847 OUT_RING(ring, 0x00000000);
0848
0849 a6xx_flush(gpu, ring);
0850 return a6xx_idle(gpu, ring) ? 0 : -EINVAL;
0851 }
0852
0853
0854
0855
0856
0857 static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
0858 struct drm_gem_object *obj)
0859 {
0860 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
0861 struct msm_gpu *gpu = &adreno_gpu->base;
0862 const char *sqe_name = adreno_gpu->info->fw[ADRENO_FW_SQE];
0863 u32 *buf = msm_gem_get_vaddr(obj);
0864 bool ret = false;
0865
0866 if (IS_ERR(buf))
0867 return false;
0868
0869
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879 if (!strcmp(sqe_name, "a630_sqe.fw")) {
0880
0881
0882
0883
0884
0885
0886
0887
0888
0889
0890 if ((((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) ||
0891 (buf[0] & 0xfff) >= 0x190) {
0892 a6xx_gpu->has_whereami = true;
0893 ret = true;
0894 goto out;
0895 }
0896
0897 DRM_DEV_ERROR(&gpu->pdev->dev,
0898 "a630 SQE ucode is too old. Have version %x need at least %x\n",
0899 buf[0] & 0xfff, 0x190);
0900 } else if (!strcmp(sqe_name, "a650_sqe.fw")) {
0901 if ((buf[0] & 0xfff) >= 0x095) {
0902 ret = true;
0903 goto out;
0904 }
0905
0906 DRM_DEV_ERROR(&gpu->pdev->dev,
0907 "a650 SQE ucode is too old. Have version %x need at least %x\n",
0908 buf[0] & 0xfff, 0x095);
0909 } else if (!strcmp(sqe_name, "a660_sqe.fw")) {
0910 ret = true;
0911 } else {
0912 DRM_DEV_ERROR(&gpu->pdev->dev,
0913 "unknown GPU, add it to a6xx_ucode_check_version()!!\n");
0914 }
0915 out:
0916 msm_gem_put_vaddr(obj);
0917 return ret;
0918 }
0919
0920 static int a6xx_ucode_init(struct msm_gpu *gpu)
0921 {
0922 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
0923 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
0924
0925 if (!a6xx_gpu->sqe_bo) {
0926 a6xx_gpu->sqe_bo = adreno_fw_create_bo(gpu,
0927 adreno_gpu->fw[ADRENO_FW_SQE], &a6xx_gpu->sqe_iova);
0928
0929 if (IS_ERR(a6xx_gpu->sqe_bo)) {
0930 int ret = PTR_ERR(a6xx_gpu->sqe_bo);
0931
0932 a6xx_gpu->sqe_bo = NULL;
0933 DRM_DEV_ERROR(&gpu->pdev->dev,
0934 "Could not allocate SQE ucode: %d\n", ret);
0935
0936 return ret;
0937 }
0938
0939 msm_gem_object_set_name(a6xx_gpu->sqe_bo, "sqefw");
0940 if (!a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo)) {
0941 msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace);
0942 drm_gem_object_put(a6xx_gpu->sqe_bo);
0943
0944 a6xx_gpu->sqe_bo = NULL;
0945 return -EPERM;
0946 }
0947 }
0948
0949 gpu_write64(gpu, REG_A6XX_CP_SQE_INSTR_BASE,
0950 REG_A6XX_CP_SQE_INSTR_BASE+1, a6xx_gpu->sqe_iova);
0951
0952 return 0;
0953 }
0954
0955 static int a6xx_zap_shader_init(struct msm_gpu *gpu)
0956 {
0957 static bool loaded;
0958 int ret;
0959
0960 if (loaded)
0961 return 0;
0962
0963 ret = adreno_zap_shader_load(gpu, GPU_PAS_ID);
0964
0965 loaded = !ret;
0966 return ret;
0967 }
0968
0969 #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
0970 A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
0971 A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
0972 A6XX_RBBM_INT_0_MASK_CP_IB2 | \
0973 A6XX_RBBM_INT_0_MASK_CP_IB1 | \
0974 A6XX_RBBM_INT_0_MASK_CP_RB | \
0975 A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \
0976 A6XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW | \
0977 A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
0978 A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
0979 A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR)
0980
0981 static int hw_init(struct msm_gpu *gpu)
0982 {
0983 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
0984 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
0985 int ret;
0986
0987
0988 a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
0989
0990 gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_CNTL, 0);
0991
0992
0993
0994
0995
0996
0997 gpu_write64(gpu, REG_A6XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO,
0998 REG_A6XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x00000000);
0999 gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x00000000);
1000
1001
1002 gpu_write(gpu, REG_A6XX_CP_ADDR_MODE_CNTL, 0x1);
1003 gpu_write(gpu, REG_A6XX_VSC_ADDR_MODE_CNTL, 0x1);
1004 gpu_write(gpu, REG_A6XX_GRAS_ADDR_MODE_CNTL, 0x1);
1005 gpu_write(gpu, REG_A6XX_RB_ADDR_MODE_CNTL, 0x1);
1006 gpu_write(gpu, REG_A6XX_PC_ADDR_MODE_CNTL, 0x1);
1007 gpu_write(gpu, REG_A6XX_HLSQ_ADDR_MODE_CNTL, 0x1);
1008 gpu_write(gpu, REG_A6XX_VFD_ADDR_MODE_CNTL, 0x1);
1009 gpu_write(gpu, REG_A6XX_VPC_ADDR_MODE_CNTL, 0x1);
1010 gpu_write(gpu, REG_A6XX_UCHE_ADDR_MODE_CNTL, 0x1);
1011 gpu_write(gpu, REG_A6XX_SP_ADDR_MODE_CNTL, 0x1);
1012 gpu_write(gpu, REG_A6XX_TPL1_ADDR_MODE_CNTL, 0x1);
1013 gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_ADDR_MODE_CNTL, 0x1);
1014
1015
1016 a6xx_set_hwcg(gpu, true);
1017
1018
1019 if (adreno_is_a640_family(adreno_gpu) ||
1020 adreno_is_a650_family(adreno_gpu)) {
1021 gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE0, 0x00071620);
1022 gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE1, 0x00071620);
1023 gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE2, 0x00071620);
1024 gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
1025 gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
1026 gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x3);
1027 } else {
1028 gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
1029 }
1030
1031 if (adreno_is_a630(adreno_gpu))
1032 gpu_write(gpu, REG_A6XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000009);
1033
1034
1035 gpu_write(gpu, REG_A6XX_RBBM_PERFCTR_GPU_BUSY_MASKED, 0xffffffff);
1036
1037
1038 gpu_write(gpu, REG_A6XX_UCHE_WRITE_RANGE_MAX_LO, 0xffffffc0);
1039 gpu_write(gpu, REG_A6XX_UCHE_WRITE_RANGE_MAX_HI, 0x0001ffff);
1040 gpu_write(gpu, REG_A6XX_UCHE_TRAP_BASE_LO, 0xfffff000);
1041 gpu_write(gpu, REG_A6XX_UCHE_TRAP_BASE_HI, 0x0001ffff);
1042 gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_LO, 0xfffff000);
1043 gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_HI, 0x0001ffff);
1044
1045 if (!adreno_is_a650_family(adreno_gpu)) {
1046
1047 gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN_LO,
1048 REG_A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x00100000);
1049
1050 gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX_LO,
1051 REG_A6XX_UCHE_GMEM_RANGE_MAX_HI,
1052 0x00100000 + adreno_gpu->gmem - 1);
1053 }
1054
1055 gpu_write(gpu, REG_A6XX_UCHE_FILTER_CNTL, 0x804);
1056 gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, 0x4);
1057
1058 if (adreno_is_a640_family(adreno_gpu) ||
1059 adreno_is_a650_family(adreno_gpu))
1060 gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
1061 else
1062 gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x010000c0);
1063 gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
1064
1065 if (adreno_is_a660_family(adreno_gpu))
1066 gpu_write(gpu, REG_A6XX_CP_LPAC_PROG_FIFO_SIZE, 0x00000020);
1067
1068
1069 gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
1070
1071
1072
1073
1074 if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
1075 gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
1076 else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu))
1077 gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200);
1078 else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
1079 gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
1080 else
1081 gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00180000);
1082
1083
1084 gpu_write(gpu, REG_A6XX_CP_AHB_CNTL, 0x1);
1085
1086
1087 gpu_write(gpu, REG_A6XX_RBBM_PERFCTR_CNTL, 0x1);
1088
1089
1090 gpu_write(gpu, REG_A6XX_CP_PERFCTR_CP_SEL(0), PERF_CP_ALWAYS_COUNT);
1091
1092 a6xx_set_ubwc_config(gpu);
1093
1094
1095 gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL,
1096 (1 << 30) | 0x1fffff);
1097
1098 gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, 1);
1099
1100
1101 if (adreno_is_a650_family(adreno_gpu)) {
1102 gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0, 0);
1103 gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1,
1104 0x3fe05ff4);
1105 gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_2,
1106 0x3fa0ebee);
1107 gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_3,
1108 0x3f5193ed);
1109 gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_4,
1110 0x3f0243f0);
1111 }
1112
1113
1114 a6xx_set_cp_protect(gpu);
1115
1116 if (adreno_is_a660_family(adreno_gpu)) {
1117 gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1);
1118 gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0);
1119 }
1120
1121
1122 if (adreno_is_a660(adreno_gpu))
1123 gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906);
1124
1125
1126 if (gpu->hw_apriv) {
1127 gpu_write(gpu, REG_A6XX_CP_APRIV_CNTL,
1128 (1 << 6) | (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1));
1129 }
1130
1131
1132 gpu_write(gpu, REG_A6XX_RBBM_INT_0_MASK, A6XX_INT_MASK);
1133
1134 ret = adreno_hw_init(gpu);
1135 if (ret)
1136 goto out;
1137
1138 ret = a6xx_ucode_init(gpu);
1139 if (ret)
1140 goto out;
1141
1142
1143 gpu_write64(gpu, REG_A6XX_CP_RB_BASE, REG_A6XX_CP_RB_BASE_HI,
1144 gpu->rb[0]->iova);
1145
1146
1147
1148
1149
1150 if (adreno_gpu->base.hw_apriv)
1151 gpu_write(gpu, REG_A6XX_CP_RB_CNTL, MSM_GPU_RB_CNTL_DEFAULT);
1152 else
1153 gpu_write(gpu, REG_A6XX_CP_RB_CNTL,
1154 MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE);
1155
1156
1157
1158
1159
1160
1161 if (adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami) {
1162 if (!a6xx_gpu->shadow_bo) {
1163 a6xx_gpu->shadow = msm_gem_kernel_new(gpu->dev,
1164 sizeof(u32) * gpu->nr_rings,
1165 MSM_BO_WC | MSM_BO_MAP_PRIV,
1166 gpu->aspace, &a6xx_gpu->shadow_bo,
1167 &a6xx_gpu->shadow_iova);
1168
1169 if (IS_ERR(a6xx_gpu->shadow))
1170 return PTR_ERR(a6xx_gpu->shadow);
1171
1172 msm_gem_object_set_name(a6xx_gpu->shadow_bo, "shadow");
1173 }
1174
1175 gpu_write64(gpu, REG_A6XX_CP_RB_RPTR_ADDR_LO,
1176 REG_A6XX_CP_RB_RPTR_ADDR_HI,
1177 shadowptr(a6xx_gpu, gpu->rb[0]));
1178 }
1179
1180
1181 a6xx_gpu->cur_ring = gpu->rb[0];
1182
1183 gpu->cur_ctx_seqno = 0;
1184
1185
1186 gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 1);
1187
1188 ret = a6xx_cp_init(gpu);
1189 if (ret)
1190 goto out;
1191
1192
1193
1194
1195
1196
1197
1198
1199 ret = a6xx_zap_shader_init(gpu);
1200 if (!ret) {
1201 OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
1202 OUT_RING(gpu->rb[0], 0x00000000);
1203
1204 a6xx_flush(gpu, gpu->rb[0]);
1205 if (!a6xx_idle(gpu, gpu->rb[0]))
1206 return -EINVAL;
1207 } else if (ret == -ENODEV) {
1208
1209
1210
1211
1212
1213
1214 dev_warn_once(gpu->dev->dev,
1215 "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
1216 gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
1217 ret = 0;
1218 } else {
1219 return ret;
1220 }
1221
1222 out:
1223
1224
1225
1226
1227 a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
1228
1229 if (a6xx_gpu->gmu.legacy) {
1230
1231 a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_BOOT_SLUMBER);
1232 }
1233
1234 return ret;
1235 }
1236
1237 static int a6xx_hw_init(struct msm_gpu *gpu)
1238 {
1239 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1240 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1241 int ret;
1242
1243 mutex_lock(&a6xx_gpu->gmu.lock);
1244 ret = hw_init(gpu);
1245 mutex_unlock(&a6xx_gpu->gmu.lock);
1246
1247 return ret;
1248 }
1249
1250 static void a6xx_dump(struct msm_gpu *gpu)
1251 {
1252 DRM_DEV_INFO(&gpu->pdev->dev, "status: %08x\n",
1253 gpu_read(gpu, REG_A6XX_RBBM_STATUS));
1254 adreno_dump(gpu);
1255 }
1256
1257 #define VBIF_RESET_ACK_TIMEOUT 100
1258 #define VBIF_RESET_ACK_MASK 0x00f0
1259
1260 static void a6xx_recover(struct msm_gpu *gpu)
1261 {
1262 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1263 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1264 int i;
1265
1266 adreno_dump_info(gpu);
1267
1268 for (i = 0; i < 8; i++)
1269 DRM_DEV_INFO(&gpu->pdev->dev, "CP_SCRATCH_REG%d: %u\n", i,
1270 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(i)));
1271
1272 if (hang_debug)
1273 a6xx_dump(gpu);
1274
1275
1276
1277
1278
1279 gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 0);
1280
1281 gpu->funcs->pm_suspend(gpu);
1282 gpu->funcs->pm_resume(gpu);
1283
1284 msm_gpu_hw_init(gpu);
1285 }
1286
1287 static const char *a6xx_uche_fault_block(struct msm_gpu *gpu, u32 mid)
1288 {
1289 static const char *uche_clients[7] = {
1290 "VFD", "SP", "VSC", "VPC", "HLSQ", "PC", "LRZ",
1291 };
1292 u32 val;
1293
1294 if (mid < 1 || mid > 3)
1295 return "UNKNOWN";
1296
1297
1298
1299
1300
1301 val = gpu_read(gpu, REG_A6XX_UCHE_CLIENT_PF);
1302
1303
1304 if (mid == 3)
1305 return uche_clients[val & 7];
1306
1307
1308 if (mid == 2)
1309 return ((val & 7) == 0) ? "TP" : "TP|VFD";
1310
1311
1312 return "UCHE";
1313 }
1314
1315 static const char *a6xx_fault_block(struct msm_gpu *gpu, u32 id)
1316 {
1317 if (id == 0)
1318 return "CP";
1319 else if (id == 4)
1320 return "CCU";
1321 else if (id == 6)
1322 return "CDP Prefetch";
1323
1324 return a6xx_uche_fault_block(gpu, id);
1325 }
1326
1327 #define ARM_SMMU_FSR_TF BIT(1)
1328 #define ARM_SMMU_FSR_PF BIT(3)
1329 #define ARM_SMMU_FSR_EF BIT(4)
1330
1331 static int a6xx_fault_handler(void *arg, unsigned long iova, int flags, void *data)
1332 {
1333 struct msm_gpu *gpu = arg;
1334 struct adreno_smmu_fault_info *info = data;
1335 const char *type = "UNKNOWN";
1336 const char *block;
1337 bool do_devcoredump = info && !READ_ONCE(gpu->crashstate);
1338
1339
1340
1341
1342
1343 if (!do_devcoredump) {
1344 gpu->aspace->mmu->funcs->resume_translation(gpu->aspace->mmu);
1345 }
1346
1347
1348
1349
1350
1351 if (!info) {
1352 pr_warn_ratelimited("*** gpu fault: iova=%.16lx flags=%d (%u,%u,%u,%u)\n",
1353 iova, flags,
1354 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(4)),
1355 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(5)),
1356 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(6)),
1357 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(7)));
1358
1359 return 0;
1360 }
1361
1362 if (info->fsr & ARM_SMMU_FSR_TF)
1363 type = "TRANSLATION";
1364 else if (info->fsr & ARM_SMMU_FSR_PF)
1365 type = "PERMISSION";
1366 else if (info->fsr & ARM_SMMU_FSR_EF)
1367 type = "EXTERNAL";
1368
1369 block = a6xx_fault_block(gpu, info->fsynr1 & 0xff);
1370
1371 pr_warn_ratelimited("*** gpu fault: ttbr0=%.16llx iova=%.16lx dir=%s type=%s source=%s (%u,%u,%u,%u)\n",
1372 info->ttbr0, iova,
1373 flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ",
1374 type, block,
1375 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(4)),
1376 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(5)),
1377 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(6)),
1378 gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(7)));
1379
1380 if (do_devcoredump) {
1381
1382 del_timer(&gpu->hangcheck_timer);
1383
1384 gpu->fault_info.ttbr0 = info->ttbr0;
1385 gpu->fault_info.iova = iova;
1386 gpu->fault_info.flags = flags;
1387 gpu->fault_info.type = type;
1388 gpu->fault_info.block = block;
1389
1390 kthread_queue_work(gpu->worker, &gpu->fault_work);
1391 }
1392
1393 return 0;
1394 }
1395
1396 static void a6xx_cp_hw_err_irq(struct msm_gpu *gpu)
1397 {
1398 u32 status = gpu_read(gpu, REG_A6XX_CP_INTERRUPT_STATUS);
1399
1400 if (status & A6XX_CP_INT_CP_OPCODE_ERROR) {
1401 u32 val;
1402
1403 gpu_write(gpu, REG_A6XX_CP_SQE_STAT_ADDR, 1);
1404 val = gpu_read(gpu, REG_A6XX_CP_SQE_STAT_DATA);
1405 dev_err_ratelimited(&gpu->pdev->dev,
1406 "CP | opcode error | possible opcode=0x%8.8X\n",
1407 val);
1408 }
1409
1410 if (status & A6XX_CP_INT_CP_UCODE_ERROR)
1411 dev_err_ratelimited(&gpu->pdev->dev,
1412 "CP ucode error interrupt\n");
1413
1414 if (status & A6XX_CP_INT_CP_HW_FAULT_ERROR)
1415 dev_err_ratelimited(&gpu->pdev->dev, "CP | HW fault | status=0x%8.8X\n",
1416 gpu_read(gpu, REG_A6XX_CP_HW_FAULT));
1417
1418 if (status & A6XX_CP_INT_CP_REGISTER_PROTECTION_ERROR) {
1419 u32 val = gpu_read(gpu, REG_A6XX_CP_PROTECT_STATUS);
1420
1421 dev_err_ratelimited(&gpu->pdev->dev,
1422 "CP | protected mode error | %s | addr=0x%8.8X | status=0x%8.8X\n",
1423 val & (1 << 20) ? "READ" : "WRITE",
1424 (val & 0x3ffff), val);
1425 }
1426
1427 if (status & A6XX_CP_INT_CP_AHB_ERROR)
1428 dev_err_ratelimited(&gpu->pdev->dev, "CP AHB error interrupt\n");
1429
1430 if (status & A6XX_CP_INT_CP_VSD_PARITY_ERROR)
1431 dev_err_ratelimited(&gpu->pdev->dev, "CP VSD decoder parity error\n");
1432
1433 if (status & A6XX_CP_INT_CP_ILLEGAL_INSTR_ERROR)
1434 dev_err_ratelimited(&gpu->pdev->dev, "CP illegal instruction error\n");
1435
1436 }
1437
1438 static void a6xx_fault_detect_irq(struct msm_gpu *gpu)
1439 {
1440 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1441 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1442 struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu);
1443
1444
1445
1446
1447
1448
1449
1450 if (gpu_read(gpu, REG_A6XX_RBBM_STATUS3) & A6XX_RBBM_STATUS3_SMMU_STALLED_ON_FAULT)
1451 return;
1452
1453
1454
1455
1456
1457 gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 1);
1458
1459 DRM_DEV_ERROR(&gpu->pdev->dev,
1460 "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
1461 ring ? ring->id : -1, ring ? ring->fctx->last_fence : 0,
1462 gpu_read(gpu, REG_A6XX_RBBM_STATUS),
1463 gpu_read(gpu, REG_A6XX_CP_RB_RPTR),
1464 gpu_read(gpu, REG_A6XX_CP_RB_WPTR),
1465 gpu_read64(gpu, REG_A6XX_CP_IB1_BASE, REG_A6XX_CP_IB1_BASE_HI),
1466 gpu_read(gpu, REG_A6XX_CP_IB1_REM_SIZE),
1467 gpu_read64(gpu, REG_A6XX_CP_IB2_BASE, REG_A6XX_CP_IB2_BASE_HI),
1468 gpu_read(gpu, REG_A6XX_CP_IB2_REM_SIZE));
1469
1470
1471 del_timer(&gpu->hangcheck_timer);
1472
1473 kthread_queue_work(gpu->worker, &gpu->recover_work);
1474 }
1475
1476 static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
1477 {
1478 struct msm_drm_private *priv = gpu->dev->dev_private;
1479 u32 status = gpu_read(gpu, REG_A6XX_RBBM_INT_0_STATUS);
1480
1481 gpu_write(gpu, REG_A6XX_RBBM_INT_CLEAR_CMD, status);
1482
1483 if (priv->disable_err_irq)
1484 status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;
1485
1486 if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)
1487 a6xx_fault_detect_irq(gpu);
1488
1489 if (status & A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR)
1490 dev_err_ratelimited(&gpu->pdev->dev, "CP | AHB bus error\n");
1491
1492 if (status & A6XX_RBBM_INT_0_MASK_CP_HW_ERROR)
1493 a6xx_cp_hw_err_irq(gpu);
1494
1495 if (status & A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW)
1496 dev_err_ratelimited(&gpu->pdev->dev, "RBBM | ATB ASYNC overflow\n");
1497
1498 if (status & A6XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW)
1499 dev_err_ratelimited(&gpu->pdev->dev, "RBBM | ATB bus overflow\n");
1500
1501 if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
1502 dev_err_ratelimited(&gpu->pdev->dev, "UCHE | Out of bounds access\n");
1503
1504 if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
1505 msm_gpu_retire(gpu);
1506
1507 return IRQ_HANDLED;
1508 }
1509
1510 static void a6xx_llc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u32 or)
1511 {
1512 return msm_rmw(a6xx_gpu->llc_mmio + (reg << 2), mask, or);
1513 }
1514
1515 static void a6xx_llc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value)
1516 {
1517 msm_writel(value, a6xx_gpu->llc_mmio + (reg << 2));
1518 }
1519
1520 static void a6xx_llc_deactivate(struct a6xx_gpu *a6xx_gpu)
1521 {
1522 llcc_slice_deactivate(a6xx_gpu->llc_slice);
1523 llcc_slice_deactivate(a6xx_gpu->htw_llc_slice);
1524 }
1525
1526 static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
1527 {
1528 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
1529 struct msm_gpu *gpu = &adreno_gpu->base;
1530 u32 cntl1_regval = 0;
1531
1532 if (IS_ERR(a6xx_gpu->llc_mmio))
1533 return;
1534
1535 if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
1536 u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice);
1537
1538 gpu_scid &= 0x1f;
1539 cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) |
1540 (gpu_scid << 15) | (gpu_scid << 20);
1541
1542
1543
1544
1545 if (adreno_is_a660_family(adreno_gpu))
1546 gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) |
1547 (1 << 8), (gpu_scid << 10) | (1 << 8));
1548 }
1549
1550
1551
1552
1553
1554 if (!llcc_slice_activate(a6xx_gpu->htw_llc_slice)) {
1555 if (!a6xx_gpu->have_mmu500) {
1556 u32 gpuhtw_scid = llcc_get_slice_id(a6xx_gpu->htw_llc_slice);
1557
1558 gpuhtw_scid &= 0x1f;
1559 cntl1_regval |= FIELD_PREP(GENMASK(29, 25), gpuhtw_scid);
1560 }
1561 }
1562
1563 if (!cntl1_regval)
1564 return;
1565
1566
1567
1568
1569
1570 if (!a6xx_gpu->have_mmu500) {
1571 a6xx_llc_write(a6xx_gpu,
1572 REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval);
1573
1574
1575
1576
1577
1578 a6xx_llc_rmw(a6xx_gpu,
1579 REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03);
1580 return;
1581 }
1582
1583 gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval);
1584 }
1585
1586 static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu)
1587 {
1588 llcc_slice_putd(a6xx_gpu->llc_slice);
1589 llcc_slice_putd(a6xx_gpu->htw_llc_slice);
1590 }
1591
1592 static void a6xx_llc_slices_init(struct platform_device *pdev,
1593 struct a6xx_gpu *a6xx_gpu)
1594 {
1595 struct device_node *phandle;
1596
1597
1598
1599
1600
1601 phandle = of_parse_phandle(pdev->dev.of_node, "iommus", 0);
1602 a6xx_gpu->have_mmu500 = (phandle &&
1603 of_device_is_compatible(phandle, "arm,mmu-500"));
1604 of_node_put(phandle);
1605
1606 if (a6xx_gpu->have_mmu500)
1607 a6xx_gpu->llc_mmio = NULL;
1608 else
1609 a6xx_gpu->llc_mmio = msm_ioremap(pdev, "cx_mem");
1610
1611 a6xx_gpu->llc_slice = llcc_slice_getd(LLCC_GPU);
1612 a6xx_gpu->htw_llc_slice = llcc_slice_getd(LLCC_GPUHTW);
1613
1614 if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
1615 a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
1616 }
1617
1618 static int a6xx_pm_resume(struct msm_gpu *gpu)
1619 {
1620 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1621 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1622 int ret;
1623
1624 gpu->needs_hw_init = true;
1625
1626 trace_msm_gpu_resume(0);
1627
1628 mutex_lock(&a6xx_gpu->gmu.lock);
1629 ret = a6xx_gmu_resume(a6xx_gpu);
1630 mutex_unlock(&a6xx_gpu->gmu.lock);
1631 if (ret)
1632 return ret;
1633
1634 msm_devfreq_resume(gpu);
1635
1636 a6xx_llc_activate(a6xx_gpu);
1637
1638 return 0;
1639 }
1640
1641 static int a6xx_pm_suspend(struct msm_gpu *gpu)
1642 {
1643 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1644 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1645 int i, ret;
1646
1647 trace_msm_gpu_suspend(0);
1648
1649 a6xx_llc_deactivate(a6xx_gpu);
1650
1651 msm_devfreq_suspend(gpu);
1652
1653 mutex_lock(&a6xx_gpu->gmu.lock);
1654 ret = a6xx_gmu_stop(a6xx_gpu);
1655 mutex_unlock(&a6xx_gpu->gmu.lock);
1656 if (ret)
1657 return ret;
1658
1659 if (a6xx_gpu->shadow_bo)
1660 for (i = 0; i < gpu->nr_rings; i++)
1661 a6xx_gpu->shadow[i] = 0;
1662
1663 gpu->suspend_count++;
1664
1665 return 0;
1666 }
1667
1668 static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
1669 {
1670 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1671 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1672
1673 mutex_lock(&a6xx_gpu->gmu.lock);
1674
1675
1676 a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
1677
1678 *value = gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
1679 REG_A6XX_CP_ALWAYS_ON_COUNTER_HI);
1680
1681 a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
1682
1683 mutex_unlock(&a6xx_gpu->gmu.lock);
1684
1685 return 0;
1686 }
1687
1688 static struct msm_ringbuffer *a6xx_active_ring(struct msm_gpu *gpu)
1689 {
1690 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1691 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1692
1693 return a6xx_gpu->cur_ring;
1694 }
1695
1696 static void a6xx_destroy(struct msm_gpu *gpu)
1697 {
1698 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1699 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1700
1701 if (a6xx_gpu->sqe_bo) {
1702 msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace);
1703 drm_gem_object_put(a6xx_gpu->sqe_bo);
1704 }
1705
1706 if (a6xx_gpu->shadow_bo) {
1707 msm_gem_unpin_iova(a6xx_gpu->shadow_bo, gpu->aspace);
1708 drm_gem_object_put(a6xx_gpu->shadow_bo);
1709 }
1710
1711 a6xx_llc_slices_destroy(a6xx_gpu);
1712
1713 a6xx_gmu_remove(a6xx_gpu);
1714
1715 adreno_gpu_cleanup(adreno_gpu);
1716
1717 kfree(a6xx_gpu);
1718 }
1719
1720 static u64 a6xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
1721 {
1722 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1723 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1724 u64 busy_cycles;
1725
1726
1727 *out_sample_rate = 19200000;
1728
1729 busy_cycles = gmu_read64(&a6xx_gpu->gmu,
1730 REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L,
1731 REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H);
1732
1733 return busy_cycles;
1734 }
1735
1736 static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
1737 bool suspended)
1738 {
1739 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1740 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1741
1742 mutex_lock(&a6xx_gpu->gmu.lock);
1743 a6xx_gmu_set_freq(gpu, opp, suspended);
1744 mutex_unlock(&a6xx_gpu->gmu.lock);
1745 }
1746
1747 static struct msm_gem_address_space *
1748 a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
1749 {
1750 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1751 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1752 struct iommu_domain *iommu;
1753 struct msm_mmu *mmu;
1754 struct msm_gem_address_space *aspace;
1755 u64 start, size;
1756
1757 iommu = iommu_domain_alloc(&platform_bus_type);
1758 if (!iommu)
1759 return NULL;
1760
1761
1762
1763
1764
1765 if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
1766 adreno_set_llc_attributes(iommu);
1767
1768 mmu = msm_iommu_new(&pdev->dev, iommu);
1769 if (IS_ERR(mmu)) {
1770 iommu_domain_free(iommu);
1771 return ERR_CAST(mmu);
1772 }
1773
1774
1775
1776
1777
1778
1779 start = max_t(u64, SZ_16M, iommu->geometry.aperture_start);
1780 size = iommu->geometry.aperture_end - start + 1;
1781
1782 aspace = msm_gem_address_space_create(mmu, "gpu",
1783 start & GENMASK_ULL(48, 0), size);
1784
1785 if (IS_ERR(aspace) && !IS_ERR(mmu))
1786 mmu->funcs->destroy(mmu);
1787
1788 return aspace;
1789 }
1790
1791 static struct msm_gem_address_space *
1792 a6xx_create_private_address_space(struct msm_gpu *gpu)
1793 {
1794 struct msm_mmu *mmu;
1795
1796 mmu = msm_iommu_pagetable_create(gpu->aspace->mmu);
1797
1798 if (IS_ERR(mmu))
1799 return ERR_CAST(mmu);
1800
1801 return msm_gem_address_space_create(mmu,
1802 "gpu", 0x100000000ULL,
1803 adreno_private_address_space_size(gpu));
1804 }
1805
1806 static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
1807 {
1808 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1809 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1810
1811 if (adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami)
1812 return a6xx_gpu->shadow[ring->id];
1813
1814 return ring->memptrs->rptr = gpu_read(gpu, REG_A6XX_CP_RB_RPTR);
1815 }
1816
1817 static u32 a618_get_speed_bin(u32 fuse)
1818 {
1819 if (fuse == 0)
1820 return 0;
1821 else if (fuse == 169)
1822 return 1;
1823 else if (fuse == 174)
1824 return 2;
1825
1826 return UINT_MAX;
1827 }
1828
1829 static u32 a619_get_speed_bin(u32 fuse)
1830 {
1831 if (fuse == 0)
1832 return 0;
1833 else if (fuse == 120)
1834 return 4;
1835 else if (fuse == 138)
1836 return 3;
1837 else if (fuse == 169)
1838 return 2;
1839 else if (fuse == 180)
1840 return 1;
1841
1842 return UINT_MAX;
1843 }
1844
1845 static u32 adreno_7c3_get_speed_bin(u32 fuse)
1846 {
1847 if (fuse == 0)
1848 return 0;
1849 else if (fuse == 117)
1850 return 0;
1851 else if (fuse == 190)
1852 return 1;
1853
1854 return UINT_MAX;
1855 }
1856
1857 static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse)
1858 {
1859 u32 val = UINT_MAX;
1860
1861 if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev))
1862 val = a618_get_speed_bin(fuse);
1863
1864 if (adreno_cmp_rev(ADRENO_REV(6, 1, 9, ANY_ID), rev))
1865 val = a619_get_speed_bin(fuse);
1866
1867 if (adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), rev))
1868 val = adreno_7c3_get_speed_bin(fuse);
1869
1870 if (val == UINT_MAX) {
1871 DRM_DEV_ERROR(dev,
1872 "missing support for speed-bin: %u. Some OPPs may not be supported by hardware",
1873 fuse);
1874 return UINT_MAX;
1875 }
1876
1877 return (1 << val);
1878 }
1879
1880 static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev)
1881 {
1882 u32 supp_hw = UINT_MAX;
1883 u32 speedbin;
1884 int ret;
1885
1886 ret = adreno_read_speedbin(dev, &speedbin);
1887
1888
1889
1890
1891 if (ret == -ENOENT) {
1892 return 0;
1893 } else if (ret) {
1894 DRM_DEV_ERROR(dev,
1895 "failed to read speed-bin (%d). Some OPPs may not be supported by hardware",
1896 ret);
1897 goto done;
1898 }
1899
1900 supp_hw = fuse_to_supp_hw(dev, rev, speedbin);
1901
1902 done:
1903 ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1);
1904 if (ret)
1905 return ret;
1906
1907 return 0;
1908 }
1909
1910 static const struct adreno_gpu_funcs funcs = {
1911 .base = {
1912 .get_param = adreno_get_param,
1913 .set_param = adreno_set_param,
1914 .hw_init = a6xx_hw_init,
1915 .pm_suspend = a6xx_pm_suspend,
1916 .pm_resume = a6xx_pm_resume,
1917 .recover = a6xx_recover,
1918 .submit = a6xx_submit,
1919 .active_ring = a6xx_active_ring,
1920 .irq = a6xx_irq,
1921 .destroy = a6xx_destroy,
1922 #if defined(CONFIG_DRM_MSM_GPU_STATE)
1923 .show = a6xx_show,
1924 #endif
1925 .gpu_busy = a6xx_gpu_busy,
1926 .gpu_get_freq = a6xx_gmu_get_freq,
1927 .gpu_set_freq = a6xx_gpu_set_freq,
1928 #if defined(CONFIG_DRM_MSM_GPU_STATE)
1929 .gpu_state_get = a6xx_gpu_state_get,
1930 .gpu_state_put = a6xx_gpu_state_put,
1931 #endif
1932 .create_address_space = a6xx_create_address_space,
1933 .create_private_address_space = a6xx_create_private_address_space,
1934 .get_rptr = a6xx_get_rptr,
1935 },
1936 .get_timestamp = a6xx_get_timestamp,
1937 };
1938
1939 struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
1940 {
1941 struct msm_drm_private *priv = dev->dev_private;
1942 struct platform_device *pdev = priv->gpu_pdev;
1943 struct adreno_platform_config *config = pdev->dev.platform_data;
1944 const struct adreno_info *info;
1945 struct device_node *node;
1946 struct a6xx_gpu *a6xx_gpu;
1947 struct adreno_gpu *adreno_gpu;
1948 struct msm_gpu *gpu;
1949 int ret;
1950
1951 a6xx_gpu = kzalloc(sizeof(*a6xx_gpu), GFP_KERNEL);
1952 if (!a6xx_gpu)
1953 return ERR_PTR(-ENOMEM);
1954
1955 adreno_gpu = &a6xx_gpu->base;
1956 gpu = &adreno_gpu->base;
1957
1958 adreno_gpu->registers = NULL;
1959
1960
1961
1962
1963
1964
1965 info = adreno_info(config->rev);
1966
1967 if (info && (info->revn == 650 || info->revn == 660 ||
1968 adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), info->rev)))
1969 adreno_gpu->base.hw_apriv = true;
1970
1971
1972
1973
1974
1975 if (info && (info->revn == 618))
1976 gpu->clamp_to_idle = true;
1977
1978 a6xx_llc_slices_init(pdev, a6xx_gpu);
1979
1980 ret = a6xx_set_supported_hw(&pdev->dev, config->rev);
1981 if (ret) {
1982 a6xx_destroy(&(a6xx_gpu->base.base));
1983 return ERR_PTR(ret);
1984 }
1985
1986 ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
1987 if (ret) {
1988 a6xx_destroy(&(a6xx_gpu->base.base));
1989 return ERR_PTR(ret);
1990 }
1991
1992
1993 node = of_parse_phandle(pdev->dev.of_node, "qcom,gmu", 0);
1994
1995
1996 BUG_ON(!node);
1997
1998 ret = a6xx_gmu_init(a6xx_gpu, node);
1999 of_node_put(node);
2000 if (ret) {
2001 a6xx_destroy(&(a6xx_gpu->base.base));
2002 return ERR_PTR(ret);
2003 }
2004
2005 if (gpu->aspace)
2006 msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
2007 a6xx_fault_handler);
2008
2009 return gpu;
2010 }