History

Merge tag 'drm-msm-next-2026-08-01' of https://gitlab.freedesktop.org/drm/msm into drm-next

Changes for v7.3 Bindings: - Added Shikra support - Document a840, a704, a722 Core: - Use drm_client buffers for fbdev emulation - teardown fixes - ARM32 DMA fixup - Remove objects from evict list when re-validated - Bunch of corner case and error path fixes DPU: - Dropped dev_pm_opp_set_rate(0) preventing burnout - Fixed SSPP offsets of Kaanapali DP: - Dropped dev_pm_opp_set_rate(0) preventing burnout - Cleaned up core code in preparation for MST support - Fixed prepare() to let Pipewire continue in case of the unplugged cable GPU: - Add support for a704 - Add support for a722 HDMI: - Simplifed register access

Dave Airlie committed 2 months ago

Commit e91d58c2 parents bb11536 140b13457 files · +1553 −825Browse files

Unified · Split

57 files
  1. Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml +4 −0
  2. Documentation/devicetree/bindings/display/msm/gmu.yaml +1 −0
  3. Documentation/devicetree/bindings/display/msm/gpu.yaml +4 −0
  4. Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml +5 −1
  5. Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml +12 −7
  6. Documentation/devicetree/bindings/iommu/arm,smmu.yaml +4 −0
  7. drivers/gpu/drm/msm/adreno/a3xx_gpu.c +35 −1
  8. drivers/gpu/drm/msm/adreno/a5xx_gpu.c +5 −0
  9. drivers/gpu/drm/msm/adreno/a6xx_catalog.c +37 −3
  10. drivers/gpu/drm/msm/adreno/a6xx_gmu.c +16 −8
  11. drivers/gpu/drm/msm/adreno/a6xx_gpu.c +10 −4
  12. drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +68 −18
  13. drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h +17 −0
  14. drivers/gpu/drm/msm/adreno/a8xx_gpu.c +5 −2
  15. drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h +428 −0
  16. drivers/gpu/drm/msm/adreno/adreno_gpu.c +13 −4
  17. drivers/gpu/drm/msm/adreno/adreno_gpu.h +5 −0
  18. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_13_0_kaanapali.h +6 −6
  19. drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +5 −1
  20. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +1 −2
  21. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +12 −0
  22. drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +9 −15
  23. drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +3 −8
  24. drivers/gpu/drm/msm/dp/dp_audio.c +1 −3
  25. drivers/gpu/drm/msm/dp/dp_ctrl.c +223 −172
  26. drivers/gpu/drm/msm/dp/dp_ctrl.h +20 −10
  27. drivers/gpu/drm/msm/dp/dp_display.c +160 −151
  28. drivers/gpu/drm/msm/dp/dp_display.h +9 −0
  29. drivers/gpu/drm/msm/dp/dp_drm.c +49 −3
  30. drivers/gpu/drm/msm/dp/dp_drm.h +0 −12
  31. drivers/gpu/drm/msm/dp/dp_panel.c +20 −55
  32. drivers/gpu/drm/msm/dp/dp_panel.h +7 −10
  33. drivers/gpu/drm/msm/dp/dp_reg.h +2 −0
  34. drivers/gpu/drm/msm/dsi/dsi_host.c +12 −2
  35. drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +1 −0
  36. drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +16 −2
  37. drivers/gpu/drm/msm/hdmi/hdmi.h +19 −0
  38. drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +41 −57
  39. drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c +28 −57
  40. drivers/gpu/drm/msm/msm_drv.c +17 −9
  41. drivers/gpu/drm/msm/msm_drv.h +0 −17
  42. drivers/gpu/drm/msm/msm_fb.c +25 −73
  43. drivers/gpu/drm/msm/msm_fbdev.c +61 −25
  44. drivers/gpu/drm/msm/msm_gem.c +55 −39
  45. drivers/gpu/drm/msm/msm_gem.h +3 −2
  46. drivers/gpu/drm/msm/msm_gem_prime.c +1 −1
  47. drivers/gpu/drm/msm/msm_gem_submit.c +14 −17
  48. drivers/gpu/drm/msm/msm_gem_vma.c +10 −4
  49. drivers/gpu/drm/msm/msm_gpu.c +7 −3
  50. drivers/gpu/drm/msm/msm_gpu.h +2 −2
  51. drivers/gpu/drm/msm/msm_iommu.c +22 −0
  52. drivers/gpu/drm/msm/msm_ringbuffer.c +4 −3
  53. drivers/gpu/drm/msm/msm_ringbuffer.h +1 −0
  54. drivers/gpu/drm/msm/msm_submitqueue.c +12 −12
  55. drivers/gpu/drm/msm/registers/adreno/a3xx.xml +2 −0
  56. drivers/gpu/drm/msm/registers/adreno/a6xx.xml +1 −1
  57. include/uapi/drm/msm_drm.h +3 −3
Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml+4−0
@@ -47,6 +47,10 @@ properties: · 46 unmodified lines
47 - qcom,sm8650-dsi-ctrl47 - qcom,sm8650-dsi-ctrl
48 - qcom,sm8750-dsi-ctrl48 - qcom,sm8750-dsi-ctrl
49 - const: qcom,mdss-dsi-ctrl49 - const: qcom,mdss-dsi-ctrl
50 - items:
51 - const: qcom,shikra-dsi-ctrl
52 - const: qcom,qcm2290-dsi-ctrl
53 - const: qcom,mdss-dsi-ctrl
50 - items:54 - items:
51 - enum:55 - enum:
52 - qcom,qcs8300-dsi-ctrl56 - qcom,qcs8300-dsi-ctrl
Documentation/devicetree/bindings/display/msm/gmu.yaml+1−0
@@ -262,6 +262,7 @@ allOf: · 261 unmodified lines
262 compatible:262 compatible:
263 contains:263 contains:
264 enum:264 enum:
265 - qcom,adreno-gmu-722.0
265 - qcom,adreno-gmu-730.1266 - qcom,adreno-gmu-730.1
266 - qcom,adreno-gmu-740.1267 - qcom,adreno-gmu-740.1
267 - qcom,adreno-gmu-750.1268 - qcom,adreno-gmu-750.1
Documentation/devicetree/bindings/display/msm/gpu.yaml+4−0
@@ -353,6 +353,7 @@ allOf: · 352 unmodified lines
353 - qcom,adreno-610.0353 - qcom,adreno-610.0
354 - qcom,adreno-619.1354 - qcom,adreno-619.1
355 - qcom,adreno-07000200355 - qcom,adreno-07000200
356 - qcom,adreno-07000400
356 then:357 then:
357 properties:358 properties:
358 clocks:359 clocks:
@@ -413,6 +414,7 @@ allOf: · 54 unmodified lines
413 contains:414 contains:
414 enum:415 enum:
415 - qcom,adreno-44010000416 - qcom,adreno-44010000
417 - qcom,adreno-44050a01
416 - qcom,adreno-44070001418 - qcom,adreno-44070001
417 then:419 then:
418 properties:420 properties:
@@ -443,11 +445,13 @@ allOf: · 24 unmodified lines
443 - qcom,adreno-680.1445 - qcom,adreno-680.1
444 - qcom,adreno-690.0446 - qcom,adreno-690.0
445 - qcom,adreno-730.1447 - qcom,adreno-730.1
448 - qcom,adreno-43020100
446 - qcom,adreno-43030c00449 - qcom,adreno-43030c00
447 - qcom,adreno-43050a01450 - qcom,adreno-43050a01
448 - qcom,adreno-43050c01451 - qcom,adreno-43050c01
449 - qcom,adreno-43051401452 - qcom,adreno-43051401
450 - qcom,adreno-44010000453 - qcom,adreno-44010000
454 - qcom,adreno-44050a01
451 - qcom,adreno-44070001455 - qcom,adreno-44070001
452 456
453 then: # Starting with A6xx, the clocks are usually defined in the GMU node457 then: # Starting with A6xx, the clocks are usually defined in the GMU node
Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml+5−1
@@ -13,7 +13,11 @@ $ref: /schemas/display/msm/dpu-common.yaml# · 12 unmodified lines
13 13
14properties:14properties:
15 compatible:15 compatible:
16 const: qcom,qcm2290-dpu16 oneOf:
17 - const: qcom,qcm2290-dpu
18 - items:
19 - const: qcom,shikra-dpu
20 - const: qcom,qcm2290-dpu
17 21
18 reg:22 reg:
19 items:23 items:
Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml+12−7
@@ -4,7 +4,7 @@ · 3 unmodified lines
4$id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-mdss.yaml#4$id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-mdss.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#5$schema: http://devicetree.org/meta-schemas/core.yaml#
6 6
7title: Qualcomm QCM220 Display MDSS7title: Qualcomm QCM2290 and Shikra Display MDSS
8 8
9maintainers:9maintainers:
10 - Loic Poulain <loic.poulain@linaro.org>10 - Loic Poulain <loic.poulain@linaro.org>
@@ -12,13 +12,18 @@ maintainers: · 1 unmodified line
12description:12description:
13 Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates13 Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
14 sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS14 sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS
15 are mentioned for QCM2290 target.15 are mentioned for QCM2290 and Shikra targets. Shikra uses the same MDSS/DPU/DSI
16 hardware as QCM2290 (DPU 6.5) and shares the same register layout.
16 17
17$ref: /schemas/display/msm/mdss-common.yaml#18$ref: /schemas/display/msm/mdss-common.yaml#
18 19
19properties:20properties:
20 compatible:21 compatible:
21 const: qcom,qcm2290-mdss22 oneOf:
23 - const: qcom,qcm2290-mdss
24 - items:
25 - const: qcom,shikra-mdss
26 - const: qcom,qcm2290-mdss
22 27
23 clocks:28 clocks:
24 items:29 items:
@@ -52,7 +57,8 @@ patternProperties: · 27 unmodified lines
52 57
53 properties:58 properties:
54 compatible:59 compatible:
55 const: qcom,qcm2290-dpu60 contains:
61 const: qcom,qcm2290-dpu
56 62
57 "^dsi@[0-9a-f]+$":63 "^dsi@[0-9a-f]+$":
58 type: object64 type: object
@@ -60,9 +66,8 @@ patternProperties: · 1 unmodified line
60 66
61 properties:67 properties:
62 compatible:68 compatible:
63 items:69 contains:
64 - const: qcom,qcm2290-dsi-ctrl70 const: qcom,qcm2290-dsi-ctrl
65 - const: qcom,mdss-dsi-ctrl
66 71
67 "^phy@[0-9a-f]+$":72 "^phy@[0-9a-f]+$":
68 type: object73 type: object
Documentation/devicetree/bindings/iommu/arm,smmu.yaml+4−0
@@ -95,6 +95,7 @@ properties: · 94 unmodified lines
95 - description: Qcom Adreno GPUs implementing "qcom,smmu-500" and "arm,mmu-500"95 - description: Qcom Adreno GPUs implementing "qcom,smmu-500" and "arm,mmu-500"
96 items:96 items:
97 - enum:97 - enum:
98 - qcom,eliza-smmu-500
98 - qcom,glymur-smmu-50099 - qcom,glymur-smmu-500
99 - qcom,hawi-smmu-500100 - qcom,hawi-smmu-500
100 - qcom,kaanapali-smmu-500101 - qcom,kaanapali-smmu-500
@@ -108,6 +109,7 @@ properties: · 7 unmodified lines
108 - qcom,sc7280-smmu-500109 - qcom,sc7280-smmu-500
109 - qcom,sc8180x-smmu-500110 - qcom,sc8180x-smmu-500
110 - qcom,sc8280xp-smmu-500111 - qcom,sc8280xp-smmu-500
112 - qcom,shikra-smmu-500
111 - qcom,sm6115-smmu-500113 - qcom,sm6115-smmu-500
112 - qcom,sm6125-smmu-500114 - qcom,sm6125-smmu-500
113 - qcom,sm8150-smmu-500115 - qcom,sm8150-smmu-500
@@ -543,6 +545,7 @@ allOf: · 429 unmodified lines
543 - enum:545 - enum:
544 - qcom,milos-smmu-500546 - qcom,milos-smmu-500
545 - qcom,sar2130p-smmu-500547 - qcom,sar2130p-smmu-500
548 - qcom,shikra-smmu-500
546 - qcom,sm8550-smmu-500549 - qcom,sm8550-smmu-500
547 - qcom,sm8650-smmu-500550 - qcom,sm8650-smmu-500
548 - qcom,x1e80100-smmu-500551 - qcom,x1e80100-smmu-500
@@ -570,6 +573,7 @@ allOf: · 21 unmodified lines
570 compatible:573 compatible:
571 items:574 items:
572 - enum:575 - enum:
576 - qcom,eliza-smmu-500
573 - qcom,glymur-smmu-500577 - qcom,glymur-smmu-500
574 - qcom,hawi-smmu-500578 - qcom,hawi-smmu-500
575 - qcom,kaanapali-smmu-500579 - qcom,kaanapali-smmu-500
drivers/gpu/drm/msm/adreno/a3xx_gpu.c+35−1
@@ -25,6 +25,8 @@ · 24 unmodified lines
25 25
26extern bool hang_debug;26extern bool hang_debug;
27 27
28#define A3XX_VBIF_XIN_HALT_CTRL0_MASK GENMASK(5, 0)
29
28static void a3xx_dump(struct msm_gpu *gpu);30static void a3xx_dump(struct msm_gpu *gpu);
29static bool a3xx_idle(struct msm_gpu *gpu);31static bool a3xx_idle(struct msm_gpu *gpu);
30 32
@@ -496,6 +498,38 @@ static u64 a3xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate) · 465 unmodified lines
496 return busy_cycles;498 return busy_cycles;
497}499}
498 500
501static int a3xx_vbif_halt(struct msm_gpu *gpu)
502{
503 u32 ack;
504 int ret;
505
506 gpu_write(gpu, REG_A3XX_VBIF_XIN_HALT_CTRL0,
507 A3XX_VBIF_XIN_HALT_CTRL0_MASK);
508 ret = spin_until(((ack = gpu_read(gpu, REG_A3XX_VBIF_XIN_HALT_CTRL1)) &
509 A3XX_VBIF_XIN_HALT_CTRL0_MASK) ==
510 A3XX_VBIF_XIN_HALT_CTRL0_MASK);
511 gpu_write(gpu, REG_A3XX_VBIF_XIN_HALT_CTRL0, 0);
512
513 if (ret)
514 return -EBUSY;
515
516 return 0;
517}
518
519static int a3xx_pm_suspend(struct msm_gpu *gpu)
520{
521 int ret;
522
523 if (!a3xx_idle(gpu))
524 return -EBUSY;
525
526 ret = a3xx_vbif_halt(gpu);
527 if (ret)
528 return ret;
529
530 return msm_gpu_pm_suspend(gpu);
531}
532
499static u32 a3xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)533static u32 a3xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
500{534{
501 ring->memptrs->rptr = gpu_read(gpu, REG_AXXX_CP_RB_RPTR);535 ring->memptrs->rptr = gpu_read(gpu, REG_AXXX_CP_RB_RPTR);
@@ -581,7 +615,7 @@ const struct adreno_gpu_funcs a3xx_gpu_funcs = { · 79 unmodified lines
581 .get_param = adreno_get_param,615 .get_param = adreno_get_param,
582 .set_param = adreno_set_param,616 .set_param = adreno_set_param,
583 .hw_init = a3xx_hw_init,617 .hw_init = a3xx_hw_init,
584 .pm_suspend = msm_gpu_pm_suspend,618 .pm_suspend = a3xx_pm_suspend,
585 .pm_resume = msm_gpu_pm_resume,619 .pm_resume = msm_gpu_pm_resume,
586 .recover = a3xx_recover,620 .recover = a3xx_recover,
587 .submit = a3xx_submit,621 .submit = a3xx_submit,
drivers/gpu/drm/msm/adreno/a5xx_gpu.c+5−0
@@ -1275,6 +1275,11 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu) · 1274 unmodified lines
1275 status & ~A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR);1275 status & ~A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR);
1276 1276
1277 if (priv->disable_err_irq) {1277 if (priv->disable_err_irq) {
1278 /* Turn off interrupts to avoid interrupt storm */
1279 gpu_write(gpu, REG_A5XX_RBBM_INT_0_MASK,
1280 A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS |
1281 A5XX_RBBM_INT_0_MASK_CP_SW);
1282
1278 status &= A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS |1283 status &= A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS |
1279 A5XX_RBBM_INT_0_MASK_CP_SW;1284 A5XX_RBBM_INT_0_MASK_CP_SW;
1280 }1285 }
drivers/gpu/drm/msm/adreno/a6xx_catalog.c+37−3
@@ -1199,7 +1199,7 @@ static const struct adreno_reglist a730_hwcg[] = { · 1198 unmodified lines
1199 { REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },1199 { REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
1200 { REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },1200 { REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
1201 { REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },1201 { REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
1202 { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },1202 { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22220222 },
1203 { REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },1203 { REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
1204 { REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },1204 { REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
1205 { REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },1205 { REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
@@ -1454,7 +1454,7 @@ DECLARE_ADRENO_REGLIST_PIPE_LIST(a7xx_dyn_pwrup_reglist); · 248 unmodified lines
1454 1454
1455static const struct adreno_info a7xx_gpus[] = {1455static const struct adreno_info a7xx_gpus[] = {
1456 {1456 {
1457 .chip_ids = ADRENO_CHIP_IDS(0x07000200),1457 .chip_ids = ADRENO_CHIP_IDS(0x07000200, 0x07000400),
1458 .family = ADRENO_6XX_GEN1, /* NOT a mistake! */1458 .family = ADRENO_6XX_GEN1, /* NOT a mistake! */
1459 .fw = {1459 .fw = {
1460 [ADRENO_FW_SQE] = "a702_sqe.fw",1460 [ADRENO_FW_SQE] = "a702_sqe.fw",
@@ -1500,6 +1500,40 @@ static const struct adreno_info a7xx_gpus[] = { · 39 unmodified lines
1500 .gmu_cgc_mode = 0x00020000,1500 .gmu_cgc_mode = 0x00020000,
1501 },1501 },
1502 .preempt_record_size = 2860 * SZ_1K,1502 .preempt_record_size = 2860 * SZ_1K,
1503 }, {
1504 .chip_ids = ADRENO_CHIP_IDS(0x43020100),
1505 .family = ADRENO_7XX_GEN1,
1506 .fw = {
1507 [ADRENO_FW_SQE] = "qcom/gen71700_sqe.fw",
1508 [ADRENO_FW_GMU] = "qcom/gen71700_gmu.bin",
1509 },
1510 .gmem = SZ_1M,
1511 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
1512 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
1513 ADRENO_QUIRK_HAS_HW_APRIV |
1514 ADRENO_QUIRK_PREEMPTION,
1515 .funcs = &a7xx_gpu_funcs,
1516 .a6xx = &(const struct a6xx_info) {
1517 .hwcg = a730_hwcg,
1518 .protect = &a730_protect,
1519 .pwrup_reglist = &a7xx_pwrup_reglist,
1520 .dyn_pwrup_reglist = &a7xx_dyn_pwrup_reglist,
1521 .gbif_cx = a640_gbif,
1522 .gmu_chipid = 0x07110000,
1523 .gmu_cgc_mode = 0x00020000,
1524 .bcms = (const struct a6xx_bcm[]) {
1525 { .name = "SH0", .buswidth = 16 },
1526 { .name = "MC0", .buswidth = 4 },
1527 {
1528 .name = "ACV",
1529 .fixed = true,
1530 .perfmode = BIT(3),
1531 .perfmode_bw = 16500000,
1532 },
1533 { /* sentinel */ },
1534 },
1535 },
1536 .preempt_record_size = 1536 * SZ_1K,
1503 }, {1537 }, {
1504 .chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */1538 .chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */
1505 .family = ADRENO_7XX_GEN2,1539 .family = ADRENO_7XX_GEN2,
@@ -2180,7 +2214,7 @@ static const struct adreno_reglist a840_gbif[] = { · 674 unmodified lines
2180 { REG_A6XX_GBIF_QSB_SIDE1, 0x00071e20 },2214 { REG_A6XX_GBIF_QSB_SIDE1, 0x00071e20 },
2181 { REG_A6XX_GBIF_QSB_SIDE2, 0x00071e20 },2215 { REG_A6XX_GBIF_QSB_SIDE2, 0x00071e20 },
2182 { REG_A6XX_GBIF_QSB_SIDE3, 0x00071e20 },2216 { REG_A6XX_GBIF_QSB_SIDE3, 0x00071e20 },
2183 { REG_A8XX_GBIF_CX_CONFIG, 0x20023000 },2217 { REG_A6XX_GBIF_CX_CONFIG, 0x20023000 },
2184 { },2218 { },
2185};2219};
2186 2220
drivers/gpu/drm/msm/adreno/a6xx_gmu.c+16−8
@@ -642,7 +642,7 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu) · 641 unmodified lines
642 int ret;642 int ret;
643 u32 val;643 u32 val;
644 644
645 if (test_and_clear_bit(GMU_STATUS_FW_START, &gmu->status))645 if (!test_and_clear_bit(GMU_STATUS_FW_START, &gmu->status))
646 return;646 return;
647 647
648 if (adreno_is_a840(adreno_gpu))648 if (adreno_is_a840(adreno_gpu))
@@ -710,7 +710,8 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) · 61 unmodified lines
710 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);710 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
711 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);711 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
712 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4,712 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4,
713 adreno_is_a740_family(adreno_gpu) ? 0x80000021 : 0x80000000);713 (adreno_is_a740_family(adreno_gpu) ||
714 adreno_is_a722(adreno_gpu)) ? 0x80000021 : 0x80000000);
714 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);715 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
715 gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);716 gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
716 gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);717 gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);
@@ -718,7 +719,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) · 1 unmodified line
718 gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);719 gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
719 720
720 /* The second spin of A7xx GPUs messed with some register offsets.. */721 /* The second spin of A7xx GPUs messed with some register offsets.. */
721 if (adreno_is_a740_family(adreno_gpu))722 if (adreno_is_a740_family(adreno_gpu) || adreno_is_a722(adreno_gpu))
722 seqmem0_drv0_reg = REG_A7XX_RSCC_SEQ_MEM_0_DRV0_A740;723 seqmem0_drv0_reg = REG_A7XX_RSCC_SEQ_MEM_0_DRV0_A740;
723 724
724 /* Load RSC sequencer uCode for sleep and wakeup */725 /* Load RSC sequencer uCode for sleep and wakeup */
@@ -1032,9 +1033,11 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) · 307 unmodified lines
1032 gpu_write(gpu, gbif_cx[i].offset, gbif_cx[i].value);1033 gpu_write(gpu, gbif_cx[i].offset, gbif_cx[i].value);
1033 1034
1034 if (adreno_is_a8xx(adreno_gpu)) {1035 if (adreno_is_a8xx(adreno_gpu)) {
1035 gpu_write(gpu, REG_A8XX_GBIF_CX_CONFIG, 0x20023000);1036 gpu_write(gpu, REG_A6XX_GBIF_CX_CONFIG, 0x20023000);
1036 gmu_write(gmu, REG_A6XX_GMU_MRC_GBIF_QOS_CTRL, 0x33);1037 gmu_write(gmu, REG_A6XX_GMU_MRC_GBIF_QOS_CTRL, 0x33);
1037 }1038 } else if (adreno_is_a722(adreno_gpu))
1039 gpu_rmw(gpu, REG_A6XX_GBIF_CX_CONFIG, GENMASK(31, 29),
1040 FIELD_PREP(GENMASK(31, 29), 2));
1038 1041
1039 /* Set up the lowest idle level on the GMU */1042 /* Set up the lowest idle level on the GMU */
1040 a6xx_gmu_power_config(gmu);1043 a6xx_gmu_power_config(gmu);
@@ -1087,7 +1090,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu) · 46 unmodified lines
1087 u32 val, seqmem_off = 0;1090 u32 val, seqmem_off = 0;
1088 1091
1089 /* The second spin of A7xx GPUs messed with some register offsets.. */1092 /* The second spin of A7xx GPUs messed with some register offsets.. */
1090 if (adreno_is_a740_family(adreno_gpu) || adreno_is_a8xx(adreno_gpu))1093 if (adreno_is_a740_family(adreno_gpu) || adreno_is_a722(adreno_gpu) ||
1094 adreno_is_a8xx(adreno_gpu))
1091 seqmem_off = 4;1095 seqmem_off = 4;
1092 1096
1093 /* Make sure there are no outstanding RPMh votes */1097 /* Make sure there are no outstanding RPMh votes */
@@ -1100,7 +1104,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu) · 6 unmodified lines
1100 gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS + seqmem_off,1104 gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS + seqmem_off,
1101 val, (val & 1), 100, 1000);1105 val, (val & 1), 100, 1000);
1102 1106
1103 if (!adreno_is_a740_family(adreno_gpu) && !adreno_is_a8xx(adreno_gpu))1107 if (!adreno_is_a740_family(adreno_gpu) && !adreno_is_a722(adreno_gpu) &&
1108 !adreno_is_a8xx(adreno_gpu))
1104 return;1109 return;
1105 1110
1106 gmu_poll_timeout_rscc(gmu, REG_A7XX_RSCC_TCS4_DRV0_STATUS + seqmem_off,1111 gmu_poll_timeout_rscc(gmu, REG_A7XX_RSCC_TCS4_DRV0_STATUS + seqmem_off,
@@ -1465,6 +1470,9 @@ static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu) · 358 unmodified lines
1465 /* Stop the interrupts and mask the hardware */1470 /* Stop the interrupts and mask the hardware */
1466 a6xx_gmu_irq_disable(gmu);1471 a6xx_gmu_irq_disable(gmu);
1467 1472
1473 /* Halt the gmu cm3 core */
1474 gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
1475
1468 /* Tell RPMh to power off the GPU */1476 /* Tell RPMh to power off the GPU */
1469 a6xx_rpmh_stop(gmu);1477 a6xx_rpmh_stop(gmu);
1470 1478
@@ -1546,7 +1554,7 @@ static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo, · 75 unmodified lines
1546 flags |= MSM_BO_MAP_PRIV;1554 flags |= MSM_BO_MAP_PRIV;
1547 }1555 }
1548 1556
1549 bo->obj = msm_gem_new(dev, size, flags);1557 bo->obj = msm_gem_new(dev, size, flags, NULL);
1550 if (IS_ERR(bo->obj))1558 if (IS_ERR(bo->obj))
1551 return PTR_ERR(bo->obj);1559 return PTR_ERR(bo->obj);
1552 1560
drivers/gpu/drm/msm/adreno/a6xx_gpu.c+10−4
@@ -229,7 +229,7 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, · 228 unmodified lines
229{229{
230 bool sysprof = msm_gpu_sysprof_no_perfcntr_zap(&a6xx_gpu->base.base);230 bool sysprof = msm_gpu_sysprof_no_perfcntr_zap(&a6xx_gpu->base.base);
231 struct msm_context *ctx = submit->queue->ctx;231 struct msm_context *ctx = submit->queue->ctx;
232 struct drm_gpuvm *vm = msm_context_vm(submit->dev, ctx);232 struct drm_gpuvm *vm = ctx->vm;
233 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;233 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
234 phys_addr_t ttbr;234 phys_addr_t ttbr;
235 u32 asid;235 u32 asid;
@@ -1273,7 +1273,8 @@ static int hw_init(struct msm_gpu *gpu) · 1037 unmodified lines
1273 if (!(adreno_is_a650_family(adreno_gpu) ||1273 if (!(adreno_is_a650_family(adreno_gpu) ||
1274 adreno_is_a702(adreno_gpu) ||1274 adreno_is_a702(adreno_gpu) ||
1275 adreno_is_a730(adreno_gpu))) {1275 adreno_is_a730(adreno_gpu))) {
1276 gmem_range_min = adreno_is_a740_family(adreno_gpu) ? SZ_16M : SZ_1M;1276 gmem_range_min = (adreno_is_a740_family(adreno_gpu) ||
1277 adreno_is_a722(adreno_gpu)) ? SZ_16M : SZ_1M;
1277 1278
1278 /* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */1279 /* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */
1279 gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN, gmem_range_min);1280 gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN, gmem_range_min);
@@ -1338,6 +1339,7 @@ static int hw_init(struct msm_gpu *gpu) · 58 unmodified lines
1338 1339
1339 /* Enable fault detection */1340 /* Enable fault detection */
1340 if (adreno_is_a612(adreno_gpu) ||1341 if (adreno_is_a612(adreno_gpu) ||
1342 adreno_is_a722(adreno_gpu) ||
1341 adreno_is_a730(adreno_gpu) ||1343 adreno_is_a730(adreno_gpu) ||
1342 adreno_is_a740_family(adreno_gpu))1344 adreno_is_a740_family(adreno_gpu))
1343 gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0xcfffff);1345 gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0xcfffff);
@@ -1911,8 +1913,11 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu) · 567 unmodified lines
1911 1913
1912 gpu_write(gpu, REG_A6XX_RBBM_INT_CLEAR_CMD, status);1914 gpu_write(gpu, REG_A6XX_RBBM_INT_CLEAR_CMD, status);
1913 1915
1914 if (priv->disable_err_irq)1916 if (priv->disable_err_irq) {
1917 /* Turn off interrupts to avoid interrupt storm */
1918 gpu_write(gpu, REG_A6XX_RBBM_INT_0_MASK, A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS);
1915 status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;1919 status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;
1920 }
1916 1921
1917 if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)1922 if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)
1918 a6xx_fault_detect_irq(gpu);1923 a6xx_fault_detect_irq(gpu);
@@ -2770,8 +2775,9 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) · 851 unmodified lines
2770 2775
2771 adreno_gpu->ubwc_config = qcom_ubwc_config_get_data();2776 adreno_gpu->ubwc_config = qcom_ubwc_config_get_data();
2772 if (IS_ERR(adreno_gpu->ubwc_config)) {2777 if (IS_ERR(adreno_gpu->ubwc_config)) {
2778 ret = PTR_ERR(adreno_gpu->ubwc_config);
2773 a6xx_destroy(&(a6xx_gpu->base.base));2779 a6xx_destroy(&(a6xx_gpu->base.base));
2774 return ERR_CAST(adreno_gpu->ubwc_config);2780 return ERR_PTR(ret);
2775 }2781 }
2776 2782
2777 /* Set up the preemption specific bits and pieces for each ringbuffer */2783 /* Set up the preemption specific bits and pieces for each ringbuffer */
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c+68−18
@@ -11,12 +11,14 @@ · 10 unmodified lines
11static const unsigned int *gen7_0_0_external_core_regs[] __always_unused;11static const unsigned int *gen7_0_0_external_core_regs[] __always_unused;
12static const unsigned int *gen7_2_0_external_core_regs[] __always_unused;12static const unsigned int *gen7_2_0_external_core_regs[] __always_unused;
13static const unsigned int *gen7_9_0_external_core_regs[] __always_unused;13static const unsigned int *gen7_9_0_external_core_regs[] __always_unused;
14static const unsigned int *gen7_17_0_external_core_regs[] __always_unused;
14static const struct gen7_sptp_cluster_registers gen7_9_0_sptp_clusters[] __always_unused;15static const struct gen7_sptp_cluster_registers gen7_9_0_sptp_clusters[] __always_unused;
15static const u32 gen7_9_0_cx_debugbus_blocks[] __always_unused;16static const u32 gen7_9_0_cx_debugbus_blocks[] __always_unused;
16 17
17#include "adreno_gen7_0_0_snapshot.h"18#include "adreno_gen7_0_0_snapshot.h"
18#include "adreno_gen7_2_0_snapshot.h"19#include "adreno_gen7_2_0_snapshot.h"
19#include "adreno_gen7_9_0_snapshot.h"20#include "adreno_gen7_9_0_snapshot.h"
21#include "adreno_gen7_17_0_snapshot.h"
20 22
21struct a6xx_gpu_state_obj {23struct a6xx_gpu_state_obj {
22 const void *handle;24 const void *handle;
@@ -404,8 +406,13 @@ static void a7xx_get_debugbus_blocks(struct msm_gpu *gpu, · 381 unmodified lines
404 int i;406 int i;
405 407
406 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {408 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
407 debugbus_blocks = gen7_0_0_debugbus_blocks;409 if (adreno_is_a722(adreno_gpu)) {
408 debugbus_blocks_count = ARRAY_SIZE(gen7_0_0_debugbus_blocks);410 debugbus_blocks = gen7_17_0_debugbus_blocks;
411 debugbus_blocks_count = ARRAY_SIZE(gen7_17_0_debugbus_blocks);
412 } else {
413 debugbus_blocks = gen7_0_0_debugbus_blocks;
414 debugbus_blocks_count = ARRAY_SIZE(gen7_0_0_debugbus_blocks);
415 }
409 gbif_debugbus_blocks = a7xx_gbif_debugbus_blocks;416 gbif_debugbus_blocks = a7xx_gbif_debugbus_blocks;
410 gbif_debugbus_blocks_count = ARRAY_SIZE(a7xx_gbif_debugbus_blocks);417 gbif_debugbus_blocks_count = ARRAY_SIZE(a7xx_gbif_debugbus_blocks);
411 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {418 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
@@ -678,8 +685,13 @@ static void a7xx_get_dbgahb_clusters(struct msm_gpu *gpu, · 266 unmodified lines
678 unsigned dbgahb_clusters_size;685 unsigned dbgahb_clusters_size;
679 686
680 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {687 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
681 dbgahb_clusters = gen7_0_0_sptp_clusters;688 if (adreno_is_a722(adreno_gpu)) {
682 dbgahb_clusters_size = ARRAY_SIZE(gen7_0_0_sptp_clusters);689 dbgahb_clusters = gen7_17_0_sptp_clusters;
690 dbgahb_clusters_size = ARRAY_SIZE(gen7_17_0_sptp_clusters);
691 } else {
692 dbgahb_clusters = gen7_0_0_sptp_clusters;
693 dbgahb_clusters_size = ARRAY_SIZE(gen7_0_0_sptp_clusters);
694 }
683 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {695 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
684 dbgahb_clusters = gen7_2_0_sptp_clusters;696 dbgahb_clusters = gen7_2_0_sptp_clusters;
685 dbgahb_clusters_size = ARRAY_SIZE(gen7_2_0_sptp_clusters);697 dbgahb_clusters_size = ARRAY_SIZE(gen7_2_0_sptp_clusters);
@@ -839,8 +851,13 @@ static void a7xx_get_clusters(struct msm_gpu *gpu, · 153 unmodified lines
839 unsigned clusters_size;851 unsigned clusters_size;
840 852
841 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {853 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
842 clusters = gen7_0_0_clusters;854 if (adreno_is_a722(adreno_gpu)) {
843 clusters_size = ARRAY_SIZE(gen7_0_0_clusters);855 clusters = gen7_17_0_clusters;
856 clusters_size = ARRAY_SIZE(gen7_17_0_clusters);
857 } else {
858 clusters = gen7_0_0_clusters;
859 clusters_size = ARRAY_SIZE(gen7_0_0_clusters);
860 }
844 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {861 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
845 clusters = gen7_2_0_clusters;862 clusters = gen7_2_0_clusters;
846 clusters_size = ARRAY_SIZE(gen7_2_0_clusters);863 clusters_size = ARRAY_SIZE(gen7_2_0_clusters);
@@ -977,8 +994,13 @@ static void a7xx_get_shaders(struct msm_gpu *gpu, · 130 unmodified lines
977 int i;994 int i;
978 995
979 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {996 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
980 shader_blocks = gen7_0_0_shader_blocks;997 if (adreno_is_a722(adreno_gpu)) {
981 num_shader_blocks = ARRAY_SIZE(gen7_0_0_shader_blocks);998 shader_blocks = gen7_17_0_shader_blocks;
999 num_shader_blocks = ARRAY_SIZE(gen7_17_0_shader_blocks);
1000 } else {
1001 shader_blocks = gen7_0_0_shader_blocks;
1002 num_shader_blocks = ARRAY_SIZE(gen7_0_0_shader_blocks);
1003 }
982 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {1004 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
983 shader_blocks = gen7_2_0_shader_blocks;1005 shader_blocks = gen7_2_0_shader_blocks;
984 num_shader_blocks = ARRAY_SIZE(gen7_2_0_shader_blocks);1006 num_shader_blocks = ARRAY_SIZE(gen7_2_0_shader_blocks);
@@ -1244,9 +1266,12 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu, · 259 unmodified lines
1244 _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[1],1266 _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[1],
1245 &a6xx_state->gmu_registers[1], true);1267 &a6xx_state->gmu_registers[1], true);
1246 1268
1247 if (adreno_is_a621(adreno_gpu) || adreno_is_a623(adreno_gpu))1269 if (adreno_is_a621(adreno_gpu))
1248 _a6xx_get_gmu_registers(gpu, a6xx_state, &a621_gpucc_reg,1270 _a6xx_get_gmu_registers(gpu, a6xx_state, &a621_gpucc_reg,
1249 &a6xx_state->gmu_registers[2], false);1271 &a6xx_state->gmu_registers[2], false);
1272 else if (adreno_is_a623(adreno_gpu) || adreno_is_a663(adreno_gpu))
1273 _a6xx_get_gmu_registers(gpu, a6xx_state, &a623_gpucc_reg,
1274 &a6xx_state->gmu_registers[2], false);
1250 else1275 else
1251 _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gpucc_reg,1276 _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gpucc_reg,
1252 &a6xx_state->gmu_registers[2], false);1277 &a6xx_state->gmu_registers[2], false);
@@ -1376,8 +1401,13 @@ static void a7xx_get_registers(struct msm_gpu *gpu, · 123 unmodified lines
1376 const struct gen7_reg_list *reglist;1401 const struct gen7_reg_list *reglist;
1377 1402
1378 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {1403 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
1379 reglist = gen7_0_0_reg_list;1404 if (adreno_is_a722(adreno_gpu)) {
1380 pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;1405 reglist = gen7_17_0_reg_list;
1406 pre_crashdumper_regs = gen7_9_0_pre_crashdumper_gpu_registers;
1407 } else {
1408 reglist = gen7_0_0_reg_list;
1409 pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;
1410 }
1381 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {1411 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
1382 reglist = gen7_2_0_reg_list;1412 reglist = gen7_2_0_reg_list;
1383 pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;1413 pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;
@@ -1433,7 +1463,9 @@ static void a7xx_get_post_crashdumper_registers(struct msm_gpu *gpu, · 49 unmodified lines
1433 const u32 *regs;1463 const u32 *regs;
1434 1464
1435 BUG_ON(adreno_gpu->info->family > ADRENO_7XX_GEN3);1465 BUG_ON(adreno_gpu->info->family > ADRENO_7XX_GEN3);
1436 regs = gen7_0_0_post_crashdumper_registers;1466 regs = adreno_is_a722(adreno_gpu) ?
1467 gen7_17_0_post_crashdumper_registers :
1468 gen7_0_0_post_crashdumper_registers;
1437 1469
1438 a7xx_get_ahb_gpu_registers(gpu,1470 a7xx_get_ahb_gpu_registers(gpu,
1439 a6xx_state, regs,1471 a6xx_state, regs,
@@ -1540,19 +1572,35 @@ static void a7xx_get_indexed_registers(struct msm_gpu *gpu, · 100 unmodified lines
1540{1572{
1541 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);1573 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1542 const struct a6xx_indexed_registers *indexed_regs;1574 const struct a6xx_indexed_registers *indexed_regs;
1575 const struct a6xx_indexed_registers *mempool_regs;
1543 int i, indexed_count, mempool_count;1576 int i, indexed_count, mempool_count;
1577 bool concurrent_binning;
1544 1578
1545 if (adreno_gpu->info->family <= ADRENO_7XX_GEN2) {1579 if (adreno_is_a722(adreno_gpu)) {
1580 /*
1581 * Eliza has no BV or LPAC SQE — skip the BV/LPAC indexed
1582 * registers and the BV mempool
1583 */
1584 indexed_regs = gen7_17_0_cp_indexed_reglist;
1585 indexed_count = ARRAY_SIZE(gen7_17_0_cp_indexed_reglist);
1586 mempool_regs = a7xx_cp_mempool_indexed;
1587 mempool_count = ARRAY_SIZE(a7xx_cp_mempool_indexed);
1588 concurrent_binning = false;
1589 } else if (adreno_gpu->info->family <= ADRENO_7XX_GEN2) {
1546 indexed_regs = a7xx_indexed_reglist;1590 indexed_regs = a7xx_indexed_reglist;
1547 indexed_count = ARRAY_SIZE(a7xx_indexed_reglist);1591 indexed_count = ARRAY_SIZE(a7xx_indexed_reglist);
1592 mempool_regs = a7xx_cp_bv_mempool_indexed;
1593 mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
1594 concurrent_binning = true;
1548 } else {1595 } else {
1549 BUG_ON(adreno_gpu->info->family != ADRENO_7XX_GEN3);1596 BUG_ON(adreno_gpu->info->family != ADRENO_7XX_GEN3);
1550 indexed_regs = gen7_9_0_cp_indexed_reg_list;1597 indexed_regs = gen7_9_0_cp_indexed_reg_list;
1551 indexed_count = ARRAY_SIZE(gen7_9_0_cp_indexed_reg_list);1598 indexed_count = ARRAY_SIZE(gen7_9_0_cp_indexed_reg_list);
1599 mempool_regs = a7xx_cp_bv_mempool_indexed;
1600 mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
1601 concurrent_binning = true;
1552 }1602 }
1553 1603
1554 mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
1555
1556 a6xx_state->indexed_regs = state_kcalloc(a6xx_state,1604 a6xx_state->indexed_regs = state_kcalloc(a6xx_state,
1557 indexed_count + mempool_count,1605 indexed_count + mempool_count,
1558 sizeof(*a6xx_state->indexed_regs));1606 sizeof(*a6xx_state->indexed_regs));
@@ -1567,15 +1615,17 @@ static void a7xx_get_indexed_registers(struct msm_gpu *gpu, · 8 unmodified lines
1567 &a6xx_state->indexed_regs[i]);1615 &a6xx_state->indexed_regs[i]);
1568 1616
1569 gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, 0, BIT(2));1617 gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, 0, BIT(2));
1570 gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, 0, BIT(2));1618 if (concurrent_binning)
1619 gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, 0, BIT(2));
1571 1620
1572 /* Get the contents of the CP_BV mempool */1621 /* Get the contents of the CP_BV mempool */
1573 for (i = 0; i < mempool_count; i++)1622 for (i = 0; i < mempool_count; i++)
1574 a6xx_get_indexed_regs(gpu, a6xx_state, &a7xx_cp_bv_mempool_indexed[i],1623 a6xx_get_indexed_regs(gpu, a6xx_state, &mempool_regs[i],
1575 &a6xx_state->indexed_regs[indexed_count + i]);1624 &a6xx_state->indexed_regs[indexed_count + i]);
1576 1625
1577 gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(2), 0);1626 gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(2), 0);
1578 gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, BIT(2), 0);1627 if (concurrent_binning)
1628 gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, BIT(2), 0);
1579 return;1629 return;
1580}1630}
1581 1631
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h+17−0
@@ -377,6 +377,17 @@ static const u32 a6xx_gmu_gpucc_registers[] = { · 376 unmodified lines
377};377};
378 378
379static const u32 a621_gmu_gpucc_registers[] = {379static const u32 a621_gmu_gpucc_registers[] = {
380 /* GPU CC */
381 0x24000, 0x2400e, 0x24400, 0x2440e, 0x24800, 0x24805, 0x24c00, 0x24cff,
382 0x25800, 0x25804, 0x25c00, 0x25c04, 0x26000, 0x26004, 0x26400, 0x26405,
383 0x26414, 0x2641d, 0x2642a, 0x26430, 0x26432, 0x26432, 0x26441, 0x26455,
384 0x26466, 0x26468, 0x26478, 0x2647a, 0x26489, 0x2648a, 0x2649c, 0x2649e,
385 0x264a0, 0x264a3, 0x264b3, 0x264b5, 0x264c5, 0x264c7, 0x264d6, 0x264d8,
386 0x264e8, 0x264e9, 0x264f9, 0x264fc, 0x2650b, 0x2650c, 0x2651c, 0x2651e,
387 0x26540, 0x26570, 0x26600, 0x26616, 0x26620, 0x2662d,
388};
389
390static const u32 a623_gmu_gpucc_registers[] = {
380 /* GPU CC */391 /* GPU CC */
381 0x24000, 0x2400e, 0x24400, 0x2440e, 0x25800, 0x25804, 0x25c00, 0x25c04,392 0x24000, 0x2400e, 0x24400, 0x2440e, 0x25800, 0x25804, 0x25c00, 0x25c04,
382 0x26000, 0x26004, 0x26400, 0x26405, 0x26414, 0x2641d, 0x2642a, 0x26430,393 0x26000, 0x26004, 0x26400, 0x26405, 0x26414, 0x2641d, 0x2642a, 0x26430,
@@ -402,6 +413,7 @@ static const struct a6xx_registers a6xx_gmu_reglist[] = { · 19 unmodified lines
402 413
403static const struct a6xx_registers a6xx_gpucc_reg = REGS(a6xx_gmu_gpucc_registers, 0, 0);414static const struct a6xx_registers a6xx_gpucc_reg = REGS(a6xx_gmu_gpucc_registers, 0, 0);
404static const struct a6xx_registers a621_gpucc_reg = REGS(a621_gmu_gpucc_registers, 0, 0);415static const struct a6xx_registers a621_gpucc_reg = REGS(a621_gmu_gpucc_registers, 0, 0);
416static const struct a6xx_registers a623_gpucc_reg = REGS(a623_gmu_gpucc_registers, 0, 0);
405 417
406static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu);418static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu);
407static u32 a7xx_get_cp_roq_size(struct msm_gpu *gpu);419static u32 a7xx_get_cp_roq_size(struct msm_gpu *gpu);
@@ -462,6 +474,11 @@ static const struct a6xx_indexed_registers a7xx_cp_bv_mempool_indexed[] = { · 54 unmodified lines
462 REG_A7XX_CP_BV_MEM_POOL_DBG_DATA, 0x2200, NULL },474 REG_A7XX_CP_BV_MEM_POOL_DBG_DATA, 0x2200, NULL },
463};475};
464 476
477static const struct a6xx_indexed_registers a7xx_cp_mempool_indexed[] = {
478 { "CP_MEM_POOL_DBG", REG_A6XX_CP_MEM_POOL_DBG_ADDR,
479 REG_A6XX_CP_MEM_POOL_DBG_DATA, 0x2200, NULL },
480};
481
465#define DEBUGBUS(_id, _count) { .id = _id, .name = #_id, .count = _count }482#define DEBUGBUS(_id, _count) { .id = _id, .name = #_id, .count = _count }
466 483
467static const struct a6xx_debugbus_block {484static const struct a6xx_debugbus_block {
drivers/gpu/drm/msm/adreno/a8xx_gpu.c+5−2
@@ -228,7 +228,7 @@ static void a8xx_set_hwcg(struct msm_gpu *gpu, bool state) · 227 unmodified lines
228 * GMU enables clk gating in GBIF during boot up. So,228 * GMU enables clk gating in GBIF during boot up. So,
229 * override that here when hwcg feature is disabled229 * override that here when hwcg feature is disabled
230 */230 */
231 gpu_rmw(gpu, REG_A8XX_GBIF_CX_CONFIG, BIT(0), 0);231 gpu_rmw(gpu, REG_A6XX_GBIF_CX_CONFIG, BIT(0), 0);
232 }232 }
233}233}
234 234
@@ -1211,8 +1211,11 @@ irqreturn_t a8xx_irq(struct msm_gpu *gpu) · 976 unmodified lines
1211 1211
1212 gpu_write(gpu, REG_A8XX_RBBM_INT_CLEAR_CMD, status);1212 gpu_write(gpu, REG_A8XX_RBBM_INT_CLEAR_CMD, status);
1213 1213
1214 if (priv->disable_err_irq)1214 if (priv->disable_err_irq) {
1215 /* Turn off interrupts to avoid interrupt storm */
1216 gpu_write(gpu, REG_A8XX_RBBM_INT_0_MASK, A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS);
1215 status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;1217 status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;
1218 }
1216 1219
1217 if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)1220 if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)
1218 a8xx_fault_detect_irq(gpu);1221 a8xx_fault_detect_irq(gpu);
drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h+428−0
@@ -0,0 +1,428 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
4 */
5#ifndef __ADRENO_GEN7_17_0_SNAPSHOT_H
6#define __ADRENO_GEN7_17_0_SNAPSHOT_H
7
8#include "a6xx_gpu_state.h"
9
10/*
11 * Snapshot tables for Adreno A722 (Eliza).
12 * Cluster sub-arrays that are identical to A730 reference gen7_0_0_*
13 * symbols; adreno_gen7_0_0_snapshot.h is included first in the TU.
14 */
15
16static const u32 gen7_17_0_rscc_registers[] = {
17 0x14000, 0x14034, 0x14036, 0x14036, 0x14040, 0x14042, 0x14044, 0x14045,
18 0x14047, 0x14047, 0x14080, 0x14084, 0x14089, 0x1408c, 0x14091, 0x14094,
19 0x14099, 0x1409c, 0x140a1, 0x140a4, 0x140a9, 0x140ac, 0x140b1, 0x140b4,
20 0x140b9, 0x140bc, 0x14100, 0x14104, 0x14114, 0x14119, 0x14124, 0x14132,
21 0x14154, 0x1416b, 0x14340, 0x14341, 0x14344, 0x14344, 0x14346, 0x1437c,
22 0x143f0, 0x143f8, 0x143fa, 0x143fe, 0x14400, 0x14404, 0x14406, 0x1440a,
23 0x1440c, 0x14410, 0x14412, 0x14416, 0x14418, 0x1441c, 0x1441e, 0x14422,
24 0x14424, 0x14424, 0x14498, 0x144a0, 0x144a2, 0x144a6, 0x144a8, 0x144ac,
25 0x144ae, 0x144b2, 0x144b4, 0x144b8, 0x144ba, 0x144be, 0x144c0, 0x144c4,
26 0x144c6, 0x144ca, 0x144cc, 0x144cc, 0x14540, 0x14548, 0x1454a, 0x1454e,
27 0x14550, 0x14554, 0x14556, 0x1455a, 0x1455c, 0x14560, 0x14562, 0x14566,
28 0x14568, 0x1456c, 0x1456e, 0x14572, 0x14574, 0x14574, 0x145e8, 0x145f0,
29 0x145f2, 0x145f6, 0x145f8, 0x145fc, 0x145fe, 0x14602, 0x14604, 0x14608,
30 0x1460a, 0x1460e, 0x14610, 0x14614, 0x14616, 0x1461a, 0x1461c, 0x1461c,
31 0x14690, 0x14698, 0x1469a, 0x1469e, 0x146a0, 0x146a4, 0x146a6, 0x146aa,
32 0x146ac, 0x146b0, 0x146b2, 0x146b6, 0x146b8, 0x146bc, 0x146be, 0x146c2,
33 0x146c4, 0x146c4, 0x14738, 0x14740, 0x14742, 0x14746, 0x14748, 0x1474c,
34 0x1474e, 0x14752, 0x14754, 0x14758, 0x1475a, 0x1475e, 0x14760, 0x14764,
35 0x14766, 0x1476a, 0x1476c, 0x1476c, 0x147e0, 0x147e8, 0x147ea, 0x147ee,
36 0x147f0, 0x147f4, 0x147f6, 0x147fa, 0x147fc, 0x14800, 0x14802, 0x14806,
37 0x14808, 0x1480c, 0x1480e, 0x14812, 0x14814, 0x14814, 0x14888, 0x14890,
38 0x14892, 0x14896, 0x14898, 0x1489c, 0x1489e, 0x148a2, 0x148a4, 0x148a8,
39 0x148aa, 0x148ae, 0x148b0, 0x148b4, 0x148b6, 0x148ba, 0x148bc, 0x148bc,
40 0x14930, 0x14938, 0x1493a, 0x1493e, 0x14940, 0x14944, 0x14946, 0x1494a,
41 0x1494c, 0x14950, 0x14952, 0x14956, 0x14958, 0x1495c, 0x1495e, 0x14962,
42 0x14964, 0x14964,
43 UINT_MAX, UINT_MAX,
44};
45static_assert(IS_ALIGNED(sizeof(gen7_17_0_rscc_registers), 8));
46
47static const u32 gen7_17_0_cpr_registers[] = {
48 0x26800, 0x26805, 0x26808, 0x2680c, 0x26814, 0x26814, 0x2681c, 0x2681c,
49 0x26820, 0x26838, 0x26840, 0x26840, 0x26848, 0x26848, 0x26850, 0x26850,
50 0x26880, 0x2688e, 0x26980, 0x269b0, 0x269c0, 0x269c2, 0x269c6, 0x269c8,
51 0x269e0, 0x269ee, 0x269fb, 0x269ff, 0x26a02, 0x26a07, 0x26a09, 0x26a0b,
52 0x26a10, 0x26b0f, 0x27440, 0x27441, 0x27444, 0x27444, 0x27480, 0x274a2,
53 0x274ac, 0x274c4, 0x274c8, 0x274da,
54 UINT_MAX, UINT_MAX,
55};
56static_assert(IS_ALIGNED(sizeof(gen7_17_0_cpr_registers), 8));
57
58static const u32 gen7_17_0_gpucc_registers[] = {
59 0x24000, 0x2400f, 0x24400, 0x2440f, 0x24800, 0x24805, 0x24c00, 0x24cff,
60 0x25400, 0x25404, 0x25800, 0x25804, 0x25c00, 0x25c04, 0x26000, 0x26004,
61 0x26400, 0x26405, 0x26414, 0x2641d, 0x2642a, 0x2642c, 0x2642e, 0x26432,
62 0x26434, 0x26434, 0x26443, 0x26457, 0x26459, 0x2645d, 0x2645f, 0x26464,
63 0x26477, 0x26479, 0x26489, 0x2648b, 0x2649a, 0x2649b, 0x264ad, 0x264af,
64 0x264b1, 0x264b5, 0x264d6, 0x264d8, 0x264e7, 0x264e9, 0x264f9, 0x264fa,
65 0x2650a, 0x2650d, 0x2651f, 0x26520, 0x2652d, 0x2652f, 0x2653e, 0x2653e,
66 0x26540, 0x2654e, 0x26554, 0x26573, 0x26576, 0x26576, 0x26593, 0x26593,
67 0x26600, 0x26616, 0x26620, 0x2662d, 0x26630, 0x26631, 0x26635, 0x26635,
68 0x26637, 0x26637, 0x2663a, 0x2663a, 0x26642, 0x26642, 0x26656, 0x26658,
69 0x2665b, 0x2665d, 0x2665f, 0x26662,
70 UINT_MAX, UINT_MAX,
71};
72static_assert(IS_ALIGNED(sizeof(gen7_17_0_gpucc_registers), 8));
73
74static const u32 *gen7_17_0_external_core_regs[] = {
75 gen7_17_0_gpucc_registers,
76 gen7_17_0_cpr_registers,
77};
78
79static const u32 gen7_17_0_debugbus_blocks[] = {
80 A7XX_DBGBUS_CP_0_0,
81 A7XX_DBGBUS_CP_0_1,
82 A7XX_DBGBUS_RBBM,
83 A7XX_DBGBUS_HLSQ,
84 A7XX_DBGBUS_UCHE_0,
85 A7XX_DBGBUS_TESS_BR,
86 A7XX_DBGBUS_PC_BR,
87 A7XX_DBGBUS_VFDP_BR,
88 A7XX_DBGBUS_VPC_BR,
89 A7XX_DBGBUS_TSE_BR,
90 A7XX_DBGBUS_RAS_BR,
91 A7XX_DBGBUS_VSC,
92 A7XX_DBGBUS_COM_0,
93 A7XX_DBGBUS_LRZ_BR,
94 A7XX_DBGBUS_UFC_0,
95 A7XX_DBGBUS_UFC_1,
96 A7XX_DBGBUS_GMU_GX,
97 A7XX_DBGBUS_DBGC,
98 A7XX_DBGBUS_GPC_BR,
99 A7XX_DBGBUS_LARC,
100 A7XX_DBGBUS_HLSQ_SPTP,
101 A7XX_DBGBUS_RB_0,
102 A7XX_DBGBUS_RB_1,
103 A7XX_DBGBUS_UCHE_WRAPPER,
104 A7XX_DBGBUS_CCU_0,
105 A7XX_DBGBUS_CCU_1,
106 A7XX_DBGBUS_VFD_BR_0,
107 A7XX_DBGBUS_VFD_BR_1,
108 A7XX_DBGBUS_VFD_BR_2,
109 A7XX_DBGBUS_VFD_BR_3,
110 A7XX_DBGBUS_USP_0,
111 A7XX_DBGBUS_USP_1,
112 A7XX_DBGBUS_TP_0,
113 A7XX_DBGBUS_TP_1,
114 A7XX_DBGBUS_TP_2,
115 A7XX_DBGBUS_TP_3,
116 A7XX_DBGBUS_USPTP_0,
117 A7XX_DBGBUS_USPTP_1,
118 A7XX_DBGBUS_USPTP_2,
119 A7XX_DBGBUS_USPTP_3,
120};
121
122static const struct gen7_sel_reg gen7_17_0_rb_rac_sel = {
123 .host_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_HOST,
124 .cd_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_CD,
125 .val = 0x0,
126};
127
128static const struct gen7_sel_reg gen7_17_0_rb_rbp_sel = {
129 .host_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_HOST,
130 .cd_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_CD,
131 .val = 0x9,
132};
133
134static const u32 gen7_17_0_post_crashdumper_registers[] = {
135 0x00535, 0x00535,
136 UINT_MAX, UINT_MAX,
137};
138static_assert(IS_ALIGNED(sizeof(gen7_17_0_post_crashdumper_registers), 8));
139
140static const u32 gen7_17_0_gpu_registers[] = {
141 0x00000, 0x00000, 0x00002, 0x00002, 0x00011, 0x00012, 0x00016, 0x0001b,
142 0x0001f, 0x00032, 0x00038, 0x0003c, 0x00042, 0x00042, 0x00044, 0x00044,
143 0x00047, 0x00047, 0x00049, 0x0004a, 0x0004c, 0x0004c, 0x00050, 0x00050,
144 0x00056, 0x00056, 0x00073, 0x00075, 0x000ad, 0x000ae, 0x000b0, 0x000b0,
145 0x000b4, 0x000b4, 0x000b8, 0x000b8, 0x000bc, 0x000bc, 0x000c0, 0x000c0,
146 0x000c4, 0x000c4, 0x000c8, 0x000c8, 0x000cc, 0x000cc, 0x000d0, 0x000d0,
147 0x000d4, 0x000d4, 0x000d8, 0x000d8, 0x000dc, 0x000dc, 0x000e0, 0x000e0,
148 0x000e4, 0x000e4, 0x000e8, 0x000e8, 0x000ec, 0x000ec, 0x000f0, 0x000f0,
149 0x000f4, 0x000f4, 0x000f8, 0x000f8, 0x00100, 0x00100, 0x00104, 0x0010b,
150 0x0010f, 0x0011d, 0x0012f, 0x0012f, 0x00200, 0x0020d, 0x00215, 0x00243,
151 0x00260, 0x00268, 0x00272, 0x00274, 0x00286, 0x00286, 0x0028a, 0x0028a,
152 0x0028c, 0x0028c, 0x00300, 0x00401, 0x00500, 0x00500, 0x00507, 0x0050b,
153 0x0050f, 0x0050f, 0x00511, 0x00511, 0x00533, 0x00534, 0x00540, 0x00555,
154 0x00564, 0x00567, 0x00800, 0x00808, 0x00810, 0x00813, 0x00820, 0x00821,
155 0x00823, 0x00827, 0x00830, 0x00834, 0x00840, 0x00841, 0x00843, 0x00847,
156 0x0084f, 0x00886, 0x008a0, 0x008ab, 0x008c0, 0x008c0, 0x008c4, 0x008c5,
157 0x008d0, 0x008dd, 0x008f0, 0x008f3, 0x00900, 0x00903, 0x00908, 0x00911,
158 0x00928, 0x0093e, 0x00942, 0x0094d, 0x00980, 0x00984, 0x0098d, 0x0098f,
159 0x009b0, 0x009b4, 0x009c2, 0x009c9, 0x009ce, 0x009d7, 0x00a00, 0x00a00,
160 0x00a02, 0x00a03, 0x00a10, 0x00a4f, 0x00a67, 0x00a6c, 0x00a9c, 0x00a9f,
161 0x00c00, 0x00c00, 0x00c02, 0x00c04, 0x00c06, 0x00c06, 0x00c10, 0x00cd9,
162 0x00ce0, 0x00d0c, 0x00df0, 0x00df4, 0x00e01, 0x00e02, 0x00e07, 0x00e0e,
163 0x00e10, 0x00e12, 0x00e17, 0x00e17, 0x00e19, 0x00e19, 0x00e1b, 0x00e2b,
164 0x00e30, 0x00e32, 0x00e38, 0x00e3c,
165 UINT_MAX, UINT_MAX,
166};
167static_assert(IS_ALIGNED(sizeof(gen7_17_0_gpu_registers), 8));
168
169static const u32 gen7_17_0_dbgc_registers[] = {
170 0x00600, 0x0061c, 0x0061e, 0x00634, 0x00640, 0x0065a, 0x00679, 0x0067a,
171 0x00699, 0x00699, 0x0069b, 0x0069e, 0x18400, 0x1841c, 0x1841e, 0x18434,
172 0x18440, 0x1845c, 0x18479, 0x1847c, 0x18580, 0x18581,
173 UINT_MAX, UINT_MAX,
174};
175static_assert(IS_ALIGNED(sizeof(gen7_17_0_dbgc_registers), 8));
176
177static const u32 gen7_17_0_noncontext_pipe_br_registers[] = {
178 0x00887, 0x0088c, 0x08600, 0x08600, 0x08602, 0x08602, 0x08610, 0x0861b,
179 0x08620, 0x08620, 0x08630, 0x08630, 0x08637, 0x08639, 0x08640, 0x08640,
180 0x09600, 0x09600, 0x09602, 0x09603, 0x0960a, 0x09616, 0x09624, 0x0963a,
181 0x09640, 0x09640, 0x09e00, 0x09e00, 0x09e02, 0x09e07, 0x09e0a, 0x09e16,
182 0x09e19, 0x09e19, 0x09e1c, 0x09e1c, 0x09e20, 0x09e25, 0x09e30, 0x09e31,
183 0x09e40, 0x09e51, 0x09e64, 0x09e64, 0x09e70, 0x09e72, 0x09e78, 0x09e79,
184 0x09e80, 0x09fff, 0x0a600, 0x0a600, 0x0a603, 0x0a603, 0x0a610, 0x0a61f,
185 0x0a630, 0x0a631, 0x0a638, 0x0a638,
186 UINT_MAX, UINT_MAX,
187};
188static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_pipe_br_registers), 8));
189
190static const u32 gen7_17_0_noncontext_rb_rac_pipe_br_registers[] = {
191 0x08e10, 0x08e1c, 0x08e20, 0x08e25, 0x08e51, 0x08e54,
192 UINT_MAX, UINT_MAX,
193};
194static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_rb_rac_pipe_br_registers), 8));
195
196static const u32 gen7_17_0_noncontext_rb_rbp_pipe_br_registers[] = {
197 0x08e01, 0x08e01, 0x08e04, 0x08e04, 0x08e06, 0x08e09, 0x08e0c, 0x08e0c,
198 0x08e28, 0x08e28, 0x08e2c, 0x08e35, 0x08e3b, 0x08e3f, 0x08e50, 0x08e50,
199 0x08e5b, 0x08e5d, 0x08e5f, 0x08e5f, 0x08e61, 0x08e61, 0x08e63, 0x08e65,
200 0x08e68, 0x08e68, 0x08e70, 0x08e79, 0x08e80, 0x08e8f,
201 UINT_MAX, UINT_MAX,
202};
203static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_rb_rbp_pipe_br_registers), 8));
204
205static const u32 gen7_17_0_pc_cluster_fe_pipe_br_registers[] = {
206 0x09800, 0x09804, 0x09806, 0x0980a, 0x09810, 0x09811, 0x09884, 0x09886,
207 0x09970, 0x09972, 0x09b00, 0x09b08,
208 UINT_MAX, UINT_MAX,
209};
210static_assert(IS_ALIGNED(sizeof(gen7_17_0_pc_cluster_fe_pipe_br_registers), 8));
211
212static const u32 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers[] = {
213 0x0aa40, 0x0aabf,
214 UINT_MAX, UINT_MAX,
215};
216static_assert(IS_ALIGNED(sizeof(gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers), 8));
217
218static const u32 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers[] = {
219 0x0aa40, 0x0aabf,
220 UINT_MAX, UINT_MAX,
221};
222static_assert(IS_ALIGNED(sizeof(gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers), 8));
223
224static const u32 gen7_17_0_non_context_tpl1_pipe_none_usptp_registers[] = {
225 0x0b602, 0x0b602, 0x0b604, 0x0b604, 0x0b608, 0x0b60c, 0x0b60f, 0x0b621,
226 0x0b630, 0x0b633,
227 UINT_MAX, UINT_MAX,
228};
229static_assert(IS_ALIGNED(sizeof(gen7_17_0_non_context_tpl1_pipe_none_usptp_registers), 8));
230
231static const u32 gen7_17_0_non_context_tpl1_pipe_br_usptp_registers[] = {
232 0x0b600, 0x0b600,
233 UINT_MAX, UINT_MAX,
234};
235static_assert(IS_ALIGNED(sizeof(gen7_17_0_non_context_tpl1_pipe_br_usptp_registers), 8));
236
237static const u32 gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers[] = {
238 0x0b300, 0x0b307, 0x0b309, 0x0b309, 0x0b310, 0x0b310,
239 UINT_MAX, UINT_MAX,
240};
241static_assert(IS_ALIGNED(sizeof(gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers), 8));
242
243static const u32 gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers[] = {
244 0x0b180, 0x0b183, 0x0b190, 0x0b195, 0x0b2c0, 0x0b2d5, 0x0b300, 0x0b307,
245 0x0b309, 0x0b309, 0x0b310, 0x0b310,
246 UINT_MAX, UINT_MAX,
247};
248static_assert(IS_ALIGNED(sizeof(gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers), 8));
249
250/* No BV pipe — gen7_0_0_* sub-arrays are shared from adreno_gen7_0_0_snapshot.h */
251static struct gen7_cluster_registers gen7_17_0_clusters[] = {
252 { A7XX_CLUSTER_NONE, PIPE_BR, STATE_NON_CONTEXT,
253 gen7_17_0_noncontext_pipe_br_registers, },
254 { A7XX_CLUSTER_NONE, PIPE_BR, STATE_NON_CONTEXT,
255 gen7_17_0_noncontext_rb_rac_pipe_br_registers, &gen7_17_0_rb_rac_sel, },
256 { A7XX_CLUSTER_NONE, PIPE_BR, STATE_NON_CONTEXT,
257 gen7_17_0_noncontext_rb_rbp_pipe_br_registers, &gen7_17_0_rb_rbp_sel, },
258 { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_0,
259 gen7_0_0_rb_rac_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rac_sel, },
260 { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_1,
261 gen7_0_0_rb_rac_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rac_sel, },
262 { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_0,
263 gen7_0_0_rb_rbp_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rbp_sel, },
264 { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_1,
265 gen7_0_0_rb_rbp_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rbp_sel, },
266 { A7XX_CLUSTER_GRAS, PIPE_BR, STATE_FORCE_CTXT_0,
267 gen7_0_0_gras_cluster_gras_pipe_br_registers, },
268 { A7XX_CLUSTER_GRAS, PIPE_BR, STATE_FORCE_CTXT_1,
269 gen7_0_0_gras_cluster_gras_pipe_br_registers, },
270 { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_0,
271 gen7_17_0_pc_cluster_fe_pipe_br_registers, },
272 { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_1,
273 gen7_17_0_pc_cluster_fe_pipe_br_registers, },
274 { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_0,
275 gen7_0_0_vfd_cluster_fe_pipe_bv_registers, },
276 { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_1,
277 gen7_0_0_vfd_cluster_fe_pipe_bv_registers, },
278 { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_0,
279 gen7_0_0_vpc_cluster_fe_pipe_br_registers, },
280 { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_1,
281 gen7_0_0_vpc_cluster_fe_pipe_br_registers, },
282 { A7XX_CLUSTER_PC_VS, PIPE_BR, STATE_FORCE_CTXT_0,
283 gen7_0_0_vpc_cluster_pc_vs_pipe_br_registers, },
284 { A7XX_CLUSTER_PC_VS, PIPE_BR, STATE_FORCE_CTXT_1,
285 gen7_0_0_vpc_cluster_pc_vs_pipe_br_registers, },
286 { A7XX_CLUSTER_VPC_PS, PIPE_BR, STATE_FORCE_CTXT_0,
287 gen7_0_0_vpc_cluster_vpc_ps_pipe_br_registers, },
288 { A7XX_CLUSTER_VPC_PS, PIPE_BR, STATE_FORCE_CTXT_1,
289 gen7_0_0_vpc_cluster_vpc_ps_pipe_br_registers, },
290};
291
292/* No BV pipe; 2 SPs, 2 USPTPs */
293static struct gen7_sptp_cluster_registers gen7_17_0_sptp_clusters[] = {
294 { A7XX_CLUSTER_NONE, A7XX_SP_NCTX_REG, PIPE_BR, 0, A7XX_HLSQ_STATE,
295 gen7_0_0_sp_noncontext_pipe_br_hlsq_state_registers, 0xae00 },
296 { A7XX_CLUSTER_NONE, A7XX_SP_NCTX_REG, PIPE_BR, 0, A7XX_SP_TOP,
297 gen7_0_0_sp_noncontext_pipe_br_sp_top_registers, 0xae00 },
298 { A7XX_CLUSTER_NONE, A7XX_SP_NCTX_REG, PIPE_BR, 0, A7XX_USPTP,
299 gen7_0_0_sp_noncontext_pipe_br_usptp_registers, 0xae00 },
300 { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_HLSQ_STATE,
301 gen7_0_0_sp_cluster_sp_vs_pipe_br_hlsq_state_registers, 0xa800 },
302 { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_SP_TOP,
303 gen7_0_0_sp_cluster_sp_vs_pipe_br_sp_top_registers, 0xa800 },
304 { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_USPTP,
305 gen7_0_0_sp_cluster_sp_vs_pipe_br_usptp_registers, 0xa800 },
306 { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_HLSQ_STATE,
307 gen7_0_0_sp_cluster_sp_vs_pipe_br_hlsq_state_registers, 0xa800 },
308 { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_SP_TOP,
309 gen7_0_0_sp_cluster_sp_vs_pipe_br_sp_top_registers, 0xa800 },
310 { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_USPTP,
311 gen7_0_0_sp_cluster_sp_vs_pipe_br_usptp_registers, 0xa800 },
312 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_HLSQ_STATE,
313 gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_state_registers, 0xa800 },
314 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_HLSQ_DP,
315 gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
316 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_SP_TOP,
317 gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
318 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_USPTP,
319 gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
320 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_LPAC, 0, A7XX_HLSQ_STATE,
321 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers, 0xa800 },
322 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_LPAC, 0, A7XX_USPTP,
323 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers, 0xa800 },
324 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_HLSQ_STATE,
325 gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_state_registers, 0xa800 },
326 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_HLSQ_DP,
327 gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
328 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_SP_TOP,
329 gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
330 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_USPTP,
331 gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
332 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_HLSQ_DP,
333 gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
334 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_SP_TOP,
335 gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
336 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_USPTP,
337 gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
338 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_HLSQ_DP,
339 gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
340 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_SP_TOP,
341 gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
342 { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_USPTP,
343 gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
344 { A7XX_CLUSTER_NONE, A7XX_TP0_NCTX_REG, PIPE_NONE, 0, A7XX_USPTP,
345 gen7_17_0_non_context_tpl1_pipe_none_usptp_registers, 0xb600 },
346 { A7XX_CLUSTER_NONE, A7XX_TP0_NCTX_REG, PIPE_BR, 0, A7XX_USPTP,
347 gen7_17_0_non_context_tpl1_pipe_br_usptp_registers, 0xb600 },
348 { A7XX_CLUSTER_SP_VS, A7XX_TP0_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_USPTP,
349 gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers, 0xb000 },
350 { A7XX_CLUSTER_SP_VS, A7XX_TP0_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_USPTP,
351 gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers, 0xb000 },
352 { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_USPTP,
353 gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
354 { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_USPTP,
355 gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
356 { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_USPTP,
357 gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
358 { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_USPTP,
359 gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
360};
361
362static struct gen7_shader_block gen7_17_0_shader_blocks[] = {
363 { A7XX_TP0_TMO_DATA, 0x0200, 2, 2, PIPE_BR, A7XX_USPTP },
364 { A7XX_TP0_SMO_DATA, 0x0080, 2, 2, PIPE_BR, A7XX_USPTP },
365 { A7XX_TP0_MIPMAP_BASE_DATA, 0x03c0, 2, 2, PIPE_BR, A7XX_USPTP },
366 { A7XX_SP_INST_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
367 { A7XX_SP_INST_DATA_1, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
368 { A7XX_SP_LB_0_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
369 { A7XX_SP_LB_1_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
370 { A7XX_SP_LB_2_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
371 { A7XX_SP_LB_3_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
372 { A7XX_SP_LB_4_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
373 { A7XX_SP_LB_5_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
374 { A7XX_SP_CB_RAM, 0x0390, 2, 2, PIPE_BR, A7XX_USPTP },
375 { A7XX_SP_INST_TAG, 0x0090, 2, 2, PIPE_BR, A7XX_USPTP },
376 { A7XX_SP_TMO_TAG, 0x0080, 2, 2, PIPE_BR, A7XX_USPTP },
377 { A7XX_SP_SMO_TAG, 0x0080, 2, 2, PIPE_BR, A7XX_USPTP },
378 { A7XX_SP_STATE_DATA, 0x0040, 2, 2, PIPE_BR, A7XX_USPTP },
379 { A7XX_SP_HWAVE_RAM, 0x0100, 2, 2, PIPE_BR, A7XX_USPTP },
380 { A7XX_SP_L0_INST_BUF, 0x0050, 2, 2, PIPE_BR, A7XX_USPTP },
381 { A7XX_HLSQ_CVS_BE_CTXT_BUF_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
382 { A7XX_HLSQ_CPS_BE_CTXT_BUF_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
383 { A7XX_HLSQ_GFX_CVS_BE_CTXT_BUF_RAM, 0x0300, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
384 { A7XX_HLSQ_GFX_CPS_BE_CTXT_BUF_RAM, 0x0300, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
385 { A7XX_HLSQ_CHUNK_CVS_RAM, 0x01c0, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
386 { A7XX_HLSQ_CHUNK_CPS_RAM, 0x0300, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
387 { A7XX_HLSQ_CHUNK_CVS_RAM_TAG, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
388 { A7XX_HLSQ_CHUNK_CPS_RAM_TAG, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
389 { A7XX_HLSQ_ICB_CVS_CB_BASE_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
390 { A7XX_HLSQ_ICB_CPS_CB_BASE_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
391 { A7XX_HLSQ_CVS_MISC_RAM, 0x0280, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
392 { A7XX_HLSQ_CPS_MISC_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
393 { A7XX_HLSQ_CPS_MISC_RAM_1, 0x0200, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
394 { A7XX_HLSQ_INST_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
395 { A7XX_HLSQ_GFX_CVS_CONST_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
396 { A7XX_HLSQ_GFX_CPS_CONST_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
397 { A7XX_HLSQ_CVS_MISC_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
398 { A7XX_HLSQ_CPS_MISC_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
399 { A7XX_HLSQ_INST_RAM_TAG, 0x0080, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
400 { A7XX_HLSQ_GFX_CVS_CONST_RAM_TAG, 0x0064, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
401 { A7XX_HLSQ_GFX_CPS_CONST_RAM_TAG, 0x0064, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
402 { A7XX_HLSQ_INST_RAM_1, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
403 { A7XX_HLSQ_STPROC_META, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
404 { A7XX_HLSQ_BV_BE_META, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
405 { A7XX_HLSQ_DATAPATH_META, 0x0020, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
406 { A7XX_HLSQ_FRONTEND_META, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
407 { A7XX_HLSQ_INDIRECT_META, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
408 { A7XX_HLSQ_BACKEND_META, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
409};
410
411static struct gen7_reg_list gen7_17_0_reg_list[] = {
412 { gen7_17_0_gpu_registers, NULL },
413 { gen7_17_0_dbgc_registers, NULL },
414 { NULL, NULL },
415};
416
417static const struct a6xx_indexed_registers gen7_17_0_cp_indexed_reglist[] = {
418 { "CP_SQE_STAT", REG_A6XX_CP_SQE_STAT_ADDR,
419 REG_A6XX_CP_SQE_STAT_DATA, 0x40, NULL },
420 { "CP_DRAW_STATE", REG_A6XX_CP_DRAW_STATE_ADDR,
421 REG_A6XX_CP_DRAW_STATE_DATA, 0x100, NULL },
422 { "CP_SQE_UCODE_DBG", REG_A6XX_CP_SQE_UCODE_DBG_ADDR,
423 REG_A6XX_CP_SQE_UCODE_DBG_DATA, 0x8000, NULL },
424 { "CP_ROQ_DBG", REG_A6XX_CP_ROQ_DBG_ADDR,
425 REG_A6XX_CP_ROQ_DBG_DATA, 0, a7xx_get_cp_roq_size },
426};
427
428#endif /* __ADRENO_GEN7_17_0_SNAPSHOT_H */
drivers/gpu/drm/msm/adreno/adreno_gpu.c+13−4
@@ -356,6 +356,12 @@ int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags, · 355 unmodified lines
356 return 0;356 return 0;
357}357}
358 358
359static bool
360valid_per_process_vm(struct msm_gpu *gpu, struct drm_gpuvm *vm)
361{
362 return vm && (vm != gpu->vm);
363}
364
359int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx,365int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx,
360 uint32_t param, uint64_t *value, uint32_t *len)366 uint32_t param, uint64_t *value, uint32_t *len)
361{367{
@@ -414,12 +420,12 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx, · 52 unmodified lines
414 *value = gpu->suspend_count;420 *value = gpu->suspend_count;
415 return 0;421 return 0;
416 case MSM_PARAM_VA_START:422 case MSM_PARAM_VA_START:
417 if (vm == gpu->vm)423 if (!valid_per_process_vm(gpu, vm))
418 return UERR(EINVAL, drm, "requires per-process pgtables");424 return UERR(EINVAL, drm, "requires per-process pgtables");
419 *value = vm->mm_start;425 *value = vm->mm_start;
420 return 0;426 return 0;
421 case MSM_PARAM_VA_SIZE:427 case MSM_PARAM_VA_SIZE:
422 if (vm == gpu->vm)428 if (!valid_per_process_vm(gpu, vm))
423 return UERR(EINVAL, drm, "requires per-process pgtables");429 return UERR(EINVAL, drm, "requires per-process pgtables");
424 *value = vm->mm_range;430 *value = vm->mm_range;
425 return 0;431 return 0;
@@ -503,9 +509,11 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_context *ctx, · 77 unmodified lines
503 if (!perfmon_capable())509 if (!perfmon_capable())
504 return UERR(EPERM, drm, "invalid permissions");510 return UERR(EPERM, drm, "invalid permissions");
505 return msm_context_set_sysprof(ctx, gpu, value);511 return msm_context_set_sysprof(ctx, gpu, value);
506 case MSM_PARAM_EN_VM_BIND:512 case MSM_PARAM_EN_VM_BIND: {
513 guard(rwsem_read)(&ctx->ctxlock);
514
507 /* We can only support VM_BIND with per-process pgtables: */515 /* We can only support VM_BIND with per-process pgtables: */
508 if (ctx->vm == gpu->vm)516 if (!gpu->funcs->create_private_vm)
509 return UERR(EINVAL, drm, "requires per-process pgtables");517 return UERR(EINVAL, drm, "requires per-process pgtables");
510 518
511 /*519 /*
@@ -518,6 +526,7 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_context *ctx, · 6 unmodified lines
518 ctx->userspace_managed_vm = value;526 ctx->userspace_managed_vm = value;
519 527
520 return 0;528 return 0;
529 }
521 default:530 default:
522 return UERR(EINVAL, drm, "%s: invalid param: %u", gpu->name, param);531 return UERR(EINVAL, drm, "%s: invalid param: %u", gpu->name, param);
523 }532 }
drivers/gpu/drm/msm/adreno/adreno_gpu.h+5−0
@@ -562,6 +562,11 @@ static inline int adreno_is_x185(struct adreno_gpu *gpu) · 561 unmodified lines
562 return gpu->info->chip_ids[0] == 0x43050c01;562 return gpu->info->chip_ids[0] == 0x43050c01;
563}563}
564 564
565static inline int adreno_is_a722(struct adreno_gpu *gpu)
566{
567 return gpu->info->chip_ids[0] == 0x43020100;
568}
569
565static inline int adreno_is_a740_family(struct adreno_gpu *gpu)570static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
566{571{
567 if (WARN_ON_ONCE(!gpu->info))572 if (WARN_ON_ONCE(!gpu->info))
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_13_0_kaanapali.h+6−6
@@ -86,42 +86,42 @@ static const struct dpu_sspp_cfg kaanapali_sspp[] = { · 85 unmodified lines
86 .name = "sspp_8", .id = SSPP_DMA0,86 .name = "sspp_8", .id = SSPP_DMA0,
87 .base = 0x97000, .len = 0x84,87 .base = 0x97000, .len = 0x84,
88 .features = DMA_SDM845_MASK_SDMA,88 .features = DMA_SDM845_MASK_SDMA,
89 .sblk = &dpu_dma_sblk,89 .sblk = &dpu_dma_sblk_v13,
90 .xin_id = 1,90 .xin_id = 1,
91 .type = SSPP_TYPE_DMA,91 .type = SSPP_TYPE_DMA,
92 }, {92 }, {
93 .name = "sspp_9", .id = SSPP_DMA1,93 .name = "sspp_9", .id = SSPP_DMA1,
94 .base = 0xa0000, .len = 0x84,94 .base = 0xa0000, .len = 0x84,
95 .features = DMA_SDM845_MASK_SDMA,95 .features = DMA_SDM845_MASK_SDMA,
96 .sblk = &dpu_dma_sblk,96 .sblk = &dpu_dma_sblk_v13,
97 .xin_id = 5,97 .xin_id = 5,
98 .type = SSPP_TYPE_DMA,98 .type = SSPP_TYPE_DMA,
99 }, {99 }, {
100 .name = "sspp_10", .id = SSPP_DMA2,100 .name = "sspp_10", .id = SSPP_DMA2,
101 .base = 0xa9000, .len = 0x84,101 .base = 0xa9000, .len = 0x84,
102 .features = DMA_SDM845_MASK_SDMA,102 .features = DMA_SDM845_MASK_SDMA,
103 .sblk = &dpu_dma_sblk,103 .sblk = &dpu_dma_sblk_v13,
104 .xin_id = 9,104 .xin_id = 9,
105 .type = SSPP_TYPE_DMA,105 .type = SSPP_TYPE_DMA,
106 }, {106 }, {
107 .name = "sspp_11", .id = SSPP_DMA3,107 .name = "sspp_11", .id = SSPP_DMA3,
108 .base = 0xb2000, .len = 0x84,108 .base = 0xb2000, .len = 0x84,
109 .features = DMA_SDM845_MASK_SDMA,109 .features = DMA_SDM845_MASK_SDMA,
110 .sblk = &dpu_dma_sblk,110 .sblk = &dpu_dma_sblk_v13,
111 .xin_id = 13,111 .xin_id = 13,
112 .type = SSPP_TYPE_DMA,112 .type = SSPP_TYPE_DMA,
113 }, {113 }, {
114 .name = "sspp_12", .id = SSPP_DMA4,114 .name = "sspp_12", .id = SSPP_DMA4,
115 .base = 0xbb000, .len = 0x84,115 .base = 0xbb000, .len = 0x84,
116 .features = DMA_CURSOR_SDM845_MASK_SDMA,116 .features = DMA_CURSOR_SDM845_MASK_SDMA,
117 .sblk = &dpu_dma_sblk,117 .sblk = &dpu_dma_sblk_v13,
118 .xin_id = 14,118 .xin_id = 14,
119 .type = SSPP_TYPE_DMA,119 .type = SSPP_TYPE_DMA,
120 }, {120 }, {
121 .name = "sspp_13", .id = SSPP_DMA5,121 .name = "sspp_13", .id = SSPP_DMA5,
122 .base = 0xc4000, .len = 0x84,122 .base = 0xc4000, .len = 0x84,
123 .features = DMA_CURSOR_SDM845_MASK_SDMA,123 .features = DMA_CURSOR_SDM845_MASK_SDMA,
124 .sblk = &dpu_dma_sblk,124 .sblk = &dpu_dma_sblk_v13,
125 .xin_id = 15,125 .xin_id = 15,
126 .type = SSPP_TYPE_DMA,126 .type = SSPP_TYPE_DMA,
127 },127 },
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c+5−1
@@ -34,7 +34,7 @@ enum dpu_perf_mode { · 33 unmodified lines
34/**34/**
35 * dpu_core_perf_adjusted_mode_clk - Adjust given mode clock rate according to35 * dpu_core_perf_adjusted_mode_clk - Adjust given mode clock rate according to
36 * the perf clock factor.36 * the perf clock factor.
37 * @crtc_clk_rate - Unadjusted mode clock rate37 * @mode_clk_rate: unadjusted mode clock rate
38 * @perf_cfg: performance configuration38 * @perf_cfg: performance configuration
39 */39 */
40u64 dpu_core_perf_adjusted_mode_clk(u64 mode_clk_rate,40u64 dpu_core_perf_adjusted_mode_clk(u64 mode_clk_rate,
@@ -394,6 +394,10 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc, · 353 unmodified lines
394 394
395 trace_dpu_core_perf_update_clk(kms->dev, !crtc->enabled, clk_rate);395 trace_dpu_core_perf_update_clk(kms->dev, !crtc->enabled, clk_rate);
396 396
397 /* If we're going offline, PM callbacks will disable the clocks instead */
398 if (!clk_rate)
399 return 0;
400
397 clk_rate = min(clk_rate, kms->perf.max_core_clk_rate);401 clk_rate = min(clk_rate, kms->perf.max_core_clk_rate);
398 ret = dev_pm_opp_set_rate(&kms->pdev->dev, clk_rate);402 ret = dev_pm_opp_set_rate(&kms->pdev->dev, clk_rate);
399 if (ret) {403 if (ret) {
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c+1−2
@@ -710,8 +710,7 @@ void dpu_encoder_update_topology(struct drm_encoder *drm_enc, · 709 unmodified lines
710 if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))710 if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
711 topology->num_cdm++;711 topology->num_cdm++;
712 } else if (disp_info->intf_type == INTF_DP) {712 } else if (disp_info->intf_type == INTF_DP) {
713 if (msm_dp_is_yuv_420_enabled(priv->kms->dp[disp_info->h_tile_instance[0]],713 if (drm_mode_is_420_only(&connector->display_info, adj_mode))
714 adj_mode))
715 topology->num_cdm++;714 topology->num_cdm++;
716 }715 }
717}716}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c+12−0
@@ -303,6 +303,16 @@ static const u32 wb2_formats_rgb_yuv[] = { · 302 unmodified lines
303 .num_formats = ARRAY_SIZE(plane_formats), \303 .num_formats = ARRAY_SIZE(plane_formats), \
304 }304 }
305 305
306#define _DMA_SBLK_V13() \
307 { \
308 .sspp_rec0_blk = {.name = "sspp_rec0", \
309 .base = 0x1000, .len = 0x180,}, \
310 .sspp_rec1_blk = {.name = "sspp_rec1", \
311 .base = 0x3000, .len = 0x180,}, \
312 .format_list = plane_formats, \
313 .num_formats = ARRAY_SIZE(plane_formats), \
314 }
315
306static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = {316static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = {
307 .rot_maxheight = 1088,317 .rot_maxheight = 1088,
308 .rot_num_formats = ARRAY_SIZE(rotation_v2_formats),318 .rot_num_formats = ARRAY_SIZE(rotation_v2_formats),
@@ -353,6 +363,8 @@ static const struct dpu_sspp_sub_blks dpu_rgb_sblk = _RGB_SBLK(); · 44 unmodified lines
353 363
354static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK();364static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK();
355 365
366static const struct dpu_sspp_sub_blks dpu_dma_sblk_v13 = _DMA_SBLK_V13();
367
356/*************************************************************368/*************************************************************
357 * MIXER sub blocks config369 * MIXER sub blocks config
358 *************************************************************/370 *************************************************************/
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c+9−15
@@ -398,7 +398,7 @@ static int mdp4_kms_init(struct drm_device *dev) · 397 unmodified lines
398 ret = mdp_kms_init(&mdp4_kms->base, &kms_funcs);398 ret = mdp_kms_init(&mdp4_kms->base, &kms_funcs);
399 if (ret) {399 if (ret) {
400 DRM_DEV_ERROR(dev->dev, "failed to init kms\n");400 DRM_DEV_ERROR(dev->dev, "failed to init kms\n");
401 goto fail;401 return ret;
402 }402 }
403 403
404 kms = priv->kms;404 kms = priv->kms;
@@ -409,7 +409,7 @@ static int mdp4_kms_init(struct drm_device *dev) · 4 unmodified lines
409 ret = regulator_enable(mdp4_kms->vdd);409 ret = regulator_enable(mdp4_kms->vdd);
410 if (ret) {410 if (ret) {
411 DRM_DEV_ERROR(dev->dev, "failed to enable regulator vdd: %d\n", ret);411 DRM_DEV_ERROR(dev->dev, "failed to enable regulator vdd: %d\n", ret);
412 goto fail;412 return ret;
413 }413 }
414 }414 }
415 415
@@ -421,7 +421,7 @@ static int mdp4_kms_init(struct drm_device *dev) · 5 unmodified lines
421 DRM_DEV_ERROR(dev->dev, "unexpected MDP version: v%d.%d\n",421 DRM_DEV_ERROR(dev->dev, "unexpected MDP version: v%d.%d\n",
422 major, minor);422 major, minor);
423 ret = -ENXIO;423 ret = -ENXIO;
424 goto fail;424 return ret;
425 }425 }
426 426
427 mdp4_kms->rev = minor;427 mdp4_kms->rev = minor;
@@ -430,7 +430,7 @@ static int mdp4_kms_init(struct drm_device *dev) · 2 unmodified lines
430 if (!mdp4_kms->lut_clk) {430 if (!mdp4_kms->lut_clk) {
431 DRM_DEV_ERROR(dev->dev, "failed to get lut_clk\n");431 DRM_DEV_ERROR(dev->dev, "failed to get lut_clk\n");
432 ret = -ENODEV;432 ret = -ENODEV;
433 goto fail;433 return ret;
434 }434 }
435 clk_set_rate(mdp4_kms->lut_clk, max_clk);435 clk_set_rate(mdp4_kms->lut_clk, max_clk);
436 }436 }
@@ -452,7 +452,7 @@ static int mdp4_kms_init(struct drm_device *dev) · 15 unmodified lines
452 vm = msm_kms_init_vm(mdp4_kms->dev, NULL);452 vm = msm_kms_init_vm(mdp4_kms->dev, NULL);
453 if (IS_ERR(vm)) {453 if (IS_ERR(vm)) {
454 ret = PTR_ERR(vm);454 ret = PTR_ERR(vm);
455 goto fail;455 return ret;
456 }456 }
457 457
458 kms->vm = vm;458 kms->vm = vm;
@@ -460,22 +460,22 @@ static int mdp4_kms_init(struct drm_device *dev) · 1 unmodified line
460 ret = modeset_init(mdp4_kms);460 ret = modeset_init(mdp4_kms);
461 if (ret) {461 if (ret) {
462 DRM_DEV_ERROR(dev->dev, "modeset_init failed: %d\n", ret);462 DRM_DEV_ERROR(dev->dev, "modeset_init failed: %d\n", ret);
463 goto fail;463 return ret;
464 }464 }
465 465
466 mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC | MSM_BO_SCANOUT);466 mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC | MSM_BO_SCANOUT, NULL);
467 if (IS_ERR(mdp4_kms->blank_cursor_bo)) {467 if (IS_ERR(mdp4_kms->blank_cursor_bo)) {
468 ret = PTR_ERR(mdp4_kms->blank_cursor_bo);468 ret = PTR_ERR(mdp4_kms->blank_cursor_bo);
469 DRM_DEV_ERROR(dev->dev, "could not allocate blank-cursor bo: %d\n", ret);469 DRM_DEV_ERROR(dev->dev, "could not allocate blank-cursor bo: %d\n", ret);
470 mdp4_kms->blank_cursor_bo = NULL;470 mdp4_kms->blank_cursor_bo = NULL;
471 goto fail;471 return ret;
472 }472 }
473 473
474 ret = msm_gem_get_and_pin_iova(mdp4_kms->blank_cursor_bo, kms->vm,474 ret = msm_gem_get_and_pin_iova(mdp4_kms->blank_cursor_bo, kms->vm,
475 &mdp4_kms->blank_cursor_iova);475 &mdp4_kms->blank_cursor_iova);
476 if (ret) {476 if (ret) {
477 DRM_DEV_ERROR(dev->dev, "could not pin blank-cursor bo: %d\n", ret);477 DRM_DEV_ERROR(dev->dev, "could not pin blank-cursor bo: %d\n", ret);
478 goto fail;478 return ret;
479 }479 }
480 480
481 dev->mode_config.min_width = 0;481 dev->mode_config.min_width = 0;
@@ -484,12 +484,6 @@ static int mdp4_kms_init(struct drm_device *dev) · 2 unmodified lines
484 dev->mode_config.max_height = 2048;484 dev->mode_config.max_height = 2048;
485 485
486 return 0;486 return 0;
487
488fail:
489 if (kms)
490 mdp4_destroy(kms);
491
492 return ret;
493}487}
494 488
495static const struct dev_pm_ops mdp4_pm_ops = {489static const struct dev_pm_ops mdp4_pm_ops = {
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c+3−8
@@ -517,7 +517,7 @@ static int mdp5_kms_init(struct drm_device *dev) · 516 unmodified lines
517 ret = mdp_kms_init(&mdp5_kms->base, &kms_funcs);517 ret = mdp_kms_init(&mdp5_kms->base, &kms_funcs);
518 if (ret) {518 if (ret) {
519 DRM_DEV_ERROR(&pdev->dev, "failed to init kms\n");519 DRM_DEV_ERROR(&pdev->dev, "failed to init kms\n");
520 goto fail;520 return ret;
521 }521 }
522 522
523 config = mdp5_cfg_get_config(mdp5_kms->cfg);523 config = mdp5_cfg_get_config(mdp5_kms->cfg);
@@ -540,7 +540,7 @@ static int mdp5_kms_init(struct drm_device *dev) · 16 unmodified lines
540 vm = msm_kms_init_vm(mdp5_kms->dev, pdev->dev.parent);540 vm = msm_kms_init_vm(mdp5_kms->dev, pdev->dev.parent);
541 if (IS_ERR(vm)) {541 if (IS_ERR(vm)) {
542 ret = PTR_ERR(vm);542 ret = PTR_ERR(vm);
543 goto fail;543 return ret;
544 }544 }
545 545
546 kms->vm = vm;546 kms->vm = vm;
@@ -550,7 +550,7 @@ static int mdp5_kms_init(struct drm_device *dev) · 3 unmodified lines
550 ret = modeset_init(mdp5_kms);550 ret = modeset_init(mdp5_kms);
551 if (ret) {551 if (ret) {
552 DRM_DEV_ERROR(&pdev->dev, "modeset_init failed: %d\n", ret);552 DRM_DEV_ERROR(&pdev->dev, "modeset_init failed: %d\n", ret);
553 goto fail;553 return ret;
554 }554 }
555 555
556 dev->mode_config.min_width = 0;556 dev->mode_config.min_width = 0;
@@ -562,11 +562,6 @@ static int mdp5_kms_init(struct drm_device *dev) · 5 unmodified lines
562 dev->vblank_disable_immediate = true;562 dev->vblank_disable_immediate = true;
563 563
564 return 0;564 return 0;
565fail:
566 if (kms)
567 mdp5_kms_destroy(kms);
568
569 return ret;
570}565}
571 566
572static void mdp5_destroy(struct mdp5_kms *mdp5_kms)567static void mdp5_destroy(struct mdp5_kms *mdp5_kms)
drivers/gpu/drm/msm/dp/dp_audio.c+1−3
@@ -284,10 +284,8 @@ int msm_dp_audio_prepare(struct drm_bridge *bridge, · 283 unmodified lines
284 * such cases check for connection status and bail out if not284 * such cases check for connection status and bail out if not
285 * connected.285 * connected.
286 */286 */
287 if (!msm_dp_display->power_on) {287 if (!msm_dp_display->power_on)
288 rc = -EINVAL;
289 goto end;288 goto end;
290 }
291 289
292 audio = msm_dp_audio_get_data(msm_dp_display);290 audio = msm_dp_audio_get_data(msm_dp_display);
293 if (IS_ERR(audio)) {291 if (IS_ERR(audio)) {
drivers/gpu/drm/msm/dp/dp_ctrl.c+223−172
@@ -114,7 +114,6 @@ struct msm_dp_ctrl_private { · 113 unmodified lines
114 struct drm_device *drm_dev;114 struct drm_device *drm_dev;
115 struct device *dev;115 struct device *dev;
116 struct drm_dp_aux *aux;116 struct drm_dp_aux *aux;
117 struct msm_dp_panel *panel;
118 struct msm_dp_link *link;117 struct msm_dp_link *link;
119 void __iomem *ahb_base;118 void __iomem *ahb_base;
120 void __iomem *link_base;119 void __iomem *link_base;
@@ -202,7 +201,8 @@ static int msm_dp_aux_link_configure(struct drm_dp_aux *aux, · 81 unmodified lines
202/*201/*
203 * NOTE: resetting DP controller will also clear any pending HPD related interrupts202 * NOTE: resetting DP controller will also clear any pending HPD related interrupts
204 */203 */
205void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl)204void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl,
205 struct msm_dp_panel *panel)
206{206{
207 struct msm_dp_ctrl_private *ctrl =207 struct msm_dp_ctrl_private *ctrl =
208 container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);208 container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
@@ -217,10 +217,9 @@ void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl) · 8 unmodified lines
217 sw_reset &= ~DP_SW_RESET;217 sw_reset &= ~DP_SW_RESET;
218 msm_dp_write_ahb(ctrl, REG_DP_SW_RESET, sw_reset);218 msm_dp_write_ahb(ctrl, REG_DP_SW_RESET, sw_reset);
219 219
220 if (!ctrl->hw_revision) {220 if (!ctrl->hw_revision)
221 ctrl->hw_revision = msm_dp_read_ahb(ctrl, REG_DP_HW_VERSION);221 ctrl->hw_revision = msm_dp_read_ahb(ctrl, REG_DP_HW_VERSION);
222 ctrl->panel->hw_revision = ctrl->hw_revision;222 panel->hw_revision = ctrl->hw_revision;
223 }
224}223}
225 224
226static u32 msm_dp_ctrl_get_aux_interrupt(struct msm_dp_ctrl_private *ctrl)225static u32 msm_dp_ctrl_get_aux_interrupt(struct msm_dp_ctrl_private *ctrl)
@@ -388,26 +387,49 @@ void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl) · 161 unmodified lines
388 drm_dbg_dp(ctrl->drm_dev, "mainlink off\n");387 drm_dbg_dp(ctrl->drm_dev, "mainlink off\n");
389}388}
390 389
391static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl)390static void msm_dp_ctrl_config_ctrl_streams(struct msm_dp_ctrl_private *ctrl,
391 struct msm_dp_panel *msm_dp_panel)
392{392{
393 u32 config = 0, tbd;393 u32 config = 0, tbd;
394 const u8 *dpcd = ctrl->panel->dpcd;
395 394
396 /* Default-> LSCLK DIV: 1/4 LCLK */395 /*
397 config |= (2 << DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT);396 * RMW: called from atomic_enable(), serialized by the DRM atomic framework.
397 * Clear stream-specific fields before OR-ing to avoid bit accumulation.
398 */
399 config = msm_dp_read_link(ctrl, REG_DP_CONFIGURATION_CTRL);
400 config &= ~(DP_CONFIGURATION_CTRL_RGB_YUV_MASK |
401 DP_CONFIGURATION_CTRL_BPC_MASK |
402 DP_CONFIGURATION_CTRL_SEND_VSC);
398 403
399 if (ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)404 if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
400 config |= DP_CONFIGURATION_CTRL_RGB_YUV; /* YUV420 */405 config |= DP_CONFIGURATION_CTRL_RGB_YUV; /* YUV420 */
401 406
402 /* Scrambler reset enable */
403 if (drm_dp_alternate_scrambler_reset_cap(dpcd))
404 config |= DP_CONFIGURATION_CTRL_ASSR;
405
406 tbd = msm_dp_link_get_test_bits_depth(ctrl->link,407 tbd = msm_dp_link_get_test_bits_depth(ctrl->link,
407 ctrl->panel->msm_dp_mode.bpp);408 msm_dp_panel->msm_dp_mode.bpp);
408 409
409 config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT;410 config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT;
410 411
412 if (msm_dp_panel->psr_cap.version)
413 config |= DP_CONFIGURATION_CTRL_SEND_VSC;
414
415 drm_dbg_dp(ctrl->drm_dev, "stream DP_CONFIGURATION_CTRL=0x%x\n", config);
416
417 msm_dp_write_link(ctrl, REG_DP_CONFIGURATION_CTRL, config);
418}
419
420static void msm_dp_ctrl_config_ctrl_link(struct msm_dp_ctrl_private *ctrl,
421 struct msm_dp_panel *panel)
422{
423 u32 config = 0;
424 const u8 *dpcd = panel->dpcd;
425
426 /* Default-> LSCLK DIV: 1/4 LCLK */
427 config |= (2 << DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT);
428
429 /* Scrambler reset enable */
430 if (drm_dp_alternate_scrambler_reset_cap(dpcd))
431 config |= DP_CONFIGURATION_CTRL_ASSR;
432
411 /* Num of Lanes */433 /* Num of Lanes */
412 config |= ((ctrl->link->link_params.num_lanes - 1)434 config |= ((ctrl->link->link_params.num_lanes - 1)
413 << DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT);435 << DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT);
@@ -421,10 +443,7 @@ static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl) · 7 unmodified lines
421 config |= DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN;443 config |= DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN;
422 config |= DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK;444 config |= DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK;
423 445
424 if (ctrl->panel->psr_cap.version)446 drm_dbg_dp(ctrl->drm_dev, "link DP_CONFIGURATION_CTRL=0x%x\n", config);
425 config |= DP_CONFIGURATION_CTRL_SEND_VSC;
426
427 drm_dbg_dp(ctrl->drm_dev, "DP_CONFIGURATION_CTRL=0x%x\n", config);
428 447
429 msm_dp_write_link(ctrl, REG_DP_CONFIGURATION_CTRL, config);448 msm_dp_write_link(ctrl, REG_DP_CONFIGURATION_CTRL, config);
430}449}
@@ -443,16 +462,13 @@ static void msm_dp_ctrl_lane_mapping(struct msm_dp_ctrl_private *ctrl) · 12 unmodified lines
443 ln_mapping);462 ln_mapping);
444}463}
445 464
446static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl)465static void msm_dp_ctrl_config_misc1_misc0(struct msm_dp_ctrl_private *ctrl,
466 struct msm_dp_panel *msm_dp_panel)
447{467{
448 u32 colorimetry_cfg, test_bits_depth, misc_val;468 u32 colorimetry_cfg, test_bits_depth, misc_val;
449 469
450 msm_dp_ctrl_lane_mapping(ctrl);470 test_bits_depth = msm_dp_link_get_test_bits_depth(ctrl->link,
451 msm_dp_setup_peripheral_flush(ctrl);471 msm_dp_panel->msm_dp_mode.bpp);
452
453 msm_dp_ctrl_config_ctrl(ctrl);
454
455 test_bits_depth = msm_dp_link_get_test_bits_depth(ctrl->link, ctrl->panel->msm_dp_mode.bpp);
456 colorimetry_cfg = msm_dp_link_get_colorimetry_config(ctrl->link);472 colorimetry_cfg = msm_dp_link_get_colorimetry_config(ctrl->link);
457 473
458 misc_val = msm_dp_read_link(ctrl, REG_DP_MISC1_MISC0);474 misc_val = msm_dp_read_link(ctrl, REG_DP_MISC1_MISC0);
@@ -466,8 +482,16 @@ static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl · 7 unmodified lines
466 482
467 drm_dbg_dp(ctrl->drm_dev, "misc settings = 0x%x\n", misc_val);483 drm_dbg_dp(ctrl->drm_dev, "misc settings = 0x%x\n", misc_val);
468 msm_dp_write_link(ctrl, REG_DP_MISC1_MISC0, misc_val);484 msm_dp_write_link(ctrl, REG_DP_MISC1_MISC0, misc_val);
485}
469 486
470 msm_dp_panel_timing_cfg(ctrl->panel, ctrl->msm_dp_ctrl.wide_bus_en);487static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl,
488 struct msm_dp_panel *panel)
489{
490 msm_dp_ctrl_config_ctrl_streams(ctrl, panel);
491
492 msm_dp_ctrl_config_misc1_misc0(ctrl, panel);
493
494 msm_dp_panel_timing_cfg(panel, ctrl->msm_dp_ctrl.wide_bus_en);
471}495}
472 496
473/*497/*
@@ -1237,20 +1261,21 @@ tu_size_calc: · 763 unmodified lines
1237}1261}
1238 1262
1239static void msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private *ctrl,1263static void msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private *ctrl,
1264 struct msm_dp_panel *panel,
1240 struct msm_dp_vc_tu_mapping_table *tu_table)1265 struct msm_dp_vc_tu_mapping_table *tu_table)
1241{1266{
1242 struct msm_dp_tu_calc_input in;1267 struct msm_dp_tu_calc_input in;
1243 struct drm_display_mode *drm_mode;1268 const struct drm_display_mode *drm_mode;
1244 1269
1245 drm_mode = &ctrl->panel->msm_dp_mode.drm_mode;1270 drm_mode = &panel->msm_dp_mode.drm_mode;
1246 1271
1247 in.lclk = ctrl->link->link_params.rate / 1000;1272 in.lclk = ctrl->link->link_params.rate / 1000;
1248 in.pclk_khz = drm_mode->clock;1273 in.pclk_khz = drm_mode->clock;
1249 in.hactive = drm_mode->hdisplay;1274 in.hactive = drm_mode->hdisplay;
1250 in.hporch = drm_mode->htotal - drm_mode->hdisplay;1275 in.hporch = drm_mode->htotal - drm_mode->hdisplay;
1251 in.nlanes = ctrl->link->link_params.num_lanes;1276 in.nlanes = ctrl->link->link_params.num_lanes;
1252 in.bpp = ctrl->panel->msm_dp_mode.bpp;1277 in.bpp = panel->msm_dp_mode.bpp;
1253 in.pixel_enc = ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420 ? 420 : 444;1278 in.pixel_enc = panel->msm_dp_mode.out_fmt_is_yuv_420 ? 420 : 444;
1254 in.dsc_en = 0;1279 in.dsc_en = 0;
1255 in.async_en = 0;1280 in.async_en = 0;
1256 in.fec_en = 0;1281 in.fec_en = 0;
@@ -1260,14 +1285,15 @@ static void msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private *ctrl, · 3 unmodified lines
1260 _dp_ctrl_calc_tu(ctrl, &in, tu_table);1285 _dp_ctrl_calc_tu(ctrl, &in, tu_table);
1261}1286}
1262 1287
1263static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl)1288static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl,
1289 struct msm_dp_panel *panel)
1264{1290{
1265 u32 msm_dp_tu = 0x0;1291 u32 msm_dp_tu = 0x0;
1266 u32 valid_boundary = 0x0;1292 u32 valid_boundary = 0x0;
1267 u32 valid_boundary2 = 0x0;1293 u32 valid_boundary2 = 0x0;
1268 struct msm_dp_vc_tu_mapping_table tu_calc_table;1294 struct msm_dp_vc_tu_mapping_table tu_calc_table;
1269 1295
1270 msm_dp_ctrl_calc_tu_parameters(ctrl, &tu_calc_table);1296 msm_dp_ctrl_calc_tu_parameters(ctrl, panel, &tu_calc_table);
1271 1297
1272 msm_dp_tu |= tu_calc_table.tu_size_minus1;1298 msm_dp_tu |= tu_calc_table.tu_size_minus1;
1273 valid_boundary |= tu_calc_table.valid_boundary_link;1299 valid_boundary |= tu_calc_table.valid_boundary_link;
@@ -1419,6 +1445,7 @@ static int msm_dp_ctrl_set_pattern_state_bit(struct msm_dp_ctrl_private *ctrl, · 145 unmodified lines
1419}1445}
1420 1446
1421static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,1447static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
1448 struct msm_dp_panel *panel,
1422 int *training_step, enum drm_dp_phy dp_phy)1449 int *training_step, enum drm_dp_phy dp_phy)
1423{1450{
1424 int delay_us;1451 int delay_us;
@@ -1427,7 +1454,7 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl, · 2 unmodified lines
1427 int const maximum_retries = 4;1454 int const maximum_retries = 4;
1428 1455
1429 delay_us = drm_dp_read_clock_recovery_delay(ctrl->aux,1456 delay_us = drm_dp_read_clock_recovery_delay(ctrl->aux,
1430 ctrl->panel->dpcd, dp_phy, false);1457 panel->dpcd, dp_phy, false);
1431 1458
1432 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);1459 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
1433 1460
@@ -1513,14 +1540,15 @@ static int msm_dp_ctrl_link_rate_down_shift(struct msm_dp_ctrl_private *ctrl) · 79 unmodified lines
1513 return ret;1540 return ret;
1514}1541}
1515 1542
1516static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl)1543static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl,
1544 struct msm_dp_panel *panel)
1517{1545{
1518 1546
1519 if (ctrl->link->link_params.num_lanes == 1)1547 if (ctrl->link->link_params.num_lanes == 1)
1520 return -1;1548 return -1;
1521 1549
1522 ctrl->link->link_params.num_lanes /= 2;1550 ctrl->link->link_params.num_lanes /= 2;
1523 ctrl->link->link_params.rate = ctrl->panel->link_info.rate;1551 ctrl->link->link_params.rate = panel->link_info.rate;
1524 1552
1525 ctrl->link->phy_params.p_level = 0;1553 ctrl->link->phy_params.p_level = 0;
1526 ctrl->link->phy_params.v_level = 0;1554 ctrl->link->phy_params.v_level = 0;
@@ -1529,6 +1557,7 @@ static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl) · 2 unmodified lines
1529}1557}
1530 1558
1531static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl,1559static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl,
1560 struct msm_dp_panel *panel,
1532 enum drm_dp_phy dp_phy)1561 enum drm_dp_phy dp_phy)
1533{1562{
1534 int delay_us;1563 int delay_us;
@@ -1536,11 +1565,12 @@ static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl, · 1 unmodified line
1536 msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE, dp_phy);1565 msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE, dp_phy);
1537 1566
1538 delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,1567 delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
1539 ctrl->panel->dpcd, dp_phy, false);1568 panel->dpcd, dp_phy, false);
1540 fsleep(delay_us);1569 fsleep(delay_us);
1541}1570}
1542 1571
1543static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,1572static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
1573 struct msm_dp_panel *panel,
1544 int *training_step, enum drm_dp_phy dp_phy)1574 int *training_step, enum drm_dp_phy dp_phy)
1545{1575{
1546 int delay_us;1576 int delay_us;
@@ -1551,16 +1581,16 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl, · 4 unmodified lines
1551 u8 link_status[DP_LINK_STATUS_SIZE];1581 u8 link_status[DP_LINK_STATUS_SIZE];
1552 1582
1553 delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,1583 delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
1554 ctrl->panel->dpcd, dp_phy, false);1584 panel->dpcd, dp_phy, false);
1555 1585
1556 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);1586 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
1557 1587
1558 *training_step = DP_TRAINING_2;1588 *training_step = DP_TRAINING_2;
1559 1589
1560 if (drm_dp_tps4_supported(ctrl->panel->dpcd)) {1590 if (drm_dp_tps4_supported(panel->dpcd)) {
1561 pattern = DP_TRAINING_PATTERN_4;1591 pattern = DP_TRAINING_PATTERN_4;
1562 state_ctrl_bit = 4;1592 state_ctrl_bit = 4;
1563 } else if (drm_dp_tps3_supported(ctrl->panel->dpcd)) {1593 } else if (drm_dp_tps3_supported(panel->dpcd)) {
1564 pattern = DP_TRAINING_PATTERN_3;1594 pattern = DP_TRAINING_PATTERN_3;
1565 state_ctrl_bit = 3;1595 state_ctrl_bit = 3;
1566 } else {1596 } else {
@@ -1597,18 +1627,19 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl, · 30 unmodified lines
1597}1627}
1598 1628
1599static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl,1629static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl,
1630 struct msm_dp_panel *panel,
1600 int *training_step, enum drm_dp_phy dp_phy)1631 int *training_step, enum drm_dp_phy dp_phy)
1601{1632{
1602 int ret;1633 int ret;
1603 1634
1604 ret = msm_dp_ctrl_link_train_1(ctrl, training_step, dp_phy);1635 ret = msm_dp_ctrl_link_train_1(ctrl, panel, training_step, dp_phy);
1605 if (ret) {1636 if (ret) {
1606 DRM_ERROR("link training #1 on phy %d failed. ret=%d\n", dp_phy, ret);1637 DRM_ERROR("link training #1 on phy %d failed. ret=%d\n", dp_phy, ret);
1607 return ret;1638 return ret;
1608 }1639 }
1609 drm_dbg_dp(ctrl->drm_dev, "link training #1 on phy %d successful\n", dp_phy);1640 drm_dbg_dp(ctrl->drm_dev, "link training #1 on phy %d successful\n", dp_phy);
1610 1641
1611 ret = msm_dp_ctrl_link_train_2(ctrl, training_step, dp_phy);1642 ret = msm_dp_ctrl_link_train_2(ctrl, panel, training_step, dp_phy);
1612 if (ret) {1643 if (ret) {
1613 DRM_ERROR("link training #2 on phy %d failed. ret=%d\n", dp_phy, ret);1644 DRM_ERROR("link training #2 on phy %d failed. ret=%d\n", dp_phy, ret);
1614 return ret;1645 return ret;
@@ -1619,16 +1650,18 @@ static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl, · 4 unmodified lines
1619}1650}
1620 1651
1621static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,1652static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
1653 struct msm_dp_panel *panel,
1622 int *training_step)1654 int *training_step)
1623{1655{
1624 int i;1656 int i;
1625 int ret = 0;1657 int ret = 0;
1626 const u8 *dpcd = ctrl->panel->dpcd;1658 const u8 *dpcd = panel->dpcd;
1627 u8 encoding[] = { 0, DP_SET_ANSI_8B10B };1659 u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
1628 u8 assr;1660 u8 assr;
1629 struct msm_dp_link_info link_info = {0};1661 struct msm_dp_link_info link_info = {0};
1630 1662
1631 msm_dp_ctrl_config_ctrl(ctrl);1663 msm_dp_ctrl_config_ctrl_link(ctrl, panel);
1664 msm_dp_ctrl_config_ctrl_streams(ctrl, panel);
1632 1665
1633 link_info.num_lanes = ctrl->link->link_params.num_lanes;1666 link_info.num_lanes = ctrl->link->link_params.num_lanes;
1634 link_info.rate = ctrl->link->link_params.rate;1667 link_info.rate = ctrl->link->link_params.rate;
@@ -1651,8 +1684,8 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl, · 16 unmodified lines
1651 for (i = ctrl->link->lttpr_count - 1; i >= 0; i--) {1684 for (i = ctrl->link->lttpr_count - 1; i >= 0; i--) {
1652 enum drm_dp_phy dp_phy = DP_PHY_LTTPR(i);1685 enum drm_dp_phy dp_phy = DP_PHY_LTTPR(i);
1653 1686
1654 ret = msm_dp_ctrl_link_train_1_2(ctrl, training_step, dp_phy);1687 ret = msm_dp_ctrl_link_train_1_2(ctrl, panel, training_step, dp_phy);
1655 msm_dp_ctrl_clear_training_pattern(ctrl, dp_phy);1688 msm_dp_ctrl_clear_training_pattern(ctrl, panel, dp_phy);
1656 1689
1657 if (ret)1690 if (ret)
1658 break;1691 break;
@@ -1663,7 +1696,7 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl, · 4 unmodified lines
1663 goto end;1696 goto end;
1664 }1697 }
1665 1698
1666 ret = msm_dp_ctrl_link_train_1_2(ctrl, training_step, DP_PHY_DPRX);1699 ret = msm_dp_ctrl_link_train_1_2(ctrl, panel, training_step, DP_PHY_DPRX);
1667 if (ret) {1700 if (ret) {
1668 DRM_ERROR("link training on sink failed. ret=%d\n", ret);1701 DRM_ERROR("link training on sink failed. ret=%d\n", ret);
1669 goto end;1702 goto end;
@@ -1676,6 +1709,7 @@ end: · 6 unmodified lines
1676}1709}
1677 1710
1678static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl,1711static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl,
1712 struct msm_dp_panel *panel,
1679 int *training_step)1713 int *training_step)
1680{1714{
1681 int ret = 0;1715 int ret = 0;
@@ -1691,7 +1725,7 @@ static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl, · 9 unmodified lines
1691 * a link training pattern, we have to first do soft reset.1725 * a link training pattern, we have to first do soft reset.
1692 */1726 */
1693 1727
1694 ret = msm_dp_ctrl_link_train(ctrl, training_step);1728 ret = msm_dp_ctrl_link_train(ctrl, panel, training_step);
1695 1729
1696 return ret;1730 return ret;
1697}1731}
@@ -1790,11 +1824,12 @@ static void msm_dp_ctrl_link_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl) · 92 unmodified lines
1790 str_on_off(ctrl->core_clks_on));1824 str_on_off(ctrl->core_clks_on));
1791}1825}
1792 1826
1793static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl)1827static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl,
1828 struct msm_dp_panel *panel)
1794{1829{
1795 int ret = 0;1830 int ret = 0;
1796 struct phy *phy = ctrl->phy;1831 struct phy *phy = ctrl->phy;
1797 const u8 *dpcd = ctrl->panel->dpcd;1832 const u8 *dpcd = panel->dpcd;
1798 1833
1799 ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;1834 ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
1800 ctrl->phy_opts.dp.link_rate = ctrl->link->link_params.rate / 100;1835 ctrl->phy_opts.dp.link_rate = ctrl->link->link_params.rate / 100;
@@ -1846,13 +1881,14 @@ static void msm_dp_ctrl_psr_exit(struct msm_dp_ctrl_private *ctrl) · 45 unmodified lines
1846 msm_dp_write_link(ctrl, REG_PSR_CMD, cmd);1881 msm_dp_write_link(ctrl, REG_PSR_CMD, cmd);
1847}1882}
1848 1883
1849void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl)1884void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl,
1885 struct msm_dp_panel *panel)
1850{1886{
1851 struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,1887 struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
1852 struct msm_dp_ctrl_private, msm_dp_ctrl);1888 struct msm_dp_ctrl_private, msm_dp_ctrl);
1853 u32 cfg;1889 u32 cfg;
1854 1890
1855 if (!ctrl->panel->psr_cap.version)1891 if (!panel->psr_cap.version)
1856 return;1892 return;
1857 1893
1858 /* enable PSR1 function */1894 /* enable PSR1 function */
@@ -1867,12 +1903,13 @@ void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl) · 8 unmodified lines
1867 drm_dp_dpcd_write(ctrl->aux, DP_PSR_EN_CFG, &cfg, 1);1903 drm_dp_dpcd_write(ctrl->aux, DP_PSR_EN_CFG, &cfg, 1);
1868}1904}
1869 1905
1870void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enter)1906void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl,
1907 struct msm_dp_panel *panel, bool enter)
1871{1908{
1872 struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,1909 struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
1873 struct msm_dp_ctrl_private, msm_dp_ctrl);1910 struct msm_dp_ctrl_private, msm_dp_ctrl);
1874 1911
1875 if (!ctrl->panel->psr_cap.version)1912 if (!panel->psr_cap.version)
1876 return;1913 return;
1877 1914
1878 /*1915 /*
@@ -1942,7 +1979,8 @@ void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl) · 63 unmodified lines
1942 phy_exit(phy);1979 phy_exit(phy);
1943}1980}
1944 1981
1945static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)1982static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl,
1983 struct msm_dp_panel *panel)
1946{1984{
1947 struct phy *phy = ctrl->phy;1985 struct phy *phy = ctrl->phy;
1948 int ret = 0;1986 int ret = 0;
@@ -1950,20 +1988,19 @@ static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl) · 1 unmodified line
1950 msm_dp_ctrl_mainlink_disable(ctrl);1988 msm_dp_ctrl_mainlink_disable(ctrl);
1951 ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;1989 ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
1952 phy_configure(phy, &ctrl->phy_opts);1990 phy_configure(phy, &ctrl->phy_opts);
1991
1953 /*1992 /*
1954 * Disable and re-enable the mainlink clock since the1993 * Disable and re-enable the mainlink clock since the
1955 * link clock might have been adjusted as part of the1994 * link clock might have been adjusted as part of the
1956 * link maintenance.1995 * link maintenance.
1957 */1996 */
1958 dev_pm_opp_set_rate(ctrl->dev, 0);
1959
1960 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);1997 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
1961 1998
1962 phy_power_off(phy);1999 phy_power_off(phy);
1963 /* hw recommended delay before re-enabling clocks */2000 /* hw recommended delay before re-enabling clocks */
1964 msleep(20);2001 msleep(20);
1965 2002
1966 ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl);2003 ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
1967 if (ret) {2004 if (ret) {
1968 DRM_ERROR("Failed to enable mainlink clks. ret=%d\n", ret);2005 DRM_ERROR("Failed to enable mainlink clks. ret=%d\n", ret);
1969 return ret;2006 return ret;
@@ -1972,7 +2009,8 @@ static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl) · 2 unmodified lines
1972 return ret;2009 return ret;
1973}2010}
1974 2011
1975static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)2012static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl,
2013 struct msm_dp_panel *panel)
1976{2014{
1977 struct phy *phy;2015 struct phy *phy;
1978 2016
@@ -1980,9 +2018,8 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl) · 1 unmodified line
1980 2018
1981 msm_dp_ctrl_mainlink_disable(ctrl);2019 msm_dp_ctrl_mainlink_disable(ctrl);
1982 2020
1983 msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);2021 msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl, panel);
1984 2022
1985 dev_pm_opp_set_rate(ctrl->dev, 0);
1986 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);2023 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
1987 2024
1988 phy_power_off(phy);2025 phy_power_off(phy);
@@ -1994,7 +2031,8 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl) · 5 unmodified lines
1994 return 0;2031 return 0;
1995}2032}
1996 2033
1997static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl)2034static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl,
2035 struct msm_dp_panel *panel)
1998{2036{
1999 int ret = 0;2037 int ret = 0;
2000 int training_step = DP_TRAINING_NONE;2038 int training_step = DP_TRAINING_NONE;
@@ -2004,11 +2042,11 @@ static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl) · 3 unmodified lines
2004 ctrl->link->phy_params.p_level = 0;2042 ctrl->link->phy_params.p_level = 0;
2005 ctrl->link->phy_params.v_level = 0;2043 ctrl->link->phy_params.v_level = 0;
2006 2044
2007 ret = msm_dp_ctrl_setup_main_link(ctrl, &training_step);2045 ret = msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
2008 if (ret)2046 if (ret)
2009 goto end;2047 goto end;
2010 2048
2011 msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);2049 msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
2012 2050
2013 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);2051 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
2014 2052
@@ -2152,7 +2190,43 @@ static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl) · 137 unmodified lines
2152 return success;2190 return success;
2153}2191}
2154 2192
2155static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl)2193static int msm_dp_ctrl_on_pixel_clk(struct msm_dp_ctrl_private *ctrl, unsigned long pixel_rate)
2194{
2195 int ret;
2196
2197 ret = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
2198 if (ret) {
2199 DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
2200 return ret;
2201 }
2202
2203 if (WARN_ON_ONCE(ctrl->stream_clks_on))
2204 return 0;
2205
2206 ret = clk_prepare_enable(ctrl->pixel_clk);
2207 if (ret) {
2208 DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
2209 return ret;
2210 }
2211 ctrl->stream_clks_on = true;
2212
2213 return ret;
2214}
2215
2216void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl)
2217{
2218 struct msm_dp_ctrl_private *ctrl;
2219
2220 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2221
2222 if (ctrl->stream_clks_on) {
2223 clk_disable_unprepare(ctrl->pixel_clk);
2224 ctrl->stream_clks_on = false;
2225 }
2226}
2227
2228static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl,
2229 struct msm_dp_panel *panel)
2156{2230{
2157 int ret;2231 int ret;
2158 unsigned long pixel_rate;2232 unsigned long pixel_rate;
@@ -2168,38 +2242,27 @@ static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl · 9 unmodified lines
2168 * running. Add the global reset just before disabling the2242 * running. Add the global reset just before disabling the
2169 * link clocks and core clocks.2243 * link clocks and core clocks.
2170 */2244 */
2171 msm_dp_ctrl_off(&ctrl->msm_dp_ctrl);2245 msm_dp_ctrl_off_pixel_clk(&ctrl->msm_dp_ctrl);
2246 msm_dp_ctrl_off_link(&ctrl->msm_dp_ctrl, panel);
2172 2247
2173 ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl);2248 ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl, panel);
2174 if (ret) {2249 if (ret) {
2175 DRM_ERROR("failed to enable DP link controller\n");2250 DRM_ERROR("failed to enable DP link controller\n");
2176 return ret;2251 return ret;
2177 }2252 }
2178 2253
2179 pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock;2254 pixel_rate = panel->msm_dp_mode.drm_mode.clock;
2180 ret = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);2255 ret = msm_dp_ctrl_on_pixel_clk(ctrl, pixel_rate);
2181 if (ret) {2256 if (ret)
2182 DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
2183 return ret;2257 return ret;
2184 }
2185
2186 if (ctrl->stream_clks_on) {
2187 drm_dbg_dp(ctrl->drm_dev, "pixel clks already enabled\n");
2188 } else {
2189 ret = clk_prepare_enable(ctrl->pixel_clk);
2190 if (ret) {
2191 DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
2192 return ret;
2193 }
2194 ctrl->stream_clks_on = true;
2195 }
2196 2258
2197 msm_dp_ctrl_send_phy_test_pattern(ctrl);2259 msm_dp_ctrl_send_phy_test_pattern(ctrl);
2198 2260
2199 return 0;2261 return 0;
2200}2262}
2201 2263
2202void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl)2264void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl,
2265 struct msm_dp_panel *panel)
2203{2266{
2204 struct msm_dp_ctrl_private *ctrl;2267 struct msm_dp_ctrl_private *ctrl;
2205 u32 sink_request = 0x0;2268 u32 sink_request = 0x0;
@@ -2214,14 +2277,14 @@ void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl) · 8 unmodified lines
2214 2277
2215 if (sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {2278 if (sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
2216 drm_dbg_dp(ctrl->drm_dev, "PHY_TEST_PATTERN request\n");2279 drm_dbg_dp(ctrl->drm_dev, "PHY_TEST_PATTERN request\n");
2217 if (msm_dp_ctrl_process_phy_test_request(ctrl)) {2280 if (msm_dp_ctrl_process_phy_test_request(ctrl, panel)) {
2218 DRM_ERROR("process phy_test_req failed\n");2281 DRM_ERROR("process phy_test_req failed\n");
2219 return;2282 return;
2220 }2283 }
2221 }2284 }
2222 2285
2223 if (sink_request & DP_LINK_STATUS_UPDATED) {2286 if (sink_request & DP_LINK_STATUS_UPDATED) {
2224 if (msm_dp_ctrl_link_maintenance(ctrl)) {2287 if (msm_dp_ctrl_link_maintenance(ctrl, panel)) {
2225 DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");2288 DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
2226 return;2289 return;
2227 }2290 }
@@ -2229,7 +2292,7 @@ void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
2229 2292
2230 if (sink_request & DP_TEST_LINK_TRAINING) {2293 if (sink_request & DP_TEST_LINK_TRAINING) {
2231 msm_dp_link_send_test_response(ctrl->link);2294 msm_dp_link_send_test_response(ctrl->link);
2232 if (msm_dp_ctrl_link_maintenance(ctrl)) {2295 if (msm_dp_ctrl_link_maintenance(ctrl, panel)) {
2233 DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");2296 DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
2234 return;2297 return;
2235 }2298 }
@@ -2265,7 +2328,8 @@ static bool msm_dp_ctrl_channel_eq_ok(struct msm_dp_ctrl_private *ctrl) · 29 unmodified lines
2265 return drm_dp_channel_eq_ok(link_status, num_lanes);2328 return drm_dp_channel_eq_ok(link_status, num_lanes);
2266}2329}
2267 2330
2268int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)2331int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
2332 struct msm_dp_panel *panel)
2269{2333{
2270 int rc = 0;2334 int rc = 0;
2271 struct msm_dp_ctrl_private *ctrl;2335 struct msm_dp_ctrl_private *ctrl;
@@ -2281,8 +2345,8 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 9 unmodified lines
2281 2345
2282 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);2346 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2283 2347
2284 rate = ctrl->panel->link_info.rate;2348 rate = panel->link_info.rate;
2285 pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock;2349 pixel_rate = panel->msm_dp_mode.drm_mode.clock;
2286 2350
2287 msm_dp_ctrl_core_clk_enable(&ctrl->msm_dp_ctrl);2351 msm_dp_ctrl_core_clk_enable(&ctrl->msm_dp_ctrl);
2288 2352
@@ -2294,8 +2358,8 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 5 unmodified lines
2294 } else {2358 } else {
2295 ctrl->link->link_params.rate = rate;2359 ctrl->link->link_params.rate = rate;
2296 ctrl->link->link_params.num_lanes =2360 ctrl->link->link_params.num_lanes =
2297 ctrl->panel->link_info.num_lanes;2361 panel->link_info.num_lanes;
2298 if (ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)2362 if (panel->msm_dp_mode.out_fmt_is_yuv_420)
2299 pixel_rate >>= 1;2363 pixel_rate >>= 1;
2300 }2364 }
2301 2365
@@ -2303,13 +2367,13 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
2303 ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes,2367 ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes,
2304 pixel_rate);2368 pixel_rate);
2305 2369
2306 rc = msm_dp_ctrl_enable_mainlink_clocks(ctrl);2370 rc = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
2307 if (rc)2371 if (rc)
2308 return rc;2372 return rc;
2309 2373
2310 while (--link_train_max_retries) {2374 while (--link_train_max_retries) {
2311 training_step = DP_TRAINING_NONE;2375 training_step = DP_TRAINING_NONE;
2312 rc = msm_dp_ctrl_setup_main_link(ctrl, &training_step);2376 rc = msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
2313 if (rc == 0) {2377 if (rc == 0) {
2314 /* training completed successfully */2378 /* training completed successfully */
2315 break;2379 break;
@@ -2328,7 +2392,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 12 unmodified lines
2328 * some lanes are ready,2392 * some lanes are ready,
2329 * reduce lane number2393 * reduce lane number
2330 */2394 */
2331 rc = msm_dp_ctrl_link_lane_down_shift(ctrl);2395 rc = msm_dp_ctrl_link_lane_down_shift(ctrl, panel);
2332 if (rc < 0) { /* lane == 1 already */2396 if (rc < 0) { /* lane == 1 already */
2333 /* end with failure */2397 /* end with failure */
2334 break;2398 break;
@@ -2349,7 +2413,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 14 unmodified lines
2349 ctrl->link->link_params.num_lanes))2413 ctrl->link->link_params.num_lanes))
2350 rc = msm_dp_ctrl_link_rate_down_shift(ctrl);2414 rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
2351 else2415 else
2352 rc = msm_dp_ctrl_link_lane_down_shift(ctrl);2416 rc = msm_dp_ctrl_link_lane_down_shift(ctrl, panel);
2353 2417
2354 if (rc < 0) {2418 if (rc < 0) {
2355 /* end with failure */2419 /* end with failure */
@@ -2357,10 +2421,10 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
2357 }2421 }
2358 2422
2359 /* stop link training before start re training */2423 /* stop link training before start re training */
2360 msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);2424 msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
2361 }2425 }
2362 2426
2363 rc = msm_dp_ctrl_reinitialize_mainlink(ctrl);2427 rc = msm_dp_ctrl_reinitialize_mainlink(ctrl, panel);
2364 if (rc) {2428 if (rc) {
2365 DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", rc);2429 DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", rc);
2366 break;2430 break;
@@ -2381,20 +2445,21 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 14 unmodified lines
2381 * link training failed2445 * link training failed
2382 * end txing train pattern here2446 * end txing train pattern here
2383 */2447 */
2384 msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);2448 msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
2385 2449
2386 msm_dp_ctrl_deinitialize_mainlink(ctrl);2450 msm_dp_ctrl_deinitialize_mainlink(ctrl, panel);
2387 rc = -ECONNRESET;2451 rc = -ECONNRESET;
2388 }2452 }
2389 2453
2390 return rc;2454 return rc;
2391}2455}
2392 2456
2393static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl)2457static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl,
2458 struct msm_dp_panel *panel)
2394{2459{
2395 int training_step = DP_TRAINING_NONE;2460 int training_step = DP_TRAINING_NONE;
2396 2461
2397 return msm_dp_ctrl_setup_main_link(ctrl, &training_step);2462 return msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
2398}2463}
2399 2464
2400static void msm_dp_ctrl_config_msa(struct msm_dp_ctrl_private *ctrl,2465static void msm_dp_ctrl_config_msa(struct msm_dp_ctrl_private *ctrl,
@@ -2465,62 +2530,67 @@ static void msm_dp_ctrl_config_msa(struct msm_dp_ctrl_private *ctrl, · 64 unmodified lines
2465 msm_dp_write_link(ctrl, REG_DP_SOFTWARE_NVID, nvid);2530 msm_dp_write_link(ctrl, REG_DP_SOFTWARE_NVID, nvid);
2466}2531}
2467 2532
2468int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train)2533int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl,
2534 struct msm_dp_panel *panel,
2535 bool force_link_train)
2469{2536{
2470 int ret = 0;2537 int ret = 0;
2471 bool mainlink_ready = false;
2472 struct msm_dp_ctrl_private *ctrl;2538 struct msm_dp_ctrl_private *ctrl;
2473 unsigned long pixel_rate;
2474 unsigned long pixel_rate_orig;
2475 2539
2476 if (!msm_dp_ctrl)2540 if (!msm_dp_ctrl)
2477 return -EINVAL;2541 return -EINVAL;
2478 2542
2479 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);2543 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2480 2544
2481 pixel_rate = pixel_rate_orig = ctrl->panel->msm_dp_mode.drm_mode.clock;2545 drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d\n",
2482 2546 ctrl->link->link_params.rate,
2483 if (msm_dp_ctrl->wide_bus_en || ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)2547 ctrl->link->link_params.num_lanes);
2484 pixel_rate >>= 1;
2485
2486 drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d, pixel_rate=%lu\n",
2487 ctrl->link->link_params.rate,
2488 ctrl->link->link_params.num_lanes, pixel_rate);
2489 2548
2490 drm_dbg_dp(ctrl->drm_dev,2549 drm_dbg_dp(ctrl->drm_dev,
2491 "core_clk_on=%d link_clk_on=%d stream_clk_on=%d\n",2550 "core_clk_on=%d link_clk_on=%d stream_clk_on=%d\n",
2492 ctrl->core_clks_on, ctrl->link_clks_on, ctrl->stream_clks_on);2551 ctrl->core_clks_on, ctrl->link_clks_on, ctrl->stream_clks_on);
2493 2552
2494 if (!ctrl->link_clks_on) { /* link clk is off */2553 if (!ctrl->link_clks_on) { /* link clk is off */
2495 ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl);2554 ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
2496 if (ret) {2555 if (ret) {
2497 DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);2556 DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);
2498 goto end;2557 return ret;
2499 }
2500 }
2501
2502 ret = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
2503 if (ret) {
2504 DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
2505 goto end;
2506 }
2507
2508 if (ctrl->stream_clks_on) {
2509 drm_dbg_dp(ctrl->drm_dev, "pixel clks already enabled\n");
2510 } else {
2511 ret = clk_prepare_enable(ctrl->pixel_clk);
2512 if (ret) {
2513 DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
2514 goto end;
2515 }2558 }
2516 ctrl->stream_clks_on = true;
2517 }2559 }
2518 2560
2519 if (force_link_train || !msm_dp_ctrl_channel_eq_ok(ctrl))2561 if (force_link_train || !msm_dp_ctrl_channel_eq_ok(ctrl))
2520 msm_dp_ctrl_link_retrain(ctrl);2562 msm_dp_ctrl_link_retrain(ctrl, panel);
2521 2563
2522 /* stop txing train pattern to end link training */2564 /* stop txing train pattern to end link training */
2523 msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);2565 msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
2566
2567 return ret;
2568}
2569
2570int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel)
2571{
2572 int ret = 0;
2573 bool mainlink_ready = false;
2574 struct msm_dp_ctrl_private *ctrl;
2575 unsigned long pixel_rate;
2576 unsigned long pixel_rate_orig;
2577
2578 if (!msm_dp_ctrl)
2579 return -EINVAL;
2580
2581 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2582
2583 pixel_rate_orig = panel->msm_dp_mode.drm_mode.clock;
2584 pixel_rate = pixel_rate_orig;
2585
2586 if (msm_dp_ctrl->wide_bus_en || panel->msm_dp_mode.out_fmt_is_yuv_420)
2587 pixel_rate >>= 1;
2588
2589 drm_dbg_dp(ctrl->drm_dev, "pixel_rate=%lu\n", pixel_rate);
2590
2591 ret = msm_dp_ctrl_on_pixel_clk(ctrl, pixel_rate);
2592 if (ret)
2593 return ret;
2524 2594
2525 /*2595 /*
2526 * Set up transfer unit values and set controller state to send2596 * Set up transfer unit values and set controller state to send
@@ -2528,16 +2598,20 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train · 1 unmodified line
2528 */2598 */
2529 reinit_completion(&ctrl->video_comp);2599 reinit_completion(&ctrl->video_comp);
2530 2600
2531 msm_dp_ctrl_configure_source_params(ctrl);2601 msm_dp_ctrl_lane_mapping(ctrl);
2602 msm_dp_setup_peripheral_flush(ctrl);
2603 msm_dp_ctrl_config_ctrl_link(ctrl, panel);
2604
2605 msm_dp_ctrl_configure_source_params(ctrl, panel);
2532 2606
2533 msm_dp_ctrl_config_msa(ctrl,2607 msm_dp_ctrl_config_msa(ctrl,
2534 ctrl->link->link_params.rate,2608 ctrl->link->link_params.rate,
2535 pixel_rate_orig,2609 pixel_rate_orig,
2536 ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420);2610 panel->msm_dp_mode.out_fmt_is_yuv_420);
2537 2611
2538 msm_dp_panel_clear_dsc_dto(ctrl->panel);2612 msm_dp_panel_clear_dsc_dto(panel);
2539 2613
2540 msm_dp_ctrl_setup_tr_unit(ctrl);2614 msm_dp_ctrl_setup_tr_unit(ctrl, panel);
2541 2615
2542 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);2616 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
2543 2617
@@ -2549,11 +2623,10 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train · 5 unmodified lines
2549 drm_dbg_dp(ctrl->drm_dev,2623 drm_dbg_dp(ctrl->drm_dev,
2550 "mainlink %s\n", mainlink_ready ? "READY" : "NOT READY");2624 "mainlink %s\n", mainlink_ready ? "READY" : "NOT READY");
2551 2625
2552end:
2553 return ret;2626 return ret;
2554}2627}
2555 2628
2556void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl)2629void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl)
2557{2630{
2558 struct msm_dp_ctrl_private *ctrl;2631 struct msm_dp_ctrl_private *ctrl;
2559 struct phy *phy;2632 struct phy *phy;
@@ -2561,29 +2634,13 @@ void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
2561 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);2634 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2562 phy = ctrl->phy;2635 phy = ctrl->phy;
2563 2636
2564 msm_dp_panel_disable_vsc_sdp(ctrl->panel);
2565
2566 /* set dongle to D3 (power off) mode */
2567 msm_dp_link_psm_config(ctrl->link, &ctrl->panel->link_info, true);
2568
2569 msm_dp_ctrl_mainlink_disable(ctrl);
2570
2571 if (ctrl->stream_clks_on) {
2572 clk_disable_unprepare(ctrl->pixel_clk);
2573 ctrl->stream_clks_on = false;
2574 }
2575
2576 dev_pm_opp_set_rate(ctrl->dev, 0);
2577 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
2578
2579 phy_power_off(phy);
2580
2581 /* aux channel down, reinit phy */2637 /* aux channel down, reinit phy */
2582 phy_exit(phy);2638 phy_exit(phy);
2583 phy_init(phy);2639 phy_init(phy);
2584}2640}
2585 2641
2586void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)2642void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl,
2643 struct msm_dp_panel *panel)
2587{2644{
2588 struct msm_dp_ctrl_private *ctrl;2645 struct msm_dp_ctrl_private *ctrl;
2589 struct phy *phy;2646 struct phy *phy;
@@ -2591,24 +2648,19 @@ void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
2591 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);2648 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2592 phy = ctrl->phy;2649 phy = ctrl->phy;
2593 2650
2594 msm_dp_panel_disable_vsc_sdp(ctrl->panel);2651 msm_dp_panel_disable_vsc_sdp(panel);
2595 2652
2596 msm_dp_ctrl_mainlink_disable(ctrl);2653 msm_dp_ctrl_mainlink_disable(ctrl);
2597 2654
2598 msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);2655 msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl, panel);
2599
2600 if (ctrl->stream_clks_on) {
2601 clk_disable_unprepare(ctrl->pixel_clk);
2602 ctrl->stream_clks_on = false;
2603 }
2604 2656
2605 dev_pm_opp_set_rate(ctrl->dev, 0);
2606 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);2657 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
2607 2658
2608 phy_power_off(phy);2659 phy_power_off(phy);
2609}2660}
2610 2661
2611irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)2662irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl,
2663 struct msm_dp_panel *panel)
2612{2664{
2613 struct msm_dp_ctrl_private *ctrl;2665 struct msm_dp_ctrl_private *ctrl;
2614 u32 isr;2666 u32 isr;
@@ -2619,7 +2671,7 @@ irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl) · 4 unmodified lines
2619 2671
2620 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);2672 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
2621 2673
2622 if (ctrl->panel->psr_cap.version) {2674 if (panel->psr_cap.version) {
2623 isr = msm_dp_ctrl_get_psr_interrupt(ctrl);2675 isr = msm_dp_ctrl_get_psr_interrupt(ctrl);
2624 2676
2625 if (isr)2677 if (isr)
@@ -2708,7 +2760,7 @@ static int msm_dp_ctrl_clk_init(struct msm_dp_ctrl *msm_dp_ctrl) · 82 unmodified lines
2708}2760}
2709 2761
2710struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link,2762struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link,
2711 struct msm_dp_panel *panel, struct drm_dp_aux *aux,2763 struct drm_dp_aux *aux,
2712 struct phy *phy,2764 struct phy *phy,
2713 void __iomem *ahb_base,2765 void __iomem *ahb_base,
2714 void __iomem *link_base)2766 void __iomem *link_base)
@@ -2716,7 +2768,7 @@ struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link · 1 unmodified line
2716 struct msm_dp_ctrl_private *ctrl;2768 struct msm_dp_ctrl_private *ctrl;
2717 int ret;2769 int ret;
2718 2770
2719 if (!dev || !panel || !aux || !link) {2771 if (!dev || !aux || !link) {
2720 DRM_ERROR("invalid input\n");2772 DRM_ERROR("invalid input\n");
2721 return ERR_PTR(-EINVAL);2773 return ERR_PTR(-EINVAL);
2722 }2774 }
@@ -2744,7 +2796,6 @@ struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link · 21 unmodified lines
2744 init_completion(&ctrl->video_comp);2796 init_completion(&ctrl->video_comp);
2745 2797
2746 /* in parameters */2798 /* in parameters */
2747 ctrl->panel = panel;
2748 ctrl->aux = aux;2799 ctrl->aux = aux;
2749 ctrl->link = link;2800 ctrl->link = link;
2750 ctrl->dev = dev;2801 ctrl->dev = dev;
drivers/gpu/drm/msm/dp/dp_ctrl.h+20−10
@@ -16,28 +16,37 @@ struct msm_dp_ctrl { · 15 unmodified lines
16 16
17struct phy;17struct phy;
18 18
19int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl);19int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
20int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train);20 struct msm_dp_panel *panel);
21void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl);21int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel);
22void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl);22int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl,
23 struct msm_dp_panel *panel,
24 bool force_link_train);
25void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl,
26 struct msm_dp_panel *panel);
27void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl);
23void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl);28void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl);
24irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl);29irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl,
25void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl);30 struct msm_dp_panel *panel);
31void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl,
32 struct msm_dp_panel *panel);
26struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev,33struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev,
27 struct msm_dp_link *link,34 struct msm_dp_link *link,
28 struct msm_dp_panel *panel,
29 struct drm_dp_aux *aux,35 struct drm_dp_aux *aux,
30 struct phy *phy,36 struct phy *phy,
31 void __iomem *ahb_base,37 void __iomem *ahb_base,
32 void __iomem *link_base);38 void __iomem *link_base);
33 39
34void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl);40void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl,
41 struct msm_dp_panel *panel);
35void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl);42void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl);
36void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);43void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
37void msm_dp_ctrl_irq_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);44void msm_dp_ctrl_irq_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
38 45
39void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enable);46void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl,
40void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl);47 struct msm_dp_panel *panel, bool enable);
48void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl,
49 struct msm_dp_panel *panel);
41 50
42int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl);51int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl);
43void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl);52void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl);
@@ -45,4 +54,5 @@ void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl); · 1 unmodified line
45void msm_dp_ctrl_enable_irq(struct msm_dp_ctrl *msm_dp_ctrl);54void msm_dp_ctrl_enable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
46void msm_dp_ctrl_disable_irq(struct msm_dp_ctrl *msm_dp_ctrl);55void msm_dp_ctrl_disable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
47 56
57void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl);
48#endif /* _DP_CTRL_H_ */58#endif /* _DP_CTRL_H_ */
drivers/gpu/drm/msm/dp/dp_display.c+160−151
@@ -63,7 +63,6 @@ struct msm_dp_display_private { · 62 unmodified lines
63 struct msm_dp_panel *panel;63 struct msm_dp_panel *panel;
64 struct msm_dp_ctrl *ctrl;64 struct msm_dp_ctrl *ctrl;
65 65
66 struct msm_dp_display_mode msm_dp_mode;
67 struct msm_dp msm_dp_display;66 struct msm_dp msm_dp_display;
68 67
69 /* wait for audio signaling */68 /* wait for audio signaling */
@@ -269,6 +268,7 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) · 199 unmodified lines
269 const struct drm_display_info *info = &connector->display_info;268 const struct drm_display_info *info = &connector->display_info;
270 int rc = 0;269 int rc = 0;
271 u8 dpcd[DP_RECEIVER_CAP_SIZE];270 u8 dpcd[DP_RECEIVER_CAP_SIZE];
271 const struct drm_edid *drm_edid = NULL;
272 272
273 rc = drm_dp_read_dpcd_caps(dp->aux, dpcd);273 rc = drm_dp_read_dpcd_caps(dp->aux, dpcd);
274 if (rc)274 if (rc)
@@ -276,10 +276,20 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) · 1 unmodified line
276 276
277 dp->link->lttpr_count = msm_dp_display_lttpr_init(dp, dpcd);277 dp->link->lttpr_count = msm_dp_display_lttpr_init(dp, dpcd);
278 278
279 rc = msm_dp_panel_read_sink_caps(dp->panel, connector);279 rc = msm_dp_panel_read_link_caps(dp->panel, connector);
280 if (rc)280 if (rc)
281 goto end;281 goto end;
282 282
283 drm_edid = drm_edid_read_ddc(connector, &dp->aux->ddc);
284 drm_edid_connector_update(connector, drm_edid);
285
286 if (!drm_edid) {
287 DRM_ERROR("panel edid read failed\n");
288 /* check edid read fail is due to unplug */
289 if (!msm_dp_aux_is_link_connected(dp->aux))
290 return -ETIMEDOUT;
291 }
292
283 msm_dp_link_process_request(dp->link);293 msm_dp_link_process_request(dp->link);
284 294
285 if (!dp->msm_dp_display.is_edp)295 if (!dp->msm_dp_display.is_edp)
@@ -291,7 +301,7 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) · 5 unmodified lines
291 dp->msm_dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;301 dp->msm_dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
292 302
293 dp->audio_supported = info->has_audio;303 dp->audio_supported = info->has_audio;
294 msm_dp_panel_handle_sink_request(dp->panel);304 msm_dp_panel_handle_sink_request(dp->panel, drm_edid);
295 305
296 /*306 /*
297 * set sink to normal operation mode -- D0307 * set sink to normal operation mode -- D0
@@ -302,6 +312,7 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) · 4 unmodified lines
302 msm_dp_link_reset_phy_params_vx_px(dp->link);312 msm_dp_link_reset_phy_params_vx_px(dp->link);
303 313
304end:314end:
315 drm_edid_free(drm_edid);
305 return rc;316 return rc;
306}317}
307 318
@@ -348,7 +359,7 @@ static void msm_dp_display_host_init(struct msm_dp_display_private *dp) · 40 unmodified lines
348 dp->phy_initialized);359 dp->phy_initialized);
349 360
350 msm_dp_ctrl_core_clk_enable(dp->ctrl);361 msm_dp_ctrl_core_clk_enable(dp->ctrl);
351 msm_dp_ctrl_reset(dp->ctrl);362 msm_dp_ctrl_reset(dp->ctrl, dp->panel);
352 msm_dp_ctrl_enable_irq(dp->ctrl);363 msm_dp_ctrl_enable_irq(dp->ctrl);
353 msm_dp_aux_init(dp->aux);364 msm_dp_aux_init(dp->aux);
354 dp->core_initialized = true;365 dp->core_initialized = true;
@@ -360,7 +371,7 @@ static void msm_dp_display_host_deinit(struct msm_dp_display_private *dp) · 5 unmodified lines
360 dp->msm_dp_display.connector_type, dp->core_initialized,371 dp->msm_dp_display.connector_type, dp->core_initialized,
361 dp->phy_initialized);372 dp->phy_initialized);
362 373
363 msm_dp_ctrl_reset(dp->ctrl);374 msm_dp_ctrl_reset(dp->ctrl, dp->panel);
364 msm_dp_ctrl_disable_irq(dp->ctrl);375 msm_dp_ctrl_disable_irq(dp->ctrl);
365 msm_dp_aux_deinit(dp->aux);376 msm_dp_aux_deinit(dp->aux);
366 msm_dp_ctrl_core_clk_disable(dp->ctrl);377 msm_dp_ctrl_core_clk_disable(dp->ctrl);
@@ -381,7 +392,7 @@ static int msm_dp_display_handle_irq_hpd(struct msm_dp_display_private *dp) · 14 unmodified lines
381 392
382 drm_dbg_dp(dp->drm_dev, "%d\n", sink_request);393 drm_dbg_dp(dp->drm_dev, "%d\n", sink_request);
383 394
384 msm_dp_ctrl_handle_sink_request(dp->ctrl);395 msm_dp_ctrl_handle_sink_request(dp->ctrl, dp->panel);
385 396
386 if (sink_request & DP_TEST_LINK_VIDEO_PATTERN)397 if (sink_request & DP_TEST_LINK_VIDEO_PATTERN)
387 msm_dp_display_handle_video_request(dp);398 msm_dp_display_handle_video_request(dp);
@@ -453,7 +464,7 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp) · 65 unmodified lines
453 464
454 /* Don't forget modes for eDP */465 /* Don't forget modes for eDP */
455 if (!dp->msm_dp_display.is_edp)466 if (!dp->msm_dp_display.is_edp)
456 msm_dp_panel_unplugged(dp->panel, dp->msm_dp_display.connector);467 drm_edid_connector_update(dp->msm_dp_display.connector, NULL);
457 468
458 /* triggered by irq_hdp with sink_count = 0 */469 /* triggered by irq_hdp with sink_count = 0 */
459 if (dp->link->sink_count == 0)470 if (dp->link->sink_count == 0)
@@ -515,7 +526,6 @@ static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp) · 55 unmodified lines
515static void msm_dp_display_deinit_sub_modules(struct msm_dp_display_private *dp)526static void msm_dp_display_deinit_sub_modules(struct msm_dp_display_private *dp)
516{527{
517 msm_dp_audio_put(dp->audio);528 msm_dp_audio_put(dp->audio);
518 msm_dp_panel_put(dp->panel);
519 msm_dp_aux_put(dp->aux);529 msm_dp_aux_put(dp->aux);
520}530}
521 531
@@ -560,13 +570,13 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp) · 38 unmodified lines
560 goto error_link;570 goto error_link;
561 }571 }
562 572
563 dp->ctrl = msm_dp_ctrl_get(dev, dp->link, dp->panel, dp->aux,573 dp->ctrl = msm_dp_ctrl_get(dev, dp->link, dp->aux,
564 phy, dp->ahb_base, dp->link_base);574 phy, dp->ahb_base, dp->link_base);
565 if (IS_ERR(dp->ctrl)) {575 if (IS_ERR(dp->ctrl)) {
566 rc = PTR_ERR(dp->ctrl);576 rc = PTR_ERR(dp->ctrl);
567 DRM_ERROR("failed to initialize ctrl, rc = %d\n", rc);577 DRM_ERROR("failed to initialize ctrl, rc = %d\n", rc);
568 dp->ctrl = NULL;578 dp->ctrl = NULL;
569 goto error_ctrl;579 goto error_link;
570 }580 }
571 581
572 dp->audio = msm_dp_audio_get(dp->msm_dp_display.pdev, dp->link_base);582 dp->audio = msm_dp_audio_get(dp->msm_dp_display.pdev, dp->link_base);
@@ -574,13 +584,11 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp) · 1 unmodified line
574 rc = PTR_ERR(dp->audio);584 rc = PTR_ERR(dp->audio);
575 pr_err("failed to initialize audio, rc = %d\n", rc);585 pr_err("failed to initialize audio, rc = %d\n", rc);
576 dp->audio = NULL;586 dp->audio = NULL;
577 goto error_ctrl;587 goto error_link;
578 }588 }
579 589
580 return rc;590 return rc;
581 591
582error_ctrl:
583 msm_dp_panel_put(dp->panel);
584error_link:592error_link:
585 msm_dp_aux_put(dp->aux);593 msm_dp_aux_put(dp->aux);
586error:594error:
@@ -588,20 +596,64 @@ error: · 1 unmodified line
588}596}
589 597
590static int msm_dp_display_set_mode(struct msm_dp *msm_dp_display,598static int msm_dp_display_set_mode(struct msm_dp *msm_dp_display,
591 struct msm_dp_display_mode *mode)599 const struct drm_display_mode *adjusted_mode,
600 struct msm_dp_panel *msm_dp_panel)
592{601{
593 struct msm_dp_display_private *dp;602 struct msm_dp_display_private *dp;
603 u32 bpp;
594 604
595 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);605 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
596 606
597 drm_mode_copy(&dp->panel->msm_dp_mode.drm_mode, &mode->drm_mode);607 if (msm_dp_display_check_video_test(msm_dp_display))
598 dp->panel->msm_dp_mode.bpp = mode->bpp;608 bpp = msm_dp_display_get_test_bpp(msm_dp_display);
599 dp->panel->msm_dp_mode.out_fmt_is_yuv_420 = mode->out_fmt_is_yuv_420;609 else
600 msm_dp_panel_init_panel_info(dp->panel);610 bpp = msm_dp_panel->connector->display_info.bpc * 3;
611
612 msm_dp_panel_init_panel_info(msm_dp_panel, adjusted_mode, bpp ? bpp : 24);
613
614 /* populate wide_bus_support to different layers */
615 dp->ctrl->wide_bus_en =
616 msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 ? false : dp->wide_bus_supported;
601 return 0;617 return 0;
602}618}
603 619
604static int msm_dp_display_enable(struct msm_dp_display_private *dp, bool force_link_train)620static int msm_dp_display_prepare_link(struct msm_dp_display_private *dp)
621{
622 struct msm_dp *msm_dp_display = &dp->msm_dp_display;
623 int rc = 0;
624 bool force_link_train = false;
625
626 drm_dbg_dp(dp->drm_dev, "sink_count=%d\n", dp->link->sink_count);
627
628 if (msm_dp_display->is_edp)
629 msm_dp_hpd_plug_handle(dp);
630
631 rc = pm_runtime_resume_and_get(&msm_dp_display->pdev->dev);
632 if (rc) {
633 DRM_ERROR("failed to pm_runtime_resume\n");
634 return rc;
635 }
636
637 if (dp->link->sink_count == 0)
638 return -ENOTCONN;
639
640 if (!msm_dp_display->power_on) {
641 msm_dp_display_host_phy_init(dp);
642 force_link_train = true;
643 }
644
645 rc = msm_dp_ctrl_on_link(dp->ctrl, dp->panel);
646 if (rc) {
647 DRM_ERROR("Failed link training (rc=%d)\n", rc);
648 // TODO: schedule drm_connector_set_link_status_property()
649 return rc;
650 }
651
652 return msm_dp_ctrl_prepare_stream_on(dp->ctrl, dp->panel, force_link_train);
653}
654
655static int msm_dp_display_enable(struct msm_dp_display_private *dp,
656 struct msm_dp_panel *msm_dp_panel)
605{657{
606 int rc = 0;658 int rc = 0;
607 struct msm_dp *msm_dp_display = &dp->msm_dp_display;659 struct msm_dp *msm_dp_display = &dp->msm_dp_display;
@@ -612,7 +664,7 @@ static int msm_dp_display_enable(struct msm_dp_display_private *dp, bool force_l · 4 unmodified lines
612 return 0;664 return 0;
613 }665 }
614 666
615 rc = msm_dp_ctrl_on_stream(dp->ctrl, force_link_train);667 rc = msm_dp_ctrl_on_stream(dp->ctrl, msm_dp_panel);
616 if (!rc)668 if (!rc)
617 msm_dp_display->power_on = true;669 msm_dp_display->power_on = true;
618 670
@@ -637,18 +689,15 @@ static int msm_dp_display_post_enable(struct msm_dp *msm_dp_display) · 18 unmodified lines
637 msm_dp_display_handle_plugged_change(msm_dp_display, true);689 msm_dp_display_handle_plugged_change(msm_dp_display, true);
638 690
639 if (msm_dp_display->psr_supported)691 if (msm_dp_display->psr_supported)
640 msm_dp_ctrl_config_psr(dp->ctrl);692 msm_dp_ctrl_config_psr(dp->ctrl, dp->panel);
641 693
642 return 0;694 return 0;
643}695}
644 696
645static int msm_dp_display_disable(struct msm_dp_display_private *dp)697static void msm_dp_display_audio_notify_disable(struct msm_dp_display_private *dp)
646{698{
647 struct msm_dp *msm_dp_display = &dp->msm_dp_display;699 struct msm_dp *msm_dp_display = &dp->msm_dp_display;
648 700
649 if (!msm_dp_display->power_on)
650 return 0;
651
652 /* wait only if audio was enabled */701 /* wait only if audio was enabled */
653 if (msm_dp_display->audio_enabled) {702 if (msm_dp_display->audio_enabled) {
654 /* signal the disconnect event */703 /* signal the disconnect event */
@@ -659,21 +708,31 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp) · 4 unmodified lines
659 }708 }
660 709
661 msm_dp_display->audio_enabled = false;710 msm_dp_display->audio_enabled = false;
711}
662 712
663 if (dp->link->sink_count == 0) {713static int msm_dp_display_disable(struct msm_dp_display_private *dp,
664 /*714 struct msm_dp_panel *msm_dp_panel)
665 * irq_hpd with sink_count = 0715{
666 * hdmi unplugged out of dongle716 struct msm_dp *msm_dp_display = &dp->msm_dp_display;
667 */717
668 msm_dp_ctrl_off_link_stream(dp->ctrl);718 if (!msm_dp_display->power_on)
669 } else {719 return 0;
670 /*720
671 * unplugged interrupt721 msm_dp_panel_disable_vsc_sdp(msm_dp_panel);
672 * dongle unplugged out of DUT722
673 */723 msm_dp_ctrl_off_pixel_clk(dp->ctrl);
674 msm_dp_ctrl_off(dp->ctrl);724
725 /* dongle is still connected but sinks are disconnected */
726 if (dp->link->sink_count == 0)
727 msm_dp_link_psm_config(dp->link, &msm_dp_panel->link_info, true);
728
729 msm_dp_ctrl_off_link(dp->ctrl, msm_dp_panel);
730
731 if (dp->link->sink_count == 0)
732 /* re-init the PHY so that we can listen to Dongle disconnect */
733 msm_dp_ctrl_reinit_phy(dp->ctrl);
734 else
675 msm_dp_display_host_phy_exit(dp);735 msm_dp_display_host_phy_exit(dp);
676 }
677 736
678 msm_dp_display->power_on = false;737 msm_dp_display->power_on = false;
679 738
@@ -682,24 +741,22 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp) · 2 unmodified lines
682}741}
683 742
684/**743/**
685 * msm_dp_bridge_mode_valid - callback to determine if specified mode is valid744 * msm_dp_display_mode_valid - callback to determine if specified mode is valid
686 * @bridge: Pointer to drm bridge structure745 * @dp: Pointer to dp display structure
687 * @info: display info746 * @info: display info
688 * @mode: Pointer to drm mode structure747 * @mode: Pointer to drm mode structure
689 * Returns: Validity status for specified mode748 * Returns: Validity status for specified mode
690 */749 */
691enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *bridge,750enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
692 const struct drm_display_info *info,751 const struct drm_display_info *info,
693 const struct drm_display_mode *mode)752 const struct drm_display_mode *mode)
694{753{
695 const u32 num_components = 3, default_bpp = 24;754 const u32 num_components = 3, default_bpp = 24;
696 struct msm_dp_display_private *msm_dp_display;755 struct msm_dp_display_private *msm_dp_display;
697 struct msm_dp_link_info *link_info;756 struct msm_dp_link_info *link_info;
698 u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;757 u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
699 struct msm_dp *dp;
700 int mode_pclk_khz = mode->clock;758 int mode_pclk_khz = mode->clock;
701 759 bool is_yuv_420;
702 dp = to_dp_bridge(bridge)->msm_dp_display;
703 760
704 if (!dp || !mode_pclk_khz || !dp->connector) {761 if (!dp || !mode_pclk_khz || !dp->connector) {
705 DRM_ERROR("invalid params\n");762 DRM_ERROR("invalid params\n");
@@ -709,9 +766,16 @@ enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *bridge, · 3 unmodified lines
709 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);766 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
710 link_info = &msm_dp_display->panel->link_info;767 link_info = &msm_dp_display->panel->link_info;
711 768
712 if ((drm_mode_is_420_only(&dp->connector->display_info, mode) &&769 is_yuv_420 = drm_mode_is_420_only(&dp->connector->display_info, mode);
713 msm_dp_display->panel->vsc_sdp_supported) ||770
714 msm_dp_wide_bus_available(dp))771 /*
772 * YUV 420 is carried over DP by signalling the colorimetry through a
773 * VSC SDP, so a 420-only mode cannot be driven without VSC SDP support.
774 */
775 if (is_yuv_420 && !msm_dp_display->panel->vsc_sdp_supported)
776 return MODE_NO_420;
777
778 if (is_yuv_420 || msm_dp_display->wide_bus_supported)
715 mode_pclk_khz /= 2;779 mode_pclk_khz /= 2;
716 780
717 if (mode_pclk_khz > DP_MAX_PIXEL_CLK_KHZ)781 if (mode_pclk_khz > DP_MAX_PIXEL_CLK_KHZ)
@@ -744,8 +808,7 @@ int msm_dp_display_get_modes(struct msm_dp *dp) · 26 unmodified lines
744 808
745 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);809 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
746 810
747 return msm_dp_panel_get_modes(msm_dp_display->panel,811 return drm_edid_connector_add_modes(msm_dp_display->panel->connector);
748 dp->connector);
749}812}
750 813
751bool msm_dp_display_check_video_test(struct msm_dp *dp)814bool msm_dp_display_check_video_test(struct msm_dp *dp)
@@ -808,7 +871,7 @@ void msm_dp_display_set_psr(struct msm_dp *msm_dp_display, bool enter) · 56 unmodified lines
808 }871 }
809 872
810 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);873 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
811 msm_dp_ctrl_set_psr(dp->ctrl, enter);874 msm_dp_ctrl_set_psr(dp->ctrl, dp->panel, enter);
812}875}
813 876
814/**877/**
@@ -918,7 +981,7 @@ static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id) · 103 unmodified lines
918 }981 }
919 982
920 /* DP controller isr */983 /* DP controller isr */
921 ret |= msm_dp_ctrl_isr(dp->ctrl);984 ret |= msm_dp_ctrl_isr(dp->ctrl, dp->panel);
922 985
923 return ret;986 return ret;
924}987}
@@ -1277,22 +1340,10 @@ void __exit msm_dp_unregister(void) · 352 unmodified lines
1277 platform_driver_unregister(&msm_dp_display_driver);1340 platform_driver_unregister(&msm_dp_display_driver);
1278}1341}
1279 1342
1280bool msm_dp_is_yuv_420_enabled(const struct msm_dp *msm_dp_display,
1281 const struct drm_display_mode *mode)
1282{
1283 struct msm_dp_display_private *dp;
1284 const struct drm_display_info *info;
1285
1286 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
1287 info = &msm_dp_display->connector->display_info;
1288
1289 return dp->panel->vsc_sdp_supported && drm_mode_is_420_only(info, mode);
1290}
1291
1292bool msm_dp_needs_periph_flush(const struct msm_dp *msm_dp_display,1343bool msm_dp_needs_periph_flush(const struct msm_dp *msm_dp_display,
1293 const struct drm_display_mode *mode)1344 const struct drm_display_mode *mode)
1294{1345{
1295 return msm_dp_is_yuv_420_enabled(msm_dp_display, mode);1346 return drm_mode_is_420_only(&msm_dp_display->connector->display_info, mode);
1296}1347}
1297 1348
1298bool msm_dp_wide_bus_available(const struct msm_dp *msm_dp_display)1349bool msm_dp_wide_bus_available(const struct msm_dp *msm_dp_display)
@@ -1301,7 +1352,7 @@ bool msm_dp_wide_bus_available(const struct msm_dp *msm_dp_display) · 2 unmodified lines
1301 1352
1302 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);1353 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
1303 1354
1304 if (dp->msm_dp_mode.out_fmt_is_yuv_420)1355 if (dp->panel->msm_dp_mode.out_fmt_is_yuv_420)
1305 return false;1356 return false;
1306 1357
1307 return dp->wide_bus_supported;1358 return dp->wide_bus_supported;
@@ -1352,66 +1403,57 @@ int msm_dp_modeset_init(struct msm_dp *msm_dp_display, struct drm_device *dev, · 44 unmodified lines
1352 return 0;1403 return 0;
1353}1404}
1354 1405
1355void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,1406void msm_dp_display_atomic_pre_enable(struct msm_dp *msm_dp_display,
1356 struct drm_atomic_commit *state)1407 struct drm_atomic_commit *state)
1357{1408{
1358 struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);1409 struct msm_dp_display_private *dp;
1359 struct msm_dp *dp = msm_dp_bridge->msm_dp_display;1410 struct drm_crtc *crtc;
1360 int rc = 0;1411 struct drm_crtc_state *crtc_state;
1361 struct msm_dp_display_private *msm_dp_display;
1362 bool force_link_train = false;
1363
1364 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
1365 if (!msm_dp_display->msm_dp_mode.drm_mode.clock) {
1366 DRM_ERROR("invalid params\n");
1367 return;
1368 }
1369 1412
1370 if (dp->is_edp)1413 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
1371 msm_dp_hpd_plug_handle(msm_dp_display);
1372 1414
1373 if (pm_runtime_resume_and_get(&dp->pdev->dev)) {1415 crtc = drm_atomic_get_new_crtc_for_encoder(state, msm_dp_display->bridge->encoder);
1374 DRM_ERROR("failed to pm_runtime_resume\n");1416 if (!crtc)
1375 return;1417 return;
1376 }1418 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1377 1419
1378 if (msm_dp_display->link->sink_count == 0)1420 /*
1379 return;1421 * The DPU encoder's .atomic_enable() reads the mode's YUV420 / wide bus
1422 * state and runs before the bridge's .atomic_enable(), so the mode must
1423 * be programmed here, in .atomic_pre_enable().
1424 */
1425 msm_dp_display_set_mode(msm_dp_display, &crtc_state->adjusted_mode, dp->panel);
1426}
1380 1427
1381 rc = msm_dp_display_set_mode(dp, &msm_dp_display->msm_dp_mode);1428void msm_dp_display_atomic_enable(struct msm_dp *msm_dp_display,
1382 if (rc) {1429 struct drm_atomic_commit *state)
1383 DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);1430{
1384 return;1431 int rc = 0;
1385 }1432 struct msm_dp_display_private *dp;
1386 1433
1387 if (!dp->power_on) {1434 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
1388 msm_dp_display_host_phy_init(msm_dp_display);
1389 force_link_train = true;
1390 }
1391 1435
1392 rc = msm_dp_ctrl_on_link(msm_dp_display->ctrl);1436 rc = msm_dp_display_prepare_link(dp);
1393 if (rc) {1437 if (rc) {
1394 DRM_ERROR("Failed link training (rc=%d)\n", rc);1438 DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
1395 // TODO: schedule drm_connector_set_link_status_property()
1396 return;1439 return;
1397 }1440 }
1398 1441
1399 msm_dp_display_enable(msm_dp_display, force_link_train);1442 rc = msm_dp_display_enable(dp, dp->panel);
1443 if (rc)
1444 DRM_ERROR("DP display enable failed, rc=%d\n", rc);
1400 1445
1401 rc = msm_dp_display_post_enable(dp);1446 rc = msm_dp_display_post_enable(msm_dp_display);
1402 if (rc) {1447 if (rc) {
1403 DRM_ERROR("DP display post enable failed, rc=%d\n", rc);1448 DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
1404 msm_dp_display_disable(msm_dp_display);1449 msm_dp_display_disable(dp, dp->panel);
1405 }1450 }
1406 1451
1407 drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);1452 drm_dbg_dp(msm_dp_display->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
1408}1453}
1409 1454
1410void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,1455void msm_dp_display_atomic_disable(struct msm_dp *dp)
1411 struct drm_atomic_commit *state)
1412{1456{
1413 struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
1414 struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
1415 struct msm_dp_display_private *msm_dp_display;1457 struct msm_dp_display_private *msm_dp_display;
1416 1458
1417 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);1459 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
@@ -1419,62 +1461,29 @@ void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge, · 1 unmodified line
1419 msm_dp_ctrl_push_idle(msm_dp_display->ctrl);1461 msm_dp_ctrl_push_idle(msm_dp_display->ctrl);
1420}1462}
1421 1463
1422void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,1464static void msm_dp_display_unprepare(struct msm_dp_display_private *dp)
1423 struct drm_atomic_commit *state)
1424{1465{
1425 struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);1466 struct msm_dp *msm_dp_display = &dp->msm_dp_display;
1426 struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
1427 struct msm_dp_display_private *msm_dp_display;
1428
1429 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
1430
1431 if (dp->is_edp)
1432 msm_dp_hpd_unplug_handle(msm_dp_display);
1433
1434 msm_dp_display_disable(msm_dp_display);
1435 1467
1436 drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);1468 pm_runtime_put_sync(&msm_dp_display->pdev->dev);
1437 1469
1438 pm_runtime_put_sync(&dp->pdev->dev);1470 drm_dbg_dp(dp->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
1439}1471}
1440 1472
1441void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,1473void msm_dp_display_atomic_post_disable(struct msm_dp *dp)
1442 const struct drm_display_mode *mode,
1443 const struct drm_display_mode *adjusted_mode)
1444{1474{
1445 struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
1446 struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
1447 struct msm_dp_display_private *msm_dp_display;1475 struct msm_dp_display_private *msm_dp_display;
1448 struct msm_dp_panel *msm_dp_panel;
1449 1476
1450 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);1477 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
1451 msm_dp_panel = msm_dp_display->panel;
1452 1478
1453 memset(&msm_dp_display->msm_dp_mode, 0x0, sizeof(struct msm_dp_display_mode));1479 if (dp->is_edp)
1454 1480 msm_dp_hpd_unplug_handle(msm_dp_display);
1455 if (msm_dp_display_check_video_test(dp))
1456 msm_dp_display->msm_dp_mode.bpp = msm_dp_display_get_test_bpp(dp);
1457 else /* Default num_components per pixel = 3 */
1458 msm_dp_display->msm_dp_mode.bpp = dp->connector->display_info.bpc * 3;
1459
1460 if (!msm_dp_display->msm_dp_mode.bpp)
1461 msm_dp_display->msm_dp_mode.bpp = 24; /* Default bpp */
1462
1463 drm_mode_copy(&msm_dp_display->msm_dp_mode.drm_mode, adjusted_mode);
1464
1465 msm_dp_display->msm_dp_mode.v_active_low =
1466 !!(msm_dp_display->msm_dp_mode.drm_mode.flags & DRM_MODE_FLAG_NVSYNC);
1467 1481
1468 msm_dp_display->msm_dp_mode.h_active_low =1482 msm_dp_display_audio_notify_disable(msm_dp_display);
1469 !!(msm_dp_display->msm_dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);
1470 1483
1471 msm_dp_display->msm_dp_mode.out_fmt_is_yuv_420 =1484 msm_dp_display_disable(msm_dp_display, msm_dp_display->panel);
1472 drm_mode_is_420_only(&dp->connector->display_info, adjusted_mode) &&
1473 msm_dp_panel->vsc_sdp_supported;
1474 1485
1475 /* populate wide_bus_support to different layers */1486 msm_dp_display_unprepare(msm_dp_display);
1476 msm_dp_display->ctrl->wide_bus_en =
1477 msm_dp_display->msm_dp_mode.out_fmt_is_yuv_420 ? false : msm_dp_display->wide_bus_supported;
1478}1487}
1479 1488
1480void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge)1489void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge)
drivers/gpu/drm/msm/dp/dp_display.h+9−0
@@ -33,5 +33,14 @@ void msm_dp_display_signal_audio_start(struct msm_dp *msm_dp_display); · 32 unmodified lines
33void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display);33void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display);
34void msm_dp_display_set_psr(struct msm_dp *dp, bool enter);34void msm_dp_display_set_psr(struct msm_dp *dp, bool enter);
35void msm_dp_display_debugfs_init(struct msm_dp *msm_dp_display, struct dentry *dentry, bool is_edp);35void msm_dp_display_debugfs_init(struct msm_dp *msm_dp_display, struct dentry *dentry, bool is_edp);
36void msm_dp_display_atomic_post_disable(struct msm_dp *dp_display);
37void msm_dp_display_atomic_disable(struct msm_dp *dp_display);
38void msm_dp_display_atomic_pre_enable(struct msm_dp *dp_display,
39 struct drm_atomic_commit *state);
40void msm_dp_display_atomic_enable(struct msm_dp *dp_display,
41 struct drm_atomic_commit *state);
42enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
43 const struct drm_display_info *info,
44 const struct drm_display_mode *mode);
36 45
37#endif /* _DP_DISPLAY_H_ */46#endif /* _DP_DISPLAY_H_ */
drivers/gpu/drm/msm/dp/dp_drm.c+49−3
@@ -49,14 +49,60 @@ static void msm_dp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry · 48 unmodified lines
49 msm_dp_display_debugfs_init(dp, root, false);49 msm_dp_display_debugfs_init(dp, root, false);
50}50}
51 51
52static void msm_dp_bridge_atomic_pre_enable(struct drm_bridge *drm_bridge,
53 struct drm_atomic_commit *state)
54{
55 struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
56 struct msm_dp *dp = dp_bridge->msm_dp_display;
57
58 msm_dp_display_atomic_pre_enable(dp, state);
59}
60
61static void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
62 struct drm_atomic_commit *state)
63{
64 struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
65 struct msm_dp *dp = dp_bridge->msm_dp_display;
66
67 msm_dp_display_atomic_enable(dp, state);
68}
69
70static void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
71 struct drm_atomic_commit *state)
72{
73 struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
74 struct msm_dp *dp = dp_bridge->msm_dp_display;
75
76 msm_dp_display_atomic_disable(dp);
77}
78
79static void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
80 struct drm_atomic_commit *state)
81{
82 struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
83 struct msm_dp *dp = dp_bridge->msm_dp_display;
84
85 msm_dp_display_atomic_post_disable(dp);
86}
87
88static enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *drm_bridge,
89 const struct drm_display_info *info,
90 const struct drm_display_mode *mode)
91{
92 struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
93 struct msm_dp *dp = dp_bridge->msm_dp_display;
94
95 return msm_dp_display_mode_valid(dp, info, mode);
96}
97
52static const struct drm_bridge_funcs msm_dp_bridge_ops = {98static const struct drm_bridge_funcs msm_dp_bridge_ops = {
53 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,99 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
54 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,100 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
55 .atomic_create_state = drm_atomic_helper_bridge_create_state,101 .atomic_create_state = drm_atomic_helper_bridge_create_state,
102 .atomic_pre_enable = msm_dp_bridge_atomic_pre_enable,
56 .atomic_enable = msm_dp_bridge_atomic_enable,103 .atomic_enable = msm_dp_bridge_atomic_enable,
57 .atomic_disable = msm_dp_bridge_atomic_disable,104 .atomic_disable = msm_dp_bridge_atomic_disable,
58 .atomic_post_disable = msm_dp_bridge_atomic_post_disable,105 .atomic_post_disable = msm_dp_bridge_atomic_post_disable,
59 .mode_set = msm_dp_bridge_mode_set,
60 .mode_valid = msm_dp_bridge_mode_valid,106 .mode_valid = msm_dp_bridge_mode_valid,
61 .get_modes = msm_dp_bridge_get_modes,107 .get_modes = msm_dp_bridge_get_modes,
62 .detect = msm_dp_bridge_detect,108 .detect = msm_dp_bridge_detect,
@@ -116,7 +162,7 @@ static void msm_edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, · 53 unmodified lines
116 return;162 return;
117 }163 }
118 164
119 msm_dp_bridge_atomic_enable(drm_bridge, state);165 msm_dp_display_atomic_enable(dp, state);
120}166}
121 167
122static void msm_edp_bridge_atomic_disable(struct drm_bridge *drm_bridge,168static void msm_edp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
@@ -230,10 +276,10 @@ static void msm_edp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry · 107 unmodified lines
230}276}
231 277
232static const struct drm_bridge_funcs msm_edp_bridge_ops = {278static const struct drm_bridge_funcs msm_edp_bridge_ops = {
279 .atomic_pre_enable = msm_dp_bridge_atomic_pre_enable,
233 .atomic_enable = msm_edp_bridge_atomic_enable,280 .atomic_enable = msm_edp_bridge_atomic_enable,
234 .atomic_disable = msm_edp_bridge_atomic_disable,281 .atomic_disable = msm_edp_bridge_atomic_disable,
235 .atomic_post_disable = msm_edp_bridge_atomic_post_disable,282 .atomic_post_disable = msm_edp_bridge_atomic_post_disable,
236 .mode_set = msm_dp_bridge_mode_set,
237 .mode_valid = msm_edp_bridge_mode_valid,283 .mode_valid = msm_edp_bridge_mode_valid,
238 .atomic_create_state = drm_atomic_helper_bridge_create_state,284 .atomic_create_state = drm_atomic_helper_bridge_create_state,
239 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,285 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
drivers/gpu/drm/msm/dp/dp_drm.h+0−12
@@ -27,18 +27,6 @@ int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev, · 26 unmodified lines
27 27
28enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,28enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,
29 struct drm_connector *connector);29 struct drm_connector *connector);
30void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
31 struct drm_atomic_commit *state);
32void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
33 struct drm_atomic_commit *state);
34void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
35 struct drm_atomic_commit *state);
36enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *bridge,
37 const struct drm_display_info *info,
38 const struct drm_display_mode *mode);
39void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,
40 const struct drm_display_mode *mode,
41 const struct drm_display_mode *adjusted_mode);
42void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge);30void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge);
43void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge);31void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge);
44void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,32void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
drivers/gpu/drm/msm/dp/dp_panel.c+20−55
@@ -232,8 +232,8 @@ static u32 msm_dp_panel_get_supported_bpp(struct msm_dp_panel *msm_dp_panel, · 231 unmodified lines
232 return min_supported_bpp;232 return min_supported_bpp;
233}233}
234 234
235int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,235int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
236 struct drm_connector *connector)236 struct drm_connector *connector)
237{237{
238 int rc, bw_code;238 int rc, bw_code;
239 int count;239 int count;
@@ -271,36 +271,9 @@ int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel, · 31 unmodified lines
271 271
272 rc = drm_dp_read_downstream_info(panel->aux, msm_dp_panel->dpcd,272 rc = drm_dp_read_downstream_info(panel->aux, msm_dp_panel->dpcd,
273 msm_dp_panel->downstream_ports);273 msm_dp_panel->downstream_ports);
274 if (rc)
275 return rc;
276
277 drm_edid_free(msm_dp_panel->drm_edid);
278
279 msm_dp_panel->drm_edid = drm_edid_read_ddc(connector, &panel->aux->ddc);
280
281 drm_edid_connector_update(connector, msm_dp_panel->drm_edid);
282
283 if (!msm_dp_panel->drm_edid) {
284 DRM_ERROR("panel edid read failed\n");
285 /* check edid read fail is due to unplug */
286 if (!msm_dp_aux_is_link_connected(panel->aux)) {
287 rc = -ETIMEDOUT;
288 goto end;
289 }
290 }
291
292end:
293 return rc;274 return rc;
294}275}
295 276
296void msm_dp_panel_unplugged(struct msm_dp_panel *msm_dp_panel,
297 struct drm_connector *connector)
298{
299 drm_edid_connector_update(connector, NULL);
300 drm_edid_free(msm_dp_panel->drm_edid);
301 msm_dp_panel->drm_edid = NULL;
302}
303
304u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,277u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
305 u32 mode_edid_bpp, u32 mode_pclk_khz)278 u32 mode_edid_bpp, u32 mode_pclk_khz)
306{279{
@@ -324,20 +297,6 @@ u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, · 17 unmodified lines
324 return bpp;297 return bpp;
325}298}
326 299
327int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
328 struct drm_connector *connector)
329{
330 if (!msm_dp_panel) {
331 DRM_ERROR("invalid input\n");
332 return -EINVAL;
333 }
334
335 if (msm_dp_panel->drm_edid)
336 return drm_edid_connector_add_modes(connector);
337
338 return 0;
339}
340
341static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)300static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)
342{301{
343 edid += edid->extensions;302 edid += edid->extensions;
@@ -345,7 +304,8 @@ static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid) · 1 unmodified line
345 return edid->checksum;304 return edid->checksum;
346}305}
347 306
348void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)307void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel,
308 const struct drm_edid *drm_edid)
349{309{
350 struct msm_dp_panel_private *panel;310 struct msm_dp_panel_private *panel;
351 311
@@ -358,7 +318,7 @@ void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel) · 6 unmodified lines
358 318
359 if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) {319 if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) {
360 /* FIXME: get rid of drm_edid_raw() */320 /* FIXME: get rid of drm_edid_raw() */
361 const struct edid *edid = drm_edid_raw(msm_dp_panel->drm_edid);321 const struct edid *edid = drm_edid_raw(drm_edid);
362 u8 checksum;322 u8 checksum;
363 323
364 if (edid)324 if (edid)
@@ -687,15 +647,27 @@ int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel, bool wide_bus_en) · 322 unmodified lines
687 return 0;647 return 0;
688}648}
689 649
690int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel)650int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel,
651 const struct drm_display_mode *adjusted_mode,
652 u32 bpp)
691{653{
692 struct drm_display_mode *drm_mode;654 struct drm_display_mode *drm_mode;
693 struct msm_dp_panel_private *panel;655 struct msm_dp_panel_private *panel;
694 656
695 drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
696
697 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);657 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
698 658
659 drm_mode_copy(&msm_dp_panel->msm_dp_mode.drm_mode, adjusted_mode);
660 msm_dp_panel->msm_dp_mode.bpp = bpp;
661 msm_dp_panel->msm_dp_mode.v_active_low =
662 !!(adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC);
663 msm_dp_panel->msm_dp_mode.h_active_low =
664 !!(adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC);
665 msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 =
666 drm_mode_is_420_only(&msm_dp_panel->connector->display_info, adjusted_mode) &&
667 msm_dp_panel->vsc_sdp_supported;
668
669 drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
670
699 /*671 /*
700 * print resolution info as this is a result672 * print resolution info as this is a result
701 * of user initiated action of cable connection673 * of user initiated action of cable connection
@@ -755,10 +727,3 @@ struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux · 53 unmodified lines
755 return msm_dp_panel;727 return msm_dp_panel;
756}728}
757 729
758void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel)
759{
760 if (!msm_dp_panel)
761 return;
762
763 drm_edid_free(msm_dp_panel->drm_edid);
764}
drivers/gpu/drm/msm/dp/dp_panel.h+7−10
@@ -33,7 +33,6 @@ struct msm_dp_panel { · 32 unmodified lines
33 u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];33 u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
34 34
35 struct msm_dp_link_info link_info;35 struct msm_dp_link_info link_info;
36 const struct drm_edid *drm_edid;
37 struct drm_connector *connector;36 struct drm_connector *connector;
38 struct msm_dp_display_mode msm_dp_mode;37 struct msm_dp_display_mode msm_dp_mode;
39 struct msm_dp_panel_psr psr_cap;38 struct msm_dp_panel_psr psr_cap;
@@ -44,18 +43,17 @@ struct msm_dp_panel { · 4 unmodified lines
44 u32 max_bw_code;43 u32 max_bw_code;
45};44};
46 45
47int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel);46int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel,
47 const struct drm_display_mode *adjusted_mode,
48 u32 bpp);
48int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel);49int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel);
49int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel, bool wide_bus_en);50int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel, bool wide_bus_en);
50int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,51int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
51 struct drm_connector *connector);52 struct drm_connector *connector);
52void msm_dp_panel_unplugged(struct msm_dp_panel *msm_dp_panel,
53 struct drm_connector *connector);
54u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp,53u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp,
55 u32 mode_pclk_khz);54 u32 mode_pclk_khz);
56int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,55void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel,
57 struct drm_connector *connector);56 const struct drm_edid *drm_edid);
58void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel);
59void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable);57void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable);
60 58
61void msm_dp_panel_clear_dsc_dto(struct msm_dp_panel *msm_dp_panel);59void msm_dp_panel_clear_dsc_dto(struct msm_dp_panel *msm_dp_panel);
@@ -94,5 +92,4 @@ struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux · 32 unmodified lines
94 struct msm_dp_link *link,92 struct msm_dp_link *link,
95 void __iomem *link_base,93 void __iomem *link_base,
96 void __iomem *p0_base);94 void __iomem *p0_base);
97void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel);
98#endif /* _DP_PANEL_H_ */95#endif /* _DP_PANEL_H_ */
drivers/gpu/drm/msm/dp/dp_reg.h+2−0
@@ -149,8 +149,10 @@ · 148 unmodified lines
149#define DP_CONFIGURATION_CTRL_ENHANCED_FRAMING (0x00000040)149#define DP_CONFIGURATION_CTRL_ENHANCED_FRAMING (0x00000040)
150#define DP_CONFIGURATION_CTRL_SEND_VSC (0x00000080)150#define DP_CONFIGURATION_CTRL_SEND_VSC (0x00000080)
151#define DP_CONFIGURATION_CTRL_BPC (0x00000100)151#define DP_CONFIGURATION_CTRL_BPC (0x00000100)
152#define DP_CONFIGURATION_CTRL_BPC_MASK GENMASK(9, 8)
152#define DP_CONFIGURATION_CTRL_ASSR (0x00000400)153#define DP_CONFIGURATION_CTRL_ASSR (0x00000400)
153#define DP_CONFIGURATION_CTRL_RGB_YUV (0x00000800)154#define DP_CONFIGURATION_CTRL_RGB_YUV (0x00000800)
155#define DP_CONFIGURATION_CTRL_RGB_YUV_MASK GENMASK(12, 11)
154#define DP_CONFIGURATION_CTRL_LSCLK_DIV (0x00002000)156#define DP_CONFIGURATION_CTRL_LSCLK_DIV (0x00002000)
155#define DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT (0x04)157#define DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT (0x04)
156#define DP_CONFIGURATION_CTRL_BPC_SHIFT (0x08)158#define DP_CONFIGURATION_CTRL_BPC_SHIFT (0x08)
drivers/gpu/drm/msm/dsi/dsi_host.c+12−2
@@ -550,8 +550,6 @@ error: · 549 unmodified lines
550 550
551void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)551void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
552{552{
553 /* Drop the performance state vote */
554 dev_pm_opp_set_rate(&msm_host->pdev->dev, 0);
555 clk_disable_unprepare(msm_host->esc_clk);553 clk_disable_unprepare(msm_host->esc_clk);
556 clk_disable_unprepare(msm_host->pixel_clk);554 clk_disable_unprepare(msm_host->pixel_clk);
557 clk_disable_unprepare(msm_host->byte_intf_clk);555 clk_disable_unprepare(msm_host->byte_intf_clk);
@@ -671,12 +669,24 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) · 113 unmodified lines
671 669
672int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)670int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
673{671{
672 long rounded_byte_clk_rate;
673
674 if (!msm_host->mode) {674 if (!msm_host->mode) {
675 pr_err("%s: mode not set\n", __func__);675 pr_err("%s: mode not set\n", __func__);
676 return -EINVAL;676 return -EINVAL;
677 }677 }
678 678
679 dsi_calc_pclk(msm_host, is_bonded_dsi);679 dsi_calc_pclk(msm_host, is_bonded_dsi);
680
681 rounded_byte_clk_rate = clk_round_rate(msm_host->byte_clk,
682 msm_host->byte_clk_rate);
683 if (rounded_byte_clk_rate < 0) {
684 pr_err("%s: failed to round byte clock rate, %ld\n",
685 __func__, rounded_byte_clk_rate);
686 return rounded_byte_clk_rate;
687 }
688
689 msm_host->byte_clk_rate = rounded_byte_clk_rate;
680 msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);690 msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
681 return 0;691 return 0;
682}692}
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h+1−0
@@ -111,6 +111,7 @@ struct msm_dsi_phy { · 110 unmodified lines
111 struct msm_dsi_dphy_timing timing;111 struct msm_dsi_dphy_timing timing;
112 const struct msm_dsi_phy_cfg *cfg;112 const struct msm_dsi_phy_cfg *cfg;
113 void *tuning_cfg;113 void *tuning_cfg;
114 void *pll_data;
114 115
115 enum msm_dsi_phy_usecase usecase;116 enum msm_dsi_phy_usecase usecase;
116 bool regulator_ldo_mode;117 bool regulator_ldo_mode;
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c+16−2
@@ -426,8 +426,11 @@ static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll) · 425 unmodified lines
426 u32 data;426 u32 data;
427 427
428 spin_lock_irqsave(&pll->pll_enable_lock, flags);428 spin_lock_irqsave(&pll->pll_enable_lock, flags);
429 pll->pll_enable_cnt++;429 if (pll->pll_enable_cnt++) {
430 WARN_ON(pll->pll_enable_cnt == INT_MAX);430 spin_unlock_irqrestore(&pll->pll_enable_lock, flags);
431 WARN_ON(pll->pll_enable_cnt == INT_MAX);
432 return;
433 }
431 434
432 data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);435 data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
433 data |= DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB;436 data |= DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB;
@@ -873,6 +876,7 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) · 439 unmodified lines
873 spin_lock_init(&pll_7nm->pll_enable_lock);876 spin_lock_init(&pll_7nm->pll_enable_lock);
874 877
875 pll_7nm->phy = phy;878 pll_7nm->phy = phy;
879 phy->pll_data = pll_7nm;
876 880
877 ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);881 ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);
878 if (ret) {882 if (ret) {
@@ -961,8 +965,10 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, · 82 unmodified lines
961 u32 const delay_us = 5;965 u32 const delay_us = 5;
962 u32 const timeout_us = 1000;966 u32 const timeout_us = 1000;
963 struct msm_dsi_dphy_timing *timing = &phy->timing;967 struct msm_dsi_dphy_timing *timing = &phy->timing;
968 struct dsi_pll_7nm *pll = phy->pll_data;
964 void __iomem *base = phy->base;969 void __iomem *base = phy->base;
965 bool less_than_1500_mhz;970 bool less_than_1500_mhz;
971 unsigned long flags;
966 u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;972 u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;
967 u32 glbl_pemph_ctrl_0;973 u32 glbl_pemph_ctrl_0;
968 u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0;974 u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0;
@@ -1084,10 +1090,13 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, · 115 unmodified lines
1084 glbl_rescode_bot_ctrl = 0x3c;1090 glbl_rescode_bot_ctrl = 0x3c;
1085 }1091 }
1086 1092
1093 spin_lock_irqsave(&pll->pll_enable_lock, flags);
1094 pll->pll_enable_cnt = 1;
1087 /* de-assert digital and pll power down */1095 /* de-assert digital and pll power down */
1088 data = DSI_7nm_PHY_CMN_CTRL_0_DIGTOP_PWRDN_B |1096 data = DSI_7nm_PHY_CMN_CTRL_0_DIGTOP_PWRDN_B |
1089 DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB;1097 DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB;
1090 writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);1098 writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);
1099 spin_unlock_irqrestore(&pll->pll_enable_lock, flags);
1091 1100
1092 /* Assert PLL core reset */1101 /* Assert PLL core reset */
1093 writel(0x00, base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);1102 writel(0x00, base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);
@@ -1200,7 +1209,9 @@ static bool dsi_7nm_set_continuous_clock(struct msm_dsi_phy *phy, bool enable) · 106 unmodified lines
1200 1209
1201static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)1210static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)
1202{1211{
1212 struct dsi_pll_7nm *pll = phy->pll_data;
1203 void __iomem *base = phy->base;1213 void __iomem *base = phy->base;
1214 unsigned long flags;
1204 u32 data;1215 u32 data;
1205 1216
1206 DBG("");1217 DBG("");
@@ -1227,8 +1238,11 @@ static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy) · 20 unmodified lines
1227 writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);1238 writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);
1228 writel(0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0);1239 writel(0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0);
1229 1240
1241 spin_lock_irqsave(&pll->pll_enable_lock, flags);
1242 pll->pll_enable_cnt = 0;
1230 /* Turn off all PHY blocks */1243 /* Turn off all PHY blocks */
1231 writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_0);1244 writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_0);
1245 spin_unlock_irqrestore(&pll->pll_enable_lock, flags);
1232 1246
1233 /* make sure phy is turned off */1247 /* make sure phy is turned off */
1234 wmb();1248 wmb();
drivers/gpu/drm/msm/hdmi/hdmi.h+19−0
@@ -112,6 +112,25 @@ static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg) · 111 unmodified lines
112 return readl(hdmi->mmio + reg);112 return readl(hdmi->mmio + reg);
113}113}
114 114
115static inline void hdmi_clear_bits(struct hdmi *hdmi, u32 reg, u32 mask)
116{
117 u32 val;
118
119 val = hdmi_read(hdmi, reg);
120 val &= ~mask;
121 hdmi_write(hdmi, reg, val);
122}
123
124static inline void hdmi_update_bits(struct hdmi *hdmi, u32 reg, u32 mask, u32 data)
125{
126 u32 val;
127
128 val = hdmi_read(hdmi, reg);
129 val &= ~mask;
130 val |= data & mask;
131 hdmi_write(hdmi, reg, val);
132}
133
115static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg)134static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg)
116{135{
117 return readl(hdmi->qfprom_mmio + reg);136 return readl(hdmi->qfprom_mmio + reg);
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c+41−57
@@ -58,16 +58,13 @@ static int msm_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) · 57 unmodified lines
58{58{
59 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);59 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
60 struct hdmi *hdmi = hdmi_bridge->hdmi;60 struct hdmi *hdmi = hdmi_bridge->hdmi;
61 u32 val;
62 61
63 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);62 hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0,
64 val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND |63 HDMI_INFOFRAME_CTRL0_AVI_SEND |
65 HDMI_INFOFRAME_CTRL0_AVI_CONT);64 HDMI_INFOFRAME_CTRL0_AVI_CONT);
66 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
67 65
68 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);66 hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL1,
69 val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK;67 HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK);
70 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
71 68
72 return 0;69 return 0;
73}70}
@@ -76,18 +73,15 @@ static int msm_hdmi_bridge_clear_audio_infoframe(struct drm_bridge *bridge) · 2 unmodified lines
76{73{
77 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);74 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
78 struct hdmi *hdmi = hdmi_bridge->hdmi;75 struct hdmi *hdmi = hdmi_bridge->hdmi;
79 u32 val;
80 76
81 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);77 hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0,
82 val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |78 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
83 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |79 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
84 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |80 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
85 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE);81 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE);
86 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
87 82
88 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);83 hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL1,
89 val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK;84 HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK);
90 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
91 85
92 return 0;86 return 0;
93}87}
@@ -96,13 +90,11 @@ static int msm_hdmi_bridge_clear_spd_infoframe(struct drm_bridge *bridge) · 2 unmodified lines
96{90{
97 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);91 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
98 struct hdmi *hdmi = hdmi_bridge->hdmi;92 struct hdmi *hdmi = hdmi_bridge->hdmi;
99 u32 val;
100 93
101 val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);94 hdmi_clear_bits(hdmi, REG_HDMI_GEN_PKT_CTRL,
102 val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND |95 HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
103 HDMI_GEN_PKT_CTRL_GENERIC1_CONT |96 HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
104 HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK);97 HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK);
105 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
106 98
107 return 0;99 return 0;
108}100}
@@ -111,14 +103,12 @@ static int msm_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) · 2 unmodified lines
111{103{
112 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);104 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
113 struct hdmi *hdmi = hdmi_bridge->hdmi;105 struct hdmi *hdmi = hdmi_bridge->hdmi;
114 u32 val;
115 106
116 val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);107 hdmi_clear_bits(hdmi, REG_HDMI_GEN_PKT_CTRL,
117 val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND |108 HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
118 HDMI_GEN_PKT_CTRL_GENERIC0_CONT |109 HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
119 HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |110 HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
120 HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK);111 HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK);
121 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
122 112
123 return 0;113 return 0;
124}114}
@@ -129,7 +119,6 @@ static int msm_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, · 4 unmodified lines
129 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);119 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
130 struct hdmi *hdmi = hdmi_bridge->hdmi;120 struct hdmi *hdmi = hdmi_bridge->hdmi;
131 u32 buf[4] = {};121 u32 buf[4] = {};
132 u32 val;
133 int i;122 int i;
134 123
135 if (len != HDMI_INFOFRAME_SIZE(AVI) || len - 3 > sizeof(buf)) {124 if (len != HDMI_INFOFRAME_SIZE(AVI) || len - 3 > sizeof(buf)) {
@@ -153,15 +142,13 @@ static int msm_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, · 17 unmodified lines
153 for (i = 0; i < ARRAY_SIZE(buf); i++)142 for (i = 0; i < ARRAY_SIZE(buf); i++)
154 hdmi_write(hdmi, REG_HDMI_AVI_INFO(i), buf[i]);143 hdmi_write(hdmi, REG_HDMI_AVI_INFO(i), buf[i]);
155 144
156 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);145 hdmi_update_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0,
157 val |= HDMI_INFOFRAME_CTRL0_AVI_SEND |146 HDMI_INFOFRAME_CTRL0_AVI_SEND | HDMI_INFOFRAME_CTRL0_AVI_CONT,
158 HDMI_INFOFRAME_CTRL0_AVI_CONT;147 HDMI_INFOFRAME_CTRL0_AVI_SEND | HDMI_INFOFRAME_CTRL0_AVI_CONT);
159 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
160 148
161 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);149 hdmi_update_bits(hdmi, REG_HDMI_INFOFRAME_CTRL1,
162 val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK;150 HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK,
163 val |= HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER);151 HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER));
164 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
165 152
166 return 0;153 return 0;
167}154}
@@ -193,12 +180,11 @@ static int msm_hdmi_bridge_write_audio_infoframe(struct drm_bridge *bridge, · 25 unmodified lines
193 buffer[9] << 16 |180 buffer[9] << 16 |
194 buffer[10] << 24);181 buffer[10] << 24);
195 182
196 val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);183 val = HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
197 val |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |184 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
198 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |185 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
199 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |186 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
200 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;187 hdmi_update_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0, val, val);
201 hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
202 188
203 return 0;189 return 0;
204}190}
@@ -231,11 +217,10 @@ static int msm_hdmi_bridge_write_spd_infoframe(struct drm_bridge *bridge, · 26 unmodified lines
231 for (i = 0; i < ARRAY_SIZE(buf); i++)217 for (i = 0; i < ARRAY_SIZE(buf); i++)
232 hdmi_write(hdmi, REG_HDMI_GENERIC1(i), buf[i]);218 hdmi_write(hdmi, REG_HDMI_GENERIC1(i), buf[i]);
233 219
234 val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);220 val = HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
235 val |= HDMI_GEN_PKT_CTRL_GENERIC1_SEND |221 HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
236 HDMI_GEN_PKT_CTRL_GENERIC1_CONT |222 HDMI_GEN_PKT_CTRL_GENERIC1_LINE(SPD_IFRAME_LINE_NUMBER);
237 HDMI_GEN_PKT_CTRL_GENERIC1_LINE(SPD_IFRAME_LINE_NUMBER);223 hdmi_update_bits(hdmi, REG_HDMI_GEN_PKT_CTRL, val, val);
238 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
239 224
240 return 0;225 return 0;
241}226}
@@ -269,12 +254,11 @@ static int msm_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, · 27 unmodified lines
269 for (i = 0; i < ARRAY_SIZE(buf); i++)254 for (i = 0; i < ARRAY_SIZE(buf); i++)
270 hdmi_write(hdmi, REG_HDMI_GENERIC0(i), buf[i]);255 hdmi_write(hdmi, REG_HDMI_GENERIC0(i), buf[i]);
271 256
272 val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);257 val = HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
273 val |= HDMI_GEN_PKT_CTRL_GENERIC0_SEND |258 HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
274 HDMI_GEN_PKT_CTRL_GENERIC0_CONT |259 HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
275 HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |260 HDMI_GEN_PKT_CTRL_GENERIC0_LINE(VENSPEC_IFRAME_LINE_NUMBER);
276 HDMI_GEN_PKT_CTRL_GENERIC0_LINE(VENSPEC_IFRAME_LINE_NUMBER);261 hdmi_update_bits(hdmi, REG_HDMI_GEN_PKT_CTRL, val, val);
277 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
278 262
279 return 0;263 return 0;
280}264}
drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c+28−57
@@ -306,9 +306,9 @@ static int msm_reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 305 unmodified lines
306 HDMI_HDCP_DDC_CTRL_0_DISABLE);306 HDMI_HDCP_DDC_CTRL_0_DISABLE);
307 307
308 /* ACK the Failure to Clear it */308 /* ACK the Failure to Clear it */
309 reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_CTRL_1);309 hdmi_update_bits(hdmi, REG_HDMI_HDCP_DDC_CTRL_1,
310 reg_val |= HDMI_HDCP_DDC_CTRL_1_FAILED_ACK;310 HDMI_HDCP_DDC_CTRL_1_FAILED_ACK,
311 hdmi_write(hdmi, REG_HDMI_HDCP_DDC_CTRL_1, reg_val);311 HDMI_HDCP_DDC_CTRL_1_FAILED_ACK);
312 312
313 /* Check if the FAILURE got Cleared */313 /* Check if the FAILURE got Cleared */
314 reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_STATUS);314 reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_STATUS);
@@ -324,28 +324,22 @@ static int msm_reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 9 unmodified lines
324 DBG("Before: HDMI_DDC_SW_STATUS=0x%08x",324 DBG("Before: HDMI_DDC_SW_STATUS=0x%08x",
325 hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));325 hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
326 /* Reset HDMI DDC software status */326 /* Reset HDMI DDC software status */
327 reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);327 hdmi_update_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SW_STATUS_RESET,
328 reg_val |= HDMI_DDC_CTRL_SW_STATUS_RESET;328 HDMI_DDC_CTRL_SW_STATUS_RESET);
329 hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
330 329
331 rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);330 rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
332 331
333 reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);332 hdmi_clear_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SW_STATUS_RESET);
334 reg_val &= ~HDMI_DDC_CTRL_SW_STATUS_RESET;
335 hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
336 333
337 /* Reset HDMI DDC Controller */334 /* Reset HDMI DDC Controller */
338 reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);335 hdmi_update_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SOFT_RESET,
339 reg_val |= HDMI_DDC_CTRL_SOFT_RESET;336 HDMI_DDC_CTRL_SOFT_RESET);
340 hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
341 337
342 /* If previous msleep is aborted, skip this msleep */338 /* If previous msleep is aborted, skip this msleep */
343 if (!rc)339 if (!rc)
344 rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);340 rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
345 341
346 reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);342 hdmi_clear_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SOFT_RESET);
347 reg_val &= ~HDMI_DDC_CTRL_SOFT_RESET;
348 hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
349 DBG("After: HDMI_DDC_SW_STATUS=0x%08x",343 DBG("After: HDMI_DDC_SW_STATUS=0x%08x",
350 hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));344 hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
351 }345 }
@@ -399,7 +393,6 @@ static void msm_hdmi_hdcp_reauth_work(struct work_struct *work) · 47 unmodified lines
399 struct hdmi_hdcp_ctrl, hdcp_reauth_work);393 struct hdmi_hdcp_ctrl, hdcp_reauth_work);
400 struct hdmi *hdmi = hdcp_ctrl->hdmi;394 struct hdmi *hdmi = hdcp_ctrl->hdmi;
401 unsigned long flags;395 unsigned long flags;
402 u32 reg_val;
403 396
404 DBG("HDCP REAUTH WORK");397 DBG("HDCP REAUTH WORK");
405 /*398 /*
@@ -409,9 +402,7 @@ static void msm_hdmi_hdcp_reauth_work(struct work_struct *work) · 3 unmodified lines
409 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register402 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
410 */403 */
411 spin_lock_irqsave(&hdmi->reg_lock, flags);404 spin_lock_irqsave(&hdmi->reg_lock, flags);
412 reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);405 hdmi_clear_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE);
413 reg_val &= ~HDMI_HPD_CTRL_ENABLE;
414 hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
415 406
416 /* Disable HDCP interrupts */407 /* Disable HDCP interrupts */
417 hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL, 0);408 hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL, 0);
@@ -431,9 +422,8 @@ static void msm_hdmi_hdcp_reauth_work(struct work_struct *work) · 13 unmodified lines
431 422
432 /* Enable HPD circuitry */423 /* Enable HPD circuitry */
433 spin_lock_irqsave(&hdmi->reg_lock, flags);424 spin_lock_irqsave(&hdmi->reg_lock, flags);
434 reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);425 hdmi_update_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE,
435 reg_val |= HDMI_HPD_CTRL_ENABLE;426 HDMI_HPD_CTRL_ENABLE);
436 hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
437 spin_unlock_irqrestore(&hdmi->reg_lock, flags);427 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
438 428
439 /*429 /*
@@ -456,7 +446,6 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 16 unmodified lines
456{446{
457 struct hdmi *hdmi = hdcp_ctrl->hdmi;447 struct hdmi *hdmi = hdcp_ctrl->hdmi;
458 u32 link0_status;448 u32 link0_status;
459 u32 reg_val;
460 unsigned long flags;449 unsigned long flags;
461 int rc;450 int rc;
462 451
@@ -472,14 +461,11 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 9 unmodified lines
472 461
473 spin_lock_irqsave(&hdmi->reg_lock, flags);462 spin_lock_irqsave(&hdmi->reg_lock, flags);
474 /* disable HDMI Encrypt */463 /* disable HDMI Encrypt */
475 reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);464 hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
476 reg_val &= ~HDMI_CTRL_ENCRYPTED;
477 hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
478 465
479 /* Enabling Software DDC */466 /* Enabling Software DDC */
480 reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);467 hdmi_clear_bits(hdmi, REG_HDMI_DDC_ARBITRATION,
481 reg_val &= ~HDMI_DDC_ARBITRATION_HW_ARBITRATION;468 HDMI_DDC_ARBITRATION_HW_ARBITRATION);
482 hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);
483 spin_unlock_irqrestore(&hdmi->reg_lock, flags);469 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
484 470
485 /*471 /*
@@ -498,9 +484,8 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 12 unmodified lines
498 hdmi_write(hdmi, REG_HDMI_HDCP_ENTROPY_CTRL1, 0xF00DFACE);484 hdmi_write(hdmi, REG_HDMI_HDCP_ENTROPY_CTRL1, 0xF00DFACE);
499 485
500 /* Disable the RngCipher state */486 /* Disable the RngCipher state */
501 reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL);487 hdmi_clear_bits(hdmi, REG_HDMI_HDCP_DEBUG_CTRL,
502 reg_val &= ~HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER;488 HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER);
503 hdmi_write(hdmi, REG_HDMI_HDCP_DEBUG_CTRL, reg_val);
504 DBG("HDCP_DEBUG_CTRL=0x%08x",489 DBG("HDCP_DEBUG_CTRL=0x%08x",
505 hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL));490 hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL));
506 491
@@ -537,15 +522,12 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 30 unmodified lines
537static void msm_hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl)522static void msm_hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl)
538{523{
539 struct hdmi *hdmi = hdcp_ctrl->hdmi;524 struct hdmi *hdmi = hdcp_ctrl->hdmi;
540 u32 reg_val;
541 unsigned long flags;525 unsigned long flags;
542 526
543 DBG("hdcp auth failed, queue reauth work");527 DBG("hdcp auth failed, queue reauth work");
544 /* clear HDMI Encrypt */528 /* clear HDMI Encrypt */
545 spin_lock_irqsave(&hdmi->reg_lock, flags);529 spin_lock_irqsave(&hdmi->reg_lock, flags);
546 reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);530 hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
547 reg_val &= ~HDMI_CTRL_ENCRYPTED;
548 hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
549 spin_unlock_irqrestore(&hdmi->reg_lock, flags);531 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
550 532
551 hdcp_ctrl->hdcp_state = HDCP_STATE_AUTH_FAILED;533 hdcp_ctrl->hdcp_state = HDCP_STATE_AUTH_FAILED;
@@ -555,7 +537,6 @@ static void msm_hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 3 unmodified lines
555static void msm_hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl)537static void msm_hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl)
556{538{
557 struct hdmi *hdmi = hdcp_ctrl->hdmi;539 struct hdmi *hdmi = hdcp_ctrl->hdmi;
558 u32 reg_val;
559 unsigned long flags;540 unsigned long flags;
560 541
561 /*542 /*
@@ -563,16 +544,15 @@ static void msm_hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 1 unmodified line
563 * there is no Arbitration between software and hardware for DDC544 * there is no Arbitration between software and hardware for DDC
564 */545 */
565 spin_lock_irqsave(&hdmi->reg_lock, flags);546 spin_lock_irqsave(&hdmi->reg_lock, flags);
566 reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);547 hdmi_update_bits(hdmi, REG_HDMI_DDC_ARBITRATION,
567 reg_val |= HDMI_DDC_ARBITRATION_HW_ARBITRATION;548 HDMI_DDC_ARBITRATION_HW_ARBITRATION,
568 hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);549 HDMI_DDC_ARBITRATION_HW_ARBITRATION);
569 spin_unlock_irqrestore(&hdmi->reg_lock, flags);550 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
570 551
571 /* enable HDMI Encrypt */552 /* enable HDMI Encrypt */
572 spin_lock_irqsave(&hdmi->reg_lock, flags);553 spin_lock_irqsave(&hdmi->reg_lock, flags);
573 reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);554 hdmi_update_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED,
574 reg_val |= HDMI_CTRL_ENCRYPTED;555 HDMI_CTRL_ENCRYPTED);
575 hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
576 spin_unlock_irqrestore(&hdmi->reg_lock, flags);556 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
577 557
578 hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATED;558 hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATED;
@@ -1304,7 +1284,6 @@ end: · 725 unmodified lines
1304void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl)1284void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl)
1305{1285{
1306 struct hdmi *hdmi = hdcp_ctrl->hdmi;1286 struct hdmi *hdmi = hdcp_ctrl->hdmi;
1307 u32 reg_val;
1308 unsigned long flags;1287 unsigned long flags;
1309 1288
1310 if ((HDCP_STATE_INACTIVE != hdcp_ctrl->hdcp_state) ||1289 if ((HDCP_STATE_INACTIVE != hdcp_ctrl->hdcp_state) ||
@@ -1315,9 +1294,7 @@ void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 4 unmodified lines
1315 1294
1316 /* clear HDMI Encrypt */1295 /* clear HDMI Encrypt */
1317 spin_lock_irqsave(&hdmi->reg_lock, flags);1296 spin_lock_irqsave(&hdmi->reg_lock, flags);
1318 reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);1297 hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
1319 reg_val &= ~HDMI_CTRL_ENCRYPTED;
1320 hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
1321 spin_unlock_irqrestore(&hdmi->reg_lock, flags);1298 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
1322 1299
1323 hdcp_ctrl->auth_event = 0;1300 hdcp_ctrl->auth_event = 0;
@@ -1330,7 +1307,6 @@ void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 6 unmodified lines
1330{1307{
1331 struct hdmi *hdmi = hdcp_ctrl->hdmi;1308 struct hdmi *hdmi = hdcp_ctrl->hdmi;
1332 unsigned long flags;1309 unsigned long flags;
1333 u32 reg_val;
1334 1310
1335 if ((HDCP_STATE_INACTIVE == hdcp_ctrl->hdcp_state) ||1311 if ((HDCP_STATE_INACTIVE == hdcp_ctrl->hdcp_state) ||
1336 (HDCP_STATE_NO_AKSV == hdcp_ctrl->hdcp_state)) {1312 (HDCP_STATE_NO_AKSV == hdcp_ctrl->hdcp_state)) {
@@ -1345,9 +1321,7 @@ void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 8 unmodified lines
1345 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register1321 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
1346 */1322 */
1347 spin_lock_irqsave(&hdmi->reg_lock, flags);1323 spin_lock_irqsave(&hdmi->reg_lock, flags);
1348 reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);1324 hdmi_clear_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE);
1349 reg_val &= ~HDMI_HPD_CTRL_ENABLE;
1350 hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
1351 1325
1352 /*1326 /*
1353 * Disable HDCP interrupts.1327 * Disable HDCP interrupts.
@@ -1375,14 +1349,11 @@ void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 21 unmodified lines
1375 hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, 0);1349 hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, 0);
1376 1350
1377 spin_lock_irqsave(&hdmi->reg_lock, flags);1351 spin_lock_irqsave(&hdmi->reg_lock, flags);
1378 reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);1352 hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
1379 reg_val &= ~HDMI_CTRL_ENCRYPTED;
1380 hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
1381 1353
1382 /* Enable HPD circuitry */1354 /* Enable HPD circuitry */
1383 reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);1355 hdmi_update_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE,
1384 reg_val |= HDMI_HPD_CTRL_ENABLE;1356 HDMI_HPD_CTRL_ENABLE);
1385 hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
1386 spin_unlock_irqrestore(&hdmi->reg_lock, flags);1357 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
1387 1358
1388 hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;1359 hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
drivers/gpu/drm/msm/msm_drv.c+17−9
@@ -222,20 +222,21 @@ static void load_gpu(struct drm_device *dev) · 221 unmodified lines
222 */222 */
223struct drm_gpuvm *msm_context_vm(struct drm_device *dev, struct msm_context *ctx)223struct drm_gpuvm *msm_context_vm(struct drm_device *dev, struct msm_context *ctx)
224{224{
225 static DEFINE_MUTEX(init_lock);
226 struct msm_drm_private *priv = dev->dev_private;225 struct msm_drm_private *priv = dev->dev_private;
226 struct drm_gpuvm *vm = smp_load_acquire(&ctx->vm);
227 227
228 /* Once ctx->vm is created it is valid for the lifetime of the context: */228 /* Once ctx->vm is created it is valid for the lifetime of the context: */
229 if (ctx->vm)229 if (vm)
230 return ctx->vm;230 return vm;
231
232 guard(rwsem_write)(&ctx->ctxlock);
231 233
232 mutex_lock(&init_lock);
233 if (!ctx->vm) {234 if (!ctx->vm) {
234 ctx->vm = msm_gpu_create_private_vm(235 vm = msm_gpu_create_private_vm(
235 priv->gpu, current, !ctx->userspace_managed_vm);236 priv->gpu, current, !ctx->userspace_managed_vm);
236 237 if (!IS_ERR_OR_NULL(vm))
238 smp_store_release(&ctx->vm, vm);
237 }239 }
238 mutex_unlock(&init_lock);
239 240
240 return ctx->vm;241 return ctx->vm;
241}242}
@@ -250,7 +251,7 @@ static int context_init(struct drm_device *dev, struct drm_file *file) · 8 unmodified lines
250 return -ENOMEM;251 return -ENOMEM;
251 252
252 INIT_LIST_HEAD(&ctx->submitqueues);253 INIT_LIST_HEAD(&ctx->submitqueues);
253 rwlock_init(&ctx->queuelock);254 init_rwsem(&ctx->ctxlock);
254 255
255 kref_init(&ctx->ref);256 kref_init(&ctx->ref);
256 msm_submitqueue_init(dev, ctx);257 msm_submitqueue_init(dev, ctx);
@@ -422,10 +423,14 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev, · 165 unmodified lines
422{423{
423 struct msm_drm_private *priv = dev->dev_private;424 struct msm_drm_private *priv = dev->dev_private;
424 struct msm_context *ctx = file->driver_priv;425 struct msm_context *ctx = file->driver_priv;
426 struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
425 427
426 if (!priv->gpu)428 if (!priv->gpu)
427 return -EINVAL;429 return -EINVAL;
428 430
431 if (!vm)
432 return UERR(ENOMEM, dev, "no VM");
433
429 if (msm_context_is_vmbind(ctx))434 if (msm_context_is_vmbind(ctx))
430 return UERR(EINVAL, dev, "VM_BIND is enabled");435 return UERR(EINVAL, dev, "VM_BIND is enabled");
431 436
@@ -436,7 +441,7 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev, · 4 unmodified lines
436 * Don't pin the memory here - just get an address so that userspace can441 * Don't pin the memory here - just get an address so that userspace can
437 * be productive442 * be productive
438 */443 */
439 return msm_gem_get_iova(obj, msm_context_vm(dev, ctx), iova);444 return msm_gem_get_iova(obj, vm, iova);
440}445}
441 446
442static int msm_ioctl_gem_info_set_iova(struct drm_device *dev,447static int msm_ioctl_gem_info_set_iova(struct drm_device *dev,
@@ -450,6 +455,9 @@ static int msm_ioctl_gem_info_set_iova(struct drm_device *dev, · 7 unmodified lines
450 if (!priv->gpu)455 if (!priv->gpu)
451 return -EINVAL;456 return -EINVAL;
452 457
458 if (!vm)
459 return UERR(ENOMEM, dev, "no VM");
460
453 if (msm_context_is_vmbind(ctx))461 if (msm_context_is_vmbind(ctx))
454 return UERR(EINVAL, dev, "VM_BIND is enabled");462 return UERR(EINVAL, dev, "VM_BIND is enabled");
455 463
drivers/gpu/drm/msm/msm_drv.h+0−17
@@ -261,8 +261,6 @@ const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb); · 260 unmodified lines
261struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,261struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
262 struct drm_file *file, const struct drm_format_info *info,262 struct drm_file *file, const struct drm_format_info *info,
263 const struct drm_mode_fb_cmd2 *mode_cmd);263 const struct drm_mode_fb_cmd2 *mode_cmd);
264struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
265 int w, int h, int p, uint32_t format);
266 264
267#ifdef CONFIG_DRM_MSM_KMS_FBDEV265#ifdef CONFIG_DRM_MSM_KMS_FBDEV
268int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,266int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
@@ -356,8 +354,6 @@ void __exit msm_dp_unregister(void); · 87 unmodified lines
356int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,354int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
357 struct drm_encoder *encoder, bool yuv_supported);355 struct drm_encoder *encoder, bool yuv_supported);
358void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);356void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);
359bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,
360 const struct drm_display_mode *mode);
361bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,357bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
362 const struct drm_display_mode *mode);358 const struct drm_display_mode *mode);
363bool msm_dp_wide_bus_available(const struct msm_dp *dp_display);359bool msm_dp_wide_bus_available(const struct msm_dp *dp_display);
@@ -382,12 +378,6 @@ static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm · 18 unmodified lines
382{378{
383}379}
384 380
385static inline bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,
386 const struct drm_display_mode *mode)
387{
388 return false;
389}
390
391static inline bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,381static inline bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
392 const struct drm_display_mode *mode)382 const struct drm_display_mode *mode)
393{383{
@@ -503,13 +493,6 @@ void msm_hrtimer_work_init(struct msm_hrtimer_work *work, · 109 unmodified lines
503#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)493#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
504#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)494#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
505 495
506static inline int align_pitch(int width, int bpp)
507{
508 int bytespp = (bpp + 7) / 8;
509 /* adreno needs pitch aligned to 32 pixels: */
510 return bytespp * ALIGN(width, 32);
511}
512
513/* for the generated headers: */496/* for the generated headers: */
514#define INVALID_IDX(idx) ({BUG(); 0;})497#define INVALID_IDX(idx) ({BUG(); 0;})
515#define fui(x) ({BUG(); 0;})498#define fui(x) ({BUG(); 0;})
drivers/gpu/drm/msm/msm_fb.c+25−73
@@ -6,7 +6,6 @@ · 5 unmodified lines
6 6
7#include <drm/drm_crtc.h>7#include <drm/drm_crtc.h>
8#include <drm/drm_damage_helper.h>8#include <drm/drm_damage_helper.h>
9#include <drm/drm_file.h>
10#include <drm/drm_fourcc.h>9#include <drm/drm_fourcc.h>
11#include <drm/drm_framebuffer.h>10#include <drm/drm_framebuffer.h>
12#include <drm/drm_gem_framebuffer_helper.h>11#include <drm/drm_gem_framebuffer_helper.h>
@@ -29,10 +28,6 @@ struct msm_framebuffer { · 16 unmodified lines
29};28};
30#define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)29#define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
31 30
32static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
33 const struct drm_format_info *info,
34 const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
35
36static int msm_framebuffer_dirtyfb(struct drm_framebuffer *fb,31static int msm_framebuffer_dirtyfb(struct drm_framebuffer *fb,
37 struct drm_file *file_priv, unsigned int flags,32 struct drm_file *file_priv, unsigned int flags,
38 unsigned int color, struct drm_clip_rect *clips,33 unsigned int color, struct drm_clip_rect *clips,
@@ -139,39 +134,10 @@ const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb) · 100 unmodified lines
139 return msm_fb->format;134 return msm_fb->format;
140}135}
141 136
142struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,137static struct drm_framebuffer *
143 struct drm_file *file, const struct drm_format_info *info,138msm_framebuffer_init(struct drm_device *dev, const struct drm_format_info *info,
144 const struct drm_mode_fb_cmd2 *mode_cmd)139 const struct drm_mode_fb_cmd2 *mode_cmd,
145{140 struct drm_gem_object **bos)
146 struct drm_gem_object *bos[4] = {0};
147 struct drm_framebuffer *fb;
148 int ret, i, n = info->num_planes;
149
150 for (i = 0; i < n; i++) {
151 bos[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
152 if (!bos[i]) {
153 ret = -ENXIO;
154 goto out_unref;
155 }
156 }
157
158 fb = msm_framebuffer_init(dev, info, mode_cmd, bos);
159 if (IS_ERR(fb)) {
160 ret = PTR_ERR(fb);
161 goto out_unref;
162 }
163
164 return fb;
165
166out_unref:
167 for (i = 0; i < n; i++)
168 drm_gem_object_put(bos[i]);
169 return ERR_PTR(ret);
170}
171
172static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
173 const struct drm_format_info *info,
174 const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
175{141{
176 struct msm_drm_private *priv = dev->dev_private;142 struct msm_drm_private *priv = dev->dev_private;
177 struct msm_kms *kms = priv->kms;143 struct msm_kms *kms = priv->kms;
@@ -251,47 +217,33 @@ fail: · 73 unmodified lines
251 return ERR_PTR(ret);217 return ERR_PTR(ret);
252}218}
253 219
254struct drm_framebuffer *220struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
255msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format)221 struct drm_file *file,
222 const struct drm_format_info *info,
223 const struct drm_mode_fb_cmd2 *mode_cmd)
256{224{
257 struct drm_mode_fb_cmd2 mode_cmd = {225 struct drm_gem_object *bos[4] = {0};
258 .pixel_format = format,
259 .width = w,
260 .height = h,
261 .pitches = { p },
262 };
263 struct drm_gem_object *bo;
264 struct drm_framebuffer *fb;226 struct drm_framebuffer *fb;
265 int size;227 int ret, i, n = info->num_planes;
266
267 /* allocate backing bo */
268 size = mode_cmd.pitches[0] * mode_cmd.height;
269 DBG("allocating %d bytes for fb %d", size, dev->primary->index);
270 bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN);
271 if (IS_ERR(bo)) {
272 dev_warn(dev->dev, "could not allocate stolen bo\n");
273 /* try regular bo: */
274 bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC);
275 }
276 if (IS_ERR(bo)) {
277 DRM_DEV_ERROR(dev->dev, "failed to allocate buffer object\n");
278 return ERR_CAST(bo);
279 }
280 228
281 msm_gem_object_set_name(bo, "stolenfb");229 for (i = 0; i < n; i++) {
230 bos[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
231 if (!bos[i]) {
232 ret = -ENXIO;
233 goto out_unref;
234 }
235 }
282 236
283 fb = msm_framebuffer_init(dev,237 fb = msm_framebuffer_init(dev, info, mode_cmd, bos);
284 drm_get_format_info(dev, mode_cmd.pixel_format,
285 mode_cmd.modifier[0]),
286 &mode_cmd, &bo);
287 if (IS_ERR(fb)) {238 if (IS_ERR(fb)) {
288 DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");239 ret = PTR_ERR(fb);
289 /* note: if fb creation failed, we can't rely on fb destroy240 goto out_unref;
290 * to unref the bo:
291 */
292 drm_gem_object_put(bo);
293 return ERR_CAST(fb);
294 }241 }
295 242
296 return fb;243 return fb;
244
245out_unref:
246 for (i = 0; i < n; i++)
247 drm_gem_object_put(bos[i]);
248 return ERR_PTR(ret);
297}249}
drivers/gpu/drm/msm/msm_fbdev.c+61−25
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include <drm/drm_drv.h>9#include <drm/drm_drv.h>
10#include <drm/drm_crtc_helper.h>10#include <drm/drm_crtc_helper.h>
11#include <drm/drm_fb_helper.h>11#include <drm/drm_fb_helper.h>
12#include <drm/drm_file.h>
12#include <drm/drm_fourcc.h>13#include <drm/drm_fourcc.h>
13#include <drm/drm_framebuffer.h>14#include <drm/drm_framebuffer.h>
14#include <drm/drm_prime.h>15#include <drm/drm_prime.h>
@@ -40,17 +41,15 @@ static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) · 25 unmodified lines
40static void msm_fbdev_fb_destroy(struct fb_info *info)41static void msm_fbdev_fb_destroy(struct fb_info *info)
41{42{
42 struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;43 struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
43 struct drm_framebuffer *fb = helper->fb;44 struct drm_gem_object *bo = msm_framebuffer_bo(helper->fb, 0);
44 struct drm_gem_object *bo = msm_framebuffer_bo(fb, 0);
45 45
46 DBG();46 DBG();
47 47
48 drm_fb_helper_fini(helper);48 drm_fb_helper_fini(helper);
49 49
50 /* this will free the backing object */
51 msm_gem_put_vaddr(bo);50 msm_gem_put_vaddr(bo);
52 drm_framebuffer_remove(fb);
53 51
52 drm_client_buffer_delete(helper->buffer);
54 drm_client_release(&helper->client);53 drm_client_release(&helper->client);
55}54}
56 55
@@ -89,31 +88,54 @@ static const struct drm_fb_helper_funcs msm_fbdev_helper_funcs = { · 32 unmodified lines
89int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,88int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
90 struct drm_fb_helper_surface_size *sizes)89 struct drm_fb_helper_surface_size *sizes)
91{90{
92 struct drm_device *dev = helper->dev;91 struct drm_client_dev *client = &helper->client;
92 struct drm_device *dev = client->dev;
93 struct drm_file *file = client->file;
93 struct msm_drm_private *priv = dev->dev_private;94 struct msm_drm_private *priv = dev->dev_private;
94 struct fb_info *fbi = helper->info;95 struct fb_info *fbi = helper->info;
95 struct drm_framebuffer *fb = NULL;96 const struct drm_format_info *format;
97 u32 fourcc, pitch, handle;
98 u64 size;
96 struct drm_gem_object *bo;99 struct drm_gem_object *bo;
100 struct drm_client_buffer *buffer;
97 uint64_t paddr;101 uint64_t paddr;
98 uint32_t format;102 int ret;
99 int ret, pitch;
100
101 format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
102 103
103 DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,104 DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
104 sizes->surface_height, sizes->surface_bpp,105 sizes->surface_height, sizes->surface_bpp,
105 sizes->fb_width, sizes->fb_height);106 sizes->fb_width, sizes->fb_height);
106 107
107 pitch = align_pitch(sizes->surface_width, sizes->surface_bpp);108 fourcc = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
108 fb = msm_alloc_stolen_fb(dev, sizes->surface_width,109 format = drm_get_format_info(dev, fourcc, DRM_FORMAT_MOD_LINEAR);
109 sizes->surface_height, pitch, format);110 /* adreno needs pitch aligned to 32 pixels: */
110 111 pitch = drm_format_info_min_pitch(format, 0, ALIGN(sizes->surface_width, 32));
111 if (IS_ERR(fb)) {112 size = ALIGN(pitch * sizes->surface_height, PAGE_SIZE);
112 DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");113
113 return PTR_ERR(fb);114 /* allocate backing bo */
115 DBG("allocating %llu bytes for fb %d", size, dev->primary->index);
116 bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN, NULL);
117 if (IS_ERR(bo)) {
118 drm_warn(dev, "could not allocate stolen bo\n");
119 /* try regular bo: */
120 bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC, NULL);
121 if (IS_ERR(bo)) {
122 drm_err(dev, "failed to allocate buffer object\n");
123 return PTR_ERR(bo);
124 }
114 }125 }
115 126
116 bo = msm_framebuffer_bo(fb, 0);127 msm_gem_object_set_name(bo, "stolenfb");
128
129 ret = drm_gem_handle_create(file, bo, &handle);
130 if (ret)
131 goto err_drm_gem_object_put;
132
133 buffer = drm_client_buffer_create(client, sizes->surface_width, sizes->surface_height,
134 fourcc, handle, pitch);
135 if (IS_ERR(buffer)) {
136 ret = PTR_ERR(buffer);
137 goto err_drm_gem_handle_delete;
138 }
117 139
118 /*140 /*
119 * NOTE: if we can be guaranteed to be able to map buffer141 * NOTE: if we can be guaranteed to be able to map buffer
@@ -122,14 +144,15 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, · 2 unmodified lines
122 */144 */
123 ret = msm_gem_get_and_pin_iova(bo, priv->kms->vm, &paddr);145 ret = msm_gem_get_and_pin_iova(bo, priv->kms->vm, &paddr);
124 if (ret) {146 if (ret) {
125 DRM_DEV_ERROR(dev->dev, "failed to get buffer obj iova: %d\n", ret);147 drm_err(dev, "failed to get buffer obj iova: %d\n", ret);
126 goto fail;148 goto err_drm_client_buffer_delete;
127 }149 }
128 150
129 DBG("fbi=%p, dev=%p", fbi, dev);151 DBG("fbi=%p, dev=%p", fbi, dev);
130 152
131 helper->funcs = &msm_fbdev_helper_funcs;153 helper->funcs = &msm_fbdev_helper_funcs;
132 helper->fb = fb;154 helper->buffer = buffer;
155 helper->fb = buffer->fb;
133 156
134 fbi->fbops = &msm_fb_ops;157 fbi->fbops = &msm_fb_ops;
135 158
@@ -138,18 +161,31 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, · 2 unmodified lines
138 fbi->screen_buffer = msm_gem_get_vaddr(bo);161 fbi->screen_buffer = msm_gem_get_vaddr(bo);
139 if (IS_ERR(fbi->screen_buffer)) {162 if (IS_ERR(fbi->screen_buffer)) {
140 ret = PTR_ERR(fbi->screen_buffer);163 ret = PTR_ERR(fbi->screen_buffer);
141 goto fail;164 goto err_msm_gem_unpin;
142 }165 }
143 fbi->screen_size = bo->size;166 fbi->screen_size = bo->size;
144 fbi->fix.smem_start = paddr;167 fbi->fix.smem_start = paddr;
145 fbi->fix.smem_len = bo->size;168 fbi->fix.smem_len = bo->size;
146 169
147 DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);170 DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
148 DBG("allocated %dx%d fb", fb->width, fb->height);171 DBG("allocated %dx%d fb", buffer->fb->width, buffer->fb->height);
172
173 /* The handle is only needed for creating the framebuffer. */
174 drm_gem_handle_delete(file, handle);
175
176 /* The framebuffer still holds a reference on the GEM object. */
177 drm_gem_object_put(bo);
149 178
150 return 0;179 return 0;
151 180
152fail:181err_msm_gem_unpin:
153 drm_framebuffer_remove(fb);182 msm_gem_unpin_iova(bo, priv->kms->vm);
183 msm_gem_vma_put(bo);
184err_drm_client_buffer_delete:
185 drm_client_buffer_delete(buffer);
186err_drm_gem_handle_delete:
187 drm_gem_handle_delete(file, handle);
188err_drm_gem_object_put:
189 drm_gem_object_put(bo);
154 return ret;190 return ret;
155}191}
drivers/gpu/drm/msm/msm_gem.c+55−39
@@ -1093,7 +1093,9 @@ static void msm_gem_free_object(struct drm_gem_object *obj) · 1092 unmodified lines
1093 */1093 */
1094 kvfree(msm_obj->pages);1094 kvfree(msm_obj->pages);
1095 1095
1096 drm_prime_gem_destroy(obj, msm_obj->sgt);1096 /* In msm_gem_import() error path, sgt won't be set yet: */
1097 if (msm_obj->sgt)
1098 drm_prime_gem_destroy(obj, msm_obj->sgt);
1097 } else {1099 } else {
1098 msm_gem_vunmap(obj);1100 msm_gem_vunmap(obj);
1099 put_pages(obj);1101 put_pages(obj);
@@ -1134,10 +1136,21 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, · 34 unmodified lines
1134 size_t size, uint32_t flags, uint32_t *handle,1136 size_t size, uint32_t flags, uint32_t *handle,
1135 char *name)1137 char *name)
1136{1138{
1137 struct drm_gem_object *obj;1139 struct drm_gem_object *obj, *r_obj = NULL;
1138 int ret;1140 int ret;
1139 1141
1140 obj = msm_gem_new(dev, size, flags);1142 if (flags & MSM_BO_NO_SHARE) {
1143 struct msm_drm_private *priv = dev->dev_private;
1144 struct msm_context *ctx = file->driver_priv;
1145 struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
1146
1147 if (!priv->gpu || !vm)
1148 return UERR(EINVAL, dev, "not supported with shared VM");
1149
1150 r_obj = drm_gpuvm_resv_obj(vm);
1151 }
1152
1153 obj = msm_gem_new(dev, size, flags, r_obj);
1141 1154
1142 if (IS_ERR(obj))1155 if (IS_ERR(obj))
1143 return PTR_ERR(obj);1156 return PTR_ERR(obj);
@@ -1145,15 +1158,6 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, · 1 unmodified line
1145 if (name)1158 if (name)
1146 msm_gem_object_set_name(obj, "%s", name);1159 msm_gem_object_set_name(obj, "%s", name);
1147 1160
1148 if (flags & MSM_BO_NO_SHARE) {
1149 struct msm_context *ctx = file->driver_priv;
1150 struct drm_gem_object *r_obj = drm_gpuvm_resv_obj(ctx->vm);
1151
1152 drm_gem_object_get(r_obj);
1153
1154 obj->resv = r_obj->resv;
1155 }
1156
1157 ret = drm_gem_handle_create(file, obj, handle);1161 ret = drm_gem_handle_create(file, obj, handle);
1158 1162
1159 /* drop reference from allocate - handle holds it now */1163 /* drop reference from allocate - handle holds it now */
@@ -1232,10 +1236,27 @@ static int msm_gem_new_impl(struct drm_device *dev, uint32_t flags, · 72 unmodified lines
1232 return 0;1236 return 0;
1233}1237}
1234 1238
1235struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, uint32_t flags)1239static int msm_gem_init_bookkeeping(struct drm_gem_object *obj)
1240{
1241 struct msm_drm_private *priv = obj->dev->dev_private;
1242
1243 if (drm_gem_is_imported(obj)) {
1244 drm_gem_lru_move_tail(&priv->lru.pinned, obj);
1245 } else {
1246 drm_gem_lru_move_tail(&priv->lru.unbacked, obj);
1247 }
1248
1249 mutex_lock(&priv->obj_lock);
1250 list_add_tail(&to_msm_bo(obj)->node, &priv->objects);
1251 mutex_unlock(&priv->obj_lock);
1252
1253 return drm_gem_create_mmap_offset(obj);
1254}
1255
1256struct drm_gem_object *
1257msm_gem_new(struct drm_device *dev, size_t size, uint32_t flags,
1258 struct drm_gem_object *r_obj)
1236{1259{
1237 struct msm_drm_private *priv = dev->dev_private;
1238 struct msm_gem_object *msm_obj;
1239 struct drm_gem_object *obj = NULL;1260 struct drm_gem_object *obj = NULL;
1240 int ret;1261 int ret;
1241 1262
@@ -1251,7 +1272,10 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, uint32_t · 9 unmodified lines
1251 if (ret)1272 if (ret)
1252 return ERR_PTR(ret);1273 return ERR_PTR(ret);
1253 1274
1254 msm_obj = to_msm_bo(obj);1275 if (flags & MSM_BO_NO_SHARE) {
1276 drm_gem_object_get(r_obj);
1277 obj->resv = r_obj->resv;
1278 }
1255 1279
1256 ret = drm_gem_object_init(dev, obj, size);1280 ret = drm_gem_object_init(dev, obj, size);
1257 if (ret)1281 if (ret)
@@ -1264,13 +1288,7 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, uint32_t · 6 unmodified lines
1264 */1288 */
1265 mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER);1289 mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER);
1266 1290
1267 drm_gem_lru_move_tail(&priv->lru.unbacked, obj);1291 ret = msm_gem_init_bookkeeping(obj);
1268
1269 mutex_lock(&priv->obj_lock);
1270 list_add_tail(&msm_obj->node, &priv->objects);
1271 mutex_unlock(&priv->obj_lock);
1272
1273 ret = drm_gem_create_mmap_offset(obj);
1274 if (ret)1292 if (ret)
1275 goto fail;1293 goto fail;
1276 1294
@@ -1282,11 +1300,12 @@ fail: · 5 unmodified lines
1282}1300}
1283 1301
1284struct drm_gem_object *msm_gem_import(struct drm_device *dev,1302struct drm_gem_object *msm_gem_import(struct drm_device *dev,
1285 struct dma_buf *dmabuf, struct sg_table *sgt)1303 struct dma_buf_attachment *attach,
1304 struct sg_table *sgt)
1286{1305{
1287 struct msm_drm_private *priv = dev->dev_private;
1288 struct msm_gem_object *msm_obj;1306 struct msm_gem_object *msm_obj;
1289 struct drm_gem_object *obj;1307 struct drm_gem_object *obj;
1308 struct dma_buf *dmabuf = attach->dmabuf;
1290 size_t size, npages;1309 size_t size, npages;
1291 int ret;1310 int ret;
1292 1311
@@ -1296,38 +1315,35 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, · 3 unmodified lines
1296 if (ret)1315 if (ret)
1297 return ERR_PTR(ret);1316 return ERR_PTR(ret);
1298 1317
1318 /*
1319 * Set import_attach here in case we hit an error path that ends
1320 * up in drm_gem_object_put() -> msm_gem_free_object()
1321 */
1322 obj->import_attach = attach;
1323 obj->resv = dmabuf->resv;
1299 drm_gem_private_object_init(dev, obj, size);1324 drm_gem_private_object_init(dev, obj, size);
1300 1325
1301 npages = size / PAGE_SIZE;1326 npages = size / PAGE_SIZE;
1302 1327
1303 msm_obj = to_msm_bo(obj);1328 msm_obj = to_msm_bo(obj);
1304 msm_gem_lock(obj);
1305 msm_obj->sgt = sgt;
1306 msm_obj->pages = kvmalloc_objs(struct page *, npages);1329 msm_obj->pages = kvmalloc_objs(struct page *, npages);
1307 if (!msm_obj->pages) {1330 if (!msm_obj->pages) {
1308 msm_gem_unlock(obj);
1309 ret = -ENOMEM;1331 ret = -ENOMEM;
1310 goto fail;1332 goto fail;
1311 }1333 }
1312 1334
1313 ret = drm_prime_sg_to_page_array(sgt, msm_obj->pages, npages);1335 ret = drm_prime_sg_to_page_array(sgt, msm_obj->pages, npages);
1314 if (ret) {1336 if (ret) {
1315 msm_gem_unlock(obj);
1316 goto fail;1337 goto fail;
1317 }1338 }
1318 1339
1319 msm_gem_unlock(obj);1340 ret = msm_gem_init_bookkeeping(obj);
1320
1321 drm_gem_lru_move_tail(&priv->lru.pinned, obj);
1322
1323 mutex_lock(&priv->obj_lock);
1324 list_add_tail(&msm_obj->node, &priv->objects);
1325 mutex_unlock(&priv->obj_lock);
1326
1327 ret = drm_gem_create_mmap_offset(obj);
1328 if (ret)1341 if (ret)
1329 goto fail;1342 goto fail;
1330 1343
1344 /* Now that we are past potential failure points, set sgt: */
1345 msm_obj->sgt = sgt;
1346
1331 return obj;1347 return obj;
1332 1348
1333fail:1349fail:
@@ -1340,7 +1356,7 @@ void *msm_gem_kernel_new(struct drm_device *dev, size_t size, uint32_t flags, · 6 unmodified lines
1340 uint64_t *iova)1356 uint64_t *iova)
1341{1357{
1342 void *vaddr;1358 void *vaddr;
1343 struct drm_gem_object *obj = msm_gem_new(dev, size, flags);1359 struct drm_gem_object *obj = msm_gem_new(dev, size, flags, NULL);
1344 int ret;1360 int ret;
1345 1361
1346 if (IS_ERR(obj))1362 if (IS_ERR(obj))
drivers/gpu/drm/msm/msm_gem.h+3−2
@@ -296,13 +296,14 @@ int msm_gem_cpu_fini(struct drm_gem_object *obj); · 295 unmodified lines
296int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,296int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
297 size_t size, uint32_t flags, uint32_t *handle, char *name);297 size_t size, uint32_t flags, uint32_t *handle, char *name);
298struct drm_gem_object *msm_gem_new(struct drm_device *dev,298struct drm_gem_object *msm_gem_new(struct drm_device *dev,
299 size_t size, uint32_t flags);299 size_t size, uint32_t flags, struct drm_gem_object *r_obj);
300void *msm_gem_kernel_new(struct drm_device *dev, size_t size, uint32_t flags,300void *msm_gem_kernel_new(struct drm_device *dev, size_t size, uint32_t flags,
301 struct drm_gpuvm *vm, struct drm_gem_object **bo,301 struct drm_gpuvm *vm, struct drm_gem_object **bo,
302 uint64_t *iova);302 uint64_t *iova);
303void msm_gem_kernel_put(struct drm_gem_object *bo, struct drm_gpuvm *vm);303void msm_gem_kernel_put(struct drm_gem_object *bo, struct drm_gpuvm *vm);
304struct drm_gem_object *msm_gem_import(struct drm_device *dev,304struct drm_gem_object *msm_gem_import(struct drm_device *dev,
305 struct dma_buf *dmabuf, struct sg_table *sgt);305 struct dma_buf_attachment *attach,
306 struct sg_table *sgt);
306__printf(2, 3)307__printf(2, 3)
307void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...);308void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...);
308 309
drivers/gpu/drm/msm/msm_gem_prime.c+1−1
@@ -83,7 +83,7 @@ struct drm_gem_object *msm_gem_prime_import(struct drm_device *dev, · 82 unmodified lines
83struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,83struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
84 struct dma_buf_attachment *attach, struct sg_table *sg)84 struct dma_buf_attachment *attach, struct sg_table *sg)
85{85{
86 return msm_gem_import(dev, attach->dmabuf, sg);86 return msm_gem_import(dev, attach, sg);
87}87}
88 88
89struct dma_buf *msm_gem_prime_export(struct drm_gem_object *obj, int flags)89struct dma_buf *msm_gem_prime_export(struct drm_gem_object *obj, int flags)
drivers/gpu/drm/msm/msm_gem_submit.c+14−17
@@ -30,20 +30,17 @@ · 29 unmodified lines
30 */30 */
31 31
32static struct msm_gem_submit *submit_create(struct drm_device *dev,32static struct msm_gem_submit *submit_create(struct drm_device *dev,
33 struct msm_gpu *gpu,33 struct msm_gpu *gpu, struct drm_gpuvm *vm,
34 struct msm_gpu_submitqueue *queue, uint32_t nr_bos,34 struct msm_gpu_submitqueue *queue, uint32_t nr_bos,
35 uint32_t nr_cmds, u64 drm_client_id)35 uint32_t nr_cmds, u64 drm_client_id)
36{36{
37 static atomic_t ident = ATOMIC_INIT(0);37 static atomic_t ident = ATOMIC_INIT(0);
38 struct msm_gem_submit *submit;38 struct msm_gem_submit *submit;
39 uint64_t sz;39 size_t sz;
40 int ret;40 int ret;
41 41
42 sz = struct_size(submit, bos, nr_bos) +42 sz = size_add(struct_size(submit, bos, nr_bos),
43 ((u64)nr_cmds * sizeof(submit->cmd[0]));43 array_size(sizeof(submit->cmd[0]), nr_cmds));
44
45 if (sz > SIZE_MAX)
46 return ERR_PTR(-ENOMEM);
47 44
48 submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN);45 submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN);
49 if (!submit)46 if (!submit)
@@ -66,7 +63,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, · 16 unmodified lines
66 63
67 kref_init(&submit->ref);64 kref_init(&submit->ref);
68 submit->dev = dev;65 submit->dev = dev;
69 submit->vm = msm_context_vm(dev, queue->ctx);66 submit->vm = vm;
70 submit->gpu = gpu;67 submit->gpu = gpu;
71 submit->cmd = (void *)&submit->bos[nr_bos];68 submit->cmd = (void *)&submit->bos[nr_bos];
72 submit->queue = queue;69 submit->queue = queue;
@@ -250,16 +247,14 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, · 177 unmodified lines
250 247
251 sz = array_size(submit_cmd.nr_relocs,248 sz = array_size(submit_cmd.nr_relocs,
252 sizeof(struct drm_msm_gem_submit_reloc));249 sizeof(struct drm_msm_gem_submit_reloc));
253 /* check for overflow: */
254 if (sz == SIZE_MAX) {
255 ret = -ENOMEM;
256 goto out;
257 }
258 submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN);250 submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN);
259 if (!submit->cmd[i].relocs) {251 if (!submit->cmd[i].relocs) {
260 ret = -ENOMEM;252 ret = -ENOMEM;
261 goto out;253 goto out;
262 }254 }
255
256 submit->nr_cmds = i + 1;
257
263 ret = copy_from_user(submit->cmd[i].relocs, userptr, sz);258 ret = copy_from_user(submit->cmd[i].relocs, userptr, sz);
264 if (ret) {259 if (ret) {
265 ret = -EFAULT;260 ret = -EFAULT;
@@ -554,6 +549,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 288 unmodified lines
554 struct msm_drm_private *priv = dev->dev_private;549 struct msm_drm_private *priv = dev->dev_private;
555 struct drm_msm_gem_submit *args = data;550 struct drm_msm_gem_submit *args = data;
556 struct msm_context *ctx = file->driver_priv;551 struct msm_context *ctx = file->driver_priv;
552 struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
557 struct msm_gem_submit *submit = NULL;553 struct msm_gem_submit *submit = NULL;
558 struct msm_gpu *gpu = priv->gpu;554 struct msm_gpu *gpu = priv->gpu;
559 struct msm_gpu_submitqueue *queue;555 struct msm_gpu_submitqueue *queue;
@@ -569,10 +565,13 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 9 unmodified lines
569 if (!gpu)565 if (!gpu)
570 return -ENXIO;566 return -ENXIO;
571 567
568 if (!vm)
569 return UERR(ENOMEM, dev, "no VM");
570
572 if (args->pad)571 if (args->pad)
573 return -EINVAL;572 return -EINVAL;
574 573
575 if (to_msm_vm(ctx->vm)->unusable)574 if (to_msm_vm(vm)->unusable)
576 return UERR(EPIPE, dev, "context is unusable");575 return UERR(EPIPE, dev, "context is unusable");
577 576
578 /* for now, we just have 3d pipe.. eventually this would need to577 /* for now, we just have 3d pipe.. eventually this would need to
@@ -609,7 +608,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 30 unmodified lines
609 }608 }
610 }609 }
611 610
612 submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds,611 submit = submit_create(dev, gpu, vm, queue, args->nr_bos, args->nr_cmds,
613 file->client_id);612 file->client_id);
614 if (IS_ERR(submit)) {613 if (IS_ERR(submit)) {
615 ret = PTR_ERR(submit);614 ret = PTR_ERR(submit);
@@ -719,8 +718,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 103 unmodified lines
719 goto out;718 goto out;
720 }719 }
721 720
722 submit->nr_cmds = args->nr_cmds;
723
724 idr_preload(GFP_KERNEL);721 idr_preload(GFP_KERNEL);
725 722
726 spin_lock(&queue->idr_lock);723 spin_lock(&queue->idr_lock);
drivers/gpu/drm/msm/msm_gem_vma.c+10−4
@@ -458,6 +458,8 @@ msm_gem_vm_bo_validate(struct drm_gpuvm_bo *vm_bo, struct drm_exec *exec) · 457 unmodified lines
458 return ret;458 return ret;
459 }459 }
460 460
461 drm_gpuvm_bo_evict(vm_bo, false);
462
461 return 0;463 return 0;
462}464}
463 465
@@ -955,7 +957,7 @@ msm_gem_vm_close(struct drm_gpuvm *gpuvm) · 491 unmodified lines
955 957
956 958
957static struct msm_vm_bind_job *959static struct msm_vm_bind_job *
958vm_bind_job_create(struct drm_device *dev, struct drm_file *file,960vm_bind_job_create(struct drm_device *dev, struct drm_file *file, struct drm_gpuvm *vm,
959 struct msm_gpu_submitqueue *queue, uint32_t nr_ops)961 struct msm_gpu_submitqueue *queue, uint32_t nr_ops)
960{962{
961 struct msm_vm_bind_job *job;963 struct msm_vm_bind_job *job;
@@ -972,7 +974,7 @@ vm_bind_job_create(struct drm_device *dev, struct drm_file *file, · 10 unmodified lines
972 return ERR_PTR(ret);974 return ERR_PTR(ret);
973 }975 }
974 976
975 job->vm = msm_context_vm(dev, queue->ctx);977 job->vm = vm;
976 job->queue = queue;978 job->queue = queue;
977 INIT_LIST_HEAD(&job->vm_ops);979 INIT_LIST_HEAD(&job->vm_ops);
978 980
@@ -1431,6 +1433,7 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file) · 452 unmodified lines
1431 struct msm_drm_private *priv = dev->dev_private;1433 struct msm_drm_private *priv = dev->dev_private;
1432 struct drm_msm_vm_bind *args = data;1434 struct drm_msm_vm_bind *args = data;
1433 struct msm_context *ctx = file->driver_priv;1435 struct msm_context *ctx = file->driver_priv;
1436 struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
1434 struct msm_vm_bind_job *job = NULL;1437 struct msm_vm_bind_job *job = NULL;
1435 struct msm_gpu *gpu = priv->gpu;1438 struct msm_gpu *gpu = priv->gpu;
1436 struct msm_gpu_submitqueue *queue;1439 struct msm_gpu_submitqueue *queue;
@@ -1445,11 +1448,14 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file) · 8 unmodified lines
1445 if (!gpu)1448 if (!gpu)
1446 return -ENXIO;1449 return -ENXIO;
1447 1450
1451 if (!vm)
1452 return UERR(ENOMEM, dev, "no VM");
1453
1448 /*1454 /*
1449 * Maybe we could allow just UNMAP ops? OTOH userspace should just1455 * Maybe we could allow just UNMAP ops? OTOH userspace should just
1450 * immediately close the device file and all will be torn down.1456 * immediately close the device file and all will be torn down.
1451 */1457 */
1452 if (to_msm_vm(msm_context_vm(dev, ctx))->unusable)1458 if (to_msm_vm(vm)->unusable)
1453 return UERR(EPIPE, dev, "context is unusable");1459 return UERR(EPIPE, dev, "context is unusable");
1454 1460
1455 /*1461 /*
@@ -1480,7 +1486,7 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file) · 24 unmodified lines
1480 }1486 }
1481 }1487 }
1482 1488
1483 job = vm_bind_job_create(dev, file, queue, args->nr_ops);1489 job = vm_bind_job_create(dev, file, vm, queue, args->nr_ops);
1484 if (IS_ERR(job)) {1490 if (IS_ERR(job)) {
1485 ret = PTR_ERR(job);1491 ret = PTR_ERR(job);
1486 goto out_post_unlock;1492 goto out_post_unlock;
drivers/gpu/drm/msm/msm_gpu.c+7−3
@@ -505,6 +505,8 @@ static void recover_worker(struct kthread_work *work) · 504 unmodified lines
505 */505 */
506 if (!vm->managed)506 if (!vm->managed)
507 msm_gem_vm_unusable(submit->vm);507 msm_gem_vm_unusable(submit->vm);
508
509 put_task_struct(task);
508 }510 }
509 511
510 noreclaim_flag = memalloc_noreclaim_save();512 noreclaim_flag = memalloc_noreclaim_save();
@@ -552,11 +554,13 @@ static void recover_worker(struct kthread_work *work) · 41 unmodified lines
552 msm_update_fence(ring->fctx, fence);554 msm_update_fence(ring->fctx, fence);
553 }555 }
554 556
555 /* retire completed submits, plus the one that hung: */557 priv->disable_err_irq = false;
556 retire_submits(gpu);
557 558
558 gpu->funcs->recover(gpu);559 gpu->funcs->recover(gpu);
559 560
561 /* retire completed submits, plus the one that hung: */
562 retire_submits(gpu);
563
560 /*564 /*
561 * Replay all remaining submits starting with highest priority565 * Replay all remaining submits starting with highest priority
562 * ring566 * ring
@@ -875,7 +879,7 @@ msm_gpu_create_private_vm(struct msm_gpu *gpu, struct task_struct *task, · 312 unmodified lines
875 to_msm_vm(vm)->pid = get_pid(task_pid(task));879 to_msm_vm(vm)->pid = get_pid(task_pid(task));
876 }880 }
877 881
878 if (IS_ERR_OR_NULL(vm))882 if (IS_ERR_OR_NULL(vm) && kernel_managed)
879 vm = drm_gpuvm_get(gpu->vm);883 vm = drm_gpuvm_get(gpu->vm);
880 884
881 return vm;885 return vm;
drivers/gpu/drm/msm/msm_gpu.h+2−2
@@ -392,8 +392,8 @@ msm_gpu_sysprof_no_ifpc(struct msm_gpu *gpu) · 391 unmodified lines
392 * struct msm_context - per-drm_file context392 * struct msm_context - per-drm_file context
393 */393 */
394struct msm_context {394struct msm_context {
395 /** @queuelock: synchronizes access to submitqueues list */395 /** @ctxlock: synchronizes access to submitqueues list, etc */
396 rwlock_t queuelock;396 struct rw_semaphore ctxlock;
397 /** @submitqueues: list of &msm_gpu_submitqueue created by userspace */397 /** @submitqueues: list of &msm_gpu_submitqueue created by userspace */
398 struct list_head submitqueues;398 struct list_head submitqueues;
399 /**399 /**
drivers/gpu/drm/msm/msm_iommu.c+22−0
@@ -7,6 +7,15 @@ · 6 unmodified lines
7#include <linux/adreno-smmu-priv.h>7#include <linux/adreno-smmu-priv.h>
8#include <linux/io-pgtable.h>8#include <linux/io-pgtable.h>
9#include <linux/kmemleak.h>9#include <linux/kmemleak.h>
10
11#if defined(CONFIG_ARM_DMA_USE_IOMMU)
12#include <asm/dma-iommu.h>
13#else
14#define arm_iommu_detach_device(...) ({ })
15#define arm_iommu_release_mapping(...) ({ })
16#define to_dma_iommu_mapping(dev) NULL
17#endif
18
10#include "msm_drv.h"19#include "msm_drv.h"
11#include "msm_gpu_trace.h"20#include "msm_gpu_trace.h"
12#include "msm_mmu.h"21#include "msm_mmu.h"
@@ -749,6 +758,19 @@ struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks) · 736 unmodified lines
749 758
750 mutex_init(&iommu->init_lock);759 mutex_init(&iommu->init_lock);
751 760
761 /*
762 * ARM32 attaches a DMA mapping domain to every IOMMU-backed device,
763 * which would make attaching our own domain fail with -EBUSY.
764 */
765 if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
766 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
767
768 if (mapping) {
769 arm_iommu_detach_device(dev);
770 arm_iommu_release_mapping(mapping);
771 }
772 }
773
752 ret = iommu_attach_device(iommu->domain, dev);774 ret = iommu_attach_device(iommu->domain, dev);
753 if (ret) {775 if (ret) {
754 iommu_domain_free(domain);776 iommu_domain_free(domain);
drivers/gpu/drm/msm/msm_ringbuffer.c+4−3
@@ -109,9 +109,9 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, · 108 unmodified lines
109 ring->memptrs_iova = memptrs_iova;109 ring->memptrs_iova = memptrs_iova;
110 110
111 ret = drm_sched_init(&ring->sched, &args);111 ret = drm_sched_init(&ring->sched, &args);
112 if (ret) {112 if (ret)
113 goto fail;113 goto fail;
114 }114 ring->sched_initialized = true;
115 115
116 INIT_LIST_HEAD(&ring->submits);116 INIT_LIST_HEAD(&ring->submits);
117 spin_lock_init(&ring->submit_lock);117 spin_lock_init(&ring->submit_lock);
@@ -133,7 +133,8 @@ void msm_ringbuffer_destroy(struct msm_ringbuffer *ring) · 15 unmodified lines
133 if (IS_ERR_OR_NULL(ring))133 if (IS_ERR_OR_NULL(ring))
134 return;134 return;
135 135
136 drm_sched_fini(&ring->sched);136 if (ring->sched_initialized)
137 drm_sched_fini(&ring->sched);
137 138
138 msm_fence_context_free(ring->fctx);139 msm_fence_context_free(ring->fctx);
139 140
drivers/gpu/drm/msm/msm_ringbuffer.h+1−0
@@ -56,6 +56,7 @@ struct msm_ringbuffer { · 55 unmodified lines
56 * The job scheduler for this ring.56 * The job scheduler for this ring.
57 */57 */
58 struct drm_gpu_scheduler sched;58 struct drm_gpu_scheduler sched;
59 bool sched_initialized;
59 60
60 /*61 /*
61 * List of in-flight submits on this ring. Protected by submit_lock.62 * List of in-flight submits on this ring. Protected by submit_lock.
drivers/gpu/drm/msm/msm_submitqueue.c+12−12
@@ -9,6 +9,8 @@ · 8 unmodified lines
9 9
10int msm_context_set_sysprof(struct msm_context *ctx, struct msm_gpu *gpu, int sysprof)10int msm_context_set_sysprof(struct msm_context *ctx, struct msm_gpu *gpu, int sysprof)
11{11{
12 guard(rwsem_write)(&ctx->ctxlock);
13
12 /*14 /*
13 * Since pm_runtime and sysprof_active are both refcounts, we15 * Since pm_runtime and sysprof_active are both refcounts, we
14 * call apply the new value first, and then unwind the previous16 * call apply the new value first, and then unwind the previous
@@ -93,18 +95,15 @@ struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_context *ctx, · 78 unmodified lines
93 if (!ctx)95 if (!ctx)
94 return NULL;96 return NULL;
95 97
96 read_lock(&ctx->queuelock);98 guard(rwsem_read)(&ctx->ctxlock);
97 99
98 list_for_each_entry(entry, &ctx->submitqueues, node) {100 list_for_each_entry(entry, &ctx->submitqueues, node) {
99 if (entry->id == id) {101 if (entry->id == id) {
100 kref_get(&entry->ref);102 kref_get(&entry->ref);
101 read_unlock(&ctx->queuelock);
102
103 return entry;103 return entry;
104 }104 }
105 }105 }
106 106
107 read_unlock(&ctx->queuelock);
108 return NULL;107 return NULL;
109}108}
110 109
@@ -175,6 +174,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 64 unmodified lines
175 struct msm_drm_private *priv = drm->dev_private;174 struct msm_drm_private *priv = drm->dev_private;
176 struct msm_gpu_submitqueue *queue;175 struct msm_gpu_submitqueue *queue;
177 enum drm_sched_priority sched_prio;176 enum drm_sched_priority sched_prio;
177 struct drm_gpuvm *vm = NULL;
178 unsigned ring_nr;178 unsigned ring_nr;
179 int ret;179 int ret;
180 180
@@ -187,6 +187,11 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 6 unmodified lines
187 if (flags & MSM_SUBMITQUEUE_VM_BIND) {187 if (flags & MSM_SUBMITQUEUE_VM_BIND) {
188 unsigned sz;188 unsigned sz;
189 189
190 vm = msm_context_vm(drm, ctx);
191
192 if (!vm)
193 return UERR(ENOMEM, drm, "no VM");
194
190 /* Not allowed for kernel managed VMs (ie. kernel allocs VA) */195 /* Not allowed for kernel managed VMs (ie. kernel allocs VA) */
191 if (!msm_context_is_vmbind(ctx))196 if (!msm_context_is_vmbind(ctx))
192 return -EINVAL;197 return -EINVAL;
@@ -218,7 +223,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 25 unmodified lines
218 queue->flags = flags;223 queue->flags = flags;
219 224
220 if (flags & MSM_SUBMITQUEUE_VM_BIND) {225 if (flags & MSM_SUBMITQUEUE_VM_BIND) {
221 struct drm_gpu_scheduler *sched = &to_msm_vm(msm_context_vm(drm, ctx))->sched;226 struct drm_gpu_scheduler *sched = &to_msm_vm(vm)->sched;
222 227
223 queue->entity = &queue->_vm_bind_entity[0];228 queue->entity = &queue->_vm_bind_entity[0];
224 229
@@ -237,7 +242,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 12 unmodified lines
237 return ret;242 return ret;
238 }243 }
239 244
240 write_lock(&ctx->queuelock);245 guard(rwsem_write)(&ctx->ctxlock);
241 246
242 queue->ctx = msm_context_get(ctx);247 queue->ctx = msm_context_get(ctx);
243 queue->id = ctx->queueid++;248 queue->id = ctx->queueid++;
@@ -251,8 +256,6 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 7 unmodified lines
251 256
252 list_add_tail(&queue->node, &ctx->submitqueues);257 list_add_tail(&queue->node, &ctx->submitqueues);
253 258
254 write_unlock(&ctx->queuelock);
255
256 return 0;259 return 0;
257}260}
258 261
@@ -335,19 +338,16 @@ int msm_submitqueue_remove(struct msm_context *ctx, u32 id) · 76 unmodified lines
335 if (!id)338 if (!id)
336 return -ENOENT;339 return -ENOENT;
337 340
338 write_lock(&ctx->queuelock);341 guard(rwsem_write)(&ctx->ctxlock);
339 342
340 list_for_each_entry(entry, &ctx->submitqueues, node) {343 list_for_each_entry(entry, &ctx->submitqueues, node) {
341 if (entry->id == id) {344 if (entry->id == id) {
342 list_del(&entry->node);345 list_del(&entry->node);
343 write_unlock(&ctx->queuelock);
344
345 msm_submitqueue_put(entry);346 msm_submitqueue_put(entry);
346 return 0;347 return 0;
347 }348 }
348 }349 }
349 350
350 write_unlock(&ctx->queuelock);
351 return -ENOENT;351 return -ENOENT;
352}352}
353 353
drivers/gpu/drm/msm/registers/adreno/a3xx.xml+2−0
@@ -1495,6 +1495,8 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd"> · 1494 unmodified lines
1495 <reg32 offset="0x3058" name="VBIF_OUT_AXI_AMEMTYPE_CONF0"/>1495 <reg32 offset="0x3058" name="VBIF_OUT_AXI_AMEMTYPE_CONF0"/>
1496 <reg32 offset="0x305e" name="VBIF_OUT_AXI_AOOO_EN"/>1496 <reg32 offset="0x305e" name="VBIF_OUT_AXI_AOOO_EN"/>
1497 <reg32 offset="0x305f" name="VBIF_OUT_AXI_AOOO"/>1497 <reg32 offset="0x305f" name="VBIF_OUT_AXI_AOOO"/>
1498 <reg32 offset="0x3080" name="VBIF_XIN_HALT_CTRL0"/>
1499 <reg32 offset="0x3081" name="VBIF_XIN_HALT_CTRL1"/>
1498 1500
1499 <bitset name="a3xx_vbif_perf_cnt" inline="yes">1501 <bitset name="a3xx_vbif_perf_cnt" inline="yes">
1500 <bitfield name="CNT0" pos="0" type="boolean"/>1502 <bitfield name="CNT0" pos="0" type="boolean"/>
drivers/gpu/drm/msm/registers/adreno/a6xx.xml+1−1
@@ -1268,7 +1268,7 @@ by a particular renderpass/blit. · 1267 unmodified lines
1268 <reg32 offset="0x3119" name="VBIF_PERF_PWR_CNT_HIGH1" variants="A6XX"/>1268 <reg32 offset="0x3119" name="VBIF_PERF_PWR_CNT_HIGH1" variants="A6XX"/>
1269 <reg32 offset="0x311a" name="VBIF_PERF_PWR_CNT_HIGH2" variants="A6XX"/>1269 <reg32 offset="0x311a" name="VBIF_PERF_PWR_CNT_HIGH2" variants="A6XX"/>
1270 1270
1271 <reg32 offset="0x3c00" name="GBIF_CX_CONFIG" variants="A8XX-"/>1271 <reg32 offset="0x3c00" name="GBIF_CX_CONFIG" variants="A6XX-"/>
1272 <reg32 offset="0x3c01" name="GBIF_SCACHE_CNTL0"/>1272 <reg32 offset="0x3c01" name="GBIF_SCACHE_CNTL0"/>
1273 <reg32 offset="0x3c02" name="GBIF_SCACHE_CNTL1"/>1273 <reg32 offset="0x3c02" name="GBIF_SCACHE_CNTL1"/>
1274 <reg32 offset="0x3c03" name="GBIF_QSB_SIDE0"/>1274 <reg32 offset="0x3c03" name="GBIF_QSB_SIDE0"/>
include/uapi/drm/msm_drm.h+3−3
@@ -228,7 +228,7 @@ struct drm_msm_gem_cpu_fini { · 227 unmodified lines
228 228
229struct drm_msm_syncobj {229struct drm_msm_syncobj {
230 __u32 handle; /* in, syncobj handle. */230 __u32 handle; /* in, syncobj handle. */
231 __u32 flags; /* in, from MSM_SUBMIT_SYNCOBJ_FLAGS */231 __u32 flags; /* in, from MSM_SYNCOBJ_FLAGS */
232 __u64 point; /* in, timepoint for timeline syncobjs. */232 __u64 point; /* in, timepoint for timeline syncobjs. */
233};233};
234 234
@@ -393,9 +393,9 @@ struct drm_msm_vm_bind { · 158 unmodified lines
393 __s32 fence_fd;393 __s32 fence_fd;
394 /** @queue_id: in, submitqueue id */394 /** @queue_id: in, submitqueue id */
395 __u32 queue_id;395 __u32 queue_id;
396 /** @in_syncobjs: in, ptr to array of drm_msm_gem_syncobj */396 /** @in_syncobjs: in, ptr to array of drm_msm_syncobj */
397 __u64 in_syncobjs;397 __u64 in_syncobjs;
398 /** @out_syncobjs: in, ptr to array of drm_msm_gem_syncobj */398 /** @out_syncobjs: in, ptr to array of drm_msm_syncobj */
399 __u64 out_syncobjs;399 __u64 out_syncobjs;
400 /** @nr_in_syncobjs: in, number of entries in in_syncobj */400 /** @nr_in_syncobjs: in, number of entries in in_syncobj */
401 __u32 nr_in_syncobjs;401 __u32 nr_in_syncobjs;

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