History

Merge https://gitlab.freedesktop.org/drm/msm into drm-next-msm-5.8

* new gpu support: a405, a640, a650 * dpu: color processing support * mdp5: support for msm8x36 (the thing with a405) * some prep work for per-context pagetables (ie the part that does not depend on in-flight iommu patches) * last but not least, UABI update for submit ioctl to support syncobj (from Bas)

Dave Airlie committed 6 years ago

Commit efe792f2 parents 3d77e6a 1cb2c4a47 files · +1697 −382Browse files

Unified · Split

47 files
  1. drivers/gpu/drm/msm/Makefile +1 −0
  2. drivers/gpu/drm/msm/adreno/a2xx_gpu.c +16 −0
  3. drivers/gpu/drm/msm/adreno/a3xx_gpu.c +1 −0
  4. drivers/gpu/drm/msm/adreno/a4xx_gpu.c +68 −15
  5. drivers/gpu/drm/msm/adreno/a5xx_gpu.c +7 −0
  6. drivers/gpu/drm/msm/adreno/a6xx.xml.h +14 −0
  7. drivers/gpu/drm/msm/adreno/a6xx_gmu.c +321 −97
  8. drivers/gpu/drm/msm/adreno/a6xx_gmu.h +34 −3
  9. drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h +29 −19
  10. drivers/gpu/drm/msm/adreno/a6xx_gpu.c +59 −11
  11. drivers/gpu/drm/msm/adreno/a6xx_hfi.c +114 −9
  12. drivers/gpu/drm/msm/adreno/a6xx_hfi.h +48 −2
  13. drivers/gpu/drm/msm/adreno/adreno_device.c +35 −0
  14. drivers/gpu/drm/msm/adreno/adreno_gpu.c +19 −8
  15. drivers/gpu/drm/msm/adreno/adreno_gpu.h +23 −0
  16. drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +1 −22
  17. drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +77 −18
  18. drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +2 −0
  19. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +11 −1
  20. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +36 −12
  21. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +39 −0
  22. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +26 −0
  23. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +3 −0
  24. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c +129 −0
  25. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h +100 −0
  26. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +2 −0
  27. drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +5 −13
  28. drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +1 −0
  29. drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +54 −4
  30. drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +2 −0
  31. drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +8 −10
  32. drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c +76 −4
  33. drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +2 −2
  34. drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +11 −10
  35. drivers/gpu/drm/msm/msm_drv.c +4 −2
  36. drivers/gpu/drm/msm/msm_drv.h +8 −7
  37. drivers/gpu/drm/msm/msm_gem.c +24 −7
  38. drivers/gpu/drm/msm/msm_gem.h +1 −0
  39. drivers/gpu/drm/msm/msm_gem_submit.c +231 −1
  40. drivers/gpu/drm/msm/msm_gem_vma.c +10 −32
  41. drivers/gpu/drm/msm/msm_gpu.c +2 −47
  42. drivers/gpu/drm/msm/msm_gpu.h +2 −2
  43. drivers/gpu/drm/msm/msm_gpummu.c +2 −8
  44. drivers/gpu/drm/msm/msm_iommu.c +12 −10
  45. drivers/gpu/drm/msm/msm_mmu.h +2 −3
  46. drivers/gpu/drm/msm/msm_rd.c +2 −2
  47. include/uapi/drm/msm_drm.h +23 −1
