a5xx_gpu.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. /* Copyright (c) 2016 The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include "msm_gem.h"
  14. #include "msm_mmu.h"
  15. #include "a5xx_gpu.h"
  16. extern bool hang_debug;
  17. static void a5xx_dump(struct msm_gpu *gpu);
  18. static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
  19. struct msm_file_private *ctx)
  20. {
  21. struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
  22. struct msm_drm_private *priv = gpu->dev->dev_private;
  23. struct msm_ringbuffer *ring = gpu->rb;
  24. unsigned int i, ibs = 0;
  25. for (i = 0; i < submit->nr_cmds; i++) {
  26. switch (submit->cmd[i].type) {
  27. case MSM_SUBMIT_CMD_IB_TARGET_BUF:
  28. break;
  29. case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
  30. if (priv->lastctx == ctx)
  31. break;
  32. case MSM_SUBMIT_CMD_BUF:
  33. OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
  34. OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
  35. OUT_RING(ring, upper_32_bits(submit->cmd[i].iova));
  36. OUT_RING(ring, submit->cmd[i].size);
  37. ibs++;
  38. break;
  39. }
  40. }
  41. OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1);
  42. OUT_RING(ring, submit->fence->seqno);
  43. OUT_PKT7(ring, CP_EVENT_WRITE, 4);
  44. OUT_RING(ring, CACHE_FLUSH_TS | (1 << 31));
  45. OUT_RING(ring, lower_32_bits(rbmemptr(adreno_gpu, fence)));
  46. OUT_RING(ring, upper_32_bits(rbmemptr(adreno_gpu, fence)));
  47. OUT_RING(ring, submit->fence->seqno);
  48. gpu->funcs->flush(gpu);
  49. }
  50. struct a5xx_hwcg {
  51. u32 offset;
  52. u32 value;
  53. };
  54. static const struct a5xx_hwcg a530_hwcg[] = {
  55. {REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
  56. {REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222},
  57. {REG_A5XX_RBBM_CLOCK_CNTL_SP2, 0x02222222},
  58. {REG_A5XX_RBBM_CLOCK_CNTL_SP3, 0x02222222},
  59. {REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
  60. {REG_A5XX_RBBM_CLOCK_CNTL2_SP1, 0x02222220},
  61. {REG_A5XX_RBBM_CLOCK_CNTL2_SP2, 0x02222220},
  62. {REG_A5XX_RBBM_CLOCK_CNTL2_SP3, 0x02222220},
  63. {REG_A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
  64. {REG_A5XX_RBBM_CLOCK_HYST_SP1, 0x0000F3CF},
  65. {REG_A5XX_RBBM_CLOCK_HYST_SP2, 0x0000F3CF},
  66. {REG_A5XX_RBBM_CLOCK_HYST_SP3, 0x0000F3CF},
  67. {REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
  68. {REG_A5XX_RBBM_CLOCK_DELAY_SP1, 0x00000080},
  69. {REG_A5XX_RBBM_CLOCK_DELAY_SP2, 0x00000080},
  70. {REG_A5XX_RBBM_CLOCK_DELAY_SP3, 0x00000080},
  71. {REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
  72. {REG_A5XX_RBBM_CLOCK_CNTL_TP1, 0x22222222},
  73. {REG_A5XX_RBBM_CLOCK_CNTL_TP2, 0x22222222},
  74. {REG_A5XX_RBBM_CLOCK_CNTL_TP3, 0x22222222},
  75. {REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
  76. {REG_A5XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
  77. {REG_A5XX_RBBM_CLOCK_CNTL2_TP2, 0x22222222},
  78. {REG_A5XX_RBBM_CLOCK_CNTL2_TP3, 0x22222222},
  79. {REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222},
  80. {REG_A5XX_RBBM_CLOCK_CNTL3_TP1, 0x00002222},
  81. {REG_A5XX_RBBM_CLOCK_CNTL3_TP2, 0x00002222},
  82. {REG_A5XX_RBBM_CLOCK_CNTL3_TP3, 0x00002222},
  83. {REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
  84. {REG_A5XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
  85. {REG_A5XX_RBBM_CLOCK_HYST_TP2, 0x77777777},
  86. {REG_A5XX_RBBM_CLOCK_HYST_TP3, 0x77777777},
  87. {REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
  88. {REG_A5XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
  89. {REG_A5XX_RBBM_CLOCK_HYST2_TP2, 0x77777777},
  90. {REG_A5XX_RBBM_CLOCK_HYST2_TP3, 0x77777777},
  91. {REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777},
  92. {REG_A5XX_RBBM_CLOCK_HYST3_TP1, 0x00007777},
  93. {REG_A5XX_RBBM_CLOCK_HYST3_TP2, 0x00007777},
  94. {REG_A5XX_RBBM_CLOCK_HYST3_TP3, 0x00007777},
  95. {REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
  96. {REG_A5XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
  97. {REG_A5XX_RBBM_CLOCK_DELAY_TP2, 0x11111111},
  98. {REG_A5XX_RBBM_CLOCK_DELAY_TP3, 0x11111111},
  99. {REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
  100. {REG_A5XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
  101. {REG_A5XX_RBBM_CLOCK_DELAY2_TP2, 0x11111111},
  102. {REG_A5XX_RBBM_CLOCK_DELAY2_TP3, 0x11111111},
  103. {REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111},
  104. {REG_A5XX_RBBM_CLOCK_DELAY3_TP1, 0x00001111},
  105. {REG_A5XX_RBBM_CLOCK_DELAY3_TP2, 0x00001111},
  106. {REG_A5XX_RBBM_CLOCK_DELAY3_TP3, 0x00001111},
  107. {REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
  108. {REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
  109. {REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
  110. {REG_A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
  111. {REG_A5XX_RBBM_CLOCK_HYST_UCHE, 0x00444444},
  112. {REG_A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
  113. {REG_A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
  114. {REG_A5XX_RBBM_CLOCK_CNTL_RB1, 0x22222222},
  115. {REG_A5XX_RBBM_CLOCK_CNTL_RB2, 0x22222222},
  116. {REG_A5XX_RBBM_CLOCK_CNTL_RB3, 0x22222222},
  117. {REG_A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222},
  118. {REG_A5XX_RBBM_CLOCK_CNTL2_RB1, 0x00222222},
  119. {REG_A5XX_RBBM_CLOCK_CNTL2_RB2, 0x00222222},
  120. {REG_A5XX_RBBM_CLOCK_CNTL2_RB3, 0x00222222},
  121. {REG_A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220},
  122. {REG_A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220},
  123. {REG_A5XX_RBBM_CLOCK_CNTL_CCU2, 0x00022220},
  124. {REG_A5XX_RBBM_CLOCK_CNTL_CCU3, 0x00022220},
  125. {REG_A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222},
  126. {REG_A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00505555},
  127. {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404},
  128. {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404},
  129. {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU2, 0x04040404},
  130. {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU3, 0x04040404},
  131. {REG_A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044},
  132. {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002},
  133. {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_1, 0x00000002},
  134. {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_2, 0x00000002},
  135. {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_3, 0x00000002},
  136. {REG_A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011},
  137. {REG_A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
  138. {REG_A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
  139. {REG_A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
  140. {REG_A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
  141. {REG_A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
  142. {REG_A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
  143. {REG_A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
  144. {REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
  145. {REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
  146. {REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}
  147. };
  148. static const struct {
  149. int (*test)(struct adreno_gpu *gpu);
  150. const struct a5xx_hwcg *regs;
  151. unsigned int count;
  152. } a5xx_hwcg_regs[] = {
  153. { adreno_is_a530, a530_hwcg, ARRAY_SIZE(a530_hwcg), },
  154. };
  155. static void _a5xx_enable_hwcg(struct msm_gpu *gpu,
  156. const struct a5xx_hwcg *regs, unsigned int count)
  157. {
  158. unsigned int i;
  159. for (i = 0; i < count; i++)
  160. gpu_write(gpu, regs[i].offset, regs[i].value);
  161. gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0xAAA8AA00);
  162. gpu_write(gpu, REG_A5XX_RBBM_ISDB_CNT, 0x182);
  163. }
  164. static void a5xx_enable_hwcg(struct msm_gpu *gpu)
  165. {
  166. struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
  167. unsigned int i;
  168. for (i = 0; i < ARRAY_SIZE(a5xx_hwcg_regs); i++) {
  169. if (a5xx_hwcg_regs[i].test(adreno_gpu)) {
  170. _a5xx_enable_hwcg(gpu, a5xx_hwcg_regs[i].regs,
  171. a5xx_hwcg_regs[i].count);
  172. return;
  173. }
  174. }
  175. }
  176. static int a5xx_me_init(struct msm_gpu *gpu)
  177. {
  178. struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
  179. struct msm_ringbuffer *ring = gpu->rb;
  180. OUT_PKT7(ring, CP_ME_INIT, 8);
  181. OUT_RING(ring, 0x0000002F);
  182. /* Enable multiple hardware contexts */
  183. OUT_RING(ring, 0x00000003);
  184. /* Enable error detection */
  185. OUT_RING(ring, 0x20000000);
  186. /* Don't enable header dump */
  187. OUT_RING(ring, 0x00000000);
  188. OUT_RING(ring, 0x00000000);
  189. /* Specify workarounds for various microcode issues */
  190. if (adreno_is_a530(adreno_gpu)) {
  191. /* Workaround for token end syncs
  192. * Force a WFI after every direct-render 3D mode draw and every
  193. * 2D mode 3 draw
  194. */
  195. OUT_RING(ring, 0x0000000B);
  196. } else {
  197. /* No workarounds enabled */
  198. OUT_RING(ring, 0x00000000);
  199. }
  200. OUT_RING(ring, 0x00000000);
  201. OUT_RING(ring, 0x00000000);
  202. gpu->funcs->flush(gpu);
  203. return gpu->funcs->idle(gpu) ? 0 : -EINVAL;
  204. }
  205. static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu,
  206. const struct firmware *fw, u64 *iova)
  207. {
  208. struct drm_device *drm = gpu->dev;
  209. struct drm_gem_object *bo;
  210. void *ptr;
  211. mutex_lock(&drm->struct_mutex);
  212. bo = msm_gem_new(drm, fw->size - 4, MSM_BO_UNCACHED);
  213. mutex_unlock(&drm->struct_mutex);
  214. if (IS_ERR(bo))
  215. return bo;
  216. ptr = msm_gem_get_vaddr(bo);
  217. if (!ptr) {
  218. drm_gem_object_unreference_unlocked(bo);
  219. return ERR_PTR(-ENOMEM);
  220. }
  221. if (iova) {
  222. int ret = msm_gem_get_iova(bo, gpu->id, iova);
  223. if (ret) {
  224. drm_gem_object_unreference_unlocked(bo);
  225. return ERR_PTR(ret);
  226. }
  227. }
  228. memcpy(ptr, &fw->data[4], fw->size - 4);
  229. msm_gem_put_vaddr(bo);
  230. return bo;
  231. }
  232. static int a5xx_ucode_init(struct msm_gpu *gpu)
  233. {
  234. struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
  235. struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
  236. int ret;
  237. if (!a5xx_gpu->pm4_bo) {
  238. a5xx_gpu->pm4_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pm4,
  239. &a5xx_gpu->pm4_iova);
  240. if (IS_ERR(a5xx_gpu->pm4_bo)) {
  241. ret = PTR_ERR(a5xx_gpu->pm4_bo);
  242. a5xx_gpu->pm4_bo = NULL;
  243. dev_err(gpu->dev->dev, "could not allocate PM4: %d\n",
  244. ret);
  245. return ret;
  246. }
  247. }
  248. if (!a5xx_gpu->pfp_bo) {
  249. a5xx_gpu->pfp_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pfp,
  250. &a5xx_gpu->pfp_iova);
  251. if (IS_ERR(a5xx_gpu->pfp_bo)) {
  252. ret = PTR_ERR(a5xx_gpu->pfp_bo);
  253. a5xx_gpu->pfp_bo = NULL;
  254. dev_err(gpu->dev->dev, "could not allocate PFP: %d\n",
  255. ret);
  256. return ret;
  257. }
  258. }
  259. gpu_write64(gpu, REG_A5XX_CP_ME_INSTR_BASE_LO,
  260. REG_A5XX_CP_ME_INSTR_BASE_HI, a5xx_gpu->pm4_iova);
  261. gpu_write64(gpu, REG_A5XX_CP_PFP_INSTR_BASE_LO,
  262. REG_A5XX_CP_PFP_INSTR_BASE_HI, a5xx_gpu->pfp_iova);
  263. return 0;
  264. }
  265. #define A5XX_INT_MASK (A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \
  266. A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \
  267. A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT | \
  268. A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT | \
  269. A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \
  270. A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW | \
  271. A5XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
  272. A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \
  273. A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
  274. A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP)
  275. static int a5xx_hw_init(struct msm_gpu *gpu)
  276. {
  277. struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
  278. int ret;
  279. gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
  280. /* Make all blocks contribute to the GPU BUSY perf counter */
  281. gpu_write(gpu, REG_A5XX_RBBM_PERFCTR_GPU_BUSY_MASKED, 0xFFFFFFFF);
  282. /* Enable RBBM error reporting bits */
  283. gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL0, 0x00000001);
  284. if (adreno_gpu->info->quirks & ADRENO_QUIRK_FAULT_DETECT_MASK) {
  285. /*
  286. * Mask out the activity signals from RB1-3 to avoid false
  287. * positives
  288. */
  289. gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL11,
  290. 0xF0000000);
  291. gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL12,
  292. 0xFFFFFFFF);
  293. gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL13,
  294. 0xFFFFFFFF);
  295. gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL14,
  296. 0xFFFFFFFF);
  297. gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL15,
  298. 0xFFFFFFFF);
  299. gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL16,
  300. 0xFFFFFFFF);
  301. gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL17,
  302. 0xFFFFFFFF);
  303. gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL18,
  304. 0xFFFFFFFF);
  305. }
  306. /* Enable fault detection */
  307. gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_INT_CNTL,
  308. (1 << 30) | 0xFFFF);
  309. /* Turn on performance counters */
  310. gpu_write(gpu, REG_A5XX_RBBM_PERFCTR_CNTL, 0x01);
  311. /* Increase VFD cache access so LRZ and other data gets evicted less */
  312. gpu_write(gpu, REG_A5XX_UCHE_CACHE_WAYS, 0x02);
  313. /* Disable L2 bypass in the UCHE */
  314. gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_LO, 0xFFFF0000);
  315. gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_HI, 0x0001FFFF);
  316. gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_LO, 0xFFFF0000);
  317. gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_HI, 0x0001FFFF);
  318. /* Set the GMEM VA range (0 to gpu->gmem) */
  319. gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_LO, 0x00100000);
  320. gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_HI, 0x00000000);
  321. gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_LO,
  322. 0x00100000 + adreno_gpu->gmem - 1);
  323. gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_HI, 0x00000000);
  324. gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40);
  325. gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x40);
  326. gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060);
  327. gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16);
  328. gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, (0x400 << 11 | 0x300 << 22));
  329. if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI)
  330. gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8));
  331. gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100);
  332. /* Enable USE_RETENTION_FLOPS */
  333. gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x02000000);
  334. /* Enable ME/PFP split notification */
  335. gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF);
  336. /* Enable HWCG */
  337. a5xx_enable_hwcg(gpu);
  338. gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
  339. /* Set the highest bank bit */
  340. gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, 2 << 7);
  341. gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, 2 << 1);
  342. /* Protect registers from the CP */
  343. gpu_write(gpu, REG_A5XX_CP_PROTECT_CNTL, 0x00000007);
  344. /* RBBM */
  345. gpu_write(gpu, REG_A5XX_CP_PROTECT(0), ADRENO_PROTECT_RW(0x04, 4));
  346. gpu_write(gpu, REG_A5XX_CP_PROTECT(1), ADRENO_PROTECT_RW(0x08, 8));
  347. gpu_write(gpu, REG_A5XX_CP_PROTECT(2), ADRENO_PROTECT_RW(0x10, 16));
  348. gpu_write(gpu, REG_A5XX_CP_PROTECT(3), ADRENO_PROTECT_RW(0x20, 32));
  349. gpu_write(gpu, REG_A5XX_CP_PROTECT(4), ADRENO_PROTECT_RW(0x40, 64));
  350. gpu_write(gpu, REG_A5XX_CP_PROTECT(5), ADRENO_PROTECT_RW(0x80, 64));
  351. /* Content protect */
  352. gpu_write(gpu, REG_A5XX_CP_PROTECT(6),
  353. ADRENO_PROTECT_RW(REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO,
  354. 16));
  355. gpu_write(gpu, REG_A5XX_CP_PROTECT(7),
  356. ADRENO_PROTECT_RW(REG_A5XX_RBBM_SECVID_TRUST_CNTL, 2));
  357. /* CP */
  358. gpu_write(gpu, REG_A5XX_CP_PROTECT(8), ADRENO_PROTECT_RW(0x800, 64));
  359. gpu_write(gpu, REG_A5XX_CP_PROTECT(9), ADRENO_PROTECT_RW(0x840, 8));
  360. gpu_write(gpu, REG_A5XX_CP_PROTECT(10), ADRENO_PROTECT_RW(0x880, 32));
  361. gpu_write(gpu, REG_A5XX_CP_PROTECT(11), ADRENO_PROTECT_RW(0xAA0, 1));
  362. /* RB */
  363. gpu_write(gpu, REG_A5XX_CP_PROTECT(12), ADRENO_PROTECT_RW(0xCC0, 1));
  364. gpu_write(gpu, REG_A5XX_CP_PROTECT(13), ADRENO_PROTECT_RW(0xCF0, 2));
  365. /* VPC */
  366. gpu_write(gpu, REG_A5XX_CP_PROTECT(14), ADRENO_PROTECT_RW(0xE68, 8));
  367. gpu_write(gpu, REG_A5XX_CP_PROTECT(15), ADRENO_PROTECT_RW(0xE70, 4));
  368. /* UCHE */
  369. gpu_write(gpu, REG_A5XX_CP_PROTECT(16), ADRENO_PROTECT_RW(0xE80, 16));
  370. if (adreno_is_a530(adreno_gpu))
  371. gpu_write(gpu, REG_A5XX_CP_PROTECT(17),
  372. ADRENO_PROTECT_RW(0x10000, 0x8000));
  373. gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_CNTL, 0);
  374. /*
  375. * Disable the trusted memory range - we don't actually supported secure
  376. * memory rendering at this point in time and we don't want to block off
  377. * part of the virtual memory space.
  378. */
  379. gpu_write64(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO,
  380. REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x00000000);
  381. gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x00000000);
  382. /* Load the GPMU firmware before starting the HW init */
  383. a5xx_gpmu_ucode_init(gpu);
  384. ret = adreno_hw_init(gpu);
  385. if (ret)
  386. return ret;
  387. ret = a5xx_ucode_init(gpu);
  388. if (ret)
  389. return ret;
  390. /* Disable the interrupts through the initial bringup stage */
  391. gpu_write(gpu, REG_A5XX_RBBM_INT_0_MASK, A5XX_INT_MASK);
  392. /* Clear ME_HALT to start the micro engine */
  393. gpu_write(gpu, REG_A5XX_CP_PFP_ME_CNTL, 0);
  394. ret = a5xx_me_init(gpu);
  395. if (ret)
  396. return ret;
  397. ret = a5xx_power_init(gpu);
  398. if (ret)
  399. return ret;
  400. /*
  401. * Send a pipeline event stat to get misbehaving counters to start
  402. * ticking correctly
  403. */
  404. if (adreno_is_a530(adreno_gpu)) {
  405. OUT_PKT7(gpu->rb, CP_EVENT_WRITE, 1);
  406. OUT_RING(gpu->rb, 0x0F);
  407. gpu->funcs->flush(gpu);
  408. if (!gpu->funcs->idle(gpu))
  409. return -EINVAL;
  410. }
  411. /* Put the GPU into unsecure mode */
  412. gpu_write(gpu, REG_A5XX_RBBM_SECVID_TRUST_CNTL, 0x0);
  413. return 0;
  414. }
  415. static void a5xx_recover(struct msm_gpu *gpu)
  416. {
  417. int i;
  418. adreno_dump_info(gpu);
  419. for (i = 0; i < 8; i++) {
  420. printk("CP_SCRATCH_REG%d: %u\n", i,
  421. gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(i)));
  422. }
  423. if (hang_debug)
  424. a5xx_dump(gpu);
  425. gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 1);
  426. gpu_read(gpu, REG_A5XX_RBBM_SW_RESET_CMD);
  427. gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 0);
  428. adreno_recover(gpu);
  429. }
  430. static void a5xx_destroy(struct msm_gpu *gpu)
  431. {
  432. struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
  433. struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
  434. DBG("%s", gpu->name);
  435. if (a5xx_gpu->pm4_bo) {
  436. if (a5xx_gpu->pm4_iova)
  437. msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->id);
  438. drm_gem_object_unreference_unlocked(a5xx_gpu->pm4_bo);
  439. }
  440. if (a5xx_gpu->pfp_bo) {
  441. if (a5xx_gpu->pfp_iova)
  442. msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->id);
  443. drm_gem_object_unreference_unlocked(a5xx_gpu->pfp_bo);
  444. }
  445. if (a5xx_gpu->gpmu_bo) {
  446. if (a5xx_gpu->gpmu_bo)
  447. msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->id);
  448. drm_gem_object_unreference_unlocked(a5xx_gpu->gpmu_bo);
  449. }
  450. adreno_gpu_cleanup(adreno_gpu);
  451. kfree(a5xx_gpu);
  452. }
  453. static inline bool _a5xx_check_idle(struct msm_gpu *gpu)
  454. {
  455. if (gpu_read(gpu, REG_A5XX_RBBM_STATUS) & ~A5XX_RBBM_STATUS_HI_BUSY)
  456. return false;
  457. /*
  458. * Nearly every abnormality ends up pausing the GPU and triggering a
  459. * fault so we can safely just watch for this one interrupt to fire
  460. */
  461. return !(gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS) &
  462. A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT);
  463. }
  464. static bool a5xx_idle(struct msm_gpu *gpu)
  465. {
  466. /* wait for CP to drain ringbuffer: */
  467. if (!adreno_idle(gpu))
  468. return false;
  469. if (spin_until(_a5xx_check_idle(gpu))) {
  470. DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X\n",
  471. gpu->name, __builtin_return_address(0),
  472. gpu_read(gpu, REG_A5XX_RBBM_STATUS),
  473. gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS));
  474. return false;
  475. }
  476. return true;
  477. }
  478. static int a5xx_fault_handler(void *arg, unsigned long iova, int flags)
  479. {
  480. struct msm_gpu *gpu = arg;
  481. pr_warn_ratelimited("*** gpu fault: iova=%08lx, flags=%d (%u,%u,%u,%u)\n",
  482. iova, flags,
  483. gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(4)),
  484. gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(5)),
  485. gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(6)),
  486. gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(7)));
  487. return -EFAULT;
  488. }
  489. static void a5xx_cp_err_irq(struct msm_gpu *gpu)
  490. {
  491. u32 status = gpu_read(gpu, REG_A5XX_CP_INTERRUPT_STATUS);
  492. if (status & A5XX_CP_INT_CP_OPCODE_ERROR) {
  493. u32 val;
  494. gpu_write(gpu, REG_A5XX_CP_PFP_STAT_ADDR, 0);
  495. /*
  496. * REG_A5XX_CP_PFP_STAT_DATA is indexed, and we want index 1 so
  497. * read it twice
  498. */
  499. gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA);
  500. val = gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA);
  501. dev_err_ratelimited(gpu->dev->dev, "CP | opcode error | possible opcode=0x%8.8X\n",
  502. val);
  503. }
  504. if (status & A5XX_CP_INT_CP_HW_FAULT_ERROR)
  505. dev_err_ratelimited(gpu->dev->dev, "CP | HW fault | status=0x%8.8X\n",
  506. gpu_read(gpu, REG_A5XX_CP_HW_FAULT));
  507. if (status & A5XX_CP_INT_CP_DMA_ERROR)
  508. dev_err_ratelimited(gpu->dev->dev, "CP | DMA error\n");
  509. if (status & A5XX_CP_INT_CP_REGISTER_PROTECTION_ERROR) {
  510. u32 val = gpu_read(gpu, REG_A5XX_CP_PROTECT_STATUS);
  511. dev_err_ratelimited(gpu->dev->dev,
  512. "CP | protected mode error | %s | addr=0x%8.8X | status=0x%8.8X\n",
  513. val & (1 << 24) ? "WRITE" : "READ",
  514. (val & 0xFFFFF) >> 2, val);
  515. }
  516. if (status & A5XX_CP_INT_CP_AHB_ERROR) {
  517. u32 status = gpu_read(gpu, REG_A5XX_CP_AHB_FAULT);
  518. const char *access[16] = { "reserved", "reserved",
  519. "timestamp lo", "timestamp hi", "pfp read", "pfp write",
  520. "", "", "me read", "me write", "", "", "crashdump read",
  521. "crashdump write" };
  522. dev_err_ratelimited(gpu->dev->dev,
  523. "CP | AHB error | addr=%X access=%s error=%d | status=0x%8.8X\n",
  524. status & 0xFFFFF, access[(status >> 24) & 0xF],
  525. (status & (1 << 31)), status);
  526. }
  527. }
  528. static void a5xx_rbbm_err_irq(struct msm_gpu *gpu)
  529. {
  530. u32 status = gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS);
  531. if (status & A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR) {
  532. u32 val = gpu_read(gpu, REG_A5XX_RBBM_AHB_ERROR_STATUS);
  533. dev_err_ratelimited(gpu->dev->dev,
  534. "RBBM | AHB bus error | %s | addr=0x%X | ports=0x%X:0x%X\n",
  535. val & (1 << 28) ? "WRITE" : "READ",
  536. (val & 0xFFFFF) >> 2, (val >> 20) & 0x3,
  537. (val >> 24) & 0xF);
  538. /* Clear the error */
  539. gpu_write(gpu, REG_A5XX_RBBM_AHB_CMD, (1 << 4));
  540. }
  541. if (status & A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT)
  542. dev_err_ratelimited(gpu->dev->dev, "RBBM | AHB transfer timeout\n");
  543. if (status & A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT)
  544. dev_err_ratelimited(gpu->dev->dev, "RBBM | ME master split | status=0x%X\n",
  545. gpu_read(gpu, REG_A5XX_RBBM_AHB_ME_SPLIT_STATUS));
  546. if (status & A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT)
  547. dev_err_ratelimited(gpu->dev->dev, "RBBM | PFP master split | status=0x%X\n",
  548. gpu_read(gpu, REG_A5XX_RBBM_AHB_PFP_SPLIT_STATUS));
  549. if (status & A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT)
  550. dev_err_ratelimited(gpu->dev->dev, "RBBM | ETS master split | status=0x%X\n",
  551. gpu_read(gpu, REG_A5XX_RBBM_AHB_ETS_SPLIT_STATUS));
  552. if (status & A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW)
  553. dev_err_ratelimited(gpu->dev->dev, "RBBM | ATB ASYNC overflow\n");
  554. if (status & A5XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW)
  555. dev_err_ratelimited(gpu->dev->dev, "RBBM | ATB bus overflow\n");
  556. }
  557. static void a5xx_uche_err_irq(struct msm_gpu *gpu)
  558. {
  559. uint64_t addr = (uint64_t) gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_HI);
  560. addr |= gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_LO);
  561. dev_err_ratelimited(gpu->dev->dev, "UCHE | Out of bounds access | addr=0x%llX\n",
  562. addr);
  563. }
  564. static void a5xx_gpmu_err_irq(struct msm_gpu *gpu)
  565. {
  566. dev_err_ratelimited(gpu->dev->dev, "GPMU | voltage droop\n");
  567. }
  568. #define RBBM_ERROR_MASK \
  569. (A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \
  570. A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \
  571. A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT | \
  572. A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT | \
  573. A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \
  574. A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW)
  575. static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
  576. {
  577. u32 status = gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS);
  578. gpu_write(gpu, REG_A5XX_RBBM_INT_CLEAR_CMD, status);
  579. if (status & RBBM_ERROR_MASK)
  580. a5xx_rbbm_err_irq(gpu);
  581. if (status & A5XX_RBBM_INT_0_MASK_CP_HW_ERROR)
  582. a5xx_cp_err_irq(gpu);
  583. if (status & A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
  584. a5xx_uche_err_irq(gpu);
  585. if (status & A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP)
  586. a5xx_gpmu_err_irq(gpu);
  587. if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
  588. msm_gpu_retire(gpu);
  589. return IRQ_HANDLED;
  590. }
  591. static const u32 a5xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
  592. REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_A5XX_CP_RB_BASE),
  593. REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE_HI, REG_A5XX_CP_RB_BASE_HI),
  594. REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_A5XX_CP_RB_RPTR_ADDR),
  595. REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR_HI,
  596. REG_A5XX_CP_RB_RPTR_ADDR_HI),
  597. REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_A5XX_CP_RB_RPTR),
  598. REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_A5XX_CP_RB_WPTR),
  599. REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A5XX_CP_RB_CNTL),
  600. };
  601. static const u32 a5xx_registers[] = {
  602. 0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B,
  603. 0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095,
  604. 0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3,
  605. 0x04E0, 0x0533, 0x0540, 0x0555, 0xF400, 0xF400, 0xF800, 0xF807,
  606. 0x0800, 0x081A, 0x081F, 0x0841, 0x0860, 0x0860, 0x0880, 0x08A0,
  607. 0x0B00, 0x0B12, 0x0B15, 0x0B28, 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD,
  608. 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53, 0x0C60, 0x0C61, 0x0C80, 0x0C82,
  609. 0x0C84, 0x0C85, 0x0C90, 0x0C98, 0x0CA0, 0x0CA0, 0x0CB0, 0x0CB2,
  610. 0x2180, 0x2185, 0x2580, 0x2585, 0x0CC1, 0x0CC1, 0x0CC4, 0x0CC7,
  611. 0x0CCC, 0x0CCC, 0x0CD0, 0x0CD8, 0x0CE0, 0x0CE5, 0x0CE8, 0x0CE8,
  612. 0x0CEC, 0x0CF1, 0x0CFB, 0x0D0E, 0x2100, 0x211E, 0x2140, 0x2145,
  613. 0x2500, 0x251E, 0x2540, 0x2545, 0x0D10, 0x0D17, 0x0D20, 0x0D23,
  614. 0x0D30, 0x0D30, 0x20C0, 0x20C0, 0x24C0, 0x24C0, 0x0E40, 0x0E43,
  615. 0x0E4A, 0x0E4A, 0x0E50, 0x0E57, 0x0E60, 0x0E7C, 0x0E80, 0x0E8E,
  616. 0x0E90, 0x0E96, 0x0EA0, 0x0EA8, 0x0EB0, 0x0EB2, 0xE140, 0xE147,
  617. 0xE150, 0xE187, 0xE1A0, 0xE1A9, 0xE1B0, 0xE1B6, 0xE1C0, 0xE1C7,
  618. 0xE1D0, 0xE1D1, 0xE200, 0xE201, 0xE210, 0xE21C, 0xE240, 0xE268,
  619. 0xE000, 0xE006, 0xE010, 0xE09A, 0xE0A0, 0xE0A4, 0xE0AA, 0xE0EB,
  620. 0xE100, 0xE105, 0xE380, 0xE38F, 0xE3B0, 0xE3B0, 0xE400, 0xE405,
  621. 0xE408, 0xE4E9, 0xE4F0, 0xE4F0, 0xE280, 0xE280, 0xE282, 0xE2A3,
  622. 0xE2A5, 0xE2C2, 0xE940, 0xE947, 0xE950, 0xE987, 0xE9A0, 0xE9A9,
  623. 0xE9B0, 0xE9B6, 0xE9C0, 0xE9C7, 0xE9D0, 0xE9D1, 0xEA00, 0xEA01,
  624. 0xEA10, 0xEA1C, 0xEA40, 0xEA68, 0xE800, 0xE806, 0xE810, 0xE89A,
  625. 0xE8A0, 0xE8A4, 0xE8AA, 0xE8EB, 0xE900, 0xE905, 0xEB80, 0xEB8F,
  626. 0xEBB0, 0xEBB0, 0xEC00, 0xEC05, 0xEC08, 0xECE9, 0xECF0, 0xECF0,
  627. 0xEA80, 0xEA80, 0xEA82, 0xEAA3, 0xEAA5, 0xEAC2, 0xA800, 0xA8FF,
  628. 0xAC60, 0xAC60, 0xB000, 0xB97F, 0xB9A0, 0xB9BF,
  629. ~0
  630. };
  631. static void a5xx_dump(struct msm_gpu *gpu)
  632. {
  633. dev_info(gpu->dev->dev, "status: %08x\n",
  634. gpu_read(gpu, REG_A5XX_RBBM_STATUS));
  635. adreno_dump(gpu);
  636. }
  637. static int a5xx_pm_resume(struct msm_gpu *gpu)
  638. {
  639. int ret;
  640. /* Turn on the core power */
  641. ret = msm_gpu_pm_resume(gpu);
  642. if (ret)
  643. return ret;
  644. /* Turn the RBCCU domain first to limit the chances of voltage droop */
  645. gpu_write(gpu, REG_A5XX_GPMU_RBCCU_POWER_CNTL, 0x778000);
  646. /* Wait 3 usecs before polling */
  647. udelay(3);
  648. ret = spin_usecs(gpu, 20, REG_A5XX_GPMU_RBCCU_PWR_CLK_STATUS,
  649. (1 << 20), (1 << 20));
  650. if (ret) {
  651. DRM_ERROR("%s: timeout waiting for RBCCU GDSC enable: %X\n",
  652. gpu->name,
  653. gpu_read(gpu, REG_A5XX_GPMU_RBCCU_PWR_CLK_STATUS));
  654. return ret;
  655. }
  656. /* Turn on the SP domain */
  657. gpu_write(gpu, REG_A5XX_GPMU_SP_POWER_CNTL, 0x778000);
  658. ret = spin_usecs(gpu, 20, REG_A5XX_GPMU_SP_PWR_CLK_STATUS,
  659. (1 << 20), (1 << 20));
  660. if (ret)
  661. DRM_ERROR("%s: timeout waiting for SP GDSC enable\n",
  662. gpu->name);
  663. return ret;
  664. }
  665. static int a5xx_pm_suspend(struct msm_gpu *gpu)
  666. {
  667. /* Clear the VBIF pipe before shutting down */
  668. gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0xF);
  669. spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) & 0xF) == 0xF);
  670. gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0);
  671. /*
  672. * Reset the VBIF before power collapse to avoid issue with FIFO
  673. * entries
  674. */
  675. gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x003C0000);
  676. gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x00000000);
  677. return msm_gpu_pm_suspend(gpu);
  678. }
  679. static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
  680. {
  681. *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_CP_0_LO,
  682. REG_A5XX_RBBM_PERFCTR_CP_0_HI);
  683. return 0;
  684. }
  685. #ifdef CONFIG_DEBUG_FS
  686. static void a5xx_show(struct msm_gpu *gpu, struct seq_file *m)
  687. {
  688. gpu->funcs->pm_resume(gpu);
  689. seq_printf(m, "status: %08x\n",
  690. gpu_read(gpu, REG_A5XX_RBBM_STATUS));
  691. gpu->funcs->pm_suspend(gpu);
  692. adreno_show(gpu, m);
  693. }
  694. #endif
  695. static const struct adreno_gpu_funcs funcs = {
  696. .base = {
  697. .get_param = adreno_get_param,
  698. .hw_init = a5xx_hw_init,
  699. .pm_suspend = a5xx_pm_suspend,
  700. .pm_resume = a5xx_pm_resume,
  701. .recover = a5xx_recover,
  702. .last_fence = adreno_last_fence,
  703. .submit = a5xx_submit,
  704. .flush = adreno_flush,
  705. .idle = a5xx_idle,
  706. .irq = a5xx_irq,
  707. .destroy = a5xx_destroy,
  708. .show = a5xx_show,
  709. },
  710. .get_timestamp = a5xx_get_timestamp,
  711. };
  712. struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
  713. {
  714. struct msm_drm_private *priv = dev->dev_private;
  715. struct platform_device *pdev = priv->gpu_pdev;
  716. struct a5xx_gpu *a5xx_gpu = NULL;
  717. struct adreno_gpu *adreno_gpu;
  718. struct msm_gpu *gpu;
  719. int ret;
  720. if (!pdev) {
  721. dev_err(dev->dev, "No A5XX device is defined\n");
  722. return ERR_PTR(-ENXIO);
  723. }
  724. a5xx_gpu = kzalloc(sizeof(*a5xx_gpu), GFP_KERNEL);
  725. if (!a5xx_gpu)
  726. return ERR_PTR(-ENOMEM);
  727. adreno_gpu = &a5xx_gpu->base;
  728. gpu = &adreno_gpu->base;
  729. a5xx_gpu->pdev = pdev;
  730. adreno_gpu->registers = a5xx_registers;
  731. adreno_gpu->reg_offsets = a5xx_register_offsets;
  732. a5xx_gpu->lm_leakage = 0x4E001A;
  733. ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs);
  734. if (ret) {
  735. a5xx_destroy(&(a5xx_gpu->base.base));
  736. return ERR_PTR(ret);
  737. }
  738. if (gpu->aspace)
  739. msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, a5xx_fault_handler);
  740. return gpu;
  741. }