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
4747 - qcom,sm8650-dsi-ctrl
4848 - qcom,sm8750-dsi-ctrl
4949 - 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
5054 - items:
5155 - enum:
5256 - qcom,qcs8300-dsi-ctrl
Documentation/devicetree/bindings/display/msm/gmu.yaml+1−0
@@ -262,6 +262,7 @@ allOf: · 261 unmodified lines
262262 compatible:
263263 contains:
264264 enum:
265+ - qcom,adreno-gmu-722.0
265266 - qcom,adreno-gmu-730.1
266267 - qcom,adreno-gmu-740.1
267268 - qcom,adreno-gmu-750.1
Documentation/devicetree/bindings/display/msm/gpu.yaml+4−0
@@ -353,6 +353,7 @@ allOf: · 352 unmodified lines
353353 - qcom,adreno-610.0
354354 - qcom,adreno-619.1
355355 - qcom,adreno-07000200
356+ - qcom,adreno-07000400
356357 then:
357358 properties:
358359 clocks:
@@ -413,6 +414,7 @@ allOf: · 54 unmodified lines
413414 contains:
414415 enum:
415416 - qcom,adreno-44010000
417+ - qcom,adreno-44050a01
416418 - qcom,adreno-44070001
417419 then:
418420 properties:
@@ -443,11 +445,13 @@ allOf: · 24 unmodified lines
443445 - qcom,adreno-680.1
444446 - qcom,adreno-690.0
445447 - qcom,adreno-730.1
448+ - qcom,adreno-43020100
446449 - qcom,adreno-43030c00
447450 - qcom,adreno-43050a01
448451 - qcom,adreno-43050c01
449452 - qcom,adreno-43051401
450453 - qcom,adreno-44010000
454+ - qcom,adreno-44050a01
451455 - qcom,adreno-44070001
452456
453457 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
1313
1414 properties:
1515 compatible:
16− const: qcom,qcm2290-dpu
16+ oneOf:
17+ - const: qcom,qcm2290-dpu
18+ - items:
19+ - const: qcom,shikra-dpu
20+ - const: qcom,qcm2290-dpu
1721
1822 reg:
1923 items:
Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml+12−7
@@ -4,7 +4,7 @@ · 3 unmodified lines
44 $id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-mdss.yaml#
55 $schema: http://devicetree.org/meta-schemas/core.yaml#
66
7−title: Qualcomm QCM220 Display MDSS
7+title: Qualcomm QCM2290 and Shikra Display MDSS
88
99 maintainers:
1010 - Loic Poulain <loic.poulain@linaro.org>
@@ -12,13 +12,18 @@ maintainers: · 1 unmodified line
1212 description:
1313 Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
1414 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.
1617
1718 $ref: /schemas/display/msm/mdss-common.yaml#
1819
1920 properties:
2021 compatible:
21− const: qcom,qcm2290-mdss
22+ oneOf:
23+ - const: qcom,qcm2290-mdss
24+ - items:
25+ - const: qcom,shikra-mdss
26+ - const: qcom,qcm2290-mdss
2227
2328 clocks:
2429 items:
@@ -52,7 +57,8 @@ patternProperties: · 27 unmodified lines
5257
5358 properties:
5459 compatible:
55− const: qcom,qcm2290-dpu
60+ contains:
61+ const: qcom,qcm2290-dpu
5662
5763 "^dsi@[0-9a-f]+$":
5864 type: object
@@ -60,9 +66,8 @@ patternProperties: · 1 unmodified line
6066
6167 properties:
6268 compatible:
63− items:
64− - const: qcom,qcm2290-dsi-ctrl
65− - const: qcom,mdss-dsi-ctrl
69+ contains:
70+ const: qcom,qcm2290-dsi-ctrl
6671
6772 "^phy@[0-9a-f]+$":
6873 type: object
Documentation/devicetree/bindings/iommu/arm,smmu.yaml+4−0
@@ -95,6 +95,7 @@ properties: · 94 unmodified lines
9595 - description: Qcom Adreno GPUs implementing "qcom,smmu-500" and "arm,mmu-500"
9696 items:
9797 - enum:
98+ - qcom,eliza-smmu-500
9899 - qcom,glymur-smmu-500
99100 - qcom,hawi-smmu-500
100101 - qcom,kaanapali-smmu-500
@@ -108,6 +109,7 @@ properties: · 7 unmodified lines
108109 - qcom,sc7280-smmu-500
109110 - qcom,sc8180x-smmu-500
110111 - qcom,sc8280xp-smmu-500
112+ - qcom,shikra-smmu-500
111113 - qcom,sm6115-smmu-500
112114 - qcom,sm6125-smmu-500
113115 - qcom,sm8150-smmu-500
@@ -543,6 +545,7 @@ allOf: · 429 unmodified lines
543545 - enum:
544546 - qcom,milos-smmu-500
545547 - qcom,sar2130p-smmu-500
548+ - qcom,shikra-smmu-500
546549 - qcom,sm8550-smmu-500
547550 - qcom,sm8650-smmu-500
548551 - qcom,x1e80100-smmu-500
@@ -570,6 +573,7 @@ allOf: · 21 unmodified lines
570573 compatible:
571574 items:
572575 - enum:
576+ - qcom,eliza-smmu-500
573577 - qcom,glymur-smmu-500
574578 - qcom,hawi-smmu-500
575579 - qcom,kaanapali-smmu-500
drivers/gpu/drm/msm/adreno/a3xx_gpu.c+35−1
@@ -25,6 +25,8 @@ · 24 unmodified lines
2525
2626 extern bool hang_debug;
2727
28+#define A3XX_VBIF_XIN_HALT_CTRL0_MASK GENMASK(5, 0)
29+
2830 static void a3xx_dump(struct msm_gpu *gpu);
2931 static bool a3xx_idle(struct msm_gpu *gpu);
3032
@@ -496,6 +498,38 @@ static u64 a3xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate) · 465 unmodified lines
496498 return busy_cycles;
497499 }
498500
501+static 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+
519+static 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+
499533 static u32 a3xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
500534 {
501535 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
581615 .get_param = adreno_get_param,
582616 .set_param = adreno_set_param,
583617 .hw_init = a3xx_hw_init,
584− .pm_suspend = msm_gpu_pm_suspend,
618+ .pm_suspend = a3xx_pm_suspend,
585619 .pm_resume = msm_gpu_pm_resume,
586620 .recover = a3xx_recover,
587621 .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
12751275 status & ~A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR);
12761276
12771277 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+
12781283 status &= A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS |
12791284 A5XX_RBBM_INT_0_MASK_CP_SW;
12801285 }
drivers/gpu/drm/msm/adreno/a6xx_catalog.c+37−3
@@ -1199,7 +1199,7 @@ static const struct adreno_reglist a730_hwcg[] = { · 1198 unmodified lines
11991199 { REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
12001200 { REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
12011201 { REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
1202− { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
1202+ { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22220222 },
12031203 { REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
12041204 { REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
12051205 { REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
@@ -1454,7 +1454,7 @@ DECLARE_ADRENO_REGLIST_PIPE_LIST(a7xx_dyn_pwrup_reglist); · 248 unmodified lines
14541454
14551455 static const struct adreno_info a7xx_gpus[] = {
14561456 {
1457− .chip_ids = ADRENO_CHIP_IDS(0x07000200),
1457+ .chip_ids = ADRENO_CHIP_IDS(0x07000200, 0x07000400),
14581458 .family = ADRENO_6XX_GEN1, /* NOT a mistake! */
14591459 .fw = {
14601460 [ADRENO_FW_SQE] = "a702_sqe.fw",
@@ -1500,6 +1500,40 @@ static const struct adreno_info a7xx_gpus[] = { · 39 unmodified lines
15001500 .gmu_cgc_mode = 0x00020000,
15011501 },
15021502 .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,
15031537 }, {
15041538 .chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */
15051539 .family = ADRENO_7XX_GEN2,
@@ -2180,7 +2214,7 @@ static const struct adreno_reglist a840_gbif[] = { · 674 unmodified lines
21802214 { REG_A6XX_GBIF_QSB_SIDE1, 0x00071e20 },
21812215 { REG_A6XX_GBIF_QSB_SIDE2, 0x00071e20 },
21822216 { REG_A6XX_GBIF_QSB_SIDE3, 0x00071e20 },
2183− { REG_A8XX_GBIF_CX_CONFIG, 0x20023000 },
2217+ { REG_A6XX_GBIF_CX_CONFIG, 0x20023000 },
21842218 { },
21852219 };
21862220
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
642642 int ret;
643643 u32 val;
644644
645− if (test_and_clear_bit(GMU_STATUS_FW_START, &gmu->status))
645+ if (!test_and_clear_bit(GMU_STATUS_FW_START, &gmu->status))
646646 return;
647647
648648 if (adreno_is_a840(adreno_gpu))
@@ -710,7 +710,8 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) · 61 unmodified lines
710710 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
711711 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
712712 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);
714715 gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
715716 gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
716717 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
718719 gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
719720
720721 /* 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))
722723 seqmem0_drv0_reg = REG_A7XX_RSCC_SEQ_MEM_0_DRV0_A740;
723724
724725 /* 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
10321033 gpu_write(gpu, gbif_cx[i].offset, gbif_cx[i].value);
10331034
10341035 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);
10361037 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));
10381041
10391042 /* Set up the lowest idle level on the GMU */
10401043 a6xx_gmu_power_config(gmu);
@@ -1087,7 +1090,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu) · 46 unmodified lines
10871090 u32 val, seqmem_off = 0;
10881091
10891092 /* 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))
10911095 seqmem_off = 4;
10921096
10931097 /* 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
11001104 gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS + seqmem_off,
11011105 val, (val & 1), 100, 1000);
11021106
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))
11041109 return;
11051110
11061111 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
14651470 /* Stop the interrupts and mask the hardware */
14661471 a6xx_gmu_irq_disable(gmu);
14671472
1473+ /* Halt the gmu cm3 core */
1474+ gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
1475+
14681476 /* Tell RPMh to power off the GPU */
14691477 a6xx_rpmh_stop(gmu);
14701478
@@ -1546,7 +1554,7 @@ static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo, · 75 unmodified lines
15461554 flags |= MSM_BO_MAP_PRIV;
15471555 }
15481556
1549− bo->obj = msm_gem_new(dev, size, flags);
1557+ bo->obj = msm_gem_new(dev, size, flags, NULL);
15501558 if (IS_ERR(bo->obj))
15511559 return PTR_ERR(bo->obj);
15521560
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
229229 {
230230 bool sysprof = msm_gpu_sysprof_no_perfcntr_zap(&a6xx_gpu->base.base);
231231 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;
233233 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
234234 phys_addr_t ttbr;
235235 u32 asid;
@@ -1273,7 +1273,8 @@ static int hw_init(struct msm_gpu *gpu) · 1037 unmodified lines
12731273 if (!(adreno_is_a650_family(adreno_gpu) ||
12741274 adreno_is_a702(adreno_gpu) ||
12751275 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;
12771278
12781279 /* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */
12791280 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
13381339
13391340 /* Enable fault detection */
13401341 if (adreno_is_a612(adreno_gpu) ||
1342+ adreno_is_a722(adreno_gpu) ||
13411343 adreno_is_a730(adreno_gpu) ||
13421344 adreno_is_a740_family(adreno_gpu))
13431345 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
19111913
19121914 gpu_write(gpu, REG_A6XX_RBBM_INT_CLEAR_CMD, status);
19131915
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);
19151919 status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;
1920+ }
19161921
19171922 if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)
19181923 a6xx_fault_detect_irq(gpu);
@@ -2770,8 +2775,9 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) · 851 unmodified lines
27702775
27712776 adreno_gpu->ubwc_config = qcom_ubwc_config_get_data();
27722777 if (IS_ERR(adreno_gpu->ubwc_config)) {
2778+ ret = PTR_ERR(adreno_gpu->ubwc_config);
27732779 a6xx_destroy(&(a6xx_gpu->base.base));
2774− return ERR_CAST(adreno_gpu->ubwc_config);
2780+ return ERR_PTR(ret);
27752781 }
27762782
27772783 /* 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
1111 static const unsigned int *gen7_0_0_external_core_regs[] __always_unused;
1212 static const unsigned int *gen7_2_0_external_core_regs[] __always_unused;
1313 static const unsigned int *gen7_9_0_external_core_regs[] __always_unused;
14+static const unsigned int *gen7_17_0_external_core_regs[] __always_unused;
1415 static const struct gen7_sptp_cluster_registers gen7_9_0_sptp_clusters[] __always_unused;
1516 static const u32 gen7_9_0_cx_debugbus_blocks[] __always_unused;
1617
1718 #include "adreno_gen7_0_0_snapshot.h"
1819 #include "adreno_gen7_2_0_snapshot.h"
1920 #include "adreno_gen7_9_0_snapshot.h"
21+#include "adreno_gen7_17_0_snapshot.h"
2022
2123 struct a6xx_gpu_state_obj {
2224 const void *handle;
@@ -404,8 +406,13 @@ static void a7xx_get_debugbus_blocks(struct msm_gpu *gpu, · 381 unmodified lines
404406 int i;
405407
406408 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
407− debugbus_blocks = gen7_0_0_debugbus_blocks;
408− debugbus_blocks_count = ARRAY_SIZE(gen7_0_0_debugbus_blocks);
409+ if (adreno_is_a722(adreno_gpu)) {
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+ }
409416 gbif_debugbus_blocks = a7xx_gbif_debugbus_blocks;
410417 gbif_debugbus_blocks_count = ARRAY_SIZE(a7xx_gbif_debugbus_blocks);
411418 } 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
678685 unsigned dbgahb_clusters_size;
679686
680687 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
681− dbgahb_clusters = gen7_0_0_sptp_clusters;
682− dbgahb_clusters_size = ARRAY_SIZE(gen7_0_0_sptp_clusters);
688+ if (adreno_is_a722(adreno_gpu)) {
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+ }
683695 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
684696 dbgahb_clusters = gen7_2_0_sptp_clusters;
685697 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
839851 unsigned clusters_size;
840852
841853 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
842− clusters = gen7_0_0_clusters;
843− clusters_size = ARRAY_SIZE(gen7_0_0_clusters);
854+ if (adreno_is_a722(adreno_gpu)) {
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+ }
844861 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
845862 clusters = gen7_2_0_clusters;
846863 clusters_size = ARRAY_SIZE(gen7_2_0_clusters);
@@ -977,8 +994,13 @@ static void a7xx_get_shaders(struct msm_gpu *gpu, · 130 unmodified lines
977994 int i;
978995
979996 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
980− shader_blocks = gen7_0_0_shader_blocks;
981− num_shader_blocks = ARRAY_SIZE(gen7_0_0_shader_blocks);
997+ if (adreno_is_a722(adreno_gpu)) {
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+ }
9821004 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
9831005 shader_blocks = gen7_2_0_shader_blocks;
9841006 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
12441266 _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[1],
12451267 &a6xx_state->gmu_registers[1], true);
12461268
1247− if (adreno_is_a621(adreno_gpu) || adreno_is_a623(adreno_gpu))
1269+ if (adreno_is_a621(adreno_gpu))
12481270 _a6xx_get_gmu_registers(gpu, a6xx_state, &a621_gpucc_reg,
12491271 &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);
12501275 else
12511276 _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gpucc_reg,
12521277 &a6xx_state->gmu_registers[2], false);
@@ -1376,8 +1401,13 @@ static void a7xx_get_registers(struct msm_gpu *gpu, · 123 unmodified lines
13761401 const struct gen7_reg_list *reglist;
13771402
13781403 if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
1379− reglist = gen7_0_0_reg_list;
1380− pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;
1404+ if (adreno_is_a722(adreno_gpu)) {
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+ }
13811411 } else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
13821412 reglist = gen7_2_0_reg_list;
13831413 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
14331463 const u32 *regs;
14341464
14351465 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;
14371469
14381470 a7xx_get_ahb_gpu_registers(gpu,
14391471 a6xx_state, regs,
@@ -1540,19 +1572,35 @@ static void a7xx_get_indexed_registers(struct msm_gpu *gpu, · 100 unmodified lines
15401572 {
15411573 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
15421574 const struct a6xx_indexed_registers *indexed_regs;
1575+ const struct a6xx_indexed_registers *mempool_regs;
15431576 int i, indexed_count, mempool_count;
1577+ bool concurrent_binning;
15441578
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) {
15461590 indexed_regs = a7xx_indexed_reglist;
15471591 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;
15481595 } else {
15491596 BUG_ON(adreno_gpu->info->family != ADRENO_7XX_GEN3);
15501597 indexed_regs = gen7_9_0_cp_indexed_reg_list;
15511598 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;
15521602 }
15531603
1554− mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
1555−
15561604 a6xx_state->indexed_regs = state_kcalloc(a6xx_state,
15571605 indexed_count + mempool_count,
15581606 sizeof(*a6xx_state->indexed_regs));
@@ -1567,15 +1615,17 @@ static void a7xx_get_indexed_registers(struct msm_gpu *gpu, · 8 unmodified lines
15671615 &a6xx_state->indexed_regs[i]);
15681616
15691617 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));
15711620
15721621 /* Get the contents of the CP_BV mempool */
15731622 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],
15751624 &a6xx_state->indexed_regs[indexed_count + i]);
15761625
15771626 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);
15791629 return;
15801630 }
15811631
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
377377 };
378378
379379 static 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+
390+static const u32 a623_gmu_gpucc_registers[] = {
380391 /* GPU CC */
381392 0x24000, 0x2400e, 0x24400, 0x2440e, 0x25800, 0x25804, 0x25c00, 0x25c04,
382393 0x26000, 0x26004, 0x26400, 0x26405, 0x26414, 0x2641d, 0x2642a, 0x26430,
@@ -402,6 +413,7 @@ static const struct a6xx_registers a6xx_gmu_reglist[] = { · 19 unmodified lines
402413
403414 static const struct a6xx_registers a6xx_gpucc_reg = REGS(a6xx_gmu_gpucc_registers, 0, 0);
404415 static const struct a6xx_registers a621_gpucc_reg = REGS(a621_gmu_gpucc_registers, 0, 0);
416+static const struct a6xx_registers a623_gpucc_reg = REGS(a623_gmu_gpucc_registers, 0, 0);
405417
406418 static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu);
407419 static 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
462474 REG_A7XX_CP_BV_MEM_POOL_DBG_DATA, 0x2200, NULL },
463475 };
464476
477+static 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+
465482 #define DEBUGBUS(_id, _count) { .id = _id, .name = #_id, .count = _count }
466483
467484 static 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
228228 * GMU enables clk gating in GBIF during boot up. So,
229229 * override that here when hwcg feature is disabled
230230 */
231− gpu_rmw(gpu, REG_A8XX_GBIF_CX_CONFIG, BIT(0), 0);
231+ gpu_rmw(gpu, REG_A6XX_GBIF_CX_CONFIG, BIT(0), 0);
232232 }
233233 }
234234
@@ -1211,8 +1211,11 @@ irqreturn_t a8xx_irq(struct msm_gpu *gpu) · 976 unmodified lines
12111211
12121212 gpu_write(gpu, REG_A8XX_RBBM_INT_CLEAR_CMD, status);
12131213
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);
12151217 status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;
1218+ }
12161219
12171220 if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)
12181221 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+
16+static 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+};
45+static_assert(IS_ALIGNED(sizeof(gen7_17_0_rscc_registers), 8));
46+
47+static 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+};
56+static_assert(IS_ALIGNED(sizeof(gen7_17_0_cpr_registers), 8));
57+
58+static 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+};
72+static_assert(IS_ALIGNED(sizeof(gen7_17_0_gpucc_registers), 8));
73+
74+static const u32 *gen7_17_0_external_core_regs[] = {
75+ gen7_17_0_gpucc_registers,
76+ gen7_17_0_cpr_registers,
77+};
78+
79+static 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+
122+static 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+
128+static 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+
134+static const u32 gen7_17_0_post_crashdumper_registers[] = {
135+ 0x00535, 0x00535,
136+ UINT_MAX, UINT_MAX,
137+};
138+static_assert(IS_ALIGNED(sizeof(gen7_17_0_post_crashdumper_registers), 8));
139+
140+static 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+};
167+static_assert(IS_ALIGNED(sizeof(gen7_17_0_gpu_registers), 8));
168+
169+static 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+};
175+static_assert(IS_ALIGNED(sizeof(gen7_17_0_dbgc_registers), 8));
176+
177+static 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+};
188+static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_pipe_br_registers), 8));
189+
190+static const u32 gen7_17_0_noncontext_rb_rac_pipe_br_registers[] = {
191+ 0x08e10, 0x08e1c, 0x08e20, 0x08e25, 0x08e51, 0x08e54,
192+ UINT_MAX, UINT_MAX,
193+};
194+static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_rb_rac_pipe_br_registers), 8));
195+
196+static 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+};
203+static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_rb_rbp_pipe_br_registers), 8));
204+
205+static 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+};
210+static_assert(IS_ALIGNED(sizeof(gen7_17_0_pc_cluster_fe_pipe_br_registers), 8));
211+
212+static const u32 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers[] = {
213+ 0x0aa40, 0x0aabf,
214+ UINT_MAX, UINT_MAX,
215+};
216+static_assert(IS_ALIGNED(sizeof(gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers), 8));
217+
218+static const u32 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers[] = {
219+ 0x0aa40, 0x0aabf,
220+ UINT_MAX, UINT_MAX,
221+};
222+static_assert(IS_ALIGNED(sizeof(gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers), 8));
223+
224+static 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+};
229+static_assert(IS_ALIGNED(sizeof(gen7_17_0_non_context_tpl1_pipe_none_usptp_registers), 8));
230+
231+static const u32 gen7_17_0_non_context_tpl1_pipe_br_usptp_registers[] = {
232+ 0x0b600, 0x0b600,
233+ UINT_MAX, UINT_MAX,
234+};
235+static_assert(IS_ALIGNED(sizeof(gen7_17_0_non_context_tpl1_pipe_br_usptp_registers), 8));
236+
237+static 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+};
241+static_assert(IS_ALIGNED(sizeof(gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers), 8));
242+
243+static 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+};
248+static_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 */
251+static 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 */
293+static 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+
362+static 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+
411+static 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+
417+static 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
356356 return 0;
357357 }
358358
359+static bool
360+valid_per_process_vm(struct msm_gpu *gpu, struct drm_gpuvm *vm)
361+{
362+ return vm && (vm != gpu->vm);
363+}
364+
359365 int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx,
360366 uint32_t param, uint64_t *value, uint32_t *len)
361367 {
@@ -414,12 +420,12 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx, · 52 unmodified lines
414420 *value = gpu->suspend_count;
415421 return 0;
416422 case MSM_PARAM_VA_START:
417− if (vm == gpu->vm)
423+ if (!valid_per_process_vm(gpu, vm))
418424 return UERR(EINVAL, drm, "requires per-process pgtables");
419425 *value = vm->mm_start;
420426 return 0;
421427 case MSM_PARAM_VA_SIZE:
422− if (vm == gpu->vm)
428+ if (!valid_per_process_vm(gpu, vm))
423429 return UERR(EINVAL, drm, "requires per-process pgtables");
424430 *value = vm->mm_range;
425431 return 0;
@@ -503,9 +509,11 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_context *ctx, · 77 unmodified lines
503509 if (!perfmon_capable())
504510 return UERR(EPERM, drm, "invalid permissions");
505511 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+
507515 /* We can only support VM_BIND with per-process pgtables: */
508− if (ctx->vm == gpu->vm)
516+ if (!gpu->funcs->create_private_vm)
509517 return UERR(EINVAL, drm, "requires per-process pgtables");
510518
511519 /*
@@ -518,6 +526,7 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_context *ctx, · 6 unmodified lines
518526 ctx->userspace_managed_vm = value;
519527
520528 return 0;
529+ }
521530 default:
522531 return UERR(EINVAL, drm, "%s: invalid param: %u", gpu->name, param);
523532 }
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
562562 return gpu->info->chip_ids[0] == 0x43050c01;
563563 }
564564
565+static inline int adreno_is_a722(struct adreno_gpu *gpu)
566+{
567+ return gpu->info->chip_ids[0] == 0x43020100;
568+}
569+
565570 static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
566571 {
567572 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
8686 .name = "sspp_8", .id = SSPP_DMA0,
8787 .base = 0x97000, .len = 0x84,
8888 .features = DMA_SDM845_MASK_SDMA,
89− .sblk = &dpu_dma_sblk,
89+ .sblk = &dpu_dma_sblk_v13,
9090 .xin_id = 1,
9191 .type = SSPP_TYPE_DMA,
9292 }, {
9393 .name = "sspp_9", .id = SSPP_DMA1,
9494 .base = 0xa0000, .len = 0x84,
9595 .features = DMA_SDM845_MASK_SDMA,
96− .sblk = &dpu_dma_sblk,
96+ .sblk = &dpu_dma_sblk_v13,
9797 .xin_id = 5,
9898 .type = SSPP_TYPE_DMA,
9999 }, {
100100 .name = "sspp_10", .id = SSPP_DMA2,
101101 .base = 0xa9000, .len = 0x84,
102102 .features = DMA_SDM845_MASK_SDMA,
103− .sblk = &dpu_dma_sblk,
103+ .sblk = &dpu_dma_sblk_v13,
104104 .xin_id = 9,
105105 .type = SSPP_TYPE_DMA,
106106 }, {
107107 .name = "sspp_11", .id = SSPP_DMA3,
108108 .base = 0xb2000, .len = 0x84,
109109 .features = DMA_SDM845_MASK_SDMA,
110− .sblk = &dpu_dma_sblk,
110+ .sblk = &dpu_dma_sblk_v13,
111111 .xin_id = 13,
112112 .type = SSPP_TYPE_DMA,
113113 }, {
114114 .name = "sspp_12", .id = SSPP_DMA4,
115115 .base = 0xbb000, .len = 0x84,
116116 .features = DMA_CURSOR_SDM845_MASK_SDMA,
117− .sblk = &dpu_dma_sblk,
117+ .sblk = &dpu_dma_sblk_v13,
118118 .xin_id = 14,
119119 .type = SSPP_TYPE_DMA,
120120 }, {
121121 .name = "sspp_13", .id = SSPP_DMA5,
122122 .base = 0xc4000, .len = 0x84,
123123 .features = DMA_CURSOR_SDM845_MASK_SDMA,
124− .sblk = &dpu_dma_sblk,
124+ .sblk = &dpu_dma_sblk_v13,
125125 .xin_id = 15,
126126 .type = SSPP_TYPE_DMA,
127127 },
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c+5−1
@@ -34,7 +34,7 @@ enum dpu_perf_mode { · 33 unmodified lines
3434 /**
3535 * dpu_core_perf_adjusted_mode_clk - Adjust given mode clock rate according to
3636 * the perf clock factor.
37− * @crtc_clk_rate - Unadjusted mode clock rate
37+ * @mode_clk_rate: unadjusted mode clock rate
3838 * @perf_cfg: performance configuration
3939 */
4040 u64 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
394394
395395 trace_dpu_core_perf_update_clk(kms->dev, !crtc->enabled, clk_rate);
396396
397+ /* If we're going offline, PM callbacks will disable the clocks instead */
398+ if (!clk_rate)
399+ return 0;
400+
397401 clk_rate = min(clk_rate, kms->perf.max_core_clk_rate);
398402 ret = dev_pm_opp_set_rate(&kms->pdev->dev, clk_rate);
399403 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
710710 if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
711711 topology->num_cdm++;
712712 } 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]],
714− adj_mode))
713+ if (drm_mode_is_420_only(&connector->display_info, adj_mode))
715714 topology->num_cdm++;
716715 }
717716 }
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
303303 .num_formats = ARRAY_SIZE(plane_formats), \
304304 }
305305
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+
306316 static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = {
307317 .rot_maxheight = 1088,
308318 .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
353363
354364 static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK();
355365
366+static const struct dpu_sspp_sub_blks dpu_dma_sblk_v13 = _DMA_SBLK_V13();
367+
356368 /*************************************************************
357369 * MIXER sub blocks config
358370 *************************************************************/
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
398398 ret = mdp_kms_init(&mdp4_kms->base, &kms_funcs);
399399 if (ret) {
400400 DRM_DEV_ERROR(dev->dev, "failed to init kms\n");
401− goto fail;
401+ return ret;
402402 }
403403
404404 kms = priv->kms;
@@ -409,7 +409,7 @@ static int mdp4_kms_init(struct drm_device *dev) · 4 unmodified lines
409409 ret = regulator_enable(mdp4_kms->vdd);
410410 if (ret) {
411411 DRM_DEV_ERROR(dev->dev, "failed to enable regulator vdd: %d\n", ret);
412− goto fail;
412+ return ret;
413413 }
414414 }
415415
@@ -421,7 +421,7 @@ static int mdp4_kms_init(struct drm_device *dev) · 5 unmodified lines
421421 DRM_DEV_ERROR(dev->dev, "unexpected MDP version: v%d.%d\n",
422422 major, minor);
423423 ret = -ENXIO;
424− goto fail;
424+ return ret;
425425 }
426426
427427 mdp4_kms->rev = minor;
@@ -430,7 +430,7 @@ static int mdp4_kms_init(struct drm_device *dev) · 2 unmodified lines
430430 if (!mdp4_kms->lut_clk) {
431431 DRM_DEV_ERROR(dev->dev, "failed to get lut_clk\n");
432432 ret = -ENODEV;
433− goto fail;
433+ return ret;
434434 }
435435 clk_set_rate(mdp4_kms->lut_clk, max_clk);
436436 }
@@ -452,7 +452,7 @@ static int mdp4_kms_init(struct drm_device *dev) · 15 unmodified lines
452452 vm = msm_kms_init_vm(mdp4_kms->dev, NULL);
453453 if (IS_ERR(vm)) {
454454 ret = PTR_ERR(vm);
455− goto fail;
455+ return ret;
456456 }
457457
458458 kms->vm = vm;
@@ -460,22 +460,22 @@ static int mdp4_kms_init(struct drm_device *dev) · 1 unmodified line
460460 ret = modeset_init(mdp4_kms);
461461 if (ret) {
462462 DRM_DEV_ERROR(dev->dev, "modeset_init failed: %d\n", ret);
463− goto fail;
463+ return ret;
464464 }
465465
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);
467467 if (IS_ERR(mdp4_kms->blank_cursor_bo)) {
468468 ret = PTR_ERR(mdp4_kms->blank_cursor_bo);
469469 DRM_DEV_ERROR(dev->dev, "could not allocate blank-cursor bo: %d\n", ret);
470470 mdp4_kms->blank_cursor_bo = NULL;
471− goto fail;
471+ return ret;
472472 }
473473
474474 ret = msm_gem_get_and_pin_iova(mdp4_kms->blank_cursor_bo, kms->vm,
475475 &mdp4_kms->blank_cursor_iova);
476476 if (ret) {
477477 DRM_DEV_ERROR(dev->dev, "could not pin blank-cursor bo: %d\n", ret);
478− goto fail;
478+ return ret;
479479 }
480480
481481 dev->mode_config.min_width = 0;
@@ -484,12 +484,6 @@ static int mdp4_kms_init(struct drm_device *dev) · 2 unmodified lines
484484 dev->mode_config.max_height = 2048;
485485
486486 return 0;
487−
488−fail:
489− if (kms)
490− mdp4_destroy(kms);
491−
492− return ret;
493487 }
494488
495489 static 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
517517 ret = mdp_kms_init(&mdp5_kms->base, &kms_funcs);
518518 if (ret) {
519519 DRM_DEV_ERROR(&pdev->dev, "failed to init kms\n");
520− goto fail;
520+ return ret;
521521 }
522522
523523 config = mdp5_cfg_get_config(mdp5_kms->cfg);
@@ -540,7 +540,7 @@ static int mdp5_kms_init(struct drm_device *dev) · 16 unmodified lines
540540 vm = msm_kms_init_vm(mdp5_kms->dev, pdev->dev.parent);
541541 if (IS_ERR(vm)) {
542542 ret = PTR_ERR(vm);
543− goto fail;
543+ return ret;
544544 }
545545
546546 kms->vm = vm;
@@ -550,7 +550,7 @@ static int mdp5_kms_init(struct drm_device *dev) · 3 unmodified lines
550550 ret = modeset_init(mdp5_kms);
551551 if (ret) {
552552 DRM_DEV_ERROR(&pdev->dev, "modeset_init failed: %d\n", ret);
553− goto fail;
553+ return ret;
554554 }
555555
556556 dev->mode_config.min_width = 0;
@@ -562,11 +562,6 @@ static int mdp5_kms_init(struct drm_device *dev) · 5 unmodified lines
562562 dev->vblank_disable_immediate = true;
563563
564564 return 0;
565−fail:
566− if (kms)
567− mdp5_kms_destroy(kms);
568−
569− return ret;
570565 }
571566
572567 static 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
284284 * such cases check for connection status and bail out if not
285285 * connected.
286286 */
287− if (!msm_dp_display->power_on) {
288− rc = -EINVAL;
287+ if (!msm_dp_display->power_on)
289288 goto end;
290− }
291289
292290 audio = msm_dp_audio_get_data(msm_dp_display);
293291 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
114114 struct drm_device *drm_dev;
115115 struct device *dev;
116116 struct drm_dp_aux *aux;
117− struct msm_dp_panel *panel;
118117 struct msm_dp_link *link;
119118 void __iomem *ahb_base;
120119 void __iomem *link_base;
@@ -202,7 +201,8 @@ static int msm_dp_aux_link_configure(struct drm_dp_aux *aux, · 81 unmodified lines
202201 /*
203202 * NOTE: resetting DP controller will also clear any pending HPD related interrupts
204203 */
205−void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl)
204+void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl,
205+ struct msm_dp_panel *panel)
206206 {
207207 struct msm_dp_ctrl_private *ctrl =
208208 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
217217 sw_reset &= ~DP_SW_RESET;
218218 msm_dp_write_ahb(ctrl, REG_DP_SW_RESET, sw_reset);
219219
220− if (!ctrl->hw_revision) {
220+ if (!ctrl->hw_revision)
221221 ctrl->hw_revision = msm_dp_read_ahb(ctrl, REG_DP_HW_VERSION);
222− ctrl->panel->hw_revision = ctrl->hw_revision;
223− }
222+ panel->hw_revision = ctrl->hw_revision;
224223 }
225224
226225 static 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
388387 drm_dbg_dp(ctrl->drm_dev, "mainlink off\n");
389388 }
390389
391−static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl)
390+static void msm_dp_ctrl_config_ctrl_streams(struct msm_dp_ctrl_private *ctrl,
391+ struct msm_dp_panel *msm_dp_panel)
392392 {
393393 u32 config = 0, tbd;
394− const u8 *dpcd = ctrl->panel->dpcd;
395394
396− /* Default-> LSCLK DIV: 1/4 LCLK */
397− config |= (2 << DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT);
395+ /*
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);
398403
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)
400405 config |= DP_CONFIGURATION_CTRL_RGB_YUV; /* YUV420 */
401406
402− /* Scrambler reset enable */
403− if (drm_dp_alternate_scrambler_reset_cap(dpcd))
404− config |= DP_CONFIGURATION_CTRL_ASSR;
405−
406407 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);
408409
409410 config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT;
410411
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+
420+static 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+
411433 /* Num of Lanes */
412434 config |= ((ctrl->link->link_params.num_lanes - 1)
413435 << 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
421443 config |= DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN;
422444 config |= DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK;
423445
424− if (ctrl->panel->psr_cap.version)
425− config |= DP_CONFIGURATION_CTRL_SEND_VSC;
426−
427− drm_dbg_dp(ctrl->drm_dev, "DP_CONFIGURATION_CTRL=0x%x\n", config);
446+ drm_dbg_dp(ctrl->drm_dev, "link DP_CONFIGURATION_CTRL=0x%x\n", config);
428447
429448 msm_dp_write_link(ctrl, REG_DP_CONFIGURATION_CTRL, config);
430449 }
@@ -443,16 +462,13 @@ static void msm_dp_ctrl_lane_mapping(struct msm_dp_ctrl_private *ctrl) · 12 unmodified lines
443462 ln_mapping);
444463 }
445464
446−static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl)
465+static void msm_dp_ctrl_config_misc1_misc0(struct msm_dp_ctrl_private *ctrl,
466+ struct msm_dp_panel *msm_dp_panel)
447467 {
448468 u32 colorimetry_cfg, test_bits_depth, misc_val;
449469
450− msm_dp_ctrl_lane_mapping(ctrl);
451− msm_dp_setup_peripheral_flush(ctrl);
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);
470+ test_bits_depth = msm_dp_link_get_test_bits_depth(ctrl->link,
471+ msm_dp_panel->msm_dp_mode.bpp);
456472 colorimetry_cfg = msm_dp_link_get_colorimetry_config(ctrl->link);
457473
458474 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
466482
467483 drm_dbg_dp(ctrl->drm_dev, "misc settings = 0x%x\n", misc_val);
468484 msm_dp_write_link(ctrl, REG_DP_MISC1_MISC0, misc_val);
485+}
469486
470− msm_dp_panel_timing_cfg(ctrl->panel, ctrl->msm_dp_ctrl.wide_bus_en);
487+static 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);
471495 }
472496
473497 /*
@@ -1237,20 +1261,21 @@ tu_size_calc: · 763 unmodified lines
12371261 }
12381262
12391263 static void msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private *ctrl,
1264+ struct msm_dp_panel *panel,
12401265 struct msm_dp_vc_tu_mapping_table *tu_table)
12411266 {
12421267 struct msm_dp_tu_calc_input in;
1243− struct drm_display_mode *drm_mode;
1268+ const struct drm_display_mode *drm_mode;
12441269
1245− drm_mode = &ctrl->panel->msm_dp_mode.drm_mode;
1270+ drm_mode = &panel->msm_dp_mode.drm_mode;
12461271
12471272 in.lclk = ctrl->link->link_params.rate / 1000;
12481273 in.pclk_khz = drm_mode->clock;
12491274 in.hactive = drm_mode->hdisplay;
12501275 in.hporch = drm_mode->htotal - drm_mode->hdisplay;
12511276 in.nlanes = ctrl->link->link_params.num_lanes;
1252− in.bpp = ctrl->panel->msm_dp_mode.bpp;
1253− in.pixel_enc = ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420 ? 420 : 444;
1277+ in.bpp = panel->msm_dp_mode.bpp;
1278+ in.pixel_enc = panel->msm_dp_mode.out_fmt_is_yuv_420 ? 420 : 444;
12541279 in.dsc_en = 0;
12551280 in.async_en = 0;
12561281 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
12601285 _dp_ctrl_calc_tu(ctrl, &in, tu_table);
12611286 }
12621287
1263−static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl)
1288+static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl,
1289+ struct msm_dp_panel *panel)
12641290 {
12651291 u32 msm_dp_tu = 0x0;
12661292 u32 valid_boundary = 0x0;
12671293 u32 valid_boundary2 = 0x0;
12681294 struct msm_dp_vc_tu_mapping_table tu_calc_table;
12691295
1270− msm_dp_ctrl_calc_tu_parameters(ctrl, &tu_calc_table);
1296+ msm_dp_ctrl_calc_tu_parameters(ctrl, panel, &tu_calc_table);
12711297
12721298 msm_dp_tu |= tu_calc_table.tu_size_minus1;
12731299 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
14191445 }
14201446
14211447 static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
1448+ struct msm_dp_panel *panel,
14221449 int *training_step, enum drm_dp_phy dp_phy)
14231450 {
14241451 int delay_us;
@@ -1427,7 +1454,7 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl, · 2 unmodified lines
14271454 int const maximum_retries = 4;
14281455
14291456 delay_us = drm_dp_read_clock_recovery_delay(ctrl->aux,
1430− ctrl->panel->dpcd, dp_phy, false);
1457+ panel->dpcd, dp_phy, false);
14311458
14321459 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
14331460
@@ -1513,14 +1540,15 @@ static int msm_dp_ctrl_link_rate_down_shift(struct msm_dp_ctrl_private *ctrl) · 79 unmodified lines
15131540 return ret;
15141541 }
15151542
1516−static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl)
1543+static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl,
1544+ struct msm_dp_panel *panel)
15171545 {
15181546
15191547 if (ctrl->link->link_params.num_lanes == 1)
15201548 return -1;
15211549
15221550 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;
15241552
15251553 ctrl->link->phy_params.p_level = 0;
15261554 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
15291557 }
15301558
15311559 static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl,
1560+ struct msm_dp_panel *panel,
15321561 enum drm_dp_phy dp_phy)
15331562 {
15341563 int delay_us;
@@ -1536,11 +1565,12 @@ static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl, · 1 unmodified line
15361565 msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE, dp_phy);
15371566
15381567 delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
1539− ctrl->panel->dpcd, dp_phy, false);
1568+ panel->dpcd, dp_phy, false);
15401569 fsleep(delay_us);
15411570 }
15421571
15431572 static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
1573+ struct msm_dp_panel *panel,
15441574 int *training_step, enum drm_dp_phy dp_phy)
15451575 {
15461576 int delay_us;
@@ -1551,16 +1581,16 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl, · 4 unmodified lines
15511581 u8 link_status[DP_LINK_STATUS_SIZE];
15521582
15531583 delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
1554− ctrl->panel->dpcd, dp_phy, false);
1584+ panel->dpcd, dp_phy, false);
15551585
15561586 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
15571587
15581588 *training_step = DP_TRAINING_2;
15591589
1560− if (drm_dp_tps4_supported(ctrl->panel->dpcd)) {
1590+ if (drm_dp_tps4_supported(panel->dpcd)) {
15611591 pattern = DP_TRAINING_PATTERN_4;
15621592 state_ctrl_bit = 4;
1563− } else if (drm_dp_tps3_supported(ctrl->panel->dpcd)) {
1593+ } else if (drm_dp_tps3_supported(panel->dpcd)) {
15641594 pattern = DP_TRAINING_PATTERN_3;
15651595 state_ctrl_bit = 3;
15661596 } else {
@@ -1597,18 +1627,19 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl, · 30 unmodified lines
15971627 }
15981628
15991629 static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl,
1630+ struct msm_dp_panel *panel,
16001631 int *training_step, enum drm_dp_phy dp_phy)
16011632 {
16021633 int ret;
16031634
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);
16051636 if (ret) {
16061637 DRM_ERROR("link training #1 on phy %d failed. ret=%d\n", dp_phy, ret);
16071638 return ret;
16081639 }
16091640 drm_dbg_dp(ctrl->drm_dev, "link training #1 on phy %d successful\n", dp_phy);
16101641
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);
16121643 if (ret) {
16131644 DRM_ERROR("link training #2 on phy %d failed. ret=%d\n", dp_phy, ret);
16141645 return ret;
@@ -1619,16 +1650,18 @@ static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl, · 4 unmodified lines
16191650 }
16201651
16211652 static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
1653+ struct msm_dp_panel *panel,
16221654 int *training_step)
16231655 {
16241656 int i;
16251657 int ret = 0;
1626− const u8 *dpcd = ctrl->panel->dpcd;
1658+ const u8 *dpcd = panel->dpcd;
16271659 u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
16281660 u8 assr;
16291661 struct msm_dp_link_info link_info = {0};
16301662
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);
16321665
16331666 link_info.num_lanes = ctrl->link->link_params.num_lanes;
16341667 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
16511684 for (i = ctrl->link->lttpr_count - 1; i >= 0; i--) {
16521685 enum drm_dp_phy dp_phy = DP_PHY_LTTPR(i);
16531686
1654− ret = msm_dp_ctrl_link_train_1_2(ctrl, training_step, dp_phy);
1655− msm_dp_ctrl_clear_training_pattern(ctrl, dp_phy);
1687+ ret = msm_dp_ctrl_link_train_1_2(ctrl, panel, training_step, dp_phy);
1688+ msm_dp_ctrl_clear_training_pattern(ctrl, panel, dp_phy);
16561689
16571690 if (ret)
16581691 break;
@@ -1663,7 +1696,7 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl, · 4 unmodified lines
16631696 goto end;
16641697 }
16651698
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);
16671700 if (ret) {
16681701 DRM_ERROR("link training on sink failed. ret=%d\n", ret);
16691702 goto end;
@@ -1676,6 +1709,7 @@ end: · 6 unmodified lines
16761709 }
16771710
16781711 static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl,
1712+ struct msm_dp_panel *panel,
16791713 int *training_step)
16801714 {
16811715 int ret = 0;
@@ -1691,7 +1725,7 @@ static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl, · 9 unmodified lines
16911725 * a link training pattern, we have to first do soft reset.
16921726 */
16931727
1694− ret = msm_dp_ctrl_link_train(ctrl, training_step);
1728+ ret = msm_dp_ctrl_link_train(ctrl, panel, training_step);
16951729
16961730 return ret;
16971731 }
@@ -1790,11 +1824,12 @@ static void msm_dp_ctrl_link_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl) · 92 unmodified lines
17901824 str_on_off(ctrl->core_clks_on));
17911825 }
17921826
1793−static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl)
1827+static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl,
1828+ struct msm_dp_panel *panel)
17941829 {
17951830 int ret = 0;
17961831 struct phy *phy = ctrl->phy;
1797− const u8 *dpcd = ctrl->panel->dpcd;
1832+ const u8 *dpcd = panel->dpcd;
17981833
17991834 ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
18001835 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
18461881 msm_dp_write_link(ctrl, REG_PSR_CMD, cmd);
18471882 }
18481883
1849−void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl)
1884+void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl,
1885+ struct msm_dp_panel *panel)
18501886 {
18511887 struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
18521888 struct msm_dp_ctrl_private, msm_dp_ctrl);
18531889 u32 cfg;
18541890
1855− if (!ctrl->panel->psr_cap.version)
1891+ if (!panel->psr_cap.version)
18561892 return;
18571893
18581894 /* enable PSR1 function */
@@ -1867,12 +1903,13 @@ void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl) · 8 unmodified lines
18671903 drm_dp_dpcd_write(ctrl->aux, DP_PSR_EN_CFG, &cfg, 1);
18681904 }
18691905
1870−void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enter)
1906+void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl,
1907+ struct msm_dp_panel *panel, bool enter)
18711908 {
18721909 struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
18731910 struct msm_dp_ctrl_private, msm_dp_ctrl);
18741911
1875− if (!ctrl->panel->psr_cap.version)
1912+ if (!panel->psr_cap.version)
18761913 return;
18771914
18781915 /*
@@ -1942,7 +1979,8 @@ void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl) · 63 unmodified lines
19421979 phy_exit(phy);
19431980 }
19441981
1945−static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
1982+static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl,
1983+ struct msm_dp_panel *panel)
19461984 {
19471985 struct phy *phy = ctrl->phy;
19481986 int ret = 0;
@@ -1950,20 +1988,19 @@ static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl) · 1 unmodified line
19501988 msm_dp_ctrl_mainlink_disable(ctrl);
19511989 ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
19521990 phy_configure(phy, &ctrl->phy_opts);
1991+
19531992 /*
19541993 * Disable and re-enable the mainlink clock since the
19551994 * link clock might have been adjusted as part of the
19561995 * link maintenance.
19571996 */
1958− dev_pm_opp_set_rate(ctrl->dev, 0);
1959−
19601997 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
19611998
19621999 phy_power_off(phy);
19632000 /* hw recommended delay before re-enabling clocks */
19642001 msleep(20);
19652002
1966− ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
2003+ ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
19672004 if (ret) {
19682005 DRM_ERROR("Failed to enable mainlink clks. ret=%d\n", ret);
19692006 return ret;
@@ -1972,7 +2009,8 @@ static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl) · 2 unmodified lines
19722009 return ret;
19732010 }
19742011
1975−static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
2012+static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl,
2013+ struct msm_dp_panel *panel)
19762014 {
19772015 struct phy *phy;
19782016
@@ -1980,9 +2018,8 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl) · 1 unmodified line
19802018
19812019 msm_dp_ctrl_mainlink_disable(ctrl);
19822020
1983− msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);
2021+ msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl, panel);
19842022
1985− dev_pm_opp_set_rate(ctrl->dev, 0);
19862023 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
19872024
19882025 phy_power_off(phy);
@@ -1994,7 +2031,8 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl) · 5 unmodified lines
19942031 return 0;
19952032 }
19962033
1997−static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl)
2034+static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl,
2035+ struct msm_dp_panel *panel)
19982036 {
19992037 int ret = 0;
20002038 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
20042042 ctrl->link->phy_params.p_level = 0;
20052043 ctrl->link->phy_params.v_level = 0;
20062044
2007− ret = msm_dp_ctrl_setup_main_link(ctrl, &training_step);
2045+ ret = msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
20082046 if (ret)
20092047 goto end;
20102048
2011− msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
2049+ msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
20122050
20132051 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
20142052
@@ -2152,7 +2190,43 @@ static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl) · 137 unmodified lines
21522190 return success;
21532191 }
21542192
2155−static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl)
2193+static 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+
2216+void 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+
2228+static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl,
2229+ struct msm_dp_panel *panel)
21562230 {
21572231 int ret;
21582232 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
21682242 * running. Add the global reset just before disabling the
21692243 * link clocks and core clocks.
21702244 */
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);
21722247
2173− ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl);
2248+ ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl, panel);
21742249 if (ret) {
21752250 DRM_ERROR("failed to enable DP link controller\n");
21762251 return ret;
21772252 }
21782253
2179− pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock;
2180− ret = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
2181− if (ret) {
2182− DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
2254+ pixel_rate = panel->msm_dp_mode.drm_mode.clock;
2255+ ret = msm_dp_ctrl_on_pixel_clk(ctrl, pixel_rate);
2256+ if (ret)
21832257 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− }
21962258
21972259 msm_dp_ctrl_send_phy_test_pattern(ctrl);
21982260
21992261 return 0;
22002262 }
22012263
2202−void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl)
2264+void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl,
2265+ struct msm_dp_panel *panel)
22032266 {
22042267 struct msm_dp_ctrl_private *ctrl;
22052268 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
22142277
22152278 if (sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
22162279 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)) {
22182281 DRM_ERROR("process phy_test_req failed\n");
22192282 return;
22202283 }
22212284 }
22222285
22232286 if (sink_request & DP_LINK_STATUS_UPDATED) {
2224− if (msm_dp_ctrl_link_maintenance(ctrl)) {
2287+ if (msm_dp_ctrl_link_maintenance(ctrl, panel)) {
22252288 DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
22262289 return;
22272290 }
@@ -2229,7 +2292,7 @@ void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
22292292
22302293 if (sink_request & DP_TEST_LINK_TRAINING) {
22312294 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)) {
22332296 DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
22342297 return;
22352298 }
@@ -2265,7 +2328,8 @@ static bool msm_dp_ctrl_channel_eq_ok(struct msm_dp_ctrl_private *ctrl) · 29 unmodified lines
22652328 return drm_dp_channel_eq_ok(link_status, num_lanes);
22662329 }
22672330
2268−int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
2331+int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
2332+ struct msm_dp_panel *panel)
22692333 {
22702334 int rc = 0;
22712335 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
22812345
22822346 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
22832347
2284− rate = ctrl->panel->link_info.rate;
2285− pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock;
2348+ rate = panel->link_info.rate;
2349+ pixel_rate = panel->msm_dp_mode.drm_mode.clock;
22862350
22872351 msm_dp_ctrl_core_clk_enable(&ctrl->msm_dp_ctrl);
22882352
@@ -2294,8 +2358,8 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 5 unmodified lines
22942358 } else {
22952359 ctrl->link->link_params.rate = rate;
22962360 ctrl->link->link_params.num_lanes =
2297− ctrl->panel->link_info.num_lanes;
2298− if (ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)
2361+ panel->link_info.num_lanes;
2362+ if (panel->msm_dp_mode.out_fmt_is_yuv_420)
22992363 pixel_rate >>= 1;
23002364 }
23012365
@@ -2303,13 +2367,13 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
23032367 ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes,
23042368 pixel_rate);
23052369
2306− rc = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
2370+ rc = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
23072371 if (rc)
23082372 return rc;
23092373
23102374 while (--link_train_max_retries) {
23112375 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);
23132377 if (rc == 0) {
23142378 /* training completed successfully */
23152379 break;
@@ -2328,7 +2392,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 12 unmodified lines
23282392 * some lanes are ready,
23292393 * reduce lane number
23302394 */
2331− rc = msm_dp_ctrl_link_lane_down_shift(ctrl);
2395+ rc = msm_dp_ctrl_link_lane_down_shift(ctrl, panel);
23322396 if (rc < 0) { /* lane == 1 already */
23332397 /* end with failure */
23342398 break;
@@ -2349,7 +2413,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 14 unmodified lines
23492413 ctrl->link->link_params.num_lanes))
23502414 rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
23512415 else
2352− rc = msm_dp_ctrl_link_lane_down_shift(ctrl);
2416+ rc = msm_dp_ctrl_link_lane_down_shift(ctrl, panel);
23532417
23542418 if (rc < 0) {
23552419 /* end with failure */
@@ -2357,10 +2421,10 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
23572421 }
23582422
23592423 /* 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);
23612425 }
23622426
2363− rc = msm_dp_ctrl_reinitialize_mainlink(ctrl);
2427+ rc = msm_dp_ctrl_reinitialize_mainlink(ctrl, panel);
23642428 if (rc) {
23652429 DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", rc);
23662430 break;
@@ -2381,20 +2445,21 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl) · 14 unmodified lines
23812445 * link training failed
23822446 * end txing train pattern here
23832447 */
2384− msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
2448+ msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
23852449
2386− msm_dp_ctrl_deinitialize_mainlink(ctrl);
2450+ msm_dp_ctrl_deinitialize_mainlink(ctrl, panel);
23872451 rc = -ECONNRESET;
23882452 }
23892453
23902454 return rc;
23912455 }
23922456
2393−static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl)
2457+static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl,
2458+ struct msm_dp_panel *panel)
23942459 {
23952460 int training_step = DP_TRAINING_NONE;
23962461
2397− return msm_dp_ctrl_setup_main_link(ctrl, &training_step);
2462+ return msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
23982463 }
23992464
24002465 static 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
24652530 msm_dp_write_link(ctrl, REG_DP_SOFTWARE_NVID, nvid);
24662531 }
24672532
2468−int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train)
2533+int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl,
2534+ struct msm_dp_panel *panel,
2535+ bool force_link_train)
24692536 {
24702537 int ret = 0;
2471− bool mainlink_ready = false;
24722538 struct msm_dp_ctrl_private *ctrl;
2473− unsigned long pixel_rate;
2474− unsigned long pixel_rate_orig;
24752539
24762540 if (!msm_dp_ctrl)
24772541 return -EINVAL;
24782542
24792543 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
24802544
2481− pixel_rate = pixel_rate_orig = ctrl->panel->msm_dp_mode.drm_mode.clock;
2482−
2483− if (msm_dp_ctrl->wide_bus_en || ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)
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);
2545+ drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d\n",
2546+ ctrl->link->link_params.rate,
2547+ ctrl->link->link_params.num_lanes);
24892548
24902549 drm_dbg_dp(ctrl->drm_dev,
24912550 "core_clk_on=%d link_clk_on=%d stream_clk_on=%d\n",
24922551 ctrl->core_clks_on, ctrl->link_clks_on, ctrl->stream_clks_on);
24932552
24942553 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);
24962555 if (ret) {
24972556 DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);
2498− goto end;
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;
2557+ return ret;
25152558 }
2516− ctrl->stream_clks_on = true;
25172559 }
25182560
25192561 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);
25212563
25222564 /* 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+
2570+int 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;
25242594
25252595 /*
25262596 * 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
25282598 */
25292599 reinit_completion(&ctrl->video_comp);
25302600
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);
25322606
25332607 msm_dp_ctrl_config_msa(ctrl,
25342608 ctrl->link->link_params.rate,
25352609 pixel_rate_orig,
2536− ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420);
2610+ panel->msm_dp_mode.out_fmt_is_yuv_420);
25372611
2538− msm_dp_panel_clear_dsc_dto(ctrl->panel);
2612+ msm_dp_panel_clear_dsc_dto(panel);
25392613
2540− msm_dp_ctrl_setup_tr_unit(ctrl);
2614+ msm_dp_ctrl_setup_tr_unit(ctrl, panel);
25412615
25422616 msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
25432617
@@ -2549,11 +2623,10 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train · 5 unmodified lines
25492623 drm_dbg_dp(ctrl->drm_dev,
25502624 "mainlink %s\n", mainlink_ready ? "READY" : "NOT READY");
25512625
2552−end:
25532626 return ret;
25542627 }
25552628
2556−void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl)
2629+void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl)
25572630 {
25582631 struct msm_dp_ctrl_private *ctrl;
25592632 struct phy *phy;
@@ -2561,29 +2634,13 @@ void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
25612634 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
25622635 phy = ctrl->phy;
25632636
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−
25812637 /* aux channel down, reinit phy */
25822638 phy_exit(phy);
25832639 phy_init(phy);
25842640 }
25852641
2586−void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)
2642+void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl,
2643+ struct msm_dp_panel *panel)
25872644 {
25882645 struct msm_dp_ctrl_private *ctrl;
25892646 struct phy *phy;
@@ -2591,24 +2648,19 @@ void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl) · 1 unmodified line
25912648 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
25922649 phy = ctrl->phy;
25932650
2594− msm_dp_panel_disable_vsc_sdp(ctrl->panel);
2651+ msm_dp_panel_disable_vsc_sdp(panel);
25952652
25962653 msm_dp_ctrl_mainlink_disable(ctrl);
25972654
2598− msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);
2599−
2600− if (ctrl->stream_clks_on) {
2601− clk_disable_unprepare(ctrl->pixel_clk);
2602− ctrl->stream_clks_on = false;
2603− }
2655+ msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl, panel);
26042656
2605− dev_pm_opp_set_rate(ctrl->dev, 0);
26062657 msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
26072658
26082659 phy_power_off(phy);
26092660 }
26102661
2611−irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
2662+irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl,
2663+ struct msm_dp_panel *panel)
26122664 {
26132665 struct msm_dp_ctrl_private *ctrl;
26142666 u32 isr;
@@ -2619,7 +2671,7 @@ irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl) · 4 unmodified lines
26192671
26202672 ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
26212673
2622− if (ctrl->panel->psr_cap.version) {
2674+ if (panel->psr_cap.version) {
26232675 isr = msm_dp_ctrl_get_psr_interrupt(ctrl);
26242676
26252677 if (isr)
@@ -2708,7 +2760,7 @@ static int msm_dp_ctrl_clk_init(struct msm_dp_ctrl *msm_dp_ctrl) · 82 unmodified lines
27082760 }
27092761
27102762 struct 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,
27122764 struct phy *phy,
27132765 void __iomem *ahb_base,
27142766 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
27162768 struct msm_dp_ctrl_private *ctrl;
27172769 int ret;
27182770
2719− if (!dev || !panel || !aux || !link) {
2771+ if (!dev || !aux || !link) {
27202772 DRM_ERROR("invalid input\n");
27212773 return ERR_PTR(-EINVAL);
27222774 }
@@ -2744,7 +2796,6 @@ struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link · 21 unmodified lines
27442796 init_completion(&ctrl->video_comp);
27452797
27462798 /* in parameters */
2747− ctrl->panel = panel;
27482799 ctrl->aux = aux;
27492800 ctrl->link = link;
27502801 ctrl->dev = dev;
drivers/gpu/drm/msm/dp/dp_ctrl.h+20−10
@@ -16,28 +16,37 @@ struct msm_dp_ctrl { · 15 unmodified lines
1616
1717 struct phy;
1818
19−int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl);
20−int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train);
21−void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl);
22−void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl);
19+int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
20+ struct msm_dp_panel *panel);
21+int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel);
22+int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl,
23+ struct msm_dp_panel *panel,
24+ bool force_link_train);
25+void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl,
26+ struct msm_dp_panel *panel);
27+void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl);
2328 void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl);
24−irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl);
25−void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl);
29+irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl,
30+ struct msm_dp_panel *panel);
31+void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl,
32+ struct msm_dp_panel *panel);
2633 struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev,
2734 struct msm_dp_link *link,
28− struct msm_dp_panel *panel,
2935 struct drm_dp_aux *aux,
3036 struct phy *phy,
3137 void __iomem *ahb_base,
3238 void __iomem *link_base);
3339
34−void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl);
40+void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl,
41+ struct msm_dp_panel *panel);
3542 void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl);
3643 void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
3744 void msm_dp_ctrl_irq_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
3845
39−void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enable);
40−void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl);
46+void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl,
47+ struct msm_dp_panel *panel, bool enable);
48+void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl,
49+ struct msm_dp_panel *panel);
4150
4251 int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl);
4352 void 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
4554 void msm_dp_ctrl_enable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
4655 void msm_dp_ctrl_disable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
4756
57+void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl);
4858 #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
6363 struct msm_dp_panel *panel;
6464 struct msm_dp_ctrl *ctrl;
6565
66− struct msm_dp_display_mode msm_dp_mode;
6766 struct msm_dp msm_dp_display;
6867
6968 /* 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
269268 const struct drm_display_info *info = &connector->display_info;
270269 int rc = 0;
271270 u8 dpcd[DP_RECEIVER_CAP_SIZE];
271+ const struct drm_edid *drm_edid = NULL;
272272
273273 rc = drm_dp_read_dpcd_caps(dp->aux, dpcd);
274274 if (rc)
@@ -276,10 +276,20 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) · 1 unmodified line
276276
277277 dp->link->lttpr_count = msm_dp_display_lttpr_init(dp, dpcd);
278278
279− rc = msm_dp_panel_read_sink_caps(dp->panel, connector);
279+ rc = msm_dp_panel_read_link_caps(dp->panel, connector);
280280 if (rc)
281281 goto end;
282282
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+
283293 msm_dp_link_process_request(dp->link);
284294
285295 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
291301 dp->msm_dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
292302
293303 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);
295305
296306 /*
297307 * 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
302312 msm_dp_link_reset_phy_params_vx_px(dp->link);
303313
304314 end:
315+ drm_edid_free(drm_edid);
305316 return rc;
306317 }
307318
@@ -348,7 +359,7 @@ static void msm_dp_display_host_init(struct msm_dp_display_private *dp) · 40 unmodified lines
348359 dp->phy_initialized);
349360
350361 msm_dp_ctrl_core_clk_enable(dp->ctrl);
351− msm_dp_ctrl_reset(dp->ctrl);
362+ msm_dp_ctrl_reset(dp->ctrl, dp->panel);
352363 msm_dp_ctrl_enable_irq(dp->ctrl);
353364 msm_dp_aux_init(dp->aux);
354365 dp->core_initialized = true;
@@ -360,7 +371,7 @@ static void msm_dp_display_host_deinit(struct msm_dp_display_private *dp) · 5 unmodified lines
360371 dp->msm_dp_display.connector_type, dp->core_initialized,
361372 dp->phy_initialized);
362373
363− msm_dp_ctrl_reset(dp->ctrl);
374+ msm_dp_ctrl_reset(dp->ctrl, dp->panel);
364375 msm_dp_ctrl_disable_irq(dp->ctrl);
365376 msm_dp_aux_deinit(dp->aux);
366377 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
381392
382393 drm_dbg_dp(dp->drm_dev, "%d\n", sink_request);
383394
384− msm_dp_ctrl_handle_sink_request(dp->ctrl);
395+ msm_dp_ctrl_handle_sink_request(dp->ctrl, dp->panel);
385396
386397 if (sink_request & DP_TEST_LINK_VIDEO_PATTERN)
387398 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
453464
454465 /* Don't forget modes for eDP */
455466 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);
457468
458469 /* triggered by irq_hdp with sink_count = 0 */
459470 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
515526 static void msm_dp_display_deinit_sub_modules(struct msm_dp_display_private *dp)
516527 {
517528 msm_dp_audio_put(dp->audio);
518− msm_dp_panel_put(dp->panel);
519529 msm_dp_aux_put(dp->aux);
520530 }
521531
@@ -560,13 +570,13 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp) · 38 unmodified lines
560570 goto error_link;
561571 }
562572
563− dp->ctrl = msm_dp_ctrl_get(dev, dp->link, dp->panel, dp->aux,
564− phy, dp->ahb_base, dp->link_base);
573+ dp->ctrl = msm_dp_ctrl_get(dev, dp->link, dp->aux,
574+ phy, dp->ahb_base, dp->link_base);
565575 if (IS_ERR(dp->ctrl)) {
566576 rc = PTR_ERR(dp->ctrl);
567577 DRM_ERROR("failed to initialize ctrl, rc = %d\n", rc);
568578 dp->ctrl = NULL;
569− goto error_ctrl;
579+ goto error_link;
570580 }
571581
572582 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
574584 rc = PTR_ERR(dp->audio);
575585 pr_err("failed to initialize audio, rc = %d\n", rc);
576586 dp->audio = NULL;
577− goto error_ctrl;
587+ goto error_link;
578588 }
579589
580590 return rc;
581591
582−error_ctrl:
583− msm_dp_panel_put(dp->panel);
584592 error_link:
585593 msm_dp_aux_put(dp->aux);
586594 error:
@@ -588,20 +596,64 @@ error: · 1 unmodified line
588596 }
589597
590598 static 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)
592601 {
593602 struct msm_dp_display_private *dp;
603+ u32 bpp;
594604
595605 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
596606
597− drm_mode_copy(&dp->panel->msm_dp_mode.drm_mode, &mode->drm_mode);
598− dp->panel->msm_dp_mode.bpp = mode->bpp;
599− dp->panel->msm_dp_mode.out_fmt_is_yuv_420 = mode->out_fmt_is_yuv_420;
600− msm_dp_panel_init_panel_info(dp->panel);
607+ if (msm_dp_display_check_video_test(msm_dp_display))
608+ bpp = msm_dp_display_get_test_bpp(msm_dp_display);
609+ else
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;
601617 return 0;
602618 }
603619
604−static int msm_dp_display_enable(struct msm_dp_display_private *dp, bool force_link_train)
620+static 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+
655+static int msm_dp_display_enable(struct msm_dp_display_private *dp,
656+ struct msm_dp_panel *msm_dp_panel)
605657 {
606658 int rc = 0;
607659 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
612664 return 0;
613665 }
614666
615− rc = msm_dp_ctrl_on_stream(dp->ctrl, force_link_train);
667+ rc = msm_dp_ctrl_on_stream(dp->ctrl, msm_dp_panel);
616668 if (!rc)
617669 msm_dp_display->power_on = true;
618670
@@ -637,18 +689,15 @@ static int msm_dp_display_post_enable(struct msm_dp *msm_dp_display) · 18 unmodified lines
637689 msm_dp_display_handle_plugged_change(msm_dp_display, true);
638690
639691 if (msm_dp_display->psr_supported)
640− msm_dp_ctrl_config_psr(dp->ctrl);
692+ msm_dp_ctrl_config_psr(dp->ctrl, dp->panel);
641693
642694 return 0;
643695 }
644696
645−static int msm_dp_display_disable(struct msm_dp_display_private *dp)
697+static void msm_dp_display_audio_notify_disable(struct msm_dp_display_private *dp)
646698 {
647699 struct msm_dp *msm_dp_display = &dp->msm_dp_display;
648700
649− if (!msm_dp_display->power_on)
650− return 0;
651−
652701 /* wait only if audio was enabled */
653702 if (msm_dp_display->audio_enabled) {
654703 /* signal the disconnect event */
@@ -659,21 +708,31 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp) · 4 unmodified lines
659708 }
660709
661710 msm_dp_display->audio_enabled = false;
711+}
662712
663− if (dp->link->sink_count == 0) {
664− /*
665− * irq_hpd with sink_count = 0
666− * hdmi unplugged out of dongle
667− */
668− msm_dp_ctrl_off_link_stream(dp->ctrl);
669− } else {
670− /*
671− * unplugged interrupt
672− * dongle unplugged out of DUT
673− */
674− msm_dp_ctrl_off(dp->ctrl);
713+static int msm_dp_display_disable(struct msm_dp_display_private *dp,
714+ struct msm_dp_panel *msm_dp_panel)
715+{
716+ struct msm_dp *msm_dp_display = &dp->msm_dp_display;
717+
718+ if (!msm_dp_display->power_on)
719+ return 0;
720+
721+ msm_dp_panel_disable_vsc_sdp(msm_dp_panel);
722+
723+ msm_dp_ctrl_off_pixel_clk(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
675735 msm_dp_display_host_phy_exit(dp);
676− }
677736
678737 msm_dp_display->power_on = false;
679738
@@ -682,24 +741,22 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp) · 2 unmodified lines
682741 }
683742
684743 /**
685− * msm_dp_bridge_mode_valid - callback to determine if specified mode is valid
686− * @bridge: Pointer to drm bridge structure
744+ * msm_dp_display_mode_valid - callback to determine if specified mode is valid
745+ * @dp: Pointer to dp display structure
687746 * @info: display info
688747 * @mode: Pointer to drm mode structure
689748 * Returns: Validity status for specified mode
690749 */
691−enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *bridge,
692− const struct drm_display_info *info,
693− const struct drm_display_mode *mode)
750+enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
751+ const struct drm_display_info *info,
752+ const struct drm_display_mode *mode)
694753 {
695754 const u32 num_components = 3, default_bpp = 24;
696755 struct msm_dp_display_private *msm_dp_display;
697756 struct msm_dp_link_info *link_info;
698757 u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
699− struct msm_dp *dp;
700758 int mode_pclk_khz = mode->clock;
701−
702− dp = to_dp_bridge(bridge)->msm_dp_display;
759+ bool is_yuv_420;
703760
704761 if (!dp || !mode_pclk_khz || !dp->connector) {
705762 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
709766 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
710767 link_info = &msm_dp_display->panel->link_info;
711768
712− if ((drm_mode_is_420_only(&dp->connector->display_info, mode) &&
713− msm_dp_display->panel->vsc_sdp_supported) ||
714− msm_dp_wide_bus_available(dp))
769+ is_yuv_420 = drm_mode_is_420_only(&dp->connector->display_info, mode);
770+
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)
715779 mode_pclk_khz /= 2;
716780
717781 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
744808
745809 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
746810
747− return msm_dp_panel_get_modes(msm_dp_display->panel,
748− dp->connector);
811+ return drm_edid_connector_add_modes(msm_dp_display->panel->connector);
749812 }
750813
751814 bool 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
808871 }
809872
810873 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);
812875 }
813876
814877 /**
@@ -918,7 +981,7 @@ static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id) · 103 unmodified lines
918981 }
919982
920983 /* DP controller isr */
921− ret |= msm_dp_ctrl_isr(dp->ctrl);
984+ ret |= msm_dp_ctrl_isr(dp->ctrl, dp->panel);
922985
923986 return ret;
924987 }
@@ -1277,22 +1340,10 @@ void __exit msm_dp_unregister(void) · 352 unmodified lines
12771340 platform_driver_unregister(&msm_dp_display_driver);
12781341 }
12791342
1280−bool 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−
12921343 bool msm_dp_needs_periph_flush(const struct msm_dp *msm_dp_display,
12931344 const struct drm_display_mode *mode)
12941345 {
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);
12961347 }
12971348
12981349 bool 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
13011352
13021353 dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
13031354
1304− if (dp->msm_dp_mode.out_fmt_is_yuv_420)
1355+ if (dp->panel->msm_dp_mode.out_fmt_is_yuv_420)
13051356 return false;
13061357
13071358 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
13521403 return 0;
13531404 }
13541405
1355−void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
1356− struct drm_atomic_commit *state)
1406+void msm_dp_display_atomic_pre_enable(struct msm_dp *msm_dp_display,
1407+ struct drm_atomic_commit *state)
13571408 {
1358− struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
1359− struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
1360− int rc = 0;
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− }
1409+ struct msm_dp_display_private *dp;
1410+ struct drm_crtc *crtc;
1411+ struct drm_crtc_state *crtc_state;
13691412
1370− if (dp->is_edp)
1371− msm_dp_hpd_plug_handle(msm_dp_display);
1413+ dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
13721414
1373− if (pm_runtime_resume_and_get(&dp->pdev->dev)) {
1374− DRM_ERROR("failed to pm_runtime_resume\n");
1415+ crtc = drm_atomic_get_new_crtc_for_encoder(state, msm_dp_display->bridge->encoder);
1416+ if (!crtc)
13751417 return;
1376− }
1418+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
13771419
1378− if (msm_dp_display->link->sink_count == 0)
1379− return;
1420+ /*
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+}
13801427
1381− rc = msm_dp_display_set_mode(dp, &msm_dp_display->msm_dp_mode);
1382− if (rc) {
1383− DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
1384− return;
1385− }
1428+void msm_dp_display_atomic_enable(struct msm_dp *msm_dp_display,
1429+ struct drm_atomic_commit *state)
1430+{
1431+ int rc = 0;
1432+ struct msm_dp_display_private *dp;
13861433
1387− if (!dp->power_on) {
1388− msm_dp_display_host_phy_init(msm_dp_display);
1389− force_link_train = true;
1390− }
1434+ dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
13911435
1392− rc = msm_dp_ctrl_on_link(msm_dp_display->ctrl);
1436+ rc = msm_dp_display_prepare_link(dp);
13931437 if (rc) {
1394− DRM_ERROR("Failed link training (rc=%d)\n", rc);
1395− // TODO: schedule drm_connector_set_link_status_property()
1438+ DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
13961439 return;
13971440 }
13981441
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);
14001445
1401− rc = msm_dp_display_post_enable(dp);
1446+ rc = msm_dp_display_post_enable(msm_dp_display);
14021447 if (rc) {
14031448 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);
14051450 }
14061451
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);
14081453 }
14091454
1410−void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
1411− struct drm_atomic_commit *state)
1455+void msm_dp_display_atomic_disable(struct msm_dp *dp)
14121456 {
1413− struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
1414− struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
14151457 struct msm_dp_display_private *msm_dp_display;
14161458
14171459 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
14191461 msm_dp_ctrl_push_idle(msm_dp_display->ctrl);
14201462 }
14211463
1422−void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
1423− struct drm_atomic_commit *state)
1464+static void msm_dp_display_unprepare(struct msm_dp_display_private *dp)
14241465 {
1425− struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
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);
1466+ struct msm_dp *msm_dp_display = &dp->msm_dp_display;
14351467
1436− drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
1468+ pm_runtime_put_sync(&msm_dp_display->pdev->dev);
14371469
1438− pm_runtime_put_sync(&dp->pdev->dev);
1470+ drm_dbg_dp(dp->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
14391471 }
14401472
1441−void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,
1442− const struct drm_display_mode *mode,
1443− const struct drm_display_mode *adjusted_mode)
1473+void msm_dp_display_atomic_post_disable(struct msm_dp *dp)
14441474 {
1445− struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
1446− struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
14471475 struct msm_dp_display_private *msm_dp_display;
1448− struct msm_dp_panel *msm_dp_panel;
14491476
14501477 msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
1451− msm_dp_panel = msm_dp_display->panel;
14521478
1453− memset(&msm_dp_display->msm_dp_mode, 0x0, sizeof(struct msm_dp_display_mode));
1454−
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);
1479+ if (dp->is_edp)
1480+ msm_dp_hpd_unplug_handle(msm_dp_display);
14671481
1468− msm_dp_display->msm_dp_mode.h_active_low =
1469− !!(msm_dp_display->msm_dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);
1482+ msm_dp_display_audio_notify_disable(msm_dp_display);
14701483
1471− msm_dp_display->msm_dp_mode.out_fmt_is_yuv_420 =
1472− drm_mode_is_420_only(&dp->connector->display_info, adjusted_mode) &&
1473− msm_dp_panel->vsc_sdp_supported;
1484+ msm_dp_display_disable(msm_dp_display, msm_dp_display->panel);
14741485
1475− /* populate wide_bus_support to different layers */
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;
1486+ msm_dp_display_unprepare(msm_dp_display);
14781487 }
14791488
14801489 void 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
3333 void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display);
3434 void msm_dp_display_set_psr(struct msm_dp *dp, bool enter);
3535 void msm_dp_display_debugfs_init(struct msm_dp *msm_dp_display, struct dentry *dentry, bool is_edp);
36+void msm_dp_display_atomic_post_disable(struct msm_dp *dp_display);
37+void msm_dp_display_atomic_disable(struct msm_dp *dp_display);
38+void msm_dp_display_atomic_pre_enable(struct msm_dp *dp_display,
39+ struct drm_atomic_commit *state);
40+void msm_dp_display_atomic_enable(struct msm_dp *dp_display,
41+ struct drm_atomic_commit *state);
42+enum 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);
3645
3746 #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
4949 msm_dp_display_debugfs_init(dp, root, false);
5050 }
5151
52+static 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+
61+static 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+
70+static 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+
79+static 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+
88+static 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+
5298 static const struct drm_bridge_funcs msm_dp_bridge_ops = {
5399 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
54100 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
55101 .atomic_create_state = drm_atomic_helper_bridge_create_state,
102+ .atomic_pre_enable = msm_dp_bridge_atomic_pre_enable,
56103 .atomic_enable = msm_dp_bridge_atomic_enable,
57104 .atomic_disable = msm_dp_bridge_atomic_disable,
58105 .atomic_post_disable = msm_dp_bridge_atomic_post_disable,
59− .mode_set = msm_dp_bridge_mode_set,
60106 .mode_valid = msm_dp_bridge_mode_valid,
61107 .get_modes = msm_dp_bridge_get_modes,
62108 .detect = msm_dp_bridge_detect,
@@ -116,7 +162,7 @@ static void msm_edp_bridge_atomic_enable(struct drm_bridge *drm_bridge, · 53 unmodified lines
116162 return;
117163 }
118164
119− msm_dp_bridge_atomic_enable(drm_bridge, state);
165+ msm_dp_display_atomic_enable(dp, state);
120166 }
121167
122168 static 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
230276 }
231277
232278 static const struct drm_bridge_funcs msm_edp_bridge_ops = {
279+ .atomic_pre_enable = msm_dp_bridge_atomic_pre_enable,
233280 .atomic_enable = msm_edp_bridge_atomic_enable,
234281 .atomic_disable = msm_edp_bridge_atomic_disable,
235282 .atomic_post_disable = msm_edp_bridge_atomic_post_disable,
236− .mode_set = msm_dp_bridge_mode_set,
237283 .mode_valid = msm_edp_bridge_mode_valid,
238284 .atomic_create_state = drm_atomic_helper_bridge_create_state,
239285 .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
2727
2828 enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,
2929 struct drm_connector *connector);
30−void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
31− struct drm_atomic_commit *state);
32−void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
33− struct drm_atomic_commit *state);
34−void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
35− struct drm_atomic_commit *state);
36−enum 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);
39−void 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);
4230 void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge);
4331 void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge);
4432 void 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
232232 return min_supported_bpp;
233233 }
234234
235−int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
236− struct drm_connector *connector)
235+int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
236+ struct drm_connector *connector)
237237 {
238238 int rc, bw_code;
239239 int count;
@@ -271,36 +271,9 @@ int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel, · 31 unmodified lines
271271
272272 rc = drm_dp_read_downstream_info(panel->aux, msm_dp_panel->dpcd,
273273 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−
292−end:
293274 return rc;
294275 }
295276
296−void 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−
304277 u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
305278 u32 mode_edid_bpp, u32 mode_pclk_khz)
306279 {
@@ -324,20 +297,6 @@ u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, · 17 unmodified lines
324297 return bpp;
325298 }
326299
327−int 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−
341300 static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)
342301 {
343302 edid += edid->extensions;
@@ -345,7 +304,8 @@ static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid) · 1 unmodified line
345304 return edid->checksum;
346305 }
347306
348−void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)
307+void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel,
308+ const struct drm_edid *drm_edid)
349309 {
350310 struct msm_dp_panel_private *panel;
351311
@@ -358,7 +318,7 @@ void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel) · 6 unmodified lines
358318
359319 if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) {
360320 /* 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);
362322 u8 checksum;
363323
364324 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
687647 return 0;
688648 }
689649
690−int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel)
650+int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel,
651+ const struct drm_display_mode *adjusted_mode,
652+ u32 bpp)
691653 {
692654 struct drm_display_mode *drm_mode;
693655 struct msm_dp_panel_private *panel;
694656
695− drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
696−
697657 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
698658
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+
699671 /*
700672 * print resolution info as this is a result
701673 * 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
755727 return msm_dp_panel;
756728 }
757729
758−void 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
3333 u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
3434
3535 struct msm_dp_link_info link_info;
36− const struct drm_edid *drm_edid;
3736 struct drm_connector *connector;
3837 struct msm_dp_display_mode msm_dp_mode;
3938 struct msm_dp_panel_psr psr_cap;
@@ -44,18 +43,17 @@ struct msm_dp_panel { · 4 unmodified lines
4443 u32 max_bw_code;
4544 };
4645
47−int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel);
46+int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel,
47+ const struct drm_display_mode *adjusted_mode,
48+ u32 bpp);
4849 int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel);
4950 int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel, bool wide_bus_en);
50−int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
51− struct drm_connector *connector);
52−void msm_dp_panel_unplugged(struct msm_dp_panel *msm_dp_panel,
53− struct drm_connector *connector);
51+int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
52+ struct drm_connector *connector);
5453 u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp,
5554 u32 mode_pclk_khz);
56−int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
57− struct drm_connector *connector);
58−void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel);
55+void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel,
56+ const struct drm_edid *drm_edid);
5957 void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable);
6058
6159 void 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
9492 struct msm_dp_link *link,
9593 void __iomem *link_base,
9694 void __iomem *p0_base);
97−void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel);
9895 #endif /* _DP_PANEL_H_ */
drivers/gpu/drm/msm/dp/dp_reg.h+2−0
@@ -149,8 +149,10 @@ · 148 unmodified lines
149149 #define DP_CONFIGURATION_CTRL_ENHANCED_FRAMING (0x00000040)
150150 #define DP_CONFIGURATION_CTRL_SEND_VSC (0x00000080)
151151 #define DP_CONFIGURATION_CTRL_BPC (0x00000100)
152+#define DP_CONFIGURATION_CTRL_BPC_MASK GENMASK(9, 8)
152153 #define DP_CONFIGURATION_CTRL_ASSR (0x00000400)
153154 #define DP_CONFIGURATION_CTRL_RGB_YUV (0x00000800)
155+#define DP_CONFIGURATION_CTRL_RGB_YUV_MASK GENMASK(12, 11)
154156 #define DP_CONFIGURATION_CTRL_LSCLK_DIV (0x00002000)
155157 #define DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT (0x04)
156158 #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
550550
551551 void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
552552 {
553− /* Drop the performance state vote */
554− dev_pm_opp_set_rate(&msm_host->pdev->dev, 0);
555553 clk_disable_unprepare(msm_host->esc_clk);
556554 clk_disable_unprepare(msm_host->pixel_clk);
557555 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
671669
672670 int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
673671 {
672+ long rounded_byte_clk_rate;
673+
674674 if (!msm_host->mode) {
675675 pr_err("%s: mode not set\n", __func__);
676676 return -EINVAL;
677677 }
678678
679679 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;
680690 msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
681691 return 0;
682692 }
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h+1−0
@@ -111,6 +111,7 @@ struct msm_dsi_phy { · 110 unmodified lines
111111 struct msm_dsi_dphy_timing timing;
112112 const struct msm_dsi_phy_cfg *cfg;
113113 void *tuning_cfg;
114+ void *pll_data;
114115
115116 enum msm_dsi_phy_usecase usecase;
116117 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
426426 u32 data;
427427
428428 spin_lock_irqsave(&pll->pll_enable_lock, flags);
429− pll->pll_enable_cnt++;
430− WARN_ON(pll->pll_enable_cnt == INT_MAX);
429+ if (pll->pll_enable_cnt++) {
430+ spin_unlock_irqrestore(&pll->pll_enable_lock, flags);
431+ WARN_ON(pll->pll_enable_cnt == INT_MAX);
432+ return;
433+ }
431434
432435 data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
433436 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
873876 spin_lock_init(&pll_7nm->pll_enable_lock);
874877
875878 pll_7nm->phy = phy;
879+ phy->pll_data = pll_7nm;
876880
877881 ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);
878882 if (ret) {
@@ -961,8 +965,10 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, · 82 unmodified lines
961965 u32 const delay_us = 5;
962966 u32 const timeout_us = 1000;
963967 struct msm_dsi_dphy_timing *timing = &phy->timing;
968+ struct dsi_pll_7nm *pll = phy->pll_data;
964969 void __iomem *base = phy->base;
965970 bool less_than_1500_mhz;
971+ unsigned long flags;
966972 u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;
967973 u32 glbl_pemph_ctrl_0;
968974 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
10841090 glbl_rescode_bot_ctrl = 0x3c;
10851091 }
10861092
1093+ spin_lock_irqsave(&pll->pll_enable_lock, flags);
1094+ pll->pll_enable_cnt = 1;
10871095 /* de-assert digital and pll power down */
10881096 data = DSI_7nm_PHY_CMN_CTRL_0_DIGTOP_PWRDN_B |
10891097 DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB;
10901098 writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);
1099+ spin_unlock_irqrestore(&pll->pll_enable_lock, flags);
10911100
10921101 /* Assert PLL core reset */
10931102 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
12001209
12011210 static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)
12021211 {
1212+ struct dsi_pll_7nm *pll = phy->pll_data;
12031213 void __iomem *base = phy->base;
1214+ unsigned long flags;
12041215 u32 data;
12051216
12061217 DBG("");
@@ -1227,8 +1238,11 @@ static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy) · 20 unmodified lines
12271238 writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);
12281239 writel(0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0);
12291240
1241+ spin_lock_irqsave(&pll->pll_enable_lock, flags);
1242+ pll->pll_enable_cnt = 0;
12301243 /* Turn off all PHY blocks */
12311244 writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_0);
1245+ spin_unlock_irqrestore(&pll->pll_enable_lock, flags);
12321246
12331247 /* make sure phy is turned off */
12341248 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
112112 return readl(hdmi->mmio + reg);
113113 }
114114
115+static 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+
124+static 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+
115134 static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg)
116135 {
117136 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
5858 {
5959 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
6060 struct hdmi *hdmi = hdmi_bridge->hdmi;
61− u32 val;
6261
63− val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
64− val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND |
65− HDMI_INFOFRAME_CTRL0_AVI_CONT);
66− hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
62+ hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0,
63+ HDMI_INFOFRAME_CTRL0_AVI_SEND |
64+ HDMI_INFOFRAME_CTRL0_AVI_CONT);
6765
68− val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
69− val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK;
70− hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
66+ hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL1,
67+ HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK);
7168
7269 return 0;
7370 }
@@ -76,18 +73,15 @@ static int msm_hdmi_bridge_clear_audio_infoframe(struct drm_bridge *bridge) · 2 unmodified lines
7673 {
7774 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
7875 struct hdmi *hdmi = hdmi_bridge->hdmi;
79− u32 val;
8076
81− val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
82− val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
83− HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
84− HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
85− HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE);
86− hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
77+ hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0,
78+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
79+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
80+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
81+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE);
8782
88− val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
89− val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK;
90− hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
83+ hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL1,
84+ HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK);
9185
9286 return 0;
9387 }
@@ -96,13 +90,11 @@ static int msm_hdmi_bridge_clear_spd_infoframe(struct drm_bridge *bridge) · 2 unmodified lines
9690 {
9791 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
9892 struct hdmi *hdmi = hdmi_bridge->hdmi;
99− u32 val;
10093
101− val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
102− val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
103− HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
104− HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK);
105− hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
94+ hdmi_clear_bits(hdmi, REG_HDMI_GEN_PKT_CTRL,
95+ HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
96+ HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
97+ HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK);
10698
10799 return 0;
108100 }
@@ -111,14 +103,12 @@ static int msm_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) · 2 unmodified lines
111103 {
112104 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
113105 struct hdmi *hdmi = hdmi_bridge->hdmi;
114− u32 val;
115106
116− val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
117− val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
118− HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
119− HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
120− HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK);
121− hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
107+ hdmi_clear_bits(hdmi, REG_HDMI_GEN_PKT_CTRL,
108+ HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
109+ HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
110+ HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
111+ HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK);
122112
123113 return 0;
124114 }
@@ -129,7 +119,6 @@ static int msm_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, · 4 unmodified lines
129119 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
130120 struct hdmi *hdmi = hdmi_bridge->hdmi;
131121 u32 buf[4] = {};
132− u32 val;
133122 int i;
134123
135124 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
153142 for (i = 0; i < ARRAY_SIZE(buf); i++)
154143 hdmi_write(hdmi, REG_HDMI_AVI_INFO(i), buf[i]);
155144
156− val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
157− val |= HDMI_INFOFRAME_CTRL0_AVI_SEND |
158− HDMI_INFOFRAME_CTRL0_AVI_CONT;
159− hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
145+ hdmi_update_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0,
146+ HDMI_INFOFRAME_CTRL0_AVI_SEND | HDMI_INFOFRAME_CTRL0_AVI_CONT,
147+ HDMI_INFOFRAME_CTRL0_AVI_SEND | HDMI_INFOFRAME_CTRL0_AVI_CONT);
160148
161− val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
162− val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK;
163− val |= HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER);
164− hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
149+ hdmi_update_bits(hdmi, REG_HDMI_INFOFRAME_CTRL1,
150+ HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK,
151+ HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER));
165152
166153 return 0;
167154 }
@@ -193,12 +180,11 @@ static int msm_hdmi_bridge_write_audio_infoframe(struct drm_bridge *bridge, · 25 unmodified lines
193180 buffer[9] << 16 |
194181 buffer[10] << 24);
195182
196− val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
197− val |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
198− HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
199− HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
200− HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
201− hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
183+ val = HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
184+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
185+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
186+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
187+ hdmi_update_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0, val, val);
202188
203189 return 0;
204190 }
@@ -231,11 +217,10 @@ static int msm_hdmi_bridge_write_spd_infoframe(struct drm_bridge *bridge, · 26 unmodified lines
231217 for (i = 0; i < ARRAY_SIZE(buf); i++)
232218 hdmi_write(hdmi, REG_HDMI_GENERIC1(i), buf[i]);
233219
234− val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
235− val |= HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
236− HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
237− HDMI_GEN_PKT_CTRL_GENERIC1_LINE(SPD_IFRAME_LINE_NUMBER);
238− hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
220+ val = HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
221+ HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
222+ HDMI_GEN_PKT_CTRL_GENERIC1_LINE(SPD_IFRAME_LINE_NUMBER);
223+ hdmi_update_bits(hdmi, REG_HDMI_GEN_PKT_CTRL, val, val);
239224
240225 return 0;
241226 }
@@ -269,12 +254,11 @@ static int msm_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, · 27 unmodified lines
269254 for (i = 0; i < ARRAY_SIZE(buf); i++)
270255 hdmi_write(hdmi, REG_HDMI_GENERIC0(i), buf[i]);
271256
272− val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
273− val |= HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
274− HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
275− HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
276− HDMI_GEN_PKT_CTRL_GENERIC0_LINE(VENSPEC_IFRAME_LINE_NUMBER);
277− hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
257+ val = HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
258+ HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
259+ HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
260+ HDMI_GEN_PKT_CTRL_GENERIC0_LINE(VENSPEC_IFRAME_LINE_NUMBER);
261+ hdmi_update_bits(hdmi, REG_HDMI_GEN_PKT_CTRL, val, val);
278262
279263 return 0;
280264 }
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
306306 HDMI_HDCP_DDC_CTRL_0_DISABLE);
307307
308308 /* ACK the Failure to Clear it */
309− reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_CTRL_1);
310− reg_val |= HDMI_HDCP_DDC_CTRL_1_FAILED_ACK;
311− hdmi_write(hdmi, REG_HDMI_HDCP_DDC_CTRL_1, reg_val);
309+ hdmi_update_bits(hdmi, REG_HDMI_HDCP_DDC_CTRL_1,
310+ HDMI_HDCP_DDC_CTRL_1_FAILED_ACK,
311+ HDMI_HDCP_DDC_CTRL_1_FAILED_ACK);
312312
313313 /* Check if the FAILURE got Cleared */
314314 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
324324 DBG("Before: HDMI_DDC_SW_STATUS=0x%08x",
325325 hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
326326 /* Reset HDMI DDC software status */
327− reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
328− reg_val |= HDMI_DDC_CTRL_SW_STATUS_RESET;
329− hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
327+ hdmi_update_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SW_STATUS_RESET,
328+ HDMI_DDC_CTRL_SW_STATUS_RESET);
330329
331330 rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
332331
333− reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
334− reg_val &= ~HDMI_DDC_CTRL_SW_STATUS_RESET;
335− hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
332+ hdmi_clear_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SW_STATUS_RESET);
336333
337334 /* Reset HDMI DDC Controller */
338− reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
339− reg_val |= HDMI_DDC_CTRL_SOFT_RESET;
340− hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
335+ hdmi_update_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SOFT_RESET,
336+ HDMI_DDC_CTRL_SOFT_RESET);
341337
342338 /* If previous msleep is aborted, skip this msleep */
343339 if (!rc)
344340 rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
345341
346− reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
347− reg_val &= ~HDMI_DDC_CTRL_SOFT_RESET;
348− hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
342+ hdmi_clear_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SOFT_RESET);
349343 DBG("After: HDMI_DDC_SW_STATUS=0x%08x",
350344 hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
351345 }
@@ -399,7 +393,6 @@ static void msm_hdmi_hdcp_reauth_work(struct work_struct *work) · 47 unmodified lines
399393 struct hdmi_hdcp_ctrl, hdcp_reauth_work);
400394 struct hdmi *hdmi = hdcp_ctrl->hdmi;
401395 unsigned long flags;
402− u32 reg_val;
403396
404397 DBG("HDCP REAUTH WORK");
405398 /*
@@ -409,9 +402,7 @@ static void msm_hdmi_hdcp_reauth_work(struct work_struct *work) · 3 unmodified lines
409402 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
410403 */
411404 spin_lock_irqsave(&hdmi->reg_lock, flags);
412− reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
413− reg_val &= ~HDMI_HPD_CTRL_ENABLE;
414− hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
405+ hdmi_clear_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE);
415406
416407 /* Disable HDCP interrupts */
417408 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
431422
432423 /* Enable HPD circuitry */
433424 spin_lock_irqsave(&hdmi->reg_lock, flags);
434− reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
435− reg_val |= HDMI_HPD_CTRL_ENABLE;
436− hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
425+ hdmi_update_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE,
426+ HDMI_HPD_CTRL_ENABLE);
437427 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
438428
439429 /*
@@ -456,7 +446,6 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 16 unmodified lines
456446 {
457447 struct hdmi *hdmi = hdcp_ctrl->hdmi;
458448 u32 link0_status;
459− u32 reg_val;
460449 unsigned long flags;
461450 int rc;
462451
@@ -472,14 +461,11 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 9 unmodified lines
472461
473462 spin_lock_irqsave(&hdmi->reg_lock, flags);
474463 /* disable HDMI Encrypt */
475− reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
476− reg_val &= ~HDMI_CTRL_ENCRYPTED;
477− hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
464+ hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
478465
479466 /* Enabling Software DDC */
480− reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);
481− reg_val &= ~HDMI_DDC_ARBITRATION_HW_ARBITRATION;
482− hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);
467+ hdmi_clear_bits(hdmi, REG_HDMI_DDC_ARBITRATION,
468+ HDMI_DDC_ARBITRATION_HW_ARBITRATION);
483469 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
484470
485471 /*
@@ -498,9 +484,8 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 12 unmodified lines
498484 hdmi_write(hdmi, REG_HDMI_HDCP_ENTROPY_CTRL1, 0xF00DFACE);
499485
500486 /* Disable the RngCipher state */
501− reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL);
502− reg_val &= ~HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER;
503− hdmi_write(hdmi, REG_HDMI_HDCP_DEBUG_CTRL, reg_val);
487+ hdmi_clear_bits(hdmi, REG_HDMI_HDCP_DEBUG_CTRL,
488+ HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER);
504489 DBG("HDCP_DEBUG_CTRL=0x%08x",
505490 hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL));
506491
@@ -537,15 +522,12 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 30 unmodified lines
537522 static void msm_hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl)
538523 {
539524 struct hdmi *hdmi = hdcp_ctrl->hdmi;
540− u32 reg_val;
541525 unsigned long flags;
542526
543527 DBG("hdcp auth failed, queue reauth work");
544528 /* clear HDMI Encrypt */
545529 spin_lock_irqsave(&hdmi->reg_lock, flags);
546− reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
547− reg_val &= ~HDMI_CTRL_ENCRYPTED;
548− hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
530+ hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
549531 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
550532
551533 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
555537 static void msm_hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl)
556538 {
557539 struct hdmi *hdmi = hdcp_ctrl->hdmi;
558− u32 reg_val;
559540 unsigned long flags;
560541
561542 /*
@@ -563,16 +544,15 @@ static void msm_hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 1 unmodified line
563544 * there is no Arbitration between software and hardware for DDC
564545 */
565546 spin_lock_irqsave(&hdmi->reg_lock, flags);
566− reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);
567− reg_val |= HDMI_DDC_ARBITRATION_HW_ARBITRATION;
568− hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);
547+ hdmi_update_bits(hdmi, REG_HDMI_DDC_ARBITRATION,
548+ HDMI_DDC_ARBITRATION_HW_ARBITRATION,
549+ HDMI_DDC_ARBITRATION_HW_ARBITRATION);
569550 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
570551
571552 /* enable HDMI Encrypt */
572553 spin_lock_irqsave(&hdmi->reg_lock, flags);
573− reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
574− reg_val |= HDMI_CTRL_ENCRYPTED;
575− hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
554+ hdmi_update_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED,
555+ HDMI_CTRL_ENCRYPTED);
576556 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
577557
578558 hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATED;
@@ -1304,7 +1284,6 @@ end: · 725 unmodified lines
13041284 void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl)
13051285 {
13061286 struct hdmi *hdmi = hdcp_ctrl->hdmi;
1307− u32 reg_val;
13081287 unsigned long flags;
13091288
13101289 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
13151294
13161295 /* clear HDMI Encrypt */
13171296 spin_lock_irqsave(&hdmi->reg_lock, flags);
1318− reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
1319− reg_val &= ~HDMI_CTRL_ENCRYPTED;
1320− hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
1297+ hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
13211298 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
13221299
13231300 hdcp_ctrl->auth_event = 0;
@@ -1330,7 +1307,6 @@ void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 6 unmodified lines
13301307 {
13311308 struct hdmi *hdmi = hdcp_ctrl->hdmi;
13321309 unsigned long flags;
1333− u32 reg_val;
13341310
13351311 if ((HDCP_STATE_INACTIVE == hdcp_ctrl->hdcp_state) ||
13361312 (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
13451321 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
13461322 */
13471323 spin_lock_irqsave(&hdmi->reg_lock, flags);
1348− reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
1349− reg_val &= ~HDMI_HPD_CTRL_ENABLE;
1350− hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
1324+ hdmi_clear_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE);
13511325
13521326 /*
13531327 * Disable HDCP interrupts.
@@ -1375,14 +1349,11 @@ void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) · 21 unmodified lines
13751349 hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, 0);
13761350
13771351 spin_lock_irqsave(&hdmi->reg_lock, flags);
1378− reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
1379− reg_val &= ~HDMI_CTRL_ENCRYPTED;
1380− hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
1352+ hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
13811353
13821354 /* Enable HPD circuitry */
1383− reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
1384− reg_val |= HDMI_HPD_CTRL_ENABLE;
1385− hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
1355+ hdmi_update_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE,
1356+ HDMI_HPD_CTRL_ENABLE);
13861357 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
13871358
13881359 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
222222 */
223223 struct drm_gpuvm *msm_context_vm(struct drm_device *dev, struct msm_context *ctx)
224224 {
225− static DEFINE_MUTEX(init_lock);
226225 struct msm_drm_private *priv = dev->dev_private;
226+ struct drm_gpuvm *vm = smp_load_acquire(&ctx->vm);
227227
228228 /* Once ctx->vm is created it is valid for the lifetime of the context: */
229− if (ctx->vm)
230− return ctx->vm;
229+ if (vm)
230+ return vm;
231+
232+ guard(rwsem_write)(&ctx->ctxlock);
231233
232− mutex_lock(&init_lock);
233234 if (!ctx->vm) {
234− ctx->vm = msm_gpu_create_private_vm(
235+ vm = msm_gpu_create_private_vm(
235236 priv->gpu, current, !ctx->userspace_managed_vm);
236−
237+ if (!IS_ERR_OR_NULL(vm))
238+ smp_store_release(&ctx->vm, vm);
237239 }
238− mutex_unlock(&init_lock);
239240
240241 return ctx->vm;
241242 }
@@ -250,7 +251,7 @@ static int context_init(struct drm_device *dev, struct drm_file *file) · 8 unmodified lines
250251 return -ENOMEM;
251252
252253 INIT_LIST_HEAD(&ctx->submitqueues);
253− rwlock_init(&ctx->queuelock);
254+ init_rwsem(&ctx->ctxlock);
254255
255256 kref_init(&ctx->ref);
256257 msm_submitqueue_init(dev, ctx);
@@ -422,10 +423,14 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev, · 165 unmodified lines
422423 {
423424 struct msm_drm_private *priv = dev->dev_private;
424425 struct msm_context *ctx = file->driver_priv;
426+ struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
425427
426428 if (!priv->gpu)
427429 return -EINVAL;
428430
431+ if (!vm)
432+ return UERR(ENOMEM, dev, "no VM");
433+
429434 if (msm_context_is_vmbind(ctx))
430435 return UERR(EINVAL, dev, "VM_BIND is enabled");
431436
@@ -436,7 +441,7 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev, · 4 unmodified lines
436441 * Don't pin the memory here - just get an address so that userspace can
437442 * be productive
438443 */
439− return msm_gem_get_iova(obj, msm_context_vm(dev, ctx), iova);
444+ return msm_gem_get_iova(obj, vm, iova);
440445 }
441446
442447 static 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
450455 if (!priv->gpu)
451456 return -EINVAL;
452457
458+ if (!vm)
459+ return UERR(ENOMEM, dev, "no VM");
460+
453461 if (msm_context_is_vmbind(ctx))
454462 return UERR(EINVAL, dev, "VM_BIND is enabled");
455463
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
261261 struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
262262 struct drm_file *file, const struct drm_format_info *info,
263263 const struct drm_mode_fb_cmd2 *mode_cmd);
264−struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
265− int w, int h, int p, uint32_t format);
266264
267265 #ifdef CONFIG_DRM_MSM_KMS_FBDEV
268266 int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
@@ -356,8 +354,6 @@ void __exit msm_dp_unregister(void); · 87 unmodified lines
356354 int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
357355 struct drm_encoder *encoder, bool yuv_supported);
358356 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);
359−bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,
360− const struct drm_display_mode *mode);
361357 bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
362358 const struct drm_display_mode *mode);
363359 bool 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
382378 {
383379 }
384380
385−static 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−
391381 static inline bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
392382 const struct drm_display_mode *mode)
393383 {
@@ -503,13 +493,6 @@ void msm_hrtimer_work_init(struct msm_hrtimer_work *work, · 109 unmodified lines
503493 #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
504494 #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
505495
506−static 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−
513496 /* for the generated headers: */
514497 #define INVALID_IDX(idx) ({BUG(); 0;})
515498 #define fui(x) ({BUG(); 0;})
drivers/gpu/drm/msm/msm_fb.c+25−73
@@ -6,7 +6,6 @@ · 5 unmodified lines
66
77 #include <drm/drm_crtc.h>
88 #include <drm/drm_damage_helper.h>
9−#include <drm/drm_file.h>
109 #include <drm/drm_fourcc.h>
1110 #include <drm/drm_framebuffer.h>
1211 #include <drm/drm_gem_framebuffer_helper.h>
@@ -29,10 +28,6 @@ struct msm_framebuffer { · 16 unmodified lines
2928 };
3029 #define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
3130
32−static 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−
3631 static int msm_framebuffer_dirtyfb(struct drm_framebuffer *fb,
3732 struct drm_file *file_priv, unsigned int flags,
3833 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
139134 return msm_fb->format;
140135 }
141136
142−struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
143− struct drm_file *file, const struct drm_format_info *info,
144− const struct drm_mode_fb_cmd2 *mode_cmd)
145−{
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−
166−out_unref:
167− for (i = 0; i < n; i++)
168− drm_gem_object_put(bos[i]);
169− return ERR_PTR(ret);
170−}
171−
172−static 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)
137+static struct drm_framebuffer *
138+msm_framebuffer_init(struct drm_device *dev, const struct drm_format_info *info,
139+ const struct drm_mode_fb_cmd2 *mode_cmd,
140+ struct drm_gem_object **bos)
175141 {
176142 struct msm_drm_private *priv = dev->dev_private;
177143 struct msm_kms *kms = priv->kms;
@@ -251,47 +217,33 @@ fail: · 73 unmodified lines
251217 return ERR_PTR(ret);
252218 }
253219
254−struct drm_framebuffer *
255−msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format)
220+struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
221+ struct drm_file *file,
222+ const struct drm_format_info *info,
223+ const struct drm_mode_fb_cmd2 *mode_cmd)
256224 {
257− struct drm_mode_fb_cmd2 mode_cmd = {
258− .pixel_format = format,
259− .width = w,
260− .height = h,
261− .pitches = { p },
262− };
263− struct drm_gem_object *bo;
225+ struct drm_gem_object *bos[4] = {0};
264226 struct drm_framebuffer *fb;
265− int size;
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− }
227+ int ret, i, n = info->num_planes;
280228
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+ }
282236
283− fb = msm_framebuffer_init(dev,
284− drm_get_format_info(dev, mode_cmd.pixel_format,
285− mode_cmd.modifier[0]),
286− &mode_cmd, &bo);
237+ fb = msm_framebuffer_init(dev, info, mode_cmd, bos);
287238 if (IS_ERR(fb)) {
288− DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");
289− /* note: if fb creation failed, we can't rely on fb destroy
290− * to unref the bo:
291− */
292− drm_gem_object_put(bo);
293− return ERR_CAST(fb);
239+ ret = PTR_ERR(fb);
240+ goto out_unref;
294241 }
295242
296243 return fb;
244+
245+out_unref:
246+ for (i = 0; i < n; i++)
247+ drm_gem_object_put(bos[i]);
248+ return ERR_PTR(ret);
297249 }
drivers/gpu/drm/msm/msm_fbdev.c+61−25
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 #include <drm/drm_drv.h>
1010 #include <drm/drm_crtc_helper.h>
1111 #include <drm/drm_fb_helper.h>
12+#include <drm/drm_file.h>
1213 #include <drm/drm_fourcc.h>
1314 #include <drm/drm_framebuffer.h>
1415 #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
4041 static void msm_fbdev_fb_destroy(struct fb_info *info)
4142 {
4243 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(fb, 0);
44+ struct drm_gem_object *bo = msm_framebuffer_bo(helper->fb, 0);
4545
4646 DBG();
4747
4848 drm_fb_helper_fini(helper);
4949
50− /* this will free the backing object */
5150 msm_gem_put_vaddr(bo);
52− drm_framebuffer_remove(fb);
5351
52+ drm_client_buffer_delete(helper->buffer);
5453 drm_client_release(&helper->client);
5554 }
5655
@@ -89,31 +88,54 @@ static const struct drm_fb_helper_funcs msm_fbdev_helper_funcs = { · 32 unmodified lines
8988 int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
9089 struct drm_fb_helper_surface_size *sizes)
9190 {
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;
9394 struct msm_drm_private *priv = dev->dev_private;
9495 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;
9699 struct drm_gem_object *bo;
100+ struct drm_client_buffer *buffer;
97101 uint64_t paddr;
98− uint32_t format;
99− int ret, pitch;
100−
101− format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
102+ int ret;
102103
103104 DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
104105 sizes->surface_height, sizes->surface_bpp,
105106 sizes->fb_width, sizes->fb_height);
106107
107− pitch = align_pitch(sizes->surface_width, sizes->surface_bpp);
108− fb = msm_alloc_stolen_fb(dev, sizes->surface_width,
109− sizes->surface_height, pitch, format);
110−
111− if (IS_ERR(fb)) {
112− DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");
113− return PTR_ERR(fb);
108+ fourcc = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
109+ format = drm_get_format_info(dev, fourcc, DRM_FORMAT_MOD_LINEAR);
110+ /* adreno needs pitch aligned to 32 pixels: */
111+ pitch = drm_format_info_min_pitch(format, 0, ALIGN(sizes->surface_width, 32));
112+ size = ALIGN(pitch * sizes->surface_height, PAGE_SIZE);
113+
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+ }
114125 }
115126
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+ }
117139
118140 /*
119141 * 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
122144 */
123145 ret = msm_gem_get_and_pin_iova(bo, priv->kms->vm, &paddr);
124146 if (ret) {
125− DRM_DEV_ERROR(dev->dev, "failed to get buffer obj iova: %d\n", ret);
126− goto fail;
147+ drm_err(dev, "failed to get buffer obj iova: %d\n", ret);
148+ goto err_drm_client_buffer_delete;
127149 }
128150
129151 DBG("fbi=%p, dev=%p", fbi, dev);
130152
131153 helper->funcs = &msm_fbdev_helper_funcs;
132− helper->fb = fb;
154+ helper->buffer = buffer;
155+ helper->fb = buffer->fb;
133156
134157 fbi->fbops = &msm_fb_ops;
135158
@@ -138,18 +161,31 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, · 2 unmodified lines
138161 fbi->screen_buffer = msm_gem_get_vaddr(bo);
139162 if (IS_ERR(fbi->screen_buffer)) {
140163 ret = PTR_ERR(fbi->screen_buffer);
141− goto fail;
164+ goto err_msm_gem_unpin;
142165 }
143166 fbi->screen_size = bo->size;
144167 fbi->fix.smem_start = paddr;
145168 fbi->fix.smem_len = bo->size;
146169
147170 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);
149178
150179 return 0;
151180
152−fail:
153− drm_framebuffer_remove(fb);
181+err_msm_gem_unpin:
182+ msm_gem_unpin_iova(bo, priv->kms->vm);
183+ msm_gem_vma_put(bo);
184+err_drm_client_buffer_delete:
185+ drm_client_buffer_delete(buffer);
186+err_drm_gem_handle_delete:
187+ drm_gem_handle_delete(file, handle);
188+err_drm_gem_object_put:
189+ drm_gem_object_put(bo);
154190 return ret;
155191 }
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
10931093 */
10941094 kvfree(msm_obj->pages);
10951095
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);
10971099 } else {
10981100 msm_gem_vunmap(obj);
10991101 put_pages(obj);
@@ -1134,10 +1136,21 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, · 34 unmodified lines
11341136 size_t size, uint32_t flags, uint32_t *handle,
11351137 char *name)
11361138 {
1137− struct drm_gem_object *obj;
1139+ struct drm_gem_object *obj, *r_obj = NULL;
11381140 int ret;
11391141
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);
11411154
11421155 if (IS_ERR(obj))
11431156 return PTR_ERR(obj);
@@ -1145,15 +1158,6 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, · 1 unmodified line
11451158 if (name)
11461159 msm_gem_object_set_name(obj, "%s", name);
11471160
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−
11571161 ret = drm_gem_handle_create(file, obj, handle);
11581162
11591163 /* 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
12321236 return 0;
12331237 }
12341238
1235−struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, uint32_t flags)
1239+static 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+
1256+struct drm_gem_object *
1257+msm_gem_new(struct drm_device *dev, size_t size, uint32_t flags,
1258+ struct drm_gem_object *r_obj)
12361259 {
1237− struct msm_drm_private *priv = dev->dev_private;
1238− struct msm_gem_object *msm_obj;
12391260 struct drm_gem_object *obj = NULL;
12401261 int ret;
12411262
@@ -1251,7 +1272,10 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, uint32_t · 9 unmodified lines
12511272 if (ret)
12521273 return ERR_PTR(ret);
12531274
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+ }
12551279
12561280 ret = drm_gem_object_init(dev, obj, size);
12571281 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
12641288 */
12651289 mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER);
12661290
1267− drm_gem_lru_move_tail(&priv->lru.unbacked, 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);
1291+ ret = msm_gem_init_bookkeeping(obj);
12741292 if (ret)
12751293 goto fail;
12761294
@@ -1282,11 +1300,12 @@ fail: · 5 unmodified lines
12821300 }
12831301
12841302 struct 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)
12861305 {
1287− struct msm_drm_private *priv = dev->dev_private;
12881306 struct msm_gem_object *msm_obj;
12891307 struct drm_gem_object *obj;
1308+ struct dma_buf *dmabuf = attach->dmabuf;
12901309 size_t size, npages;
12911310 int ret;
12921311
@@ -1296,38 +1315,35 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, · 3 unmodified lines
12961315 if (ret)
12971316 return ERR_PTR(ret);
12981317
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;
12991324 drm_gem_private_object_init(dev, obj, size);
13001325
13011326 npages = size / PAGE_SIZE;
13021327
13031328 msm_obj = to_msm_bo(obj);
1304− msm_gem_lock(obj);
1305− msm_obj->sgt = sgt;
13061329 msm_obj->pages = kvmalloc_objs(struct page *, npages);
13071330 if (!msm_obj->pages) {
1308− msm_gem_unlock(obj);
13091331 ret = -ENOMEM;
13101332 goto fail;
13111333 }
13121334
13131335 ret = drm_prime_sg_to_page_array(sgt, msm_obj->pages, npages);
13141336 if (ret) {
1315− msm_gem_unlock(obj);
13161337 goto fail;
13171338 }
13181339
1319− msm_gem_unlock(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);
1340+ ret = msm_gem_init_bookkeeping(obj);
13281341 if (ret)
13291342 goto fail;
13301343
1344+ /* Now that we are past potential failure points, set sgt: */
1345+ msm_obj->sgt = sgt;
1346+
13311347 return obj;
13321348
13331349 fail:
@@ -1340,7 +1356,7 @@ void *msm_gem_kernel_new(struct drm_device *dev, size_t size, uint32_t flags, · 6 unmodified lines
13401356 uint64_t *iova)
13411357 {
13421358 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);
13441360 int ret;
13451361
13461362 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
296296 int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
297297 size_t size, uint32_t flags, uint32_t *handle, char *name);
298298 struct 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);
300300 void *msm_gem_kernel_new(struct drm_device *dev, size_t size, uint32_t flags,
301301 struct drm_gpuvm *vm, struct drm_gem_object **bo,
302302 uint64_t *iova);
303303 void msm_gem_kernel_put(struct drm_gem_object *bo, struct drm_gpuvm *vm);
304304 struct 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);
306307 __printf(2, 3)
307308 void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...);
308309
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
8383 struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
8484 struct dma_buf_attachment *attach, struct sg_table *sg)
8585 {
86− return msm_gem_import(dev, attach->dmabuf, sg);
86+ return msm_gem_import(dev, attach, sg);
8787 }
8888
8989 struct 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
3030 */
3131
3232 static struct msm_gem_submit *submit_create(struct drm_device *dev,
33− struct msm_gpu *gpu,
33+ struct msm_gpu *gpu, struct drm_gpuvm *vm,
3434 struct msm_gpu_submitqueue *queue, uint32_t nr_bos,
3535 uint32_t nr_cmds, u64 drm_client_id)
3636 {
3737 static atomic_t ident = ATOMIC_INIT(0);
3838 struct msm_gem_submit *submit;
39− uint64_t sz;
39+ size_t sz;
4040 int ret;
4141
42− sz = struct_size(submit, bos, nr_bos) +
43− ((u64)nr_cmds * sizeof(submit->cmd[0]));
44−
45− if (sz > SIZE_MAX)
46− return ERR_PTR(-ENOMEM);
42+ sz = size_add(struct_size(submit, bos, nr_bos),
43+ array_size(sizeof(submit->cmd[0]), nr_cmds));
4744
4845 submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN);
4946 if (!submit)
@@ -66,7 +63,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, · 16 unmodified lines
6663
6764 kref_init(&submit->ref);
6865 submit->dev = dev;
69− submit->vm = msm_context_vm(dev, queue->ctx);
66+ submit->vm = vm;
7067 submit->gpu = gpu;
7168 submit->cmd = (void *)&submit->bos[nr_bos];
7269 submit->queue = queue;
@@ -250,16 +247,14 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, · 177 unmodified lines
250247
251248 sz = array_size(submit_cmd.nr_relocs,
252249 sizeof(struct drm_msm_gem_submit_reloc));
253− /* check for overflow: */
254− if (sz == SIZE_MAX) {
255− ret = -ENOMEM;
256− goto out;
257− }
258250 submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN);
259251 if (!submit->cmd[i].relocs) {
260252 ret = -ENOMEM;
261253 goto out;
262254 }
255+
256+ submit->nr_cmds = i + 1;
257+
263258 ret = copy_from_user(submit->cmd[i].relocs, userptr, sz);
264259 if (ret) {
265260 ret = -EFAULT;
@@ -554,6 +549,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 288 unmodified lines
554549 struct msm_drm_private *priv = dev->dev_private;
555550 struct drm_msm_gem_submit *args = data;
556551 struct msm_context *ctx = file->driver_priv;
552+ struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
557553 struct msm_gem_submit *submit = NULL;
558554 struct msm_gpu *gpu = priv->gpu;
559555 struct msm_gpu_submitqueue *queue;
@@ -569,10 +565,13 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 9 unmodified lines
569565 if (!gpu)
570566 return -ENXIO;
571567
568+ if (!vm)
569+ return UERR(ENOMEM, dev, "no VM");
570+
572571 if (args->pad)
573572 return -EINVAL;
574573
575− if (to_msm_vm(ctx->vm)->unusable)
574+ if (to_msm_vm(vm)->unusable)
576575 return UERR(EPIPE, dev, "context is unusable");
577576
578577 /* 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
609608 }
610609 }
611610
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,
613612 file->client_id);
614613 if (IS_ERR(submit)) {
615614 ret = PTR_ERR(submit);
@@ -719,8 +718,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 103 unmodified lines
719718 goto out;
720719 }
721720
722− submit->nr_cmds = args->nr_cmds;
723−
724721 idr_preload(GFP_KERNEL);
725722
726723 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
458458 return ret;
459459 }
460460
461+ drm_gpuvm_bo_evict(vm_bo, false);
462+
461463 return 0;
462464 }
463465
@@ -955,7 +957,7 @@ msm_gem_vm_close(struct drm_gpuvm *gpuvm) · 491 unmodified lines
955957
956958
957959 static struct msm_vm_bind_job *
958−vm_bind_job_create(struct drm_device *dev, struct drm_file *file,
960+vm_bind_job_create(struct drm_device *dev, struct drm_file *file, struct drm_gpuvm *vm,
959961 struct msm_gpu_submitqueue *queue, uint32_t nr_ops)
960962 {
961963 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
972974 return ERR_PTR(ret);
973975 }
974976
975− job->vm = msm_context_vm(dev, queue->ctx);
977+ job->vm = vm;
976978 job->queue = queue;
977979 INIT_LIST_HEAD(&job->vm_ops);
978980
@@ -1431,6 +1433,7 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file) · 452 unmodified lines
14311433 struct msm_drm_private *priv = dev->dev_private;
14321434 struct drm_msm_vm_bind *args = data;
14331435 struct msm_context *ctx = file->driver_priv;
1436+ struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
14341437 struct msm_vm_bind_job *job = NULL;
14351438 struct msm_gpu *gpu = priv->gpu;
14361439 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
14451448 if (!gpu)
14461449 return -ENXIO;
14471450
1451+ if (!vm)
1452+ return UERR(ENOMEM, dev, "no VM");
1453+
14481454 /*
14491455 * Maybe we could allow just UNMAP ops? OTOH userspace should just
14501456 * immediately close the device file and all will be torn down.
14511457 */
1452− if (to_msm_vm(msm_context_vm(dev, ctx))->unusable)
1458+ if (to_msm_vm(vm)->unusable)
14531459 return UERR(EPIPE, dev, "context is unusable");
14541460
14551461 /*
@@ -1480,7 +1486,7 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file) · 24 unmodified lines
14801486 }
14811487 }
14821488
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);
14841490 if (IS_ERR(job)) {
14851491 ret = PTR_ERR(job);
14861492 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
505505 */
506506 if (!vm->managed)
507507 msm_gem_vm_unusable(submit->vm);
508+
509+ put_task_struct(task);
508510 }
509511
510512 noreclaim_flag = memalloc_noreclaim_save();
@@ -552,11 +554,13 @@ static void recover_worker(struct kthread_work *work) · 41 unmodified lines
552554 msm_update_fence(ring->fctx, fence);
553555 }
554556
555− /* retire completed submits, plus the one that hung: */
556− retire_submits(gpu);
557+ priv->disable_err_irq = false;
557558
558559 gpu->funcs->recover(gpu);
559560
561+ /* retire completed submits, plus the one that hung: */
562+ retire_submits(gpu);
563+
560564 /*
561565 * Replay all remaining submits starting with highest priority
562566 * ring
@@ -875,7 +879,7 @@ msm_gpu_create_private_vm(struct msm_gpu *gpu, struct task_struct *task, · 312 unmodified lines
875879 to_msm_vm(vm)->pid = get_pid(task_pid(task));
876880 }
877881
878− if (IS_ERR_OR_NULL(vm))
882+ if (IS_ERR_OR_NULL(vm) && kernel_managed)
879883 vm = drm_gpuvm_get(gpu->vm);
880884
881885 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
392392 * struct msm_context - per-drm_file context
393393 */
394394 struct msm_context {
395− /** @queuelock: synchronizes access to submitqueues list */
396− rwlock_t queuelock;
395+ /** @ctxlock: synchronizes access to submitqueues list, etc */
396+ struct rw_semaphore ctxlock;
397397 /** @submitqueues: list of &msm_gpu_submitqueue created by userspace */
398398 struct list_head submitqueues;
399399 /**
drivers/gpu/drm/msm/msm_iommu.c+22−0
@@ -7,6 +7,15 @@ · 6 unmodified lines
77 #include <linux/adreno-smmu-priv.h>
88 #include <linux/io-pgtable.h>
99 #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+
1019 #include "msm_drv.h"
1120 #include "msm_gpu_trace.h"
1221 #include "msm_mmu.h"
@@ -749,6 +758,19 @@ struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks) · 736 unmodified lines
749758
750759 mutex_init(&iommu->init_lock);
751760
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+
752774 ret = iommu_attach_device(iommu->domain, dev);
753775 if (ret) {
754776 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
109109 ring->memptrs_iova = memptrs_iova;
110110
111111 ret = drm_sched_init(&ring->sched, &args);
112− if (ret) {
112+ if (ret)
113113 goto fail;
114− }
114+ ring->sched_initialized = true;
115115
116116 INIT_LIST_HEAD(&ring->submits);
117117 spin_lock_init(&ring->submit_lock);
@@ -133,7 +133,8 @@ void msm_ringbuffer_destroy(struct msm_ringbuffer *ring) · 15 unmodified lines
133133 if (IS_ERR_OR_NULL(ring))
134134 return;
135135
136− drm_sched_fini(&ring->sched);
136+ if (ring->sched_initialized)
137+ drm_sched_fini(&ring->sched);
137138
138139 msm_fence_context_free(ring->fctx);
139140
drivers/gpu/drm/msm/msm_ringbuffer.h+1−0
@@ -56,6 +56,7 @@ struct msm_ringbuffer { · 55 unmodified lines
5656 * The job scheduler for this ring.
5757 */
5858 struct drm_gpu_scheduler sched;
59+ bool sched_initialized;
5960
6061 /*
6162 * 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
99
1010 int msm_context_set_sysprof(struct msm_context *ctx, struct msm_gpu *gpu, int sysprof)
1111 {
12+ guard(rwsem_write)(&ctx->ctxlock);
13+
1214 /*
1315 * Since pm_runtime and sysprof_active are both refcounts, we
1416 * 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
9395 if (!ctx)
9496 return NULL;
9597
96− read_lock(&ctx->queuelock);
98+ guard(rwsem_read)(&ctx->ctxlock);
9799
98100 list_for_each_entry(entry, &ctx->submitqueues, node) {
99101 if (entry->id == id) {
100102 kref_get(&entry->ref);
101− read_unlock(&ctx->queuelock);
102−
103103 return entry;
104104 }
105105 }
106106
107− read_unlock(&ctx->queuelock);
108107 return NULL;
109108 }
110109
@@ -175,6 +174,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 64 unmodified lines
175174 struct msm_drm_private *priv = drm->dev_private;
176175 struct msm_gpu_submitqueue *queue;
177176 enum drm_sched_priority sched_prio;
177+ struct drm_gpuvm *vm = NULL;
178178 unsigned ring_nr;
179179 int ret;
180180
@@ -187,6 +187,11 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 6 unmodified lines
187187 if (flags & MSM_SUBMITQUEUE_VM_BIND) {
188188 unsigned sz;
189189
190+ vm = msm_context_vm(drm, ctx);
191+
192+ if (!vm)
193+ return UERR(ENOMEM, drm, "no VM");
194+
190195 /* Not allowed for kernel managed VMs (ie. kernel allocs VA) */
191196 if (!msm_context_is_vmbind(ctx))
192197 return -EINVAL;
@@ -218,7 +223,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 25 unmodified lines
218223 queue->flags = flags;
219224
220225 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;
222227
223228 queue->entity = &queue->_vm_bind_entity[0];
224229
@@ -237,7 +242,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 12 unmodified lines
237242 return ret;
238243 }
239244
240− write_lock(&ctx->queuelock);
245+ guard(rwsem_write)(&ctx->ctxlock);
241246
242247 queue->ctx = msm_context_get(ctx);
243248 queue->id = ctx->queueid++;
@@ -251,8 +256,6 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, · 7 unmodified lines
251256
252257 list_add_tail(&queue->node, &ctx->submitqueues);
253258
254− write_unlock(&ctx->queuelock);
255−
256259 return 0;
257260 }
258261
@@ -335,19 +338,16 @@ int msm_submitqueue_remove(struct msm_context *ctx, u32 id) · 76 unmodified lines
335338 if (!id)
336339 return -ENOENT;
337340
338− write_lock(&ctx->queuelock);
341+ guard(rwsem_write)(&ctx->ctxlock);
339342
340343 list_for_each_entry(entry, &ctx->submitqueues, node) {
341344 if (entry->id == id) {
342345 list_del(&entry->node);
343− write_unlock(&ctx->queuelock);
344−
345346 msm_submitqueue_put(entry);
346347 return 0;
347348 }
348349 }
349350
350− write_unlock(&ctx->queuelock);
351351 return -ENOENT;
352352 }
353353
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
14951495 <reg32 offset="0x3058" name="VBIF_OUT_AXI_AMEMTYPE_CONF0"/>
14961496 <reg32 offset="0x305e" name="VBIF_OUT_AXI_AOOO_EN"/>
14971497 <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"/>
14981500
14991501 <bitset name="a3xx_vbif_perf_cnt" inline="yes">
15001502 <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
12681268 <reg32 offset="0x3119" name="VBIF_PERF_PWR_CNT_HIGH1" variants="A6XX"/>
12691269 <reg32 offset="0x311a" name="VBIF_PERF_PWR_CNT_HIGH2" variants="A6XX"/>
12701270
1271− <reg32 offset="0x3c00" name="GBIF_CX_CONFIG" variants="A8XX-"/>
1271+ <reg32 offset="0x3c00" name="GBIF_CX_CONFIG" variants="A6XX-"/>
12721272 <reg32 offset="0x3c01" name="GBIF_SCACHE_CNTL0"/>
12731273 <reg32 offset="0x3c02" name="GBIF_SCACHE_CNTL1"/>
12741274 <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
228228
229229 struct drm_msm_syncobj {
230230 __u32 handle; /* in, syncobj handle. */
231− __u32 flags; /* in, from MSM_SUBMIT_SYNCOBJ_FLAGS */
231+ __u32 flags; /* in, from MSM_SYNCOBJ_FLAGS */
232232 __u64 point; /* in, timepoint for timeline syncobjs. */
233233 };
234234
@@ -393,9 +393,9 @@ struct drm_msm_vm_bind { · 158 unmodified lines
393393 __s32 fence_fd;
394394 /** @queue_id: in, submitqueue id */
395395 __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 */
397397 __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 */
399399 __u64 out_syncobjs;
400400 /** @nr_in_syncobjs: in, number of entries in in_syncobj */
401401 __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