drivers/gpu/drm/msm/Makefile+1−0
@@ -65,6 +65,7 @@ msm-y := \ · 64 unmodified lines
6565 disp/dpu1/dpu_hw_lm.o \
6666 disp/dpu1/dpu_hw_pingpong.o \
6767 disp/dpu1/dpu_hw_sspp.o \
68+ disp/dpu1/dpu_hw_dspp.o \
6869 disp/dpu1/dpu_hw_top.o \
6970 disp/dpu1/dpu_hw_util.o \
7071 disp/dpu1/dpu_hw_vbif.o \
drivers/gpu/drm/msm/adreno/a2xx_gpu.c+16−0
@@ -401,6 +401,21 @@ static struct msm_gpu_state *a2xx_gpu_state_get(struct msm_gpu *gpu) · 400 unmodified lines
401401 return state;
402402 }
403403
404+static struct msm_gem_address_space *
405+a2xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
406+{
407+ struct msm_mmu *mmu = msm_gpummu_new(&pdev->dev, gpu);
408+ struct msm_gem_address_space *aspace;
409+
410+ aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
411+ SZ_16M + 0xfff * SZ_64K);
412+
413+ if (IS_ERR(aspace) && !IS_ERR(mmu))
414+ mmu->funcs->destroy(mmu);
415+
416+ return aspace;
417+}
418+
404419 /* Register offset defines for A2XX - copy of A3XX */
405420 static const unsigned int a2xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
406421 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE),
@@ -429,6 +444,7 @@ static const struct adreno_gpu_funcs funcs = { · 22 unmodified lines
429444 #endif
430445 .gpu_state_get = a2xx_gpu_state_get,
431446 .gpu_state_put = adreno_gpu_state_put,
447+ .create_address_space = a2xx_create_address_space,
432448 },
433449 };
434450
drivers/gpu/drm/msm/adreno/a3xx_gpu.c+1−0
@@ -441,6 +441,7 @@ static const struct adreno_gpu_funcs funcs = { · 440 unmodified lines
441441 #endif
442442 .gpu_state_get = a3xx_gpu_state_get,
443443 .gpu_state_put = adreno_gpu_state_put,
444+ .create_address_space = adreno_iommu_create_address_space,
444445 },
445446 };
446447
drivers/gpu/drm/msm/adreno/a4xx_gpu.c+68−15
@@ -66,19 +66,22 @@ static void a4xx_enable_hwcg(struct msm_gpu *gpu) · 65 unmodified lines
6666 }
6767 }
6868
69− for (i = 0; i < 4; i++) {
70− gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_MARB_CCU(i),
71− 0x00000922);
72− }
69+ /* No CCU for A405 */
70+ if (!adreno_is_a405(adreno_gpu)) {
71+ for (i = 0; i < 4; i++) {
72+ gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_MARB_CCU(i),
73+ 0x00000922);
74+ }
7375
74− for (i = 0; i < 4; i++) {
75− gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_RB_MARB_CCU(i),
76− 0x00000000);
77− }
76+ for (i = 0; i < 4; i++) {
77+ gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_RB_MARB_CCU(i),
78+ 0x00000000);
79+ }
7880
79− for (i = 0; i < 4; i++) {
80− gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_RB_MARB_CCU_L1(i),
81− 0x00000001);
81+ for (i = 0; i < 4; i++) {
82+ gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_RB_MARB_CCU_L1(i),
83+ 0x00000001);
84+ }
8285 }
8386
8487 gpu_write(gpu, REG_A4XX_RBBM_CLOCK_MODE_GPC, 0x02222222);
@@ -137,7 +140,9 @@ static int a4xx_hw_init(struct msm_gpu *gpu) · 52 unmodified lines
137140 uint32_t *ptr, len;
138141 int i, ret;
139142
140− if (adreno_is_a420(adreno_gpu)) {
143+ if (adreno_is_a405(adreno_gpu)) {
144+ gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
145+ } else if (adreno_is_a420(adreno_gpu)) {
141146 gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT, 0x0001001F);
142147 gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
143148 gpu_write(gpu, REG_A4XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000001);
@@ -440,6 +445,52 @@ static const unsigned int a4xx_registers[] = { · 296 unmodified lines
440445 ~0 /* sentinel */
441446 };
442447
448+static const unsigned int a405_registers[] = {
449+ /* RBBM */
450+ 0x0000, 0x0002, 0x0004, 0x0021, 0x0023, 0x0024, 0x0026, 0x0026,
451+ 0x0028, 0x002B, 0x002E, 0x0034, 0x0037, 0x0044, 0x0047, 0x0066,
452+ 0x0068, 0x0095, 0x009C, 0x0170, 0x0174, 0x01AF,
453+ /* CP */
454+ 0x0200, 0x0233, 0x0240, 0x0250, 0x04C0, 0x04DD, 0x0500, 0x050B,
455+ 0x0578, 0x058F,
456+ /* VSC */
457+ 0x0C00, 0x0C03, 0x0C08, 0x0C41, 0x0C50, 0x0C51,
458+ /* GRAS */
459+ 0x0C80, 0x0C81, 0x0C88, 0x0C8F,
460+ /* RB */
461+ 0x0CC0, 0x0CC0, 0x0CC4, 0x0CD2,
462+ /* PC */
463+ 0x0D00, 0x0D0C, 0x0D10, 0x0D17, 0x0D20, 0x0D23,
464+ /* VFD */
465+ 0x0E40, 0x0E4A,
466+ /* VPC */
467+ 0x0E60, 0x0E61, 0x0E63, 0x0E68,
468+ /* UCHE */
469+ 0x0E80, 0x0E84, 0x0E88, 0x0E95,
470+ /* GRAS CTX 0 */
471+ 0x2000, 0x2004, 0x2008, 0x2067, 0x2070, 0x2078, 0x207B, 0x216E,
472+ /* PC CTX 0 */
473+ 0x21C0, 0x21C6, 0x21D0, 0x21D0, 0x21D9, 0x21D9, 0x21E5, 0x21E7,
474+ /* VFD CTX 0 */
475+ 0x2200, 0x2204, 0x2208, 0x22A9,
476+ /* GRAS CTX 1 */
477+ 0x2400, 0x2404, 0x2408, 0x2467, 0x2470, 0x2478, 0x247B, 0x256E,
478+ /* PC CTX 1 */
479+ 0x25C0, 0x25C6, 0x25D0, 0x25D0, 0x25D9, 0x25D9, 0x25E5, 0x25E7,
480+ /* VFD CTX 1 */
481+ 0x2600, 0x2604, 0x2608, 0x26A9,
482+ /* VBIF version 0x20050000*/
483+ 0x3000, 0x3007, 0x302C, 0x302C, 0x3030, 0x3030, 0x3034, 0x3036,
484+ 0x3038, 0x3038, 0x303C, 0x303D, 0x3040, 0x3040, 0x3049, 0x3049,
485+ 0x3058, 0x3058, 0x305B, 0x3061, 0x3064, 0x3068, 0x306C, 0x306D,
486+ 0x3080, 0x3088, 0x308B, 0x308C, 0x3090, 0x3094, 0x3098, 0x3098,
487+ 0x309C, 0x309C, 0x30C0, 0x30C0, 0x30C8, 0x30C8, 0x30D0, 0x30D0,
488+ 0x30D8, 0x30D8, 0x30E0, 0x30E0, 0x3100, 0x3100, 0x3108, 0x3108,
489+ 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120, 0x3124, 0x3125,
490+ 0x3129, 0x3129, 0x340C, 0x340C, 0x3410, 0x3410,
491+ ~0 /* sentinel */
492+};
493+
443494 static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu)
444495 {
445496 struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
@@ -532,6 +583,7 @@ static const struct adreno_gpu_funcs funcs = { · 86 unmodified lines
532583 #endif
533584 .gpu_state_get = a4xx_gpu_state_get,
534585 .gpu_state_put = adreno_gpu_state_put,
586+ .create_address_space = adreno_iommu_create_address_space,
535587 },
536588 .get_timestamp = a4xx_get_timestamp,
537589 };
@@ -563,13 +615,14 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) · 25 unmodified lines
563615 gpu->perfcntrs = NULL;
564616 gpu->num_perfcntrs = 0;
565617
566− adreno_gpu->registers = a4xx_registers;
567− adreno_gpu->reg_offsets = a4xx_register_offsets;
568−
569618 ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
570619 if (ret)
571620 goto fail;
572621
622+ adreno_gpu->registers = adreno_is_a405(adreno_gpu) ? a405_registers :
623+ a4xx_registers;
624+ adreno_gpu->reg_offsets = a4xx_register_offsets;
625+
573626 /* if needed, allocate gmem: */
574627 if (adreno_is_a4xx(adreno_gpu)) {
575628 ret = adreno_gpu_ocmem_init(dev->dev, adreno_gpu,
drivers/gpu/drm/msm/adreno/a5xx_gpu.c+7−0
@@ -1404,6 +1404,10 @@ static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu) · 1403 unmodified lines
14041404 {
14051405 u64 busy_cycles, busy_time;
14061406
1407+ /* Only read the gpu busy if the hardware is already active */
1408+ if (pm_runtime_get_if_in_use(&gpu->pdev->dev) == 0)
1409+ return 0;
1410+
14071411 busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
14081412 REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
14091413
@@ -1412,6 +1416,8 @@ static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu) · 2 unmodified lines
14121416
14131417 gpu->devfreq.busy_cycles = busy_cycles;
14141418
1419+ pm_runtime_put(&gpu->pdev->dev);
1420+
14151421 if (WARN_ON(busy_time > ~0LU))
14161422 return ~0LU;
14171423
@@ -1439,6 +1445,7 @@ static const struct adreno_gpu_funcs funcs = { · 21 unmodified lines
14391445 .gpu_busy = a5xx_gpu_busy,
14401446 .gpu_state_get = a5xx_gpu_state_get,
14411447 .gpu_state_put = a5xx_gpu_state_put,
1448+ .create_address_space = adreno_iommu_create_address_space,
14421449 },
14431450 .get_timestamp = a5xx_get_timestamp,
14441451 };
drivers/gpu/drm/msm/adreno/a6xx.xml.h+14−0
@@ -1047,6 +1047,8 @@ enum a6xx_tex_type { · 1046 unmodified lines
10471047
10481048 #define REG_A6XX_CP_MISC_CNTL 0x00000840
10491049
1050+#define REG_A6XX_CP_APRIV_CNTL 0x00000844
1051+
10501052 #define REG_A6XX_CP_ROQ_THRESHOLDS_1 0x000008c1
10511053
10521054 #define REG_A6XX_CP_ROQ_THRESHOLDS_2 0x000008c2
@@ -1764,6 +1766,8 @@ static inline uint32_t A6XX_CP_PROTECT_REG_MASK_LEN(uint32_t val) · 711 unmodified lines
17641766
17651767 #define REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL 0x00000010
17661768
1769+#define REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL 0x00000011
1770+
17671771 #define REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL 0x0000001f
17681772
17691773 #define REG_A6XX_RBBM_INT_CLEAR_CMD 0x00000037
@@ -2418,6 +2422,16 @@ static inline uint32_t A6XX_UCHE_CLIENT_PF_PERFSEL(uint32_t val) · 648 unmodified lines
24182422
24192423 #define REG_A6XX_TPL1_NC_MODE_CNTL 0x0000b604
24202424
2425+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0 0x0000b608
2426+
2427+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1 0x0000b609
2428+
2429+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_2 0x0000b60a
2430+
2431+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_3 0x0000b60b
2432+
2433+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_4 0x0000b60c
2434+
24212435 #define REG_A6XX_TPL1_PERFCTR_TP_SEL_0 0x0000b610
24222436
24232437 #define REG_A6XX_TPL1_PERFCTR_TP_SEL_1 0x0000b611
drivers/gpu/drm/msm/adreno/a6xx_gmu.c+321−97
@@ -2,14 +2,16 @@ · 1 unmodified line
22 /* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. */
33
44 #include <linux/clk.h>
5−#include <linux/dma-mapping.h>
65 #include <linux/interconnect.h>
76 #include <linux/pm_domain.h>
87 #include <linux/pm_opp.h>
98 #include <soc/qcom/cmd-db.h>
9+#include <drm/drm_gem.h>
1010
1111 #include "a6xx_gpu.h"
1212 #include "a6xx_gmu.xml.h"
13+#include "msm_gem.h"
14+#include "msm_mmu.h"
1315
1416 static void a6xx_gmu_fault(struct a6xx_gmu *gmu)
1517 {
@@ -127,8 +129,6 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index) · 111 unmodified lines
127129 if (ret)
128130 dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
129131
130− gmu->freq = gmu->gpu_freqs[index];
131−
132132 /*
133133 * Eventually we will want to scale the path vote with the frequency but
134134 * for now leave it at max so that the performance is nominal.
@@ -151,8 +151,21 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq) · 16 unmodified lines
151151 break;
152152
153153 gmu->current_perf_index = perf_index;
154+ gmu->freq = gmu->gpu_freqs[perf_index];
155+
156+ /*
157+ * This can get called from devfreq while the hardware is idle. Don't
158+ * bring up the power if it isn't already active
159+ */
160+ if (pm_runtime_get_if_in_use(gmu->dev) == 0)
161+ return;
154162
155− __a6xx_gmu_set_freq(gmu, perf_index);
163+ if (gmu->legacy)
164+ __a6xx_gmu_set_freq(gmu, perf_index);
165+ else
166+ a6xx_hfi_set_freq(gmu, perf_index);
167+
168+ pm_runtime_put(gmu->dev);
156169 }
157170
158171 unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)
@@ -196,6 +209,12 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu) · 37 unmodified lines
196209 u32 val;
197210
198211 gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
212+
213+ /* Set the log wptr index
214+ * note: downstream saves the value in poweroff and restores it here
215+ */
216+ gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP, 0);
217+
199218 gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);
200219
201220 ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val,
@@ -232,8 +251,13 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state) · 30 unmodified lines
232251
233252 switch (state) {
234253 case GMU_OOB_GPU_SET:
235− request = GMU_OOB_GPU_SET_REQUEST;
236− ack = GMU_OOB_GPU_SET_ACK;
254+ if (gmu->legacy) {
255+ request = GMU_OOB_GPU_SET_REQUEST;
256+ ack = GMU_OOB_GPU_SET_ACK;
257+ } else {
258+ request = GMU_OOB_GPU_SET_REQUEST_NEW;
259+ ack = GMU_OOB_GPU_SET_ACK_NEW;
260+ }
237261 name = "GPU_SET";
238262 break;
239263 case GMU_OOB_BOOT_SLUMBER:
@@ -272,6 +296,13 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state) · 32 unmodified lines
272296 /* Clear a pending OOB state in the GMU */
273297 void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
274298 {
299+ if (!gmu->legacy) {
300+ WARN_ON(state != GMU_OOB_GPU_SET);
301+ gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
302+ 1 << GMU_OOB_GPU_SET_CLEAR_NEW);
303+ return;
304+ }
305+
275306 switch (state) {
276307 case GMU_OOB_GPU_SET:
277308 gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
@@ -294,6 +325,9 @@ static int a6xx_sptprac_enable(struct a6xx_gmu *gmu) · 16 unmodified lines
294325 int ret;
295326 u32 val;
296327
328+ if (!gmu->legacy)
329+ return 0;
330+
297331 gmu_write(gmu, REG_A6XX_GMU_GX_SPTPRAC_POWER_CONTROL, 0x778000);
298332
299333 ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, val,
@@ -313,6 +347,9 @@ static void a6xx_sptprac_disable(struct a6xx_gmu *gmu) · 13 unmodified lines
313347 u32 val;
314348 int ret;
315349
350+ if (!gmu->legacy)
351+ return;
352+
316353 /* Make sure retention is on */
317354 gmu_rmw(gmu, REG_A6XX_GPU_CC_GX_GDSCR, 0, (1 << 11));
318355
@@ -356,6 +393,11 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu) · 37 unmodified lines
356393 if (gmu->idle_level < GMU_IDLE_STATE_SPTP)
357394 a6xx_sptprac_disable(gmu);
358395
396+ if (!gmu->legacy) {
397+ ret = a6xx_hfi_send_prep_slumber(gmu);
398+ goto out;
399+ }
400+
359401 /* Tell the GMU to get ready to slumber */
360402 gmu_write(gmu, REG_A6XX_GMU_BOOT_SLUMBER_OPTION, 1);
361403
@@ -371,6 +413,7 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu) · 9 unmodified lines
371413 }
372414 }
373415
416+out:
374417 /* Put fence into allow mode */
375418 gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0);
376419 return ret;
@@ -392,7 +435,7 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu) · 15 unmodified lines
392435 return ret;
393436 }
394437
395− ret = gmu_poll_timeout(gmu, REG_A6XX_RSCC_SEQ_BUSY_DRV0, val,
438+ ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_SEQ_BUSY_DRV0, val,
396439 !val, 100, 10000);
397440
398441 if (ret) {
@@ -418,7 +461,7 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu) · 19 unmodified lines
418461
419462 gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1);
420463
421− ret = gmu_poll_timeout(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0,
464+ ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0,
422465 val, val & (1 << 16), 100, 10000);
423466 if (ret)
424467 DRM_DEV_ERROR(gmu->dev, "Unable to power off the GPU RSC\n");
@@ -441,32 +484,48 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) · 16 unmodified lines
441484 struct platform_device *pdev = to_platform_device(gmu->dev);
442485 void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc");
443486 void __iomem *seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
487+ uint32_t pdc_address_offset;
444488
445489 if (!pdcptr || !seqptr)
446490 goto err;
447491
492+ if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu))
493+ pdc_address_offset = 0x30090;
494+ else if (adreno_is_a650(adreno_gpu))
495+ pdc_address_offset = 0x300a0;
496+ else
497+ pdc_address_offset = 0x30080;
498+
448499 /* Disable SDE clock gating */
449− gmu_write(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
500+ gmu_write_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
450501
451502 /* Setup RSC PDC handshake for sleep and wakeup */
452− gmu_write(gmu, REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0, 1);
453− gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA, 0);
454− gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0);
455− gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
456− gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
457− gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4, 0x80000000);
458− gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
459− gmu_write(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
460− gmu_write(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);
461− gmu_write(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510);
462− gmu_write(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
503+ gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0, 1);
504+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA, 0);
505+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0);
506+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
507+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
508+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4, 0x80000000);
509+ gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
510+ gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
511+ gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);
512+ gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510);
513+ gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
463514
464515 /* Load RSC sequencer uCode for sleep and wakeup */
465− gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0);
466− gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xa1e6a6e7);
467− gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e081e1);
468− gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xe9a982e2);
469− gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8);
516+ if (adreno_is_a650(adreno_gpu)) {
517+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xeaaae5a0);
518+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xe1a1ebab);
519+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e0a581);
520+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xecac82e2);
521+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020edad);
522+ } else {
523+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0);
524+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xa1e6a6e7);
525+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e081e1);
526+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xe9a982e2);
527+ gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8);
528+ }
470529
471530 /* Load PDC sequencer uCode for power up and power down sequence */
472531 pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0, 0xfebea1e1);
@@ -487,10 +546,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) · 14 unmodified lines
487546 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 4, 0x0);
488547
489548 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 8, 0x10108);
490− if (adreno_is_a618(adreno_gpu))
491− pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 0x30090);
492− else
493− pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 0x30080);
549+ pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, pdc_address_offset);
494550 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 8, 0x0);
495551
496552 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD_ENABLE_BANK, 7);
@@ -502,17 +558,12 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) · 5 unmodified lines
502558
503559 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108);
504560 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x30000);
505− if (adreno_is_a618(adreno_gpu))
561+ if (adreno_is_a618(adreno_gpu) || adreno_is_a650(adreno_gpu))
506562 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x2);
507563 else
508564 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3);
509−
510−
511565 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 8, 0x10108);
512− if (adreno_is_a618(adreno_gpu))
513− pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, 0x30090);
514− else
515− pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, 0x30080);
566+ pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, pdc_address_offset);
516567 pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 8, 0x3);
517568
518569 /* Setup GPU PDC */
@@ -542,6 +593,8 @@ static void a6xx_gmu_power_config(struct a6xx_gmu *gmu) · 23 unmodified lines
542593 {
543594 /* Disable GMU WB/RB buffer */
544595 gmu_write(gmu, REG_A6XX_GMU_SYS_BUS_CONFIG, 0x1);
596+ gmu_write(gmu, REG_A6XX_GMU_ICACHE_CONFIG, 0x1);
597+ gmu_write(gmu, REG_A6XX_GMU_DCACHE_CONFIG, 0x1);
545598
546599 gmu_write(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0x9c40400);
547600
@@ -571,14 +624,95 @@ static void a6xx_gmu_power_config(struct a6xx_gmu *gmu) · 23 unmodified lines
571624 A6XX_GMU_RPMH_CTRL_GFX_VOTE_ENABLE);
572625 }
573626
627+struct block_header {
628+ u32 addr;
629+ u32 size;
630+ u32 type;
631+ u32 value;
632+ u32 data[];
633+};
634+
635+/* this should be a general kernel helper */
636+static int in_range(u32 addr, u32 start, u32 size)
637+{
638+ return addr >= start && addr < start + size;
639+}
640+
641+static bool fw_block_mem(struct a6xx_gmu_bo *bo, const struct block_header *blk)
642+{
643+ if (!in_range(blk->addr, bo->iova, bo->size))
644+ return false;
645+
646+ memcpy(bo->virt + blk->addr - bo->iova, blk->data, blk->size);
647+ return true;
648+}
649+
650+static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu)
651+{
652+ struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
653+ struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
654+ const struct firmware *fw_image = adreno_gpu->fw[ADRENO_FW_GMU];
655+ const struct block_header *blk;
656+ u32 reg_offset;
657+
658+ u32 itcm_base = 0x00000000;
659+ u32 dtcm_base = 0x00040000;
660+
661+ if (adreno_is_a650(adreno_gpu))
662+ dtcm_base = 0x10004000;
663+
664+ if (gmu->legacy) {
665+ /* Sanity check the size of the firmware that was loaded */
666+ if (fw_image->size > 0x8000) {
667+ DRM_DEV_ERROR(gmu->dev,
668+ "GMU firmware is bigger than the available region\n");
669+ return -EINVAL;
670+ }
671+
672+ gmu_write_bulk(gmu, REG_A6XX_GMU_CM3_ITCM_START,
673+ (u32*) fw_image->data, fw_image->size);
674+ return 0;
675+ }
676+
677+
678+ for (blk = (const struct block_header *) fw_image->data;
679+ (const u8*) blk < fw_image->data + fw_image->size;
680+ blk = (const struct block_header *) &blk->data[blk->size >> 2]) {
681+ if (blk->size == 0)
682+ continue;
683+
684+ if (in_range(blk->addr, itcm_base, SZ_16K)) {
685+ reg_offset = (blk->addr - itcm_base) >> 2;
686+ gmu_write_bulk(gmu,
687+ REG_A6XX_GMU_CM3_ITCM_START + reg_offset,
688+ blk->data, blk->size);
689+ } else if (in_range(blk->addr, dtcm_base, SZ_16K)) {
690+ reg_offset = (blk->addr - dtcm_base) >> 2;
691+ gmu_write_bulk(gmu,
692+ REG_A6XX_GMU_CM3_DTCM_START + reg_offset,
693+ blk->data, blk->size);
694+ } else if (!fw_block_mem(&gmu->icache, blk) &&
695+ !fw_block_mem(&gmu->dcache, blk) &&
696+ !fw_block_mem(&gmu->dummy, blk)) {
697+ DRM_DEV_ERROR(gmu->dev,
698+ "failed to match fw block (addr=%.8x size=%d data[0]=%.8x)\n",
699+ blk->addr, blk->size, blk->data[0]);
700+ }
701+ }
702+
703+ return 0;
704+}
705+
574706 static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
575707 {
576708 static bool rpmh_init;
577709 struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
578710 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
579− int i, ret;
711+ int ret;
580712 u32 chipid;
581− u32 *image;
713+
714+ if (adreno_is_a650(adreno_gpu))
715+ gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF, 1);
582716
583717 if (state == GMU_WARM_BOOT) {
584718 ret = a6xx_rpmh_start(gmu);
@@ -589,13 +723,6 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) · 4 unmodified lines
589723 "GMU firmware is not loaded\n"))
590724 return -ENOENT;
591725
592− /* Sanity check the size of the firmware that was loaded */
593− if (adreno_gpu->fw[ADRENO_FW_GMU]->size > 0x8000) {
594− DRM_DEV_ERROR(gmu->dev,
595− "GMU firmware is bigger than the available region\n");
596− return -EINVAL;
597− }
598−
599726 /* Turn on register retention */
600727 gmu_write(gmu, REG_A6XX_GMU_GENERAL_7, 1);
601728
@@ -609,18 +736,16 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) · 7 unmodified lines
609736 return ret;
610737 }
611738
612− image = (u32 *) adreno_gpu->fw[ADRENO_FW_GMU]->data;
613−
614− for (i = 0; i < adreno_gpu->fw[ADRENO_FW_GMU]->size >> 2; i++)
615− gmu_write(gmu, REG_A6XX_GMU_CM3_ITCM_START + i,
616− image[i]);
739+ ret = a6xx_gmu_fw_load(gmu);
740+ if (ret)
741+ return ret;
617742 }
618743
619744 gmu_write(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, 0);
620745 gmu_write(gmu, REG_A6XX_GMU_CM3_BOOT_CONFIG, 0x02);
621746
622747 /* Write the iova of the HFI table */
623− gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_ADDR, gmu->hfi->iova);
748+ gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_ADDR, gmu->hfi.iova);
624749 gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_INFO, 1);
625750
626751 gmu_write(gmu, REG_A6XX_GMU_AHB_FENCE_RANGE_0,
@@ -633,6 +758,9 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) · 6 unmodified lines
633758
634759 gmu_write(gmu, REG_A6XX_GMU_HFI_SFR_ADDR, chipid);
635760
761+ gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG,
762+ gmu->log.iova | (gmu->log.size / SZ_4K - 1));
763+
636764 /* Set up the lowest idle level on the GMU */
637765 a6xx_gmu_power_config(gmu);
638766
@@ -640,9 +768,11 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) · 1 unmodified line
640768 if (ret)
641769 return ret;
642770
643− ret = a6xx_gmu_gfx_rail_on(gmu);
644− if (ret)
645− return ret;
771+ if (gmu->legacy) {
772+ ret = a6xx_gmu_gfx_rail_on(gmu);
773+ if (ret)
774+ return ret;
775+ }
646776
647777 /* Enable SPTP_PC if the CPU is responsible for it */
648778 if (gmu->idle_level < GMU_IDLE_STATE_SPTP) {
@@ -683,13 +813,13 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu) · 34 unmodified lines
683813 u32 val;
684814
685815 /* Make sure there are no outstanding RPMh votes */
686− gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS, val,
816+ gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS, val,
687817 (val & 1), 100, 10000);
688− gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS1_DRV0_STATUS, val,
818+ gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS1_DRV0_STATUS, val,
689819 (val & 1), 100, 10000);
690− gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS2_DRV0_STATUS, val,
820+ gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS2_DRV0_STATUS, val,
691821 (val & 1), 100, 10000);
692− gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val,
822+ gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val,
693823 (val & 1), 100, 1000);
694824 }
695825
@@ -744,6 +874,13 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) · 48 unmodified lines
744874 status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ?
745875 GMU_WARM_BOOT : GMU_COLD_BOOT;
746876
877+ /*
878+ * Warm boot path does not work on newer GPUs
879+ * Presumably this is because icache/dcache regions must be restored
880+ */
881+ if (!gmu->legacy)
882+ status = GMU_COLD_BOOT;
883+
747884 ret = a6xx_gmu_fw_start(gmu, status);
748885 if (ret)
749886 goto out;
@@ -761,7 +898,10 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) · 11 unmodified lines
761898 enable_irq(gmu->hfi_irq);
762899
763900 /* Set the GPU to the current freq */
764− __a6xx_gmu_set_freq(gmu, gmu->current_perf_index);
901+ if (gmu->legacy)
902+ __a6xx_gmu_set_freq(gmu, gmu->current_perf_index);
903+ else
904+ a6xx_hfi_set_freq(gmu, gmu->current_perf_index);
765905
766906 /*
767907 * "enable" the GX power domain which won't actually do anything but it
@@ -919,34 +1059,75 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) · 151 unmodified lines
9191059 return 0;
9201060 }
9211061
922−static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo)
1062+static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu)
9231063 {
924− if (IS_ERR_OR_NULL(bo))
925− return;
926−
927− dma_free_wc(gmu->dev, bo->size, bo->virt, bo->iova);
928− kfree(bo);
1064+ msm_gem_kernel_put(gmu->hfi.obj, gmu->aspace, false);
1065+ msm_gem_kernel_put(gmu->debug.obj, gmu->aspace, false);
1066+ msm_gem_kernel_put(gmu->icache.obj, gmu->aspace, false);
1067+ msm_gem_kernel_put(gmu->dcache.obj, gmu->aspace, false);
1068+ msm_gem_kernel_put(gmu->dummy.obj, gmu->aspace, false);
1069+ msm_gem_kernel_put(gmu->log.obj, gmu->aspace, false);
1070+
1071+ gmu->aspace->mmu->funcs->detach(gmu->aspace->mmu);
1072+ msm_gem_address_space_put(gmu->aspace);
9291073 }
9301074
931−static struct a6xx_gmu_bo *a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu,
932− size_t size)
1075+static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo,
1076+ size_t size, u64 iova)
9331077 {
934− struct a6xx_gmu_bo *bo;
1078+ struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
1079+ struct drm_device *dev = a6xx_gpu->base.base.dev;
1080+ uint32_t flags = MSM_BO_WC;
1081+ u64 range_start, range_end;
1082+ int ret;
9351083
936− bo = kzalloc(sizeof(*bo), GFP_KERNEL);
937− if (!bo)
938− return ERR_PTR(-ENOMEM);
1084+ size = PAGE_ALIGN(size);
1085+ if (!iova) {
1086+ /* no fixed address - use GMU's uncached range */
1087+ range_start = 0x60000000 + PAGE_SIZE; /* skip dummy page */
1088+ range_end = 0x80000000;
1089+ } else {
1090+ /* range for fixed address */
1091+ range_start = iova;
1092+ range_end = iova + size;
1093+ /* use IOMMU_PRIV for icache/dcache */
1094+ flags |= MSM_BO_MAP_PRIV;
1095+ }
9391096
940− bo->size = PAGE_ALIGN(size);
1097+ bo->obj = msm_gem_new(dev, size, flags);
1098+ if (IS_ERR(bo->obj))
1099+ return PTR_ERR(bo->obj);
9411100
942− bo->virt = dma_alloc_wc(gmu->dev, bo->size, &bo->iova, GFP_KERNEL);
1101+ ret = msm_gem_get_and_pin_iova_range(bo->obj, gmu->aspace, &bo->iova,
1102+ range_start >> PAGE_SHIFT, range_end >> PAGE_SHIFT);
1103+ if (ret) {
1104+ drm_gem_object_put(bo->obj);
1105+ return ret;
1106+ }
1107+
1108+ bo->virt = msm_gem_get_vaddr(bo->obj);
1109+ bo->size = size;
1110+
1111+ return 0;
1112+}
1113+
1114+static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu)
1115+{
1116+ struct iommu_domain *domain;
1117+ struct msm_mmu *mmu;
9431118
944− if (!bo->virt) {
945− kfree(bo);
946− return ERR_PTR(-ENOMEM);
1119+ domain = iommu_domain_alloc(&platform_bus_type);
1120+ if (!domain)
1121+ return -ENODEV;
1122+
1123+ mmu = msm_iommu_new(gmu->dev, domain);
1124+ gmu->aspace = msm_gem_address_space_create(mmu, "gmu", 0x0, 0x7fffffff);
1125+ if (IS_ERR(gmu->aspace)) {
1126+ iommu_domain_free(domain);
1127+ return PTR_ERR(gmu->aspace);
9471128 }
9481129
949− return bo;
1130+ return 0;
9501131 }
9511132
9521133 /* Return the 'arc-level' for the given frequency */
@@ -1011,8 +1192,8 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes, · 58 unmodified lines
10111192
10121193 if (j == pri_count) {
10131194 DRM_DEV_ERROR(dev,
1014− "Level %u not found in in the RPMh list\n",
1015− level);
1195+ "Level %u not found in the RPMh list\n",
1196+ level);
10161197 DRM_DEV_ERROR(dev, "Available levels:\n");
10171198 for (j = 0; j < pri_count; j++)
10181199 DRM_DEV_ERROR(dev, " %u\n", pri[j]);
@@ -1190,6 +1371,7 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev, · 171 unmodified lines
11901371 void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
11911372 {
11921373 struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
1374+ struct platform_device *pdev = to_platform_device(gmu->dev);
11931375
11941376 if (!gmu->initialized)
11951377 return;
@@ -1202,9 +1384,12 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) · 6 unmodified lines
12021384 }
12031385
12041386 iounmap(gmu->mmio);
1387+ if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rscc"))
1388+ iounmap(gmu->rscc);
12051389 gmu->mmio = NULL;
1390+ gmu->rscc = NULL;
12061391
1207− a6xx_gmu_memory_free(gmu, gmu->hfi);
1392+ a6xx_gmu_memory_free(gmu);
12081393
12091394 free_irq(gmu->gmu_irq, gmu);
12101395 free_irq(gmu->hfi_irq, gmu);
@@ -1217,6 +1402,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) · 6 unmodified lines
12171402
12181403 int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
12191404 {
1405+ struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
12201406 struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
12211407 struct platform_device *pdev = of_find_device_by_node(node);
12221408 int ret;
@@ -1226,15 +1412,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) · 3 unmodified lines
12261412
12271413 gmu->dev = &pdev->dev;
12281414
1229− /* Pass force_dma false to require the DT to set the dma region */
1230− ret = of_dma_configure(gmu->dev, node, false);
1231− if (ret)
1232− return ret;
1233−
1234− /* Set the mask after the of_dma_configure() */
1235− ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(31));
1236− if (ret)
1237− return ret;
1415+ of_dma_configure(gmu->dev, node, true);
12381416
12391417 /* Fow now, don't do anything fancy until we get our feet under us */
12401418 gmu->idle_level = GMU_IDLE_STATE_ACTIVE;
@@ -1246,20 +1424,64 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) · 5 unmodified lines
12461424 if (ret)
12471425 goto err_put_device;
12481426
1427+ ret = a6xx_gmu_memory_probe(gmu);
1428+ if (ret)
1429+ goto err_put_device;
1430+
1431+ /* Allocate memory for the GMU dummy page */
1432+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->dummy, SZ_4K, 0x60000000);
1433+ if (ret)
1434+ goto err_memory;
1435+
1436+ if (adreno_is_a650(adreno_gpu)) {
1437+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache,
1438+ SZ_16M - SZ_16K, 0x04000);
1439+ if (ret)
1440+ goto err_memory;
1441+ } else if (adreno_is_a640(adreno_gpu)) {
1442+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache,
1443+ SZ_256K - SZ_16K, 0x04000);
1444+ if (ret)
1445+ goto err_memory;
1446+
1447+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->dcache,
1448+ SZ_256K - SZ_16K, 0x44000);
1449+ if (ret)
1450+ goto err_memory;
1451+ } else {
1452+ /* HFI v1, has sptprac */
1453+ gmu->legacy = true;
1454+
1455+ /* Allocate memory for the GMU debug region */
1456+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_16K, 0);
1457+ if (ret)
1458+ goto err_memory;
1459+ }
1460+
12491461 /* Allocate memory for for the HFI queues */
1250− gmu->hfi = a6xx_gmu_memory_alloc(gmu, SZ_16K);
1251− if (IS_ERR(gmu->hfi))
1462+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->hfi, SZ_16K, 0);
1463+ if (ret)
12521464 goto err_memory;
12531465
1254− /* Allocate memory for the GMU debug region */
1255− gmu->debug = a6xx_gmu_memory_alloc(gmu, SZ_16K);
1256− if (IS_ERR(gmu->debug))
1466+ /* Allocate memory for the GMU log region */
1467+ ret = a6xx_gmu_memory_alloc(gmu, &gmu->log, SZ_4K, 0);
1468+ if (ret)
12571469 goto err_memory;
12581470
12591471 /* Map the GMU registers */
12601472 gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");
1261− if (IS_ERR(gmu->mmio))
1473+ if (IS_ERR(gmu->mmio)) {
1474+ ret = PTR_ERR(gmu->mmio);
12621475 goto err_memory;
1476+ }
1477+
1478+ if (adreno_is_a650(adreno_gpu)) {
1479+ gmu->rscc = a6xx_gmu_get_mmio(pdev, "rscc");
1480+ if (IS_ERR(gmu->rscc))
1481+ goto err_mmio;
1482+ } else {
1483+ gmu->rscc = gmu->mmio + 0x23000;
1484+ }
12631485
12641486 /* Get the HFI and GMU interrupts */
12651487 gmu->hfi_irq = a6xx_gmu_get_irq(gmu, pdev, "hfi", a6xx_hfi_irq);
@@ -1286,13 +1508,15 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) · 20 unmodified lines
12861508
12871509 err_mmio:
12881510 iounmap(gmu->mmio);
1511+ if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rscc"))
1512+ iounmap(gmu->rscc);
12891513 free_irq(gmu->gmu_irq, gmu);
12901514 free_irq(gmu->hfi_irq, gmu);
1291−err_memory:
1292− a6xx_gmu_memory_free(gmu, gmu->hfi);
12931515
12941516 ret = -ENODEV;
12951517
1518+err_memory:
1519+ a6xx_gmu_memory_free(gmu);
12961520 err_put_device:
12971521 /* Drop reference taken in of_find_device_by_node */
12981522 put_device(gmu->dev);
drivers/gpu/drm/msm/adreno/a6xx_gmu.h+34−3
@@ -10,9 +10,10 @@ · 9 unmodified lines
1010 #include "a6xx_hfi.h"
1111
1212 struct a6xx_gmu_bo {
13+ struct drm_gem_object *obj;
1314 void *virt;
1415 size_t size;
15− dma_addr_t iova;
16+ u64 iova;
1617 };
1718
1819 /*
@@ -43,7 +44,10 @@ struct a6xx_gmu_bo { · 24 unmodified lines
4344 struct a6xx_gmu {
4445 struct device *dev;
4546
47+ struct msm_gem_address_space *aspace;
48+
4649 void * __iomem mmio;
50+ void * __iomem rscc;
4751
4852 int hfi_irq;
4953 int gmu_irq;
@@ -52,8 +56,12 @@ struct a6xx_gmu { · 2 unmodified lines
5256
5357 int idle_level;
5458
55− struct a6xx_gmu_bo *hfi;
56− struct a6xx_gmu_bo *debug;
59+ struct a6xx_gmu_bo hfi;
60+ struct a6xx_gmu_bo debug;
61+ struct a6xx_gmu_bo icache;
62+ struct a6xx_gmu_bo dcache;
63+ struct a6xx_gmu_bo dummy;
64+ struct a6xx_gmu_bo log;
5765
5866 int nr_clocks;
5967 struct clk_bulk_data *clocks;
@@ -76,6 +84,7 @@ struct a6xx_gmu { · 16 unmodified lines
7684
7785 bool initialized;
7886 bool hung;
87+ bool legacy; /* a618 or a630 */
7988 };
8089
8190 static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset)
@@ -88,6 +97,13 @@ static inline void gmu_write(struct a6xx_gmu *gmu, u32 offset, u32 value) · 6 unmodified lines
8897 return msm_writel(value, gmu->mmio + (offset << 2));
8998 }
9099
100+static inline void
101+gmu_write_bulk(struct a6xx_gmu *gmu, u32 offset, const u32 *data, u32 size)
102+{
103+ memcpy_toio(gmu->mmio + (offset << 2), data, size);
104+ wmb();
105+}
106+
91107 static inline void gmu_rmw(struct a6xx_gmu *gmu, u32 reg, u32 mask, u32 or)
92108 {
93109 u32 val = gmu_read(gmu, reg);
@@ -111,6 +127,15 @@ static inline u64 gmu_read64(struct a6xx_gmu *gmu, u32 lo, u32 hi) · 17 unmodified lines
111127 readl_poll_timeout((gmu)->mmio + ((addr) << 2), val, cond, \
112128 interval, timeout)
113129
130+static inline void gmu_write_rscc(struct a6xx_gmu *gmu, u32 offset, u32 value)
131+{
132+ return msm_writel(value, gmu->rscc + (offset << 2));
133+}
134+
135+#define gmu_poll_timeout_rscc(gmu, addr, val, cond, interval, timeout) \
136+ readl_poll_timeout((gmu)->rscc + ((addr) << 2), val, cond, \
137+ interval, timeout)
138+
114139 /*
115140 * These are the available OOB (out of band requests) to the GMU where "out of
116141 * band" means that the CPU talks to the GMU directly and not through HFI.
@@ -156,10 +181,16 @@ enum a6xx_gmu_oob_state { · 39 unmodified lines
156181 #define GMU_OOB_GPU_SET_ACK 24
157182 #define GMU_OOB_GPU_SET_CLEAR 24
158183
184+#define GMU_OOB_GPU_SET_REQUEST_NEW 30
185+#define GMU_OOB_GPU_SET_ACK_NEW 31
186+#define GMU_OOB_GPU_SET_CLEAR_NEW 31
187+
159188
160189 void a6xx_hfi_init(struct a6xx_gmu *gmu);
161190 int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state);
162191 void a6xx_hfi_stop(struct a6xx_gmu *gmu);
192+int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu);
193+int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, int index);
163194
164195 bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu);
165196 bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu);
drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h+29−19
@@ -101,6 +101,10 @@ static inline uint32_t A6XX_HFI_IRQ_OOB_MASK(uint32_t val) · 100 unmodified lines
101101
102102 #define REG_A6XX_GMU_DCVS_RETURN 0x000023ff
103103
104+#define REG_A6XX_GMU_ICACHE_CONFIG 0x00004c00
105+
106+#define REG_A6XX_GMU_DCACHE_CONFIG 0x00004c01
107+
104108 #define REG_A6XX_GMU_SYS_BUS_CONFIG 0x00004c0f
105109
106110 #define REG_A6XX_GMU_CM3_SYSRESET 0x00005000
@@ -199,6 +203,12 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val) · 92 unmodified lines
199203
200204 #define REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE 0x000050ec
201205
206+#define REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF 0x000050f0
207+
208+#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG 0x00005100
209+
210+#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP 0x00005101
211+
202212 #define REG_A6XX_GMU_BOOT_KMD_LM_HANDSHAKE 0x000051f0
203213
204214 #define REG_A6XX_GMU_LLM_GLM_SLEEP_CTRL 0x00005157
@@ -330,8 +340,6 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val) · 125 unmodified lines
330340
331341 #define REG_A6XX_GMU_AO_SPARE_CNTL 0x00009316
332342
333−#define REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0 0x00008c04
334−
335343 #define REG_A6XX_GMU_RSCC_CONTROL_REQ 0x00009307
336344
337345 #define REG_A6XX_GMU_RSCC_CONTROL_ACK 0x00009308
@@ -344,39 +352,41 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val) · 6 unmodified lines
344352
345353 #define REG_A6XX_GPU_CC_GX_DOMAIN_MISC 0x00009d42
346354
347−#define REG_A6XX_RSCC_PDC_SEQ_START_ADDR 0x00008c08
355+#define REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0 0x00000004
356+
357+#define REG_A6XX_RSCC_PDC_SEQ_START_ADDR 0x00000008
348358
349−#define REG_A6XX_RSCC_PDC_MATCH_VALUE_LO 0x00008c09
359+#define REG_A6XX_RSCC_PDC_MATCH_VALUE_LO 0x00000009
350360
351−#define REG_A6XX_RSCC_PDC_MATCH_VALUE_HI 0x00008c0a
361+#define REG_A6XX_RSCC_PDC_MATCH_VALUE_HI 0x0000000a
352362
353−#define REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0 0x00008c0b
363+#define REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0 0x0000000b
354364
355−#define REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR 0x00008c0d
365+#define REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR 0x0000000d
356366
357−#define REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA 0x00008c0e
367+#define REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA 0x0000000e
358368
359−#define REG_A6XX_RSCC_TIMESTAMP_UNIT0_TIMESTAMP_L_DRV0 0x00008c82
369+#define REG_A6XX_RSCC_TIMESTAMP_UNIT0_TIMESTAMP_L_DRV0 0x00000082
360370
361−#define REG_A6XX_RSCC_TIMESTAMP_UNIT0_TIMESTAMP_H_DRV0 0x00008c83
371+#define REG_A6XX_RSCC_TIMESTAMP_UNIT0_TIMESTAMP_H_DRV0 0x00000083
362372
363−#define REG_A6XX_RSCC_TIMESTAMP_UNIT1_EN_DRV0 0x00008c89
373+#define REG_A6XX_RSCC_TIMESTAMP_UNIT1_EN_DRV0 0x00000089
364374
365−#define REG_A6XX_RSCC_TIMESTAMP_UNIT1_OUTPUT_DRV0 0x00008c8c
375+#define REG_A6XX_RSCC_TIMESTAMP_UNIT1_OUTPUT_DRV0 0x0000008c
366376
367−#define REG_A6XX_RSCC_OVERRIDE_START_ADDR 0x00008d00
377+#define REG_A6XX_RSCC_OVERRIDE_START_ADDR 0x00000100
368378
369−#define REG_A6XX_RSCC_SEQ_BUSY_DRV0 0x00008d01
379+#define REG_A6XX_RSCC_SEQ_BUSY_DRV0 0x00000101
370380
371−#define REG_A6XX_RSCC_SEQ_MEM_0_DRV0 0x00008d80
381+#define REG_A6XX_RSCC_SEQ_MEM_0_DRV0 0x00000180
372382
373−#define REG_A6XX_RSCC_TCS0_DRV0_STATUS 0x00008f46
383+#define REG_A6XX_RSCC_TCS0_DRV0_STATUS 0x00000346
374384
375−#define REG_A6XX_RSCC_TCS1_DRV0_STATUS 0x000090ae
385+#define REG_A6XX_RSCC_TCS1_DRV0_STATUS 0x000003ee
376386
377−#define REG_A6XX_RSCC_TCS2_DRV0_STATUS 0x00009216
387+#define REG_A6XX_RSCC_TCS2_DRV0_STATUS 0x00000496
378388
379−#define REG_A6XX_RSCC_TCS3_DRV0_STATUS 0x0000937e
389+#define REG_A6XX_RSCC_TCS3_DRV0_STATUS 0x0000053e
380390
381391
382392 #endif /* A6XX_GMU_XML */
drivers/gpu/drm/msm/adreno/a6xx_gpu.c+59−11
@@ -414,7 +414,17 @@ static int a6xx_hw_init(struct msm_gpu *gpu) · 413 unmodified lines
414414 a6xx_set_hwcg(gpu, true);
415415
416416 /* VBIF/GBIF start*/
417− gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
417+ if (adreno_is_a640(adreno_gpu) || adreno_is_a650(adreno_gpu)) {
418+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE0, 0x00071620);
419+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE1, 0x00071620);
420+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE2, 0x00071620);
421+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
422+ gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
423+ gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x3);
424+ } else {
425+ gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
426+ }
427+
418428 if (adreno_is_a630(adreno_gpu))
419429 gpu_write(gpu, REG_A6XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000009);
420430
@@ -429,25 +439,35 @@ static int a6xx_hw_init(struct msm_gpu *gpu) · 8 unmodified lines
429439 gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_LO, 0xfffff000);
430440 gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_HI, 0x0001ffff);
431441
432− /* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */
433− gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN_LO,
434− REG_A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x00100000);
442+ if (!adreno_is_a650(adreno_gpu)) {
443+ /* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */
444+ gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN_LO,
445+ REG_A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x00100000);
435446
436− gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX_LO,
437− REG_A6XX_UCHE_GMEM_RANGE_MAX_HI,
438− 0x00100000 + adreno_gpu->gmem - 1);
447+ gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX_LO,
448+ REG_A6XX_UCHE_GMEM_RANGE_MAX_HI,
449+ 0x00100000 + adreno_gpu->gmem - 1);
450+ }
439451
440452 gpu_write(gpu, REG_A6XX_UCHE_FILTER_CNTL, 0x804);
441453 gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, 0x4);
442454
443− gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x010000c0);
455+ if (adreno_is_a640(adreno_gpu) || adreno_is_a650(adreno_gpu))
456+ gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
457+ else
458+ gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x010000c0);
444459 gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
445460
446461 /* Setting the mem pool size */
447462 gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
448463
449464 /* Setting the primFifo thresholds default values */
450− gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, (0x300 << 11));
465+ if (adreno_is_a650(adreno_gpu))
466+ gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300000);
467+ else if (adreno_is_a640(adreno_gpu))
468+ gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200000);
469+ else
470+ gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, (0x300 << 11));
451471
452472 /* Set the AHB default slave response to "ERROR" */
453473 gpu_write(gpu, REG_A6XX_CP_AHB_CNTL, 0x1);
@@ -471,6 +491,19 @@ static int a6xx_hw_init(struct msm_gpu *gpu) · 17 unmodified lines
471491
472492 gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, 1);
473493
494+ /* Set weights for bicubic filtering */
495+ if (adreno_is_a650(adreno_gpu)) {
496+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0, 0);
497+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1,
498+ 0x3fe05ff4);
499+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_2,
500+ 0x3fa0ebee);
501+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_3,
502+ 0x3f5193ed);
503+ gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_4,
504+ 0x3f0243f0);
505+ }
506+
474507 /* Protect registers from the CP */
475508 gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, 0x00000003);
476509
@@ -508,6 +541,11 @@ static int a6xx_hw_init(struct msm_gpu *gpu) · 31 unmodified lines
508541 A6XX_PROTECT_RDONLY(0x980, 0x4));
509542 gpu_write(gpu, REG_A6XX_CP_PROTECT(25), A6XX_PROTECT_RW(0xa630, 0x0));
510543
544+ if (adreno_is_a650(adreno_gpu)) {
545+ gpu_write(gpu, REG_A6XX_CP_APRIV_CNTL,
546+ (1 << 6) | (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1));
547+ }
548+
511549 /* Enable interrupts */
512550 gpu_write(gpu, REG_A6XX_RBBM_INT_0_MASK, A6XX_INT_MASK);
513551
@@ -566,8 +604,10 @@ out: · 52 unmodified lines
566604 */
567605 a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
568606
569− /* Take the GMU out of its special boot mode */
570− a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_BOOT_SLUMBER);
607+ if (a6xx_gpu->gmu.legacy) {
608+ /* Take the GMU out of its special boot mode */
609+ a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_BOOT_SLUMBER);
610+ }
571611
572612 return ret;
573613 }
@@ -810,6 +850,11 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu) · 236 unmodified lines
810850 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
811851 u64 busy_cycles, busy_time;
812852
853+
854+ /* Only read the gpu busy if the hardware is already active */
855+ if (pm_runtime_get_if_in_use(a6xx_gpu->gmu.dev) == 0)
856+ return 0;
857+
813858 busy_cycles = gmu_read64(&a6xx_gpu->gmu,
814859 REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L,
815860 REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H);
@@ -819,6 +864,8 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu) · 3 unmodified lines
819864
820865 gpu->devfreq.busy_cycles = busy_cycles;
821866
867+ pm_runtime_put(a6xx_gpu->gmu.dev);
868+
822869 if (WARN_ON(busy_time > ~0LU))
823870 return ~0LU;
824871
@@ -846,6 +893,7 @@ static const struct adreno_gpu_funcs funcs = { · 21 unmodified lines
846893 #if defined(CONFIG_DRM_MSM_GPU_STATE)
847894 .gpu_state_get = a6xx_gpu_state_get,
848895 .gpu_state_put = a6xx_gpu_state_put,
896+ .create_address_space = adreno_iommu_create_address_space,
849897 #endif
850898 },
851899 .get_timestamp = a6xx_get_timestamp,
drivers/gpu/drm/msm/adreno/a6xx_hfi.c+114−9
@@ -17,10 +17,14 @@ static const char * const a6xx_hfi_msg_id[] = { · 16 unmodified lines
1717 HFI_MSG_ID(HFI_H2F_MSG_BW_TABLE),
1818 HFI_MSG_ID(HFI_H2F_MSG_PERF_TABLE),
1919 HFI_MSG_ID(HFI_H2F_MSG_TEST),
20+ HFI_MSG_ID(HFI_H2F_MSG_START),
21+ HFI_MSG_ID(HFI_H2F_MSG_CORE_FW_START),
22+ HFI_MSG_ID(HFI_H2F_MSG_GX_BW_PERF_VOTE),
23+ HFI_MSG_ID(HFI_H2F_MSG_PREPARE_SLUMBER),
2024 };
2125
22−static int a6xx_hfi_queue_read(struct a6xx_hfi_queue *queue, u32 *data,
23− u32 dwords)
26+static int a6xx_hfi_queue_read(struct a6xx_gmu *gmu,
27+ struct a6xx_hfi_queue *queue, u32 *data, u32 dwords)
2428 {
2529 struct a6xx_hfi_queue_header *header = queue->header;
2630 u32 i, hdr, index = header->read_index;
@@ -48,6 +52,9 @@ static int a6xx_hfi_queue_read(struct a6xx_hfi_queue *queue, u32 *data, · 21 unmodified lines
4852 index = (index + 1) % header->size;
4953 }
5054
55+ if (!gmu->legacy)
56+ index = ALIGN(index, 4) % header->size;
57+
5158 header->read_index = index;
5259 return HFI_HEADER_SIZE(hdr);
5360 }
@@ -73,6 +80,12 @@ static int a6xx_hfi_queue_write(struct a6xx_gmu *gmu, · 19 unmodified lines
7380 index = (index + 1) % header->size;
7481 }
7582
83+ /* Cookify any non used data at the end of the write buffer */
84+ if (!gmu->legacy) {
85+ for (; index % 4; index = (index + 1) % header->size)
86+ queue->data[index] = 0xfafafafa;
87+ }
88+
7689 header->write_index = index;
7790 spin_unlock(&queue->lock);
7891
@@ -106,7 +119,7 @@ static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum, · 27 unmodified lines
106119 struct a6xx_hfi_msg_response resp;
107120
108121 /* Get the next packet */
109− ret = a6xx_hfi_queue_read(queue, (u32 *) &resp,
122+ ret = a6xx_hfi_queue_read(gmu, queue, (u32 *) &resp,
110123 sizeof(resp) >> 2);
111124
112125 /* If the queue is empty our response never made it */
@@ -176,8 +189,8 @@ static int a6xx_hfi_send_gmu_init(struct a6xx_gmu *gmu, int boot_state) · 63 unmodified lines
176189 {
177190 struct a6xx_hfi_msg_gmu_init_cmd msg = { 0 };
178191
179− msg.dbg_buffer_addr = (u32) gmu->debug->iova;
180− msg.dbg_buffer_size = (u32) gmu->debug->size;
192+ msg.dbg_buffer_addr = (u32) gmu->debug.iova;
193+ msg.dbg_buffer_size = (u32) gmu->debug.size;
181194 msg.boot_state = boot_state;
182195
183196 return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_INIT, &msg, sizeof(msg),
@@ -195,6 +208,28 @@ static int a6xx_hfi_get_fw_version(struct a6xx_gmu *gmu, u32 *version) · 11 unmodified lines
195208 version, sizeof(*version));
196209 }
197210
211+static int a6xx_hfi_send_perf_table_v1(struct a6xx_gmu *gmu)
212+{
213+ struct a6xx_hfi_msg_perf_table_v1 msg = { 0 };
214+ int i;
215+
216+ msg.num_gpu_levels = gmu->nr_gpu_freqs;
217+ msg.num_gmu_levels = gmu->nr_gmu_freqs;
218+
219+ for (i = 0; i < gmu->nr_gpu_freqs; i++) {
220+ msg.gx_votes[i].vote = gmu->gx_arc_votes[i];
221+ msg.gx_votes[i].freq = gmu->gpu_freqs[i] / 1000;
222+ }
223+
224+ for (i = 0; i < gmu->nr_gmu_freqs; i++) {
225+ msg.cx_votes[i].vote = gmu->cx_arc_votes[i];
226+ msg.cx_votes[i].freq = gmu->gmu_freqs[i] / 1000;
227+ }
228+
229+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_PERF_TABLE, &msg, sizeof(msg),
230+ NULL, 0);
231+}
232+
198233 static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu)
199234 {
200235 struct a6xx_hfi_msg_perf_table msg = { 0 };
@@ -205,6 +240,7 @@ static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu) · 4 unmodified lines
205240
206241 for (i = 0; i < gmu->nr_gpu_freqs; i++) {
207242 msg.gx_votes[i].vote = gmu->gx_arc_votes[i];
243+ msg.gx_votes[i].acd = 0xffffffff;
208244 msg.gx_votes[i].freq = gmu->gpu_freqs[i] / 1000;
209245 }
210246
@@ -306,7 +342,45 @@ static int a6xx_hfi_send_test(struct a6xx_gmu *gmu) · 95 unmodified lines
306342 NULL, 0);
307343 }
308344
309−int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
345+static int a6xx_hfi_send_start(struct a6xx_gmu *gmu)
346+{
347+ struct a6xx_hfi_msg_start msg = { 0 };
348+
349+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_START, &msg, sizeof(msg),
350+ NULL, 0);
351+}
352+
353+static int a6xx_hfi_send_core_fw_start(struct a6xx_gmu *gmu)
354+{
355+ struct a6xx_hfi_msg_core_fw_start msg = { 0 };
356+
357+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_CORE_FW_START, &msg,
358+ sizeof(msg), NULL, 0);
359+}
360+
361+int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, int index)
362+{
363+ struct a6xx_hfi_gx_bw_perf_vote_cmd msg = { 0 };
364+
365+ msg.ack_type = 1; /* blocking */
366+ msg.freq = index;
367+ msg.bw = 0; /* TODO: bus scaling */
368+
369+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_GX_BW_PERF_VOTE, &msg,
370+ sizeof(msg), NULL, 0);
371+}
372+
373+int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu)
374+{
375+ struct a6xx_hfi_prep_slumber_cmd msg = { 0 };
376+
377+ /* TODO: should freq and bw fields be non-zero ? */
378+
379+ return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_PREPARE_SLUMBER, &msg,
380+ sizeof(msg), NULL, 0);
381+}
382+
383+static int a6xx_hfi_start_v1(struct a6xx_gmu *gmu, int boot_state)
310384 {
311385 int ret;
312386
@@ -324,7 +398,7 @@ int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state) · 11 unmodified lines
324398 * the GMU firmware
325399 */
326400
327− ret = a6xx_hfi_send_perf_table(gmu);
401+ ret = a6xx_hfi_send_perf_table_v1(gmu);
328402 if (ret)
329403 return ret;
330404
@@ -341,6 +415,37 @@ int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state) · 10 unmodified lines
341415 return 0;
342416 }
343417
418+int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
419+{
420+ int ret;
421+
422+ if (gmu->legacy)
423+ return a6xx_hfi_start_v1(gmu, boot_state);
424+
425+
426+ ret = a6xx_hfi_send_perf_table(gmu);
427+ if (ret)
428+ return ret;
429+
430+ ret = a6xx_hfi_send_bw_table(gmu);
431+ if (ret)
432+ return ret;
433+
434+ ret = a6xx_hfi_send_core_fw_start(gmu);
435+ if (ret)
436+ return ret;
437+
438+ /*
439+ * Downstream driver sends this in its "a6xx_hw_init" equivalent,
440+ * but seems to be no harm in sending it here
441+ */
442+ ret = a6xx_hfi_send_start(gmu);
443+ if (ret)
444+ return ret;
445+
446+ return 0;
447+}
448+
344449 void a6xx_hfi_stop(struct a6xx_gmu *gmu)
345450 {
346451 int i;
@@ -385,7 +490,7 @@ static void a6xx_hfi_queue_init(struct a6xx_hfi_queue *queue, · 38 unmodified lines
385490
386491 void a6xx_hfi_init(struct a6xx_gmu *gmu)
387492 {
388− struct a6xx_gmu_bo *hfi = gmu->hfi;
493+ struct a6xx_gmu_bo *hfi = &gmu->hfi;
389494 struct a6xx_hfi_queue_table_header *table = hfi->virt;
390495 struct a6xx_hfi_queue_header *headers = hfi->virt + sizeof(*table);
391496 u64 offset;
@@ -415,5 +520,5 @@ void a6xx_hfi_init(struct a6xx_gmu *gmu) · 23 unmodified lines
415520 /* GMU response queue */
416521 offset += SZ_4K;
417522 a6xx_hfi_queue_init(&gmu->queues[1], &headers[1], hfi->virt + offset,
418− hfi->iova + offset, 4);
523+ hfi->iova + offset, gmu->legacy ? 4 : 1);
419524 }
drivers/gpu/drm/msm/adreno/a6xx_hfi.h+48−2
@@ -51,7 +51,8 @@ struct a6xx_hfi_queue { · 50 unmodified lines
5151 /* HFI message types */
5252
5353 #define HFI_MSG_CMD 0
54−#define HFI_MSG_ACK 2
54+#define HFI_MSG_ACK 1
55+#define HFI_MSG_ACK_V1 2
5556
5657 #define HFI_F2H_MSG_ACK 126
5758
@@ -94,7 +95,13 @@ struct perf_level { · 36 unmodified lines
9495 u32 freq;
9596 };
9697
97−struct a6xx_hfi_msg_perf_table {
98+struct perf_gx_level {
99+ u32 vote;
100+ u32 acd;
101+ u32 freq;
102+};
103+
104+struct a6xx_hfi_msg_perf_table_v1 {
98105 u32 header;
99106 u32 num_gpu_levels;
100107 u32 num_gmu_levels;
@@ -103,6 +110,15 @@ struct a6xx_hfi_msg_perf_table { · 2 unmodified lines
103110 struct perf_level cx_votes[4];
104111 };
105112
113+struct a6xx_hfi_msg_perf_table {
114+ u32 header;
115+ u32 num_gpu_levels;
116+ u32 num_gmu_levels;
117+
118+ struct perf_gx_level gx_votes[16];
119+ struct perf_level cx_votes[4];
120+};
121+
106122 #define HFI_H2F_MSG_BW_TABLE 3
107123
108124 struct a6xx_hfi_msg_bw_table {
@@ -124,4 +140,34 @@ struct a6xx_hfi_msg_test { · 15 unmodified lines
124140 u32 header;
125141 };
126142
143+#define HFI_H2F_MSG_START 10
144+
145+struct a6xx_hfi_msg_start {
146+ u32 header;
147+};
148+
149+#define HFI_H2F_MSG_CORE_FW_START 14
150+
151+struct a6xx_hfi_msg_core_fw_start {
152+ u32 header;
153+ u32 handle;
154+};
155+
156+#define HFI_H2F_MSG_GX_BW_PERF_VOTE 30
157+
158+struct a6xx_hfi_gx_bw_perf_vote_cmd {
159+ u32 header;
160+ u32 ack_type;
161+ u32 freq;
162+ u32 bw;
163+};
164+
165+#define HFI_H2F_MSG_PREPARE_SLUMBER 33
166+
167+struct a6xx_hfi_prep_slumber_cmd {
168+ u32 header;
169+ u32 bw;
170+ u32 freq;
171+};
172+
127173 #endif
drivers/gpu/drm/msm/adreno/adreno_device.c+35−0
@@ -92,6 +92,17 @@ static const struct adreno_info gpulist[] = { · 91 unmodified lines
9292 .gmem = SZ_1M,
9393 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
9494 .init = a3xx_gpu_init,
95+ }, {
96+ .rev = ADRENO_REV(4, 0, 5, ANY_ID),
97+ .revn = 405,
98+ .name = "A405",
99+ .fw = {
100+ [ADRENO_FW_PM4] = "a420_pm4.fw",
101+ [ADRENO_FW_PFP] = "a420_pfp.fw",
102+ },
103+ .gmem = SZ_256K,
104+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
105+ .init = a4xx_gpu_init,
95106 }, {
96107 .rev = ADRENO_REV(4, 2, 0, ANY_ID),
97108 .revn = 420,
@@ -189,6 +200,30 @@ static const struct adreno_info gpulist[] = { · 91 unmodified lines
189200 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
190201 .init = a6xx_gpu_init,
191202 .zapfw = "a630_zap.mdt",
203+ }, {
204+ .rev = ADRENO_REV(6, 4, 0, ANY_ID),
205+ .revn = 640,
206+ .name = "A640",
207+ .fw = {
208+ [ADRENO_FW_SQE] = "a630_sqe.fw",
209+ [ADRENO_FW_GMU] = "a640_gmu.bin",
210+ },
211+ .gmem = SZ_1M,
212+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
213+ .init = a6xx_gpu_init,
214+ .zapfw = "a640_zap.mdt",
215+ }, {
216+ .rev = ADRENO_REV(6, 5, 0, ANY_ID),
217+ .revn = 650,
218+ .name = "A650",
219+ .fw = {
220+ [ADRENO_FW_SQE] = "a650_sqe.fw",
221+ [ADRENO_FW_GMU] = "a650_gmu.bin",
222+ },
223+ .gmem = SZ_1M + SZ_128K,
224+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
225+ .init = a6xx_gpu_init,
226+ .zapfw = "a650_zap.mdt",
192227 },
193228 };
194229
drivers/gpu/drm/msm/adreno/adreno_gpu.c+19−8
@@ -185,6 +185,23 @@ int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid) · 184 unmodified lines
185185 return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid);
186186 }
187187
188+struct msm_gem_address_space *
189+adreno_iommu_create_address_space(struct msm_gpu *gpu,
190+ struct platform_device *pdev)
191+{
192+ struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
193+ struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, iommu);
194+ struct msm_gem_address_space *aspace;
195+
196+ aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
197+ 0xfffffff);
198+
199+ if (IS_ERR(aspace) && !IS_ERR(mmu))
200+ mmu->funcs->destroy(mmu);
201+
202+ return aspace;
203+}
204+
188205 int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
189206 {
190207 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -197,7 +214,7 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) · 6 unmodified lines
197214 *value = adreno_gpu->gmem;
198215 return 0;
199216 case MSM_PARAM_GMEM_BASE:
200− *value = 0x100000;
217+ *value = !adreno_is_a650(adreno_gpu) ? 0x100000 : 0;
201218 return 0;
202219 case MSM_PARAM_CHIP_ID:
203220 *value = adreno_gpu->rev.patchid |
@@ -459,7 +476,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, · 255 unmodified lines
459476 break;
460477 /* fall-thru */
461478 case MSM_SUBMIT_CMD_BUF:
462− OUT_PKT3(ring, adreno_is_a430(adreno_gpu) ?
479+ OUT_PKT3(ring, adreno_is_a4xx(adreno_gpu) ?
463480 CP_INDIRECT_BUFFER_PFE : CP_INDIRECT_BUFFER_PFD, 2);
464481 OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
465482 OUT_RING(ring, submit->cmd[i].size);
@@ -988,12 +1005,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, · 522 unmodified lines
9881005
9891006 adreno_gpu_config.ioname = "kgsl_3d0_reg_memory";
9901007
991− adreno_gpu_config.va_start = SZ_16M;
992− adreno_gpu_config.va_end = 0xffffffff;
993− /* maximum range of a2xx mmu */
994− if (adreno_is_a2xx(adreno_gpu))
995− adreno_gpu_config.va_end = SZ_16M + 0xfff * SZ_64K;
996−
9971008 adreno_gpu_config.nr_rings = nr_rings;
9981009
9991010 adreno_get_pwrlevels(&pdev->dev, gpu);
drivers/gpu/drm/msm/adreno/adreno_gpu.h+23−0
@@ -202,6 +202,11 @@ static inline bool adreno_is_a4xx(struct adreno_gpu *gpu) · 201 unmodified lines
202202 return (gpu->revn >= 400) && (gpu->revn < 500);
203203 }
204204
205+static inline int adreno_is_a405(struct adreno_gpu *gpu)
206+{
207+ return gpu->revn == 405;
208+}
209+
205210 static inline int adreno_is_a420(struct adreno_gpu *gpu)
206211 {
207212 return gpu->revn == 420;
@@ -237,6 +242,16 @@ static inline int adreno_is_a630(struct adreno_gpu *gpu) · 29 unmodified lines
237242 return gpu->revn == 630;
238243 }
239244
245+static inline int adreno_is_a640(struct adreno_gpu *gpu)
246+{
247+ return gpu->revn == 640;
248+}
249+
250+static inline int adreno_is_a650(struct adreno_gpu *gpu)
251+{
252+ return gpu->revn == 650;
253+}
254+
240255 int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value);
241256 const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu,
242257 const char *fwname);
@@ -272,6 +287,14 @@ void adreno_gpu_state_destroy(struct msm_gpu_state *state); · 29 unmodified lines
272287 int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state);
273288 int adreno_gpu_state_put(struct msm_gpu_state *state);
274289
290+/*
291+ * Common helper function to initialize the default address space for arm-smmu
292+ * attached targets
293+ */
294+struct msm_gem_address_space *
295+adreno_iommu_create_address_space(struct msm_gpu *gpu,
296+ struct platform_device *pdev);
297+
275298 /*
276299 * For a5xx and a6xx targets load the zap shader that is used to pull the GPU
277300 * out of secure mode
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c+1−22
@@ -36,22 +36,6 @@ static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) · 35 unmodified lines
3636 return to_dpu_kms(priv->kms);
3737 }
3838
39−static bool _dpu_core_video_mode_intf_connected(struct drm_crtc *crtc)
40−{
41− struct drm_crtc *tmp_crtc;
42−
43− drm_for_each_crtc(tmp_crtc, crtc->dev) {
44− if ((dpu_crtc_get_intf_mode(tmp_crtc) == INTF_MODE_VIDEO) &&
45− tmp_crtc->enabled) {
46− DPU_DEBUG("video interface connected crtc:%d\n",
47− tmp_crtc->base.id);
48− return true;
49− }
50− }
51−
52− return false;
53−}
54−
5539 static void _dpu_core_perf_calc_crtc(struct dpu_kms *kms,
5640 struct drm_crtc *crtc,
5741 struct drm_crtc_state *state,
@@ -94,7 +78,6 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, · 36 unmodified lines
9478 u32 bw, threshold;
9579 u64 bw_sum_of_intfs = 0;
9680 enum dpu_crtc_client_type curr_client_type;
97− bool is_video_mode;
9881 struct dpu_crtc_state *dpu_cstate;
9982 struct drm_crtc *tmp_crtc;
10083 struct dpu_kms *kms;
@@ -144,11 +127,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, · 43 unmodified lines
144127 bw = DIV_ROUND_UP_ULL(bw_sum_of_intfs, 1000);
145128 DPU_DEBUG("calculated bandwidth=%uk\n", bw);
146129
147− is_video_mode = dpu_crtc_get_intf_mode(crtc) == INTF_MODE_VIDEO;
148− threshold = (is_video_mode ||
149− _dpu_core_video_mode_intf_connected(crtc)) ?
150− kms->catalog->perf.max_bw_low :
151− kms->catalog->perf.max_bw_high;
130+ threshold = kms->catalog->perf.max_bw_high;
152131
153132 DPU_DEBUG("final threshold bw limit = %d\n", threshold);
154133
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c+77−18
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 #include <linux/sort.h>
1010 #include <linux/debugfs.h>
1111 #include <linux/ktime.h>
12+#include <linux/bits.h>
1213
1314 #include <drm/drm_crtc.h>
1415 #include <drm/drm_flip_work.h>
@@ -20,6 +21,7 @@ · 5 unmodified lines
2021 #include "dpu_kms.h"
2122 #include "dpu_hw_lm.h"
2223 #include "dpu_hw_ctl.h"
24+#include "dpu_hw_dspp.h"
2325 #include "dpu_crtc.h"
2426 #include "dpu_plane.h"
2527 #include "dpu_encoder.h"
@@ -40,6 +42,9 @@ · 14 unmodified lines
4042 /* timeout in ms waiting for frame done */
4143 #define DPU_CRTC_FRAME_DONE_TIMEOUT_MS 60
4244
45+#define CONVERT_S3_15(val) \
46+ (((((u64)val) & ~BIT_ULL(63)) >> 17) & GENMASK_ULL(17, 0))
47+
4348 static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
4449 {
4550 struct msm_drm_private *priv = crtc->dev->dev_private;
@@ -88,11 +93,9 @@ static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer, · 42 unmodified lines
8893
8994 static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
9095 {
91− struct dpu_crtc *dpu_crtc;
9296 struct dpu_crtc_state *crtc_state;
9397 int lm_idx, lm_horiz_position;
9498
95− dpu_crtc = to_dpu_crtc(crtc);
9699 crtc_state = to_dpu_crtc_state(crtc->state);
97100
98101 lm_horiz_position = 0;
@@ -422,6 +425,74 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, · 323 unmodified lines
422425 drm_mode_debug_printmodeline(adj_mode);
423426 }
424427
428+static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state,
429+ struct dpu_hw_pcc_cfg *cfg)
430+{
431+ struct drm_color_ctm *ctm;
432+
433+ memset(cfg, 0, sizeof(struct dpu_hw_pcc_cfg));
434+
435+ ctm = (struct drm_color_ctm *)state->ctm->data;
436+
437+ if (!ctm)
438+ return;
439+
440+ cfg->r.r = CONVERT_S3_15(ctm->matrix[0]);
441+ cfg->g.r = CONVERT_S3_15(ctm->matrix[1]);
442+ cfg->b.r = CONVERT_S3_15(ctm->matrix[2]);
443+
444+ cfg->r.g = CONVERT_S3_15(ctm->matrix[3]);
445+ cfg->g.g = CONVERT_S3_15(ctm->matrix[4]);
446+ cfg->b.g = CONVERT_S3_15(ctm->matrix[5]);
447+
448+ cfg->r.b = CONVERT_S3_15(ctm->matrix[6]);
449+ cfg->g.b = CONVERT_S3_15(ctm->matrix[7]);
450+ cfg->b.b = CONVERT_S3_15(ctm->matrix[8]);
451+}
452+
453+static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
454+{
455+ struct drm_crtc_state *state = crtc->state;
456+ struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
457+ struct dpu_crtc_mixer *mixer = cstate->mixers;
458+ struct dpu_hw_pcc_cfg cfg;
459+ struct dpu_hw_ctl *ctl;
460+ struct dpu_hw_mixer *lm;
461+ struct dpu_hw_dspp *dspp;
462+ int i;
463+
464+
465+ if (!state->color_mgmt_changed)
466+ return;
467+
468+ for (i = 0; i < cstate->num_mixers; i++) {
469+ ctl = mixer[i].lm_ctl;
470+ lm = mixer[i].hw_lm;
471+ dspp = mixer[i].hw_dspp;
472+
473+ if (!dspp || !dspp->ops.setup_pcc)
474+ continue;
475+
476+ if (!state->ctm) {
477+ dspp->ops.setup_pcc(dspp, NULL);
478+ } else {
479+ _dpu_crtc_get_pcc_coeff(state, &cfg);
480+ dspp->ops.setup_pcc(dspp, &cfg);
481+ }
482+
483+ mixer[i].flush_mask |= ctl->ops.get_bitmask_dspp(ctl,
484+ mixer[i].hw_dspp->idx);
485+
486+ /* stage config flush mask */
487+ ctl->ops.update_pending_flush(ctl, mixer[i].flush_mask);
488+
489+ DPU_DEBUG("lm %d, ctl %d, flush mask 0x%x\n",
490+ mixer[i].hw_lm->idx - DSPP_0,
491+ ctl->idx - CTL_0,
492+ mixer[i].flush_mask);
493+ }
494+}
495+
425496 static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
426497 struct drm_crtc_state *old_state)
427498 {
@@ -430,7 +501,6 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, · 2 unmodified lines
430501 struct drm_encoder *encoder;
431502 struct drm_device *dev;
432503 unsigned long flags;
433− struct dpu_crtc_smmu_state_data *smmu_state;
434504
435505 if (!crtc) {
436506 DPU_ERROR("invalid crtc\n");
@@ -448,7 +518,6 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, · 11 unmodified lines
448518 dpu_crtc = to_dpu_crtc(crtc);
449519 cstate = to_dpu_crtc_state(crtc->state);
450520 dev = crtc->dev;
451− smmu_state = &dpu_crtc->smmu_state;
452521
453522 _dpu_crtc_setup_lm_bounds(crtc, crtc->state);
454523
@@ -475,6 +544,8 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, · 20 unmodified lines
475544
476545 _dpu_crtc_blend_setup(crtc);
477546
547+ _dpu_crtc_setup_cp_blocks(crtc);
548+
478549 /*
479550 * PP_DONE irq is only used by command mode for now.
480551 * It is better to request pending before FLUSH and START trigger
@@ -491,7 +562,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc, · 10 unmodified lines
491562 struct drm_device *dev;
492563 struct drm_plane *plane;
493564 struct msm_drm_private *priv;
494− struct msm_drm_thread *event_thread;
495565 unsigned long flags;
496566 struct dpu_crtc_state *cstate;
497567
@@ -513,8 +583,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc, · 15 unmodified lines
513583 return;
514584 }
515585
516− event_thread = &priv->event_thread[crtc->index];
517−
518586 if (dpu_crtc->event) {
519587 DPU_DEBUG("already received dpu_crtc->event\n");
520588 } else {
@@ -567,7 +635,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc, · 46 unmodified lines
567635 static void dpu_crtc_destroy_state(struct drm_crtc *crtc,
568636 struct drm_crtc_state *state)
569637 {
570− struct dpu_crtc *dpu_crtc;
571638 struct dpu_crtc_state *cstate;
572639
573640 if (!crtc || !state) {
@@ -575,7 +642,6 @@ static void dpu_crtc_destroy_state(struct drm_crtc *crtc, · 1 unmodified line
575642 return;
576643 }
577644
578− dpu_crtc = to_dpu_crtc(crtc);
579645 cstate = to_dpu_crtc_state(state);
580646
581647 DPU_DEBUG("crtc%d\n", crtc->base.id);
@@ -662,11 +728,9 @@ static void dpu_crtc_reset(struct drm_crtc *crtc) · 80 unmodified lines
662728 /**
663729 * dpu_crtc_duplicate_state - state duplicate hook
664730 * @crtc: Pointer to drm crtc structure
665− * @Returns: Pointer to new drm_crtc_state structure
666731 */
667732 static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc)
668733 {
669− struct dpu_crtc *dpu_crtc;
670734 struct dpu_crtc_state *cstate, *old_cstate;
671735
672736 if (!crtc || !crtc->state) {
@@ -674,7 +738,6 @@ static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc) · 1 unmodified line
674738 return NULL;
675739 }
676740
677− dpu_crtc = to_dpu_crtc(crtc);
678741 old_cstate = to_dpu_crtc_state(crtc->state);
679742 cstate = kmemdup(old_cstate, sizeof(*old_cstate), GFP_KERNEL);
680743 if (!cstate) {
@@ -693,9 +756,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, · 12 unmodified lines
693756 {
694757 struct dpu_crtc *dpu_crtc;
695758 struct dpu_crtc_state *cstate;
696− struct drm_display_mode *mode;
697759 struct drm_encoder *encoder;
698− struct msm_drm_private *priv;
699760 unsigned long flags;
700761 bool release_bandwidth = false;
701762
@@ -705,8 +766,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, · 3 unmodified lines
705766 }
706767 dpu_crtc = to_dpu_crtc(crtc);
707768 cstate = to_dpu_crtc_state(crtc->state);
708− mode = &cstate->base.adjusted_mode;
709− priv = crtc->dev->dev_private;
710769
711770 DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);
712771
@@ -768,14 +827,12 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, · 55 unmodified lines
768827 {
769828 struct dpu_crtc *dpu_crtc;
770829 struct drm_encoder *encoder;
771− struct msm_drm_private *priv;
772830 bool request_bandwidth;
773831
774832 if (!crtc) {
775833 DPU_ERROR("invalid crtc\n");
776834 return;
777835 }
778− priv = crtc->dev->dev_private;
779836
780837 pm_runtime_get_sync(crtc->dev->dev);
781838
@@ -1319,6 +1376,8 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, · 537 unmodified lines
13191376
13201377 drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
13211378
1379+ drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
1380+
13221381 /* save user friendly CRTC name for later */
13231382 snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
13241383
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h+2−0
@@ -73,12 +73,14 @@ struct dpu_crtc_smmu_state_data { · 72 unmodified lines
7373 * struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC
7474 * @hw_lm: LM HW Driver context
7575 * @lm_ctl: CTL Path HW driver context
76+ * @lm_dspp: DSPP HW driver context
7677 * @mixer_op_mode: mixer blending operation mode
7778 * @flush_mask: mixer flush mask for ctl, mixer and pipe
7879 */
7980 struct dpu_crtc_mixer {
8081 struct dpu_hw_mixer *hw_lm;
8182 struct dpu_hw_ctl *lm_ctl;
83+ struct dpu_hw_dspp *hw_dspp;
8284 u32 mixer_op_mode;
8385 u32 flush_mask;
8486 };
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c+11−1
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include "dpu_hw_catalog.h"
2121 #include "dpu_hw_intf.h"
2222 #include "dpu_hw_ctl.h"
23+#include "dpu_hw_dspp.h"
2324 #include "dpu_formats.h"
2425 #include "dpu_encoder_phys.h"
2526 #include "dpu_crtc.h"
@@ -536,6 +537,7 @@ static struct msm_display_topology dpu_encoder_get_topology( · 510 unmodified lines
536537 * 1 LM, 1 INTF
537538 * 2 LM, 1 INTF (stream merge to support high resolution interfaces)
538539 *
540+ * Adding color blocks only to primary interface
539541 */
540542 if (intf_count == 2)
541543 topology.num_lm = 2;
@@ -544,6 +546,9 @@ static struct msm_display_topology dpu_encoder_get_topology( · 2 unmodified lines
544546 else
545547 topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
546548
549+ if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI)
550+ topology.num_dspp = topology.num_lm;
551+
547552 topology.num_enc = 0;
548553 topology.num_intf = intf_count;
549554
@@ -959,7 +964,8 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, · 409 unmodified lines
959964 struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
960965 struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
961966 struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
962− int num_lm, num_ctl, num_pp;
967+ struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
968+ int num_lm, num_ctl, num_pp, num_dspp;
963969 int i, j;
964970
965971 if (!drm_enc) {
@@ -1008,6 +1014,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, · 42 unmodified lines
10081014 drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
10091015 num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
10101016 drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
1017+ num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
1018+ drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
1019+ ARRAY_SIZE(hw_dspp));
10111020
10121021 for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
10131022 dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
@@ -1020,6 +1029,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, · 6 unmodified lines
10201029
10211030 cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
10221031 cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
1032+ cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
10231033 }
10241034
10251035 cstate->num_mixers = num_lm;
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c+36−12
@@ -41,6 +41,8 @@ · 40 unmodified lines
4141 #define PINGPONG_SDM845_SPLIT_MASK \
4242 (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
4343
44+#define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC)
45+
4446 #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
4547 #define DEFAULT_DPU_LINE_WIDTH 2048
4648 #define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560
@@ -291,29 +293,30 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = { · 244 unmodified lines
291293 },
292294 };
293295
294−#define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair) \
296+#define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \
295297 { \
296298 .name = _name, .id = _id, \
297299 .base = _base, .len = 0x320, \
298300 .features = _fmask, \
299301 .sblk = _sblk, \
300302 .pingpong = _pp, \
301− .lm_pair_mask = (1 << _lmpair) \
303+ .lm_pair_mask = (1 << _lmpair), \
304+ .dspp = _dspp \
302305 }
303306
304307 static const struct dpu_lm_cfg sdm845_lm[] = {
305308 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK,
306− &sdm845_lm_sblk, PINGPONG_0, LM_1),
309+ &sdm845_lm_sblk, PINGPONG_0, LM_1, 0),
307310 LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK,
308− &sdm845_lm_sblk, PINGPONG_1, LM_0),
311+ &sdm845_lm_sblk, PINGPONG_1, LM_0, 0),
309312 LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK,
310− &sdm845_lm_sblk, PINGPONG_2, LM_5),
313+ &sdm845_lm_sblk, PINGPONG_2, LM_5, 0),
311314 LM_BLK("lm_3", LM_3, 0x0, MIXER_SDM845_MASK,
312− &sdm845_lm_sblk, PINGPONG_MAX, 0),
315+ &sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
313316 LM_BLK("lm_4", LM_4, 0x0, MIXER_SDM845_MASK,
314− &sdm845_lm_sblk, PINGPONG_MAX, 0),
317+ &sdm845_lm_sblk, PINGPONG_MAX, 0, 0),
315318 LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK,
316− &sdm845_lm_sblk, PINGPONG_3, LM_2),
319+ &sdm845_lm_sblk, PINGPONG_3, LM_2, 0),
317320 };
318321
319322 /* SC7180 */
@@ -328,11 +331,30 @@ static const struct dpu_lm_sub_blks sc7180_lm_sblk = { · 8 unmodified lines
328331
329332 static const struct dpu_lm_cfg sc7180_lm[] = {
330333 LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK,
331− &sc7180_lm_sblk, PINGPONG_0, LM_1),
334+ &sc7180_lm_sblk, PINGPONG_0, LM_1, DSPP_0),
332335 LM_BLK("lm_1", LM_1, 0x45000, MIXER_SC7180_MASK,
333− &sc7180_lm_sblk, PINGPONG_1, LM_0),
336+ &sc7180_lm_sblk, PINGPONG_1, LM_0, 0),
337+};
338+
339+/*************************************************************
340+ * DSPP sub blocks config
341+ *************************************************************/
342+static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = {
343+ .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700,
344+ .len = 0x90, .version = 0x10000},
334345 };
335346
347+#define DSPP_BLK(_name, _id, _base) \
348+ {\
349+ .name = _name, .id = _id, \
350+ .base = _base, .len = 0x1800, \
351+ .features = DSPP_SC7180_MASK, \
352+ .sblk = &sc7180_dspp_sblk \
353+ }
354+
355+static const struct dpu_dspp_cfg sc7180_dspp[] = {
356+ DSPP_BLK("dspp_0", DSPP_0, 0x54000),
357+};
336358 /*************************************************************
337359 * PINGPONG sub blocks config
338360 *************************************************************/
@@ -515,8 +537,8 @@ static const struct dpu_perf_cfg sdm845_perf_data = { · 176 unmodified lines
515537 };
516538
517539 static const struct dpu_perf_cfg sc7180_perf_data = {
518− .max_bw_low = 3900000,
519− .max_bw_high = 5500000,
540+ .max_bw_low = 6800000,
541+ .max_bw_high = 6800000,
520542 .min_core_ib = 2400000,
521543 .min_llcc_ib = 800000,
522544 .min_dram_ib = 800000,
@@ -587,6 +609,8 @@ static void sc7180_cfg_init(struct dpu_mdss_cfg *dpu_cfg) · 64 unmodified lines
587609 .sspp = sc7180_sspp,
588610 .mixer_count = ARRAY_SIZE(sc7180_lm),
589611 .mixer = sc7180_lm,
612+ .dspp_count = ARRAY_SIZE(sc7180_dspp),
613+ .dspp = sc7180_dspp,
590614 .pingpong_count = ARRAY_SIZE(sc7180_pp),
591615 .pingpong = sc7180_pp,
592616 .intf_count = ARRAY_SIZE(sc7180_intf),
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h+39−0
@@ -145,6 +145,17 @@ enum { · 144 unmodified lines
145145 DPU_MIXER_MAX
146146 };
147147
148+/**
149+ * DSPP sub-blocks
150+ * @DPU_DSPP_PCC Panel color correction block
151+ * @DPU_DSPP_GC Gamma correction block
152+ */
153+enum {
154+ DPU_DSPP_PCC = 0x1,
155+ DPU_DSPP_GC,
156+ DPU_DSPP_MAX
157+};
158+
148159 /**
149160 * PINGPONG sub-blocks
150161 * @DPU_PINGPONG_TE Tear check block
@@ -377,6 +388,16 @@ struct dpu_lm_sub_blks { · 226 unmodified lines
377388 struct dpu_pp_blk gc;
378389 };
379390
391+/**
392+ * struct dpu_dspp_sub_blks: Information of DSPP block
393+ * @gc : gamma correction block
394+ * @pcc: pixel color correction block
395+ */
396+struct dpu_dspp_sub_blks {
397+ struct dpu_pp_blk gc;
398+ struct dpu_pp_blk pcc;
399+};
400+
380401 struct dpu_pingpong_sub_blks {
381402 struct dpu_pp_blk te;
382403 struct dpu_pp_blk te2;
@@ -471,9 +492,23 @@ struct dpu_lm_cfg { · 88 unmodified lines
471492 DPU_HW_BLK_INFO;
472493 const struct dpu_lm_sub_blks *sblk;
473494 u32 pingpong;
495+ u32 dspp;
474496 unsigned long lm_pair_mask;
475497 };
476498
499+/**
500+ * struct dpu_dspp_cfg - information of DSPP blocks
501+ * @id enum identifying this block
502+ * @base register offset of this block
503+ * @features bit mask identifying sub-blocks/features
504+ * supported by this block
505+ * @sblk sub-blocks information
506+ */
507+struct dpu_dspp_cfg {
508+ DPU_HW_BLK_INFO;
509+ const struct dpu_dspp_sub_blks *sblk;
510+};
511+
477512 /**
478513 * struct dpu_pingpong_cfg - information of PING-PONG blocks
479514 * @id enum identifying this block
@@ -688,6 +723,9 @@ struct dpu_mdss_cfg { · 208 unmodified lines
688723
689724 u32 ad_count;
690725
726+ u32 dspp_count;
727+ const struct dpu_dspp_cfg *dspp;
728+
691729 /* Add additional block data structures here */
692730
693731 struct dpu_perf_cfg perf;
@@ -716,6 +754,7 @@ struct dpu_mdss_hw_cfg_handler { · 22 unmodified lines
716754 #define BLK_PINGPONG(s) ((s)->pingpong)
717755 #define BLK_INTF(s) ((s)->intf)
718756 #define BLK_AD(s) ((s)->ad)
757+#define BLK_DSPP(s) ((s)->dspp)
719758
720759 /**
721760 * dpu_hw_catalog_init - dpu hardware catalog init API retrieves
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c+26−0
@@ -272,6 +272,31 @@ static int dpu_hw_ctl_active_get_bitmask_intf(struct dpu_hw_ctl *ctx, · 271 unmodified lines
272272 return 0;
273273 }
274274
275+static uint32_t dpu_hw_ctl_get_bitmask_dspp(struct dpu_hw_ctl *ctx,
276+ enum dpu_dspp dspp)
277+{
278+ uint32_t flushbits = 0;
279+
280+ switch (dspp) {
281+ case DSPP_0:
282+ flushbits = BIT(13);
283+ break;
284+ case DSPP_1:
285+ flushbits = BIT(14);
286+ break;
287+ case DSPP_2:
288+ flushbits = BIT(15);
289+ break;
290+ case DSPP_3:
291+ flushbits = BIT(21);
292+ break;
293+ default:
294+ return 0;
295+ }
296+
297+ return flushbits;
298+}
299+
275300 static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
276301 {
277302 struct dpu_hw_blk_reg_map *c = &ctx->hw;
@@ -548,6 +573,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, · 270 unmodified lines
548573 ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
549574 ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp;
550575 ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer;
576+ ops->get_bitmask_dspp = dpu_hw_ctl_get_bitmask_dspp;
551577 };
552578
553579 static struct dpu_hw_blk_ops dpu_hw_ops;
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h+3−0
@@ -139,6 +139,9 @@ struct dpu_hw_ctl_ops { · 138 unmodified lines
139139 uint32_t (*get_bitmask_mixer)(struct dpu_hw_ctl *ctx,
140140 enum dpu_lm blk);
141141
142+ uint32_t (*get_bitmask_dspp)(struct dpu_hw_ctl *ctx,
143+ enum dpu_dspp blk);
144+
142145 /**
143146 * Query the value of the intf flush mask
144147 * No effect on hardware
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c+129−0
@@ -0,0 +1,129 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
3+ */
4+
5+#include "dpu_hwio.h"
6+#include "dpu_hw_catalog.h"
7+#include "dpu_hw_lm.h"
8+#include "dpu_hw_dspp.h"
9+#include "dpu_kms.h"
10+
11+
12+/* DSPP_PCC */
13+#define PCC_EN BIT(0)
14+#define PCC_DIS 0
15+#define PCC_RED_R_OFF 0x10
16+#define PCC_RED_G_OFF 0x1C
17+#define PCC_RED_B_OFF 0x28
18+#define PCC_GREEN_R_OFF 0x14
19+#define PCC_GREEN_G_OFF 0x20
20+#define PCC_GREEN_B_OFF 0x2C
21+#define PCC_BLUE_R_OFF 0x18
22+#define PCC_BLUE_G_OFF 0x24
23+#define PCC_BLUE_B_OFF 0x30
24+
25+static void dpu_setup_dspp_pcc(struct dpu_hw_dspp *ctx,
26+ struct dpu_hw_pcc_cfg *cfg)
27+{
28+
29+ u32 base = ctx->cap->sblk->pcc.base;
30+
31+ if (!ctx || !base) {
32+ DRM_ERROR("invalid ctx %pK pcc base 0x%x\n", ctx, base);
33+ return;
34+ }
35+
36+ if (!cfg) {
37+ DRM_DEBUG_DRIVER("disable pcc feature\n");
38+ DPU_REG_WRITE(&ctx->hw, base, PCC_DIS);
39+ return;
40+ }
41+
42+ DPU_REG_WRITE(&ctx->hw, base + PCC_RED_R_OFF, cfg->r.r);
43+ DPU_REG_WRITE(&ctx->hw, base + PCC_RED_G_OFF, cfg->r.g);
44+ DPU_REG_WRITE(&ctx->hw, base + PCC_RED_B_OFF, cfg->r.b);
45+
46+ DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_R_OFF, cfg->g.r);
47+ DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_G_OFF, cfg->g.g);
48+ DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_B_OFF, cfg->g.b);
49+
50+ DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_R_OFF, cfg->b.r);
51+ DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_G_OFF, cfg->b.g);
52+ DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_B_OFF, cfg->b.b);
53+
54+ DPU_REG_WRITE(&ctx->hw, base, PCC_EN);
55+}
56+
57+static void _setup_dspp_ops(struct dpu_hw_dspp *c,
58+ unsigned long features)
59+{
60+ if (test_bit(DPU_DSPP_PCC, &features) &&
61+ IS_SC7180_TARGET(c->hw.hwversion))
62+ c->ops.setup_pcc = dpu_setup_dspp_pcc;
63+}
64+
65+static const struct dpu_dspp_cfg *_dspp_offset(enum dpu_dspp dspp,
66+ const struct dpu_mdss_cfg *m,
67+ void __iomem *addr,
68+ struct dpu_hw_blk_reg_map *b)
69+{
70+ int i;
71+
72+ if (!m || !addr || !b)
73+ return ERR_PTR(-EINVAL);
74+
75+ for (i = 0; i < m->dspp_count; i++) {
76+ if (dspp == m->dspp[i].id) {
77+ b->base_off = addr;
78+ b->blk_off = m->dspp[i].base;
79+ b->length = m->dspp[i].len;
80+ b->hwversion = m->hwversion;
81+ b->log_mask = DPU_DBG_MASK_DSPP;
82+ return &m->dspp[i];
83+ }
84+ }
85+
86+ return ERR_PTR(-EINVAL);
87+}
88+
89+static struct dpu_hw_blk_ops dpu_hw_ops;
90+
91+struct dpu_hw_dspp *dpu_hw_dspp_init(enum dpu_dspp idx,
92+ void __iomem *addr,
93+ const struct dpu_mdss_cfg *m)
94+{
95+ struct dpu_hw_dspp *c;
96+ const struct dpu_dspp_cfg *cfg;
97+
98+ if (!addr || !m)
99+ return ERR_PTR(-EINVAL);
100+
101+ c = kzalloc(sizeof(*c), GFP_KERNEL);
102+ if (!c)
103+ return ERR_PTR(-ENOMEM);
104+
105+ cfg = _dspp_offset(idx, m, addr, &c->hw);
106+ if (IS_ERR_OR_NULL(cfg)) {
107+ kfree(c);
108+ return ERR_PTR(-EINVAL);
109+ }
110+
111+ /* Assign ops */
112+ c->idx = idx;
113+ c->cap = cfg;
114+ _setup_dspp_ops(c, c->cap->features);
115+
116+ dpu_hw_blk_init(&c->base, DPU_HW_BLK_DSPP, idx, &dpu_hw_ops);
117+
118+ return c;
119+}
120+
121+void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp)
122+{
123+ if (dspp)
124+ dpu_hw_blk_destroy(&dspp->base);
125+
126+ kfree(dspp);
127+}
128+
129+
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h+100−0
@@ -0,0 +1,100 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
3+ */
4+
5+#ifndef _DPU_HW_DSPP_H
6+#define _DPU_HW_DSPP_H
7+
8+#include "dpu_hw_blk.h"
9+
10+struct dpu_hw_dspp;
11+
12+/**
13+ * struct dpu_hw_pcc_coeff - PCC coefficient structure for each color
14+ * component.
15+ * @r: red coefficient.
16+ * @g: green coefficient.
17+ * @b: blue coefficient.
18+ */
19+
20+struct dpu_hw_pcc_coeff {
21+ __u32 r;
22+ __u32 g;
23+ __u32 b;
24+};
25+
26+/**
27+ * struct dpu_hw_pcc - pcc feature structure
28+ * @r: red coefficients.
29+ * @g: green coefficients.
30+ * @b: blue coefficients.
31+ */
32+struct dpu_hw_pcc_cfg {
33+ struct dpu_hw_pcc_coeff r;
34+ struct dpu_hw_pcc_coeff g;
35+ struct dpu_hw_pcc_coeff b;
36+};
37+
38+/**
39+ * struct dpu_hw_dspp_ops - interface to the dspp hardware driver functions
40+ * Caller must call the init function to get the dspp context for each dspp
41+ * Assumption is these functions will be called after clocks are enabled
42+ */
43+struct dpu_hw_dspp_ops {
44+ /**
45+ * setup_pcc - setup dspp pcc
46+ * @ctx: Pointer to dspp context
47+ * @cfg: Pointer to configuration
48+ */
49+ void (*setup_pcc)(struct dpu_hw_dspp *ctx, struct dpu_hw_pcc_cfg *cfg);
50+
51+};
52+
53+/**
54+ * struct dpu_hw_dspp - dspp description
55+ * @base: Hardware block base structure
56+ * @hw: Block hardware details
57+ * @idx: DSPP index
58+ * @cap: Pointer to layer_cfg
59+ * @ops: Pointer to operations possible for this DSPP
60+ */
61+struct dpu_hw_dspp {
62+ struct dpu_hw_blk base;
63+ struct dpu_hw_blk_reg_map hw;
64+
65+ /* dspp */
66+ int idx;
67+ const struct dpu_dspp_cfg *cap;
68+
69+ /* Ops */
70+ struct dpu_hw_dspp_ops ops;
71+};
72+
73+/**
74+ * dpu_hw_dspp - convert base object dpu_hw_base to container
75+ * @hw: Pointer to base hardware block
76+ * return: Pointer to hardware block container
77+ */
78+static inline struct dpu_hw_dspp *to_dpu_hw_dspp(struct dpu_hw_blk *hw)
79+{
80+ return container_of(hw, struct dpu_hw_dspp, base);
81+}
82+
83+/**
84+ * dpu_hw_dspp_init - initializes the dspp hw driver object.
85+ * should be called once before accessing every dspp.
86+ * @idx: DSPP index for which driver object is required
87+ * @addr: Mapped register io address of MDP
88+ * @Return: pointer to structure or ERR_PTR
89+ */
90+struct dpu_hw_dspp *dpu_hw_dspp_init(enum dpu_dspp idx,
91+ void __iomem *addr, const struct dpu_mdss_cfg *m);
92+
93+/**
94+ * dpu_hw_dspp_destroy(): Destroys DSPP driver context
95+ * @dspp: Pointer to DSPP driver context
96+ */
97+void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp);
98+
99+#endif /*_DPU_HW_DSPP_H */
100+
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h+2−0
@@ -95,6 +95,7 @@ enum dpu_hw_blk_type { · 94 unmodified lines
9595 DPU_HW_BLK_PINGPONG,
9696 DPU_HW_BLK_INTF,
9797 DPU_HW_BLK_WB,
98+ DPU_HW_BLK_DSPP,
9899 DPU_HW_BLK_MAX,
99100 };
100101
@@ -425,5 +426,6 @@ struct dpu_mdss_color { · 324 unmodified lines
425426 #define DPU_DBG_MASK_TOP (1 << 7)
426427 #define DPU_DBG_MASK_VBIF (1 << 8)
427428 #define DPU_DBG_MASK_ROT (1 << 9)
429+#define DPU_DBG_MASK_DSPP (1 << 10)
428430
429431 #endif /* _DPU_HW_MDSS_H */
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c+5−13
@@ -772,29 +772,21 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) · 771 unmodified lines
772772 {
773773 struct iommu_domain *domain;
774774 struct msm_gem_address_space *aspace;
775− int ret;
775+ struct msm_mmu *mmu;
776776
777777 domain = iommu_domain_alloc(&platform_bus_type);
778778 if (!domain)
779779 return 0;
780780
781− domain->geometry.aperture_start = 0x1000;
782− domain->geometry.aperture_end = 0xffffffff;
781+ mmu = msm_iommu_new(dpu_kms->dev->dev, domain);
782+ aspace = msm_gem_address_space_create(mmu, "dpu1",
783+ 0x1000, 0xfffffff);
783784
784− aspace = msm_gem_address_space_create(dpu_kms->dev->dev,
785− domain, "dpu1");
786785 if (IS_ERR(aspace)) {
787− iommu_domain_free(domain);
786+ mmu->funcs->destroy(mmu);
788787 return PTR_ERR(aspace);
789788 }
790789
791− ret = aspace->mmu->funcs->attach(aspace->mmu);
792− if (ret) {
793− DPU_ERROR("failed to attach iommu %d\n", ret);
794− msm_gem_address_space_put(aspace);
795− return ret;
796− }
797−
798790 dpu_kms->base.aspace = aspace;
799791 return 0;
800792 }
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h+1−0
@@ -158,6 +158,7 @@ struct dpu_global_state { · 157 unmodified lines
158158 uint32_t mixer_to_enc_id[LM_MAX - LM_0];
159159 uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
160160 uint32_t intf_to_enc_id[INTF_MAX - INTF_0];
161+ uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
161162 };
162163
163164 struct dpu_global_state
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c+54−4
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 #include "dpu_hw_ctl.h"
1010 #include "dpu_hw_pingpong.h"
1111 #include "dpu_hw_intf.h"
12+#include "dpu_hw_dspp.h"
1213 #include "dpu_encoder.h"
1314 #include "dpu_trace.h"
1415
@@ -174,6 +175,23 @@ int dpu_rm_init(struct dpu_rm *rm, · 159 unmodified lines
174175 rm->ctl_blks[ctl->id - CTL_0] = &hw->base;
175176 }
176177
178+ for (i = 0; i < cat->dspp_count; i++) {
179+ struct dpu_hw_dspp *hw;
180+ const struct dpu_dspp_cfg *dspp = &cat->dspp[i];
181+
182+ if (dspp->id < DSPP_0 || dspp->id >= DSPP_MAX) {
183+ DPU_ERROR("skip dspp %d with invalid id\n", dspp->id);
184+ continue;
185+ }
186+ hw = dpu_hw_dspp_init(dspp->id, mmio, cat);
187+ if (IS_ERR_OR_NULL(hw)) {
188+ rc = PTR_ERR(hw);
189+ DPU_ERROR("failed dspp object creation: err %d\n", rc);
190+ goto fail;
191+ }
192+ rm->dspp_blks[dspp->id - DSPP_0] = &hw->base;
193+ }
194+
177195 return 0;
178196
179197 fail:
@@ -222,12 +240,17 @@ static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int primary_idx, · 42 unmodified lines
222240 * if lm, and all other hardwired blocks connected to the lm (pp) is
223241 * available and appropriate
224242 * @pp_idx: output parameter, index of pingpong block attached to the layer
225− * mixer in rm->pongpong_blks[].
243+ * mixer in rm->pingpong_blks[].
244+ * @dspp_idx: output parameter, index of dspp block attached to the layer
245+ * mixer in rm->dspp_blks[].
246+ * @reqs: input parameter, rm requirements for HW blocks needed in the
247+ * datapath.
226248 * @Return: true if lm matches all requirements, false otherwise
227249 */
228250 static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
229251 struct dpu_global_state *global_state,
230− uint32_t enc_id, int lm_idx, int *pp_idx)
252+ uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx,
253+ struct dpu_rm_requirements *reqs)
231254 {
232255 const struct dpu_lm_cfg *lm_cfg;
233256 int idx;
@@ -251,6 +274,23 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, · 17 unmodified lines
251274 return false;
252275 }
253276 *pp_idx = idx;
277+
278+ if (!reqs->topology.num_dspp)
279+ return true;
280+
281+ idx = lm_cfg->dspp - DSPP_0;
282+ if (idx < 0 || idx >= ARRAY_SIZE(rm->dspp_blks)) {
283+ DPU_ERROR("failed to get dspp on lm %d\n", lm_cfg->dspp);
284+ return false;
285+ }
286+
287+ if (reserved_by_other(global_state->dspp_to_enc_id, idx, enc_id)) {
288+ DPU_DEBUG("lm %d dspp %d already reserved\n", lm_cfg->id,
289+ lm_cfg->dspp);
290+ return false;
291+ }
292+ *dspp_idx = idx;
293+
254294 return true;
255295 }
256296
@@ -262,6 +302,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, · 5 unmodified lines
262302 {
263303 int lm_idx[MAX_BLOCKS];
264304 int pp_idx[MAX_BLOCKS];
305+ int dspp_idx[MAX_BLOCKS] = {0};
265306 int i, j, lm_count = 0;
266307
267308 if (!reqs->topology.num_lm) {
@@ -279,7 +320,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, · 11 unmodified lines
279320 lm_idx[lm_count] = i;
280321
281322 if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
282− enc_id, i, &pp_idx[lm_count])) {
323+ enc_id, i, &pp_idx[lm_count],
324+ &dspp_idx[lm_count], reqs)) {
283325 continue;
284326 }
285327
@@ -299,7 +341,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, · 13 unmodified lines
299341
300342 if (!_dpu_rm_check_lm_and_get_connected_blks(rm,
301343 global_state, enc_id, j,
302− &pp_idx[lm_count])) {
344+ &pp_idx[lm_count], &dspp_idx[lm_count],
345+ reqs)) {
303346 continue;
304347 }
305348
@@ -316,6 +359,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, · 10 unmodified lines
316359 for (i = 0; i < lm_count; i++) {
317360 global_state->mixer_to_enc_id[lm_idx[i]] = enc_id;
318361 global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id;
362+ global_state->dspp_to_enc_id[dspp_idx[i]] =
363+ reqs->topology.num_dspp ? enc_id : 0;
319364
320365 trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id,
321366 pp_idx[i] + PINGPONG_0);
@@ -560,6 +605,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, · 238 unmodified lines
560605 hw_to_enc_id = global_state->intf_to_enc_id;
561606 max_blks = ARRAY_SIZE(rm->intf_blks);
562607 break;
608+ case DPU_HW_BLK_DSPP:
609+ hw_blks = rm->dspp_blks;
610+ hw_to_enc_id = global_state->dspp_to_enc_id;
611+ max_blks = ARRAY_SIZE(rm->dspp_blks);
612+ break;
563613 default:
564614 DPU_ERROR("blk type %d not managed by rm\n", type);
565615 return 0;
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h+2−0
@@ -19,6 +19,7 @@ struct dpu_global_state; · 18 unmodified lines
1919 * @mixer_blks: array of layer mixer hardware resources
2020 * @ctl_blks: array of ctl hardware resources
2121 * @intf_blks: array of intf hardware resources
22+ * @dspp_blks: array of dspp hardware resources
2223 * @lm_max_width: cached layer mixer maximum width
2324 * @rm_lock: resource manager mutex
2425 */
@@ -27,6 +28,7 @@ struct dpu_rm { · 2 unmodified lines
2728 struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0];
2829 struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0];
2930 struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0];
31+ struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
3032
3133 uint32_t lm_max_width;
3234 };
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c+8−10
@@ -510,18 +510,20 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) · 509 unmodified lines
510510 mdelay(16);
511511
512512 if (config->iommu) {
513− aspace = msm_gem_address_space_create(&pdev->dev,
514− config->iommu, "mdp4");
513+ struct msm_mmu *mmu = msm_iommu_new(&pdev->dev,
514+ config->iommu);
515+
516+ aspace = msm_gem_address_space_create(mmu,
517+ "mdp4", 0x1000, 0xffffffff);
518+
515519 if (IS_ERR(aspace)) {
520+ if (!IS_ERR(mmu))
521+ mmu->funcs->destroy(mmu);
516522 ret = PTR_ERR(aspace);
517523 goto fail;
518524 }
519525
520526 kms->aspace = aspace;
521−
522− ret = aspace->mmu->funcs->attach(aspace->mmu);
523− if (ret)
524− goto fail;
525527 } else {
526528 DRM_DEV_INFO(dev->dev, "no iommu, fallback to phys "
527529 "contig buffers for scanout\n");
@@ -569,10 +571,6 @@ static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev) · 41 unmodified lines
569571 /* TODO: Chips that aren't apq8064 have a 200 Mhz max_clk */
570572 config.max_clk = 266667000;
571573 config.iommu = iommu_domain_alloc(&platform_bus_type);
572− if (config.iommu) {
573− config.iommu->geometry.aperture_start = 0x1000;
574− config.iommu->geometry.aperture_end = 0xffffffff;
575− }
576574
577575 return &config;
578576 }
drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c+76−4
@@ -342,6 +342,81 @@ static const struct mdp5_cfg_hw msm8x16_config = { · 341 unmodified lines
342342 .max_clk = 320000000,
343343 };
344344
345+static const struct mdp5_cfg_hw msm8x36_config = {
346+ .name = "msm8x36",
347+ .mdp = {
348+ .count = 1,
349+ .base = { 0x0 },
350+ .caps = MDP_CAP_SMP |
351+ 0,
352+ },
353+ .smp = {
354+ .mmb_count = 8,
355+ .mmb_size = 10240,
356+ .clients = {
357+ [SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
358+ [SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
359+ },
360+ },
361+ .ctl = {
362+ .count = 3,
363+ .base = { 0x01000, 0x01200, 0x01400 },
364+ .flush_hw_mask = 0x4003ffff,
365+ },
366+ .pipe_vig = {
367+ .count = 1,
368+ .base = { 0x04000 },
369+ .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
370+ MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
371+ MDP_PIPE_CAP_DECIMATION,
372+ },
373+ .pipe_rgb = {
374+ .count = 2,
375+ .base = { 0x14000, 0x16000 },
376+ .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
377+ MDP_PIPE_CAP_DECIMATION,
378+ },
379+ .pipe_dma = {
380+ .count = 1,
381+ .base = { 0x24000 },
382+ .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
383+ },
384+ .lm = {
385+ .count = 2,
386+ .base = { 0x44000, 0x47000 },
387+ .instances = {
388+ { .id = 0, .pp = 0, .dspp = 0,
389+ .caps = MDP_LM_CAP_DISPLAY, },
390+ { .id = 1, .pp = -1, .dspp = -1,
391+ .caps = MDP_LM_CAP_WB, },
392+ },
393+ .nb_stages = 8,
394+ .max_width = 2560,
395+ .max_height = 0xFFFF,
396+ },
397+ .pp = {
398+ .count = 1,
399+ .base = { 0x70000 },
400+ },
401+ .ad = {
402+ .count = 1,
403+ .base = { 0x78000 },
404+ },
405+ .dspp = {
406+ .count = 1,
407+ .base = { 0x54000 },
408+ },
409+ .intf = {
410+ .base = { 0x00000, 0x6a800, 0x6b000 },
411+ .connect = {
412+ [0] = INTF_DISABLED,
413+ [1] = INTF_DSI,
414+ [2] = INTF_DSI,
415+ },
416+ },
417+ .max_clk = 366670000,
418+};
419+
345420 static const struct mdp5_cfg_hw msm8x94_config = {
346421 .name = "msm8x94",
347422 .mdp = {
@@ -840,6 +915,7 @@ static const struct mdp5_cfg_handler cfg_handlers_v1[] = { · 492 unmodified lines
840915 { .revision = 2, .config = { .hw = &msm8x74v2_config } },
841916 { .revision = 3, .config = { .hw = &apq8084_config } },
842917 { .revision = 6, .config = { .hw = &msm8x16_config } },
918+ { .revision = 8, .config = { .hw = &msm8x36_config } },
843919 { .revision = 9, .config = { .hw = &msm8x94_config } },
844920 { .revision = 7, .config = { .hw = &msm8x96_config } },
845921 { .revision = 11, .config = { .hw = &msm8x76_config } },
@@ -941,10 +1017,6 @@ static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev) · 95 unmodified lines
9411017 static struct mdp5_cfg_platform config = {};
9421018
9431019 config.iommu = iommu_domain_alloc(&platform_bus_type);
944− if (config.iommu) {
945− config.iommu->geometry.aperture_start = 0x1000;
946− config.iommu->geometry.aperture_end = 0xffffffff;
947− }
9481020
9491021 return &config;
9501022 }
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c+2−2
@@ -959,7 +959,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, · 958 unmodified lines
959959 if (!ctl)
960960 return -EINVAL;
961961
962− /* don't support LM cursors when we we have source split enabled */
962+ /* don't support LM cursors when we have source split enabled */
963963 if (mdp5_cstate->pipeline.r_mixer)
964964 return -EINVAL;
965965
@@ -1030,7 +1030,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) · 64 unmodified lines
10301030 return -EINVAL;
10311031 }
10321032
1033− /* don't support LM cursors when we we have source split enabled */
1033+ /* don't support LM cursors when we have source split enabled */
10341034 if (mdp5_cstate->pipeline.r_mixer)
10351035 return -EINVAL;
10361036
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c+11−10
@@ -632,25 +632,25 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) · 631 unmodified lines
632632 mdelay(16);
633633
634634 if (config->platform.iommu) {
635+ struct msm_mmu *mmu;
636+
635637 iommu_dev = &pdev->dev;
636638 if (!dev_iommu_fwspec_get(iommu_dev))
637639 iommu_dev = iommu_dev->parent;
638640
639− aspace = msm_gem_address_space_create(iommu_dev,
640− config->platform.iommu, "mdp5");
641+ mmu = msm_iommu_new(iommu_dev, config->platform.iommu);
642+
643+ aspace = msm_gem_address_space_create(mmu, "mdp5",
644+ 0x1000, 0xffffffff);
645+
641646 if (IS_ERR(aspace)) {
647+ if (!IS_ERR(mmu))
648+ mmu->funcs->destroy(mmu);
642649 ret = PTR_ERR(aspace);
643650 goto fail;
644651 }
645652
646653 kms->aspace = aspace;
647−
648− ret = aspace->mmu->funcs->attach(aspace->mmu);
649− if (ret) {
650− DRM_DEV_ERROR(&pdev->dev, "failed to attach iommu: %d\n",
651− ret);
652− goto fail;
653− }
654654 } else {
655655 DRM_DEV_INFO(&pdev->dev,
656656 "no iommu, fallback to phys contig buffers for scanout\n");
@@ -943,7 +943,8 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) · 286 unmodified lines
943943
944944 return 0;
945945 fail:
946− mdp5_destroy(pdev);
946+ if (mdp5_kms)
947+ mdp5_destroy(pdev);
947948 return ret;
948949 }
949950
drivers/gpu/drm/msm/msm_drv.c+4−2
@@ -37,9 +37,10 @@ · 36 unmodified lines
3737 * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
3838 * GEM object's debug name
3939 * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
40+ * - 1.6.0 - Syncobj support
4041 */
4142 #define MSM_VERSION_MAJOR 1
42−#define MSM_VERSION_MINOR 5
43+#define MSM_VERSION_MINOR 6
4344 #define MSM_VERSION_PATCHLEVEL 0
4445
4546 static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -1002,7 +1003,8 @@ static struct drm_driver msm_driver = { · 956 unmodified lines
10021003 .driver_features = DRIVER_GEM |
10031004 DRIVER_RENDER |
10041005 DRIVER_ATOMIC |
1005− DRIVER_MODESET,
1006+ DRIVER_MODESET |
1007+ DRIVER_SYNCOBJ,
10061008 .open = msm_open,
10071009 .postclose = msm_postclose,
10081010 .lastclose = drm_fb_helper_lastclose,
drivers/gpu/drm/msm/msm_drv.h+8−7
@@ -105,6 +105,7 @@ struct msm_display_topology { · 104 unmodified lines
105105 u32 num_lm;
106106 u32 num_enc;
107107 u32 num_intf;
108+ u32 num_dspp;
108109 };
109110
110111 /**
@@ -236,7 +237,8 @@ int msm_crtc_enable_vblank(struct drm_crtc *crtc); · 125 unmodified lines
236237 void msm_crtc_disable_vblank(struct drm_crtc *crtc);
237238
238239 int msm_gem_init_vma(struct msm_gem_address_space *aspace,
239− struct msm_gem_vma *vma, int npages);
240+ struct msm_gem_vma *vma, int npages,
241+ u64 range_start, u64 range_end);
240242 void msm_gem_purge_vma(struct msm_gem_address_space *aspace,
241243 struct msm_gem_vma *vma);
242244 void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
@@ -250,12 +252,8 @@ void msm_gem_close_vma(struct msm_gem_address_space *aspace, · 7 unmodified lines
250252 void msm_gem_address_space_put(struct msm_gem_address_space *aspace);
251253
252254 struct msm_gem_address_space *
253−msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
254− const char *name);
255−
256−struct msm_gem_address_space *
257−msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu,
258− const char *name, uint64_t va_start, uint64_t va_end);
255+msm_gem_address_space_create(struct msm_mmu *mmu, const char *name,
256+ u64 va_start, u64 size);
259257
260258 int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu);
261259 void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu);
@@ -276,6 +274,9 @@ vm_fault_t msm_gem_fault(struct vm_fault *vmf); · 14 unmodified lines
276274 uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
277275 int msm_gem_get_iova(struct drm_gem_object *obj,
278276 struct msm_gem_address_space *aspace, uint64_t *iova);
277+int msm_gem_get_and_pin_iova_range(struct drm_gem_object *obj,
278+ struct msm_gem_address_space *aspace, uint64_t *iova,
279+ u64 range_start, u64 range_end);
279280 int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
280281 struct msm_gem_address_space *aspace, uint64_t *iova);
281282 uint64_t msm_gem_iova(struct drm_gem_object *obj,
drivers/gpu/drm/msm/msm_gem.c+24−7
@@ -389,7 +389,8 @@ put_iova(struct drm_gem_object *obj) · 388 unmodified lines
389389 }
390390
391391 static int msm_gem_get_iova_locked(struct drm_gem_object *obj,
392− struct msm_gem_address_space *aspace, uint64_t *iova)
392+ struct msm_gem_address_space *aspace, uint64_t *iova,
393+ u64 range_start, u64 range_end)
393394 {
394395 struct msm_gem_object *msm_obj = to_msm_bo(obj);
395396 struct msm_gem_vma *vma;
@@ -404,7 +405,8 @@ static int msm_gem_get_iova_locked(struct drm_gem_object *obj, · 8 unmodified lines
404405 if (IS_ERR(vma))
405406 return PTR_ERR(vma);
406407
407− ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT);
408+ ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT,
409+ range_start, range_end);
408410 if (ret) {
409411 del_vma(vma);
410412 return ret;
@@ -426,6 +428,9 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj, · 15 unmodified lines
426428 if (!(msm_obj->flags & MSM_BO_GPU_READONLY))
427429 prot |= IOMMU_WRITE;
428430
431+ if (msm_obj->flags & MSM_BO_MAP_PRIV)
432+ prot |= IOMMU_PRIV;
433+
429434 WARN_ON(!mutex_is_locked(&msm_obj->lock));
430435
431436 if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED))
@@ -443,9 +448,13 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj, · 11 unmodified lines
443448 msm_obj->sgt, obj->size >> PAGE_SHIFT);
444449 }
445450
446−/* get iova and pin it. Should have a matching put */
447−int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
448− struct msm_gem_address_space *aspace, uint64_t *iova)
451+/*
452+ * get iova and pin it. Should have a matching put
453+ * limits iova to specified range (in pages)
454+ */
455+int msm_gem_get_and_pin_iova_range(struct drm_gem_object *obj,
456+ struct msm_gem_address_space *aspace, uint64_t *iova,
457+ u64 range_start, u64 range_end)
449458 {
450459 struct msm_gem_object *msm_obj = to_msm_bo(obj);
451460 u64 local;
@@ -453,7 +462,8 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, · 1 unmodified line
453462
454463 mutex_lock(&msm_obj->lock);
455464
456− ret = msm_gem_get_iova_locked(obj, aspace, &local);
465+ ret = msm_gem_get_iova_locked(obj, aspace, &local,
466+ range_start, range_end);
457467
458468 if (!ret)
459469 ret = msm_gem_pin_iova(obj, aspace);
@@ -465,6 +475,13 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, · 5 unmodified lines
465475 return ret;
466476 }
467477
478+/* get iova and pin it. Should have a matching put */
479+int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
480+ struct msm_gem_address_space *aspace, uint64_t *iova)
481+{
482+ return msm_gem_get_and_pin_iova_range(obj, aspace, iova, 0, U64_MAX);
483+}
484+
468485 /*
469486 * Get an iova but don't pin it. Doesn't need a put because iovas are currently
470487 * valid for the life of the object
@@ -476,7 +493,7 @@ int msm_gem_get_iova(struct drm_gem_object *obj, · 5 unmodified lines
476493 int ret;
477494
478495 mutex_lock(&msm_obj->lock);
479− ret = msm_gem_get_iova_locked(obj, aspace, iova);
496+ ret = msm_gem_get_iova_locked(obj, aspace, iova, 0, U64_MAX);
480497 mutex_unlock(&msm_obj->lock);
481498
482499 return ret;
drivers/gpu/drm/msm/msm_gem.h+1−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313
1414 /* Additional internal-use only BO flags: */
1515 #define MSM_BO_STOLEN 0x10000000 /* try to use stolen/splash memory */
16+#define MSM_BO_MAP_PRIV 0x20000000 /* use IOMMU_PRIV when mapping */
1617
1718 struct msm_gem_address_space {
1819 const char *name;
drivers/gpu/drm/msm/msm_gem_submit.c+231−1
@@ -8,7 +8,9 @@ · 7 unmodified lines
88 #include <linux/sync_file.h>
99 #include <linux/uaccess.h>
1010
11+#include <drm/drm_drv.h>
1112 #include <drm/drm_file.h>
13+#include <drm/drm_syncobj.h>
1214
1315 #include "msm_drv.h"
1416 #include "msm_gpu.h"
@@ -391,6 +393,186 @@ static void submit_cleanup(struct msm_gem_submit *submit) · 376 unmodified lines
391393 }
392394 }
393395
396+
397+struct msm_submit_post_dep {
398+ struct drm_syncobj *syncobj;
399+ uint64_t point;
400+ struct dma_fence_chain *chain;
401+};
402+
403+static struct drm_syncobj **msm_wait_deps(struct drm_device *dev,
404+ struct drm_file *file,
405+ uint64_t in_syncobjs_addr,
406+ uint32_t nr_in_syncobjs,
407+ size_t syncobj_stride,
408+ struct msm_ringbuffer *ring)
409+{
410+ struct drm_syncobj **syncobjs = NULL;
411+ struct drm_msm_gem_submit_syncobj syncobj_desc = {0};
412+ int ret = 0;
413+ uint32_t i, j;
414+
415+ syncobjs = kcalloc(nr_in_syncobjs, sizeof(*syncobjs),
416+ GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
417+ if (!syncobjs)
418+ return ERR_PTR(-ENOMEM);
419+
420+ for (i = 0; i < nr_in_syncobjs; ++i) {
421+ uint64_t address = in_syncobjs_addr + i * syncobj_stride;
422+ struct dma_fence *fence;
423+
424+ if (copy_from_user(&syncobj_desc,
425+ u64_to_user_ptr(address),
426+ min(syncobj_stride, sizeof(syncobj_desc)))) {
427+ ret = -EFAULT;
428+ break;
429+ }
430+
431+ if (syncobj_desc.point &&
432+ !drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) {
433+ ret = -EOPNOTSUPP;
434+ break;
435+ }
436+
437+ if (syncobj_desc.flags & ~MSM_SUBMIT_SYNCOBJ_FLAGS) {
438+ ret = -EINVAL;
439+ break;
440+ }
441+
442+ ret = drm_syncobj_find_fence(file, syncobj_desc.handle,
443+ syncobj_desc.point, 0, &fence);
444+ if (ret)
445+ break;
446+
447+ if (!dma_fence_match_context(fence, ring->fctx->context))
448+ ret = dma_fence_wait(fence, true);
449+
450+ dma_fence_put(fence);
451+ if (ret)
452+ break;
453+
454+ if (syncobj_desc.flags & MSM_SUBMIT_SYNCOBJ_RESET) {
455+ syncobjs[i] =
456+ drm_syncobj_find(file, syncobj_desc.handle);
457+ if (!syncobjs[i]) {
458+ ret = -EINVAL;
459+ break;
460+ }
461+ }
462+ }
463+
464+ if (ret) {
465+ for (j = 0; j <= i; ++j) {
466+ if (syncobjs[j])
467+ drm_syncobj_put(syncobjs[j]);
468+ }
469+ kfree(syncobjs);
470+ return ERR_PTR(ret);
471+ }
472+ return syncobjs;
473+}
474+
475+static void msm_reset_syncobjs(struct drm_syncobj **syncobjs,
476+ uint32_t nr_syncobjs)
477+{
478+ uint32_t i;
479+
480+ for (i = 0; syncobjs && i < nr_syncobjs; ++i) {
481+ if (syncobjs[i])
482+ drm_syncobj_replace_fence(syncobjs[i], NULL);
483+ }
484+}
485+
486+static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev,
487+ struct drm_file *file,
488+ uint64_t syncobjs_addr,
489+ uint32_t nr_syncobjs,
490+ size_t syncobj_stride)
491+{
492+ struct msm_submit_post_dep *post_deps;
493+ struct drm_msm_gem_submit_syncobj syncobj_desc = {0};
494+ int ret = 0;
495+ uint32_t i, j;
496+
497+ post_deps = kmalloc_array(nr_syncobjs, sizeof(*post_deps),
498+ GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
499+ if (!post_deps)
500+ return ERR_PTR(-ENOMEM);
501+
502+ for (i = 0; i < nr_syncobjs; ++i) {
503+ uint64_t address = syncobjs_addr + i * syncobj_stride;
504+
505+ if (copy_from_user(&syncobj_desc,
506+ u64_to_user_ptr(address),
507+ min(syncobj_stride, sizeof(syncobj_desc)))) {
508+ ret = -EFAULT;
509+ break;
510+ }
511+
512+ post_deps[i].point = syncobj_desc.point;
513+ post_deps[i].chain = NULL;
514+
515+ if (syncobj_desc.flags) {
516+ ret = -EINVAL;
517+ break;
518+ }
519+
520+ if (syncobj_desc.point) {
521+ if (!drm_core_check_feature(dev,
522+ DRIVER_SYNCOBJ_TIMELINE)) {
523+ ret = -EOPNOTSUPP;
524+ break;
525+ }
526+
527+ post_deps[i].chain =
528+ kmalloc(sizeof(*post_deps[i].chain),
529+ GFP_KERNEL);
530+ if (!post_deps[i].chain) {
531+ ret = -ENOMEM;
532+ break;
533+ }
534+ }
535+
536+ post_deps[i].syncobj =
537+ drm_syncobj_find(file, syncobj_desc.handle);
538+ if (!post_deps[i].syncobj) {
539+ ret = -EINVAL;
540+ break;
541+ }
542+ }
543+
544+ if (ret) {
545+ for (j = 0; j <= i; ++j) {
546+ kfree(post_deps[j].chain);
547+ if (post_deps[j].syncobj)
548+ drm_syncobj_put(post_deps[j].syncobj);
549+ }
550+
551+ kfree(post_deps);
552+ return ERR_PTR(ret);
553+ }
554+
555+ return post_deps;
556+}
557+
558+static void msm_process_post_deps(struct msm_submit_post_dep *post_deps,
559+ uint32_t count, struct dma_fence *fence)
560+{
561+ uint32_t i;
562+
563+ for (i = 0; post_deps && i < count; ++i) {
564+ if (post_deps[i].chain) {
565+ drm_syncobj_add_point(post_deps[i].syncobj,
566+ post_deps[i].chain,
567+ fence, post_deps[i].point);
568+ post_deps[i].chain = NULL;
569+ } else {
570+ drm_syncobj_replace_fence(post_deps[i].syncobj,
571+ fence);
572+ }
573+ }
574+}
575+
394576 int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
395577 struct drm_file *file)
396578 {
@@ -403,6 +585,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 6 unmodified lines
403585 struct sync_file *sync_file = NULL;
404586 struct msm_gpu_submitqueue *queue;
405587 struct msm_ringbuffer *ring;
588+ struct msm_submit_post_dep *post_deps = NULL;
589+ struct drm_syncobj **syncobjs_to_reset = NULL;
406590 int out_fence_fd = -1;
407591 struct pid *pid = get_pid(task_pid(current));
408592 bool has_ww_ticket = false;
@@ -411,6 +595,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 2 unmodified lines
411595 if (!gpu)
412596 return -ENXIO;
413597
598+ if (args->pad)
599+ return -EINVAL;
600+
414601 /* for now, we just have 3d pipe.. eventually this would need to
415602 * be more clever to dispatch to appropriate gpu module:
416603 */
@@ -458,9 +645,29 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 41 unmodified lines
458645 return ret;
459646 }
460647
648+ if (args->flags & MSM_SUBMIT_SYNCOBJ_IN) {
649+ syncobjs_to_reset = msm_wait_deps(dev, file,
650+ args->in_syncobjs,
651+ args->nr_in_syncobjs,
652+ args->syncobj_stride, ring);
653+ if (IS_ERR(syncobjs_to_reset))
654+ return PTR_ERR(syncobjs_to_reset);
655+ }
656+
657+ if (args->flags & MSM_SUBMIT_SYNCOBJ_OUT) {
658+ post_deps = msm_parse_post_deps(dev, file,
659+ args->out_syncobjs,
660+ args->nr_out_syncobjs,
661+ args->syncobj_stride);
662+ if (IS_ERR(post_deps)) {
663+ ret = PTR_ERR(post_deps);
664+ goto out_post_unlock;
665+ }
666+ }
667+
461668 ret = mutex_lock_interruptible(&dev->struct_mutex);
462669 if (ret)
463− return ret;
670+ goto out_post_unlock;
464671
465672 if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
466673 out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
@@ -587,6 +794,11 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 120 unmodified lines
587794 args->fence_fd = out_fence_fd;
588795 }
589796
797+ msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs);
798+ msm_process_post_deps(post_deps, args->nr_out_syncobjs,
799+ submit->fence);
800+
801+
590802 out:
591803 submit_cleanup(submit);
592804 if (has_ww_ticket)
@@ -597,5 +809,23 @@ out_unlock: · 4 unmodified lines
597809 if (ret && (out_fence_fd >= 0))
598810 put_unused_fd(out_fence_fd);
599811 mutex_unlock(&dev->struct_mutex);
812+
813+out_post_unlock:
814+ if (!IS_ERR_OR_NULL(post_deps)) {
815+ for (i = 0; i < args->nr_out_syncobjs; ++i) {
816+ kfree(post_deps[i].chain);
817+ drm_syncobj_put(post_deps[i].syncobj);
818+ }
819+ kfree(post_deps);
820+ }
821+
822+ if (!IS_ERR_OR_NULL(syncobjs_to_reset)) {
823+ for (i = 0; i < args->nr_in_syncobjs; ++i) {
824+ if (syncobjs_to_reset[i])
825+ drm_syncobj_put(syncobjs_to_reset[i]);
826+ }
827+ kfree(syncobjs_to_reset);
828+ }
829+
600830 return ret;
601831 }
drivers/gpu/drm/msm/msm_gem_vma.c+10−32
@@ -103,7 +103,8 @@ void msm_gem_close_vma(struct msm_gem_address_space *aspace, · 102 unmodified lines
103103
104104 /* Initialize a new vma and allocate an iova for it */
105105 int msm_gem_init_vma(struct msm_gem_address_space *aspace,
106− struct msm_gem_vma *vma, int npages)
106+ struct msm_gem_vma *vma, int npages,
107+ u64 range_start, u64 range_end)
107108 {
108109 int ret;
109110
@@ -111,7 +112,8 @@ int msm_gem_init_vma(struct msm_gem_address_space *aspace, · 1 unmodified line
111112 return -EBUSY;
112113
113114 spin_lock(&aspace->lock);
114− ret = drm_mm_insert_node(&aspace->mm, &vma->node, npages);
115+ ret = drm_mm_insert_node_in_range(&aspace->mm, &vma->node, npages, 0,
116+ 0, range_start, range_end, 0);
115117 spin_unlock(&aspace->lock);
116118
117119 if (ret)
@@ -125,37 +127,14 @@ int msm_gem_init_vma(struct msm_gem_address_space *aspace, · 7 unmodified lines
125127 return 0;
126128 }
127129
128−
129130 struct msm_gem_address_space *
130−msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
131− const char *name)
131+msm_gem_address_space_create(struct msm_mmu *mmu, const char *name,
132+ u64 va_start, u64 size)
132133 {
133134 struct msm_gem_address_space *aspace;
134− u64 size = domain->geometry.aperture_end -
135− domain->geometry.aperture_start;
136−
137− aspace = kzalloc(sizeof(*aspace), GFP_KERNEL);
138− if (!aspace)
139− return ERR_PTR(-ENOMEM);
140−
141− spin_lock_init(&aspace->lock);
142− aspace->name = name;
143− aspace->mmu = msm_iommu_new(dev, domain);
144−
145− drm_mm_init(&aspace->mm, (domain->geometry.aperture_start >> PAGE_SHIFT),
146− size >> PAGE_SHIFT);
147135
148− kref_init(&aspace->kref);
149−
150− return aspace;
151−}
152−
153−struct msm_gem_address_space *
154−msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu,
155− const char *name, uint64_t va_start, uint64_t va_end)
156−{
157− struct msm_gem_address_space *aspace;
158− u64 size = va_end - va_start;
136+ if (IS_ERR(mmu))
137+ return ERR_CAST(mmu);
159138
160139 aspace = kzalloc(sizeof(*aspace), GFP_KERNEL);
161140 if (!aspace)
@@ -163,10 +142,9 @@ msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu, · 1 unmodified line
163142
164143 spin_lock_init(&aspace->lock);
165144 aspace->name = name;
166− aspace->mmu = msm_gpummu_new(dev, gpu);
145+ aspace->mmu = mmu;
167146
168− drm_mm_init(&aspace->mm, (va_start >> PAGE_SHIFT),
169− size >> PAGE_SHIFT);
147+ drm_mm_init(&aspace->mm, va_start >> PAGE_SHIFT, size >> PAGE_SHIFT);
170148
171149 kref_init(&aspace->kref);
172150
drivers/gpu/drm/msm/msm_gpu.c+2−47
@@ -821,51 +821,6 @@ static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu) · 820 unmodified lines
821821 return 0;
822822 }
823823
824−static struct msm_gem_address_space *
825−msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev,
826− uint64_t va_start, uint64_t va_end)
827−{
828− struct msm_gem_address_space *aspace;
829− int ret;
830−
831− /*
832− * Setup IOMMU.. eventually we will (I think) do this once per context
833− * and have separate page tables per context. For now, to keep things
834− * simple and to get something working, just use a single address space:
835− */
836− if (!adreno_is_a2xx(to_adreno_gpu(gpu))) {
837− struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
838− if (!iommu)
839− return NULL;
840−
841− iommu->geometry.aperture_start = va_start;
842− iommu->geometry.aperture_end = va_end;
843−
844− DRM_DEV_INFO(gpu->dev->dev, "%s: using IOMMU\n", gpu->name);
845−
846− aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu");
847− if (IS_ERR(aspace))
848− iommu_domain_free(iommu);
849− } else {
850− aspace = msm_gem_address_space_create_a2xx(&pdev->dev, gpu, "gpu",
851− va_start, va_end);
852− }
853−
854− if (IS_ERR(aspace)) {
855− DRM_DEV_ERROR(gpu->dev->dev, "failed to init mmu: %ld\n",
856− PTR_ERR(aspace));
857− return ERR_CAST(aspace);
858− }
859−
860− ret = aspace->mmu->funcs->attach(aspace->mmu);
861− if (ret) {
862− msm_gem_address_space_put(aspace);
863− return ERR_PTR(ret);
864− }
865−
866− return aspace;
867−}
868−
869824 int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
870825 struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
871826 const char *name, struct msm_gpu_config *config)
@@ -938,8 +893,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, · 66 unmodified lines
938893
939894 msm_devfreq_init(gpu);
940895
941− gpu->aspace = msm_gpu_create_address_space(gpu, pdev,
942− config->va_start, config->va_end);
896+
897+ gpu->aspace = gpu->funcs->create_address_space(gpu, pdev);
943898
944899 if (gpu->aspace == NULL)
945900 DRM_DEV_INFO(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name);
drivers/gpu/drm/msm/msm_gpu.h+2−2
@@ -21,8 +21,6 @@ struct msm_gpu_state; · 20 unmodified lines
2121
2222 struct msm_gpu_config {
2323 const char *ioname;
24− uint64_t va_start;
25− uint64_t va_end;
2624 unsigned int nr_rings;
2725 };
2826
@@ -64,6 +62,8 @@ struct msm_gpu_funcs { · 35 unmodified lines
6462 int (*gpu_state_put)(struct msm_gpu_state *state);
6563 unsigned long (*gpu_get_freq)(struct msm_gpu *gpu);
6664 void (*gpu_set_freq)(struct msm_gpu *gpu, unsigned long freq);
65+ struct msm_gem_address_space *(*create_address_space)
66+ (struct msm_gpu *gpu, struct platform_device *pdev);
6767 };
6868
6969 struct msm_gpu {
drivers/gpu/drm/msm/msm_gpummu.c+2−8
@@ -21,17 +21,12 @@ struct msm_gpummu { · 20 unmodified lines
2121 #define GPUMMU_PAGE_SIZE SZ_4K
2222 #define TABLE_SIZE (sizeof(uint32_t) * GPUMMU_VA_RANGE / GPUMMU_PAGE_SIZE)
2323
24−static int msm_gpummu_attach(struct msm_mmu *mmu)
25−{
26− return 0;
27−}
28−
2924 static void msm_gpummu_detach(struct msm_mmu *mmu)
3025 {
3126 }
3227
3328 static int msm_gpummu_map(struct msm_mmu *mmu, uint64_t iova,
34− struct sg_table *sgt, unsigned len, int prot)
29+ struct sg_table *sgt, size_t len, int prot)
3530 {
3631 struct msm_gpummu *gpummu = to_msm_gpummu(mmu);
3732 unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE;
@@ -59,7 +54,7 @@ static int msm_gpummu_map(struct msm_mmu *mmu, uint64_t iova, · 21 unmodified lines
5954 return 0;
6055 }
6156
62−static int msm_gpummu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len)
57+static int msm_gpummu_unmap(struct msm_mmu *mmu, uint64_t iova, size_t len)
6358 {
6459 struct msm_gpummu *gpummu = to_msm_gpummu(mmu);
6560 unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE;
@@ -85,7 +80,6 @@ static void msm_gpummu_destroy(struct msm_mmu *mmu) · 19 unmodified lines
8580 }
8681
8782 static const struct msm_mmu_funcs funcs = {
88− .attach = msm_gpummu_attach,
8983 .detach = msm_gpummu_detach,
9084 .map = msm_gpummu_map,
9185 .unmap = msm_gpummu_unmap,
drivers/gpu/drm/msm/msm_iommu.c+12−10
@@ -23,13 +23,6 @@ static int msm_fault_handler(struct iommu_domain *domain, struct device *dev, · 22 unmodified lines
2323 return 0;
2424 }
2525
26−static int msm_iommu_attach(struct msm_mmu *mmu)
27−{
28− struct msm_iommu *iommu = to_msm_iommu(mmu);
29−
30− return iommu_attach_device(iommu->domain, mmu->dev);
31−}
32−
3326 static void msm_iommu_detach(struct msm_mmu *mmu)
3427 {
3528 struct msm_iommu *iommu = to_msm_iommu(mmu);
@@ -38,7 +31,7 @@ static void msm_iommu_detach(struct msm_mmu *mmu) · 2 unmodified lines
3831 }
3932
4033 static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
41− struct sg_table *sgt, unsigned len, int prot)
34+ struct sg_table *sgt, size_t len, int prot)
4235 {
4336 struct msm_iommu *iommu = to_msm_iommu(mmu);
4437 size_t ret;
@@ -49,7 +42,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, · 4 unmodified lines
4942 return (ret == len) ? 0 : -EINVAL;
5043 }
5144
52−static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len)
45+static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, size_t len)
5346 {
5447 struct msm_iommu *iommu = to_msm_iommu(mmu);
5548
@@ -66,7 +59,6 @@ static void msm_iommu_destroy(struct msm_mmu *mmu) · 10 unmodified lines
6659 }
6760
6861 static const struct msm_mmu_funcs funcs = {
69− .attach = msm_iommu_attach,
7062 .detach = msm_iommu_detach,
7163 .map = msm_iommu_map,
7264 .unmap = msm_iommu_unmap,
@@ -76,6 +68,10 @@ static const struct msm_mmu_funcs funcs = { · 3 unmodified lines
7668 struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain)
7769 {
7870 struct msm_iommu *iommu;
71+ int ret;
72+
73+ if (!domain)
74+ return ERR_PTR(-ENODEV);
7975
8076 iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
8177 if (!iommu)
@@ -85,5 +81,11 @@ struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain) · 3 unmodified lines
8581 msm_mmu_init(&iommu->base, dev, &funcs);
8682 iommu_set_fault_handler(domain, msm_fault_handler, iommu);
8783
84+ ret = iommu_attach_device(iommu->domain, dev);
85+ if (ret) {
86+ kfree(iommu);
87+ return ERR_PTR(ret);
88+ }
89+
8890 return &iommu->base;
8991 }
drivers/gpu/drm/msm/msm_mmu.h+2−3
@@ -10,11 +10,10 @@ · 9 unmodified lines
1010 #include <linux/iommu.h>
1111
1212 struct msm_mmu_funcs {
13− int (*attach)(struct msm_mmu *mmu);
1413 void (*detach)(struct msm_mmu *mmu);
1514 int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
16− unsigned len, int prot);
17− int (*unmap)(struct msm_mmu *mmu, uint64_t iova, unsigned len);
15+ size_t len, int prot);
16+ int (*unmap)(struct msm_mmu *mmu, uint64_t iova, size_t len);
1817 void (*destroy)(struct msm_mmu *mmu);
1918 };
2019
drivers/gpu/drm/msm/msm_rd.c+2−2
@@ -29,8 +29,6 @@ · 28 unmodified lines
2929 * or shader programs (if not emitted inline in cmdstream).
3030 */
3131
32−#ifdef CONFIG_DEBUG_FS
33−
3432 #include <linux/circ_buf.h>
3533 #include <linux/debugfs.h>
3634 #include <linux/kfifo.h>
@@ -47,6 +45,8 @@ bool rd_full = false; · 10 unmodified lines
4745 MODULE_PARM_DESC(rd_full, "If true, $debugfs/.../rd will snapshot all buffer contents");
4846 module_param_named(rd_full, rd_full, bool, 0600);
4947
48+#ifdef CONFIG_DEBUG_FS
49+
5050 enum rd_sect_type {
5151 RD_NONE,
5252 RD_TEST, /* ascii text */
include/uapi/drm/msm_drm.h+23−1
@@ -217,13 +217,28 @@ struct drm_msm_gem_submit_bo { · 216 unmodified lines
217217 #define MSM_SUBMIT_FENCE_FD_IN 0x40000000 /* enable input fence_fd */
218218 #define MSM_SUBMIT_FENCE_FD_OUT 0x20000000 /* enable output fence_fd */
219219 #define MSM_SUBMIT_SUDO 0x10000000 /* run submitted cmds from RB */
220+#define MSM_SUBMIT_SYNCOBJ_IN 0x08000000 /* enable input syncobj */
221+#define MSM_SUBMIT_SYNCOBJ_OUT 0x04000000 /* enable output syncobj */
220222 #define MSM_SUBMIT_FLAGS ( \
221223 MSM_SUBMIT_NO_IMPLICIT | \
222224 MSM_SUBMIT_FENCE_FD_IN | \
223225 MSM_SUBMIT_FENCE_FD_OUT | \
224226 MSM_SUBMIT_SUDO | \
227+ MSM_SUBMIT_SYNCOBJ_IN | \
228+ MSM_SUBMIT_SYNCOBJ_OUT | \
225229 0)
226230
231+#define MSM_SUBMIT_SYNCOBJ_RESET 0x00000001 /* Reset syncobj after wait. */
232+#define MSM_SUBMIT_SYNCOBJ_FLAGS ( \
233+ MSM_SUBMIT_SYNCOBJ_RESET | \
234+ 0)
235+
236+struct drm_msm_gem_submit_syncobj {
237+ __u32 handle; /* in, syncobj handle. */
238+ __u32 flags; /* in, from MSM_SUBMIT_SYNCOBJ_FLAGS */
239+ __u64 point; /* in, timepoint for timeline syncobjs. */
240+};
241+
227242 /* Each cmdstream submit consists of a table of buffers involved, and
228243 * one or more cmdstream buffers. This allows for conditional execution
229244 * (context-restore), and IB buffers needed for per tile/bin draw cmds.
@@ -236,7 +251,14 @@ struct drm_msm_gem_submit { · 6 unmodified lines
236251 __u64 bos; /* in, ptr to array of submit_bo's */
237252 __u64 cmds; /* in, ptr to array of submit_cmd's */
238253 __s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */
239− __u32 queueid; /* in, submitqueue id */
254+ __u32 queueid; /* in, submitqueue id */
255+ __u64 in_syncobjs; /* in, ptr to to array of drm_msm_gem_submit_syncobj */
256+ __u64 out_syncobjs; /* in, ptr to to array of drm_msm_gem_submit_syncobj */
257+ __u32 nr_in_syncobjs; /* in, number of entries in in_syncobj */
258+ __u32 nr_out_syncobjs; /* in, number of entries in out_syncobj. */
259+ __u32 syncobj_stride; /* in, stride of syncobj arrays. */
260+ __u32 pad; /*in, reserved for future use, always 0. */
261+
240262 };
241263
242264 /* The normal way to synchronize with the GPU is just to CPU_PREP on

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t