summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-08-24 11:21:11 +1000
committerDave Airlie <airlied@redhat.com>2026-08-24 11:21:12 +1000
commite91d58cb2f470fe15bd4e02a26d44e9aaf771346 (patch)
treec568800930e7c70ed1409c7d129683d5f70f81a5
parentbb11536efd7dbde13a8a168c66881a9b8131dd81 (diff)
parent140b13475302601368c0cf4e193e66126a49feb3 (diff)
downloadlinux-e91d58cb2f470fe15bd4e02a26d44e9aaf771346.tar.gz
linux-e91d58cb2f470fe15bd4e02a26d44e9aaf771346.zip
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 Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rob Clark <rob.clark@oss.qualcomm.com> Link: https://patch.msgid.link/CACSVV02Kp=J+w_RjEJbBbQnBYRb+SWdwMvVbCaAL70bq9EBagQ@mail.gmail.com
-rw-r--r--Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml4
-rw-r--r--Documentation/devicetree/bindings/display/msm/gmu.yaml1
-rw-r--r--Documentation/devicetree/bindings/display/msm/gpu.yaml4
-rw-r--r--Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml6
-rw-r--r--Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml19
-rw-r--r--Documentation/devicetree/bindings/iommu/arm,smmu.yaml4
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c36
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c5
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_catalog.c40
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.c24
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.c14
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c86
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h17
-rw-r--r--drivers/gpu/drm/msm/adreno/a8xx_gpu.c7
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h428
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c17
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h5
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_13_0_kaanapali.h12
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c6
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c3
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c12
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c24
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c11
-rw-r--r--drivers/gpu/drm/msm/dp/dp_audio.c4
-rw-r--r--drivers/gpu/drm/msm/dp/dp_ctrl.c395
-rw-r--r--drivers/gpu/drm/msm/dp/dp_ctrl.h30
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.c311
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.h9
-rw-r--r--drivers/gpu/drm/msm/dp/dp_drm.c52
-rw-r--r--drivers/gpu/drm/msm/dp/dp_drm.h12
-rw-r--r--drivers/gpu/drm/msm/dp/dp_panel.c75
-rw-r--r--drivers/gpu/drm/msm/dp/dp_panel.h17
-rw-r--r--drivers/gpu/drm/msm/dp/dp_reg.h2
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c14
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.h1
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c18
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.h19
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_bridge.c98
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c85
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c26
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h17
-rw-r--r--drivers/gpu/drm/msm/msm_fb.c98
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c86
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c94
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h5
-rw-r--r--drivers/gpu/drm/msm/msm_gem_prime.c2
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c31
-rw-r--r--drivers/gpu/drm/msm/msm_gem_vma.c14
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c10
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h4
-rw-r--r--drivers/gpu/drm/msm/msm_iommu.c22
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.c7
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.h1
-rw-r--r--drivers/gpu/drm/msm/msm_submitqueue.c24
-rw-r--r--drivers/gpu/drm/msm/registers/adreno/a3xx.xml2
-rw-r--r--drivers/gpu/drm/msm/registers/adreno/a6xx.xml2
-rw-r--r--include/uapi/drm/msm_drm.h6
57 files changed, 1553 insertions, 825 deletions
diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index dbc0613e427e..fd0834d09ad6 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -48,6 +48,10 @@ properties:
- qcom,sm8750-dsi-ctrl
- const: qcom,mdss-dsi-ctrl
- items:
+ - const: qcom,shikra-dsi-ctrl
+ - const: qcom,qcm2290-dsi-ctrl
+ - const: qcom,mdss-dsi-ctrl
+ - items:
- enum:
- qcom,qcs8300-dsi-ctrl
- qcom,sc8280xp-dsi-ctrl
diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml b/Documentation/devicetree/bindings/display/msm/gmu.yaml
index 8578c2f8122e..9e459f12ce3f 100644
--- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
@@ -262,6 +262,7 @@ allOf:
compatible:
contains:
enum:
+ - qcom,adreno-gmu-722.0
- qcom,adreno-gmu-730.1
- qcom,adreno-gmu-740.1
- qcom,adreno-gmu-750.1
diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml b/Documentation/devicetree/bindings/display/msm/gpu.yaml
index dbbd8b814189..e5efe2d35ddc 100644
--- a/Documentation/devicetree/bindings/display/msm/gpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml
@@ -353,6 +353,7 @@ allOf:
- qcom,adreno-610.0
- qcom,adreno-619.1
- qcom,adreno-07000200
+ - qcom,adreno-07000400
then:
properties:
clocks:
@@ -413,6 +414,7 @@ allOf:
contains:
enum:
- qcom,adreno-44010000
+ - qcom,adreno-44050a01
- qcom,adreno-44070001
then:
properties:
@@ -443,11 +445,13 @@ allOf:
- qcom,adreno-680.1
- qcom,adreno-690.0
- qcom,adreno-730.1
+ - qcom,adreno-43020100
- qcom,adreno-43030c00
- qcom,adreno-43050a01
- qcom,adreno-43050c01
- qcom,adreno-43051401
- qcom,adreno-44010000
+ - qcom,adreno-44050a01
- qcom,adreno-44070001
then: # Starting with A6xx, the clocks are usually defined in the GMU node
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml
index be6cd8adb3b6..034d3df8d247 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml
@@ -13,7 +13,11 @@ $ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
- const: qcom,qcm2290-dpu
+ oneOf:
+ - const: qcom,qcm2290-dpu
+ - items:
+ - const: qcom,shikra-dpu
+ - const: qcom,qcm2290-dpu
reg:
items:
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml
index bb09ecd1a5b4..49a7b5c4c678 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-mdss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Qualcomm QCM220 Display MDSS
+title: Qualcomm QCM2290 and Shikra Display MDSS
maintainers:
- Loic Poulain <loic.poulain@linaro.org>
@@ -12,13 +12,18 @@ maintainers:
description:
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS
- are mentioned for QCM2290 target.
+ are mentioned for QCM2290 and Shikra targets. Shikra uses the same MDSS/DPU/DSI
+ hardware as QCM2290 (DPU 6.5) and shares the same register layout.
$ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
- const: qcom,qcm2290-mdss
+ oneOf:
+ - const: qcom,qcm2290-mdss
+ - items:
+ - const: qcom,shikra-mdss
+ - const: qcom,qcm2290-mdss
clocks:
items:
@@ -52,7 +57,8 @@ patternProperties:
properties:
compatible:
- const: qcom,qcm2290-dpu
+ contains:
+ const: qcom,qcm2290-dpu
"^dsi@[0-9a-f]+$":
type: object
@@ -60,9 +66,8 @@ patternProperties:
properties:
compatible:
- items:
- - const: qcom,qcm2290-dsi-ctrl
- - const: qcom,mdss-dsi-ctrl
+ contains:
+ const: qcom,qcm2290-dsi-ctrl
"^phy@[0-9a-f]+$":
type: object
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index a701dec2fa0a..d87281026a71 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -95,6 +95,7 @@ properties:
- description: Qcom Adreno GPUs implementing "qcom,smmu-500" and "arm,mmu-500"
items:
- enum:
+ - qcom,eliza-smmu-500
- qcom,glymur-smmu-500
- qcom,hawi-smmu-500
- qcom,kaanapali-smmu-500
@@ -108,6 +109,7 @@ properties:
- qcom,sc7280-smmu-500
- qcom,sc8180x-smmu-500
- qcom,sc8280xp-smmu-500
+ - qcom,shikra-smmu-500
- qcom,sm6115-smmu-500
- qcom,sm6125-smmu-500
- qcom,sm8150-smmu-500
@@ -543,6 +545,7 @@ allOf:
- enum:
- qcom,milos-smmu-500
- qcom,sar2130p-smmu-500
+ - qcom,shikra-smmu-500
- qcom,sm8550-smmu-500
- qcom,sm8650-smmu-500
- qcom,x1e80100-smmu-500
@@ -570,6 +573,7 @@ allOf:
compatible:
items:
- enum:
+ - qcom,eliza-smmu-500
- qcom,glymur-smmu-500
- qcom,hawi-smmu-500
- qcom,kaanapali-smmu-500
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index c17e9777beae..0259e60b8011 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -25,6 +25,8 @@
extern bool hang_debug;
+#define A3XX_VBIF_XIN_HALT_CTRL0_MASK GENMASK(5, 0)
+
static void a3xx_dump(struct msm_gpu *gpu);
static bool a3xx_idle(struct msm_gpu *gpu);
@@ -496,6 +498,38 @@ static u64 a3xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
return busy_cycles;
}
+static int a3xx_vbif_halt(struct msm_gpu *gpu)
+{
+ u32 ack;
+ int ret;
+
+ gpu_write(gpu, REG_A3XX_VBIF_XIN_HALT_CTRL0,
+ A3XX_VBIF_XIN_HALT_CTRL0_MASK);
+ ret = spin_until(((ack = gpu_read(gpu, REG_A3XX_VBIF_XIN_HALT_CTRL1)) &
+ A3XX_VBIF_XIN_HALT_CTRL0_MASK) ==
+ A3XX_VBIF_XIN_HALT_CTRL0_MASK);
+ gpu_write(gpu, REG_A3XX_VBIF_XIN_HALT_CTRL0, 0);
+
+ if (ret)
+ return -EBUSY;
+
+ return 0;
+}
+
+static int a3xx_pm_suspend(struct msm_gpu *gpu)
+{
+ int ret;
+
+ if (!a3xx_idle(gpu))
+ return -EBUSY;
+
+ ret = a3xx_vbif_halt(gpu);
+ if (ret)
+ return ret;
+
+ return msm_gpu_pm_suspend(gpu);
+}
+
static u32 a3xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
{
ring->memptrs->rptr = gpu_read(gpu, REG_AXXX_CP_RB_RPTR);
@@ -581,7 +615,7 @@ const struct adreno_gpu_funcs a3xx_gpu_funcs = {
.get_param = adreno_get_param,
.set_param = adreno_set_param,
.hw_init = a3xx_hw_init,
- .pm_suspend = msm_gpu_pm_suspend,
+ .pm_suspend = a3xx_pm_suspend,
.pm_resume = msm_gpu_pm_resume,
.recover = a3xx_recover,
.submit = a3xx_submit,
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 2c0bbac43c52..f1df2514c613 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1275,6 +1275,11 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
status & ~A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR);
if (priv->disable_err_irq) {
+ /* Turn off interrupts to avoid interrupt storm */
+ gpu_write(gpu, REG_A5XX_RBBM_INT_0_MASK,
+ A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS |
+ A5XX_RBBM_INT_0_MASK_CP_SW);
+
status &= A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS |
A5XX_RBBM_INT_0_MASK_CP_SW;
}
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
index 3e6f409d13a2..90a0c7ffb3c8 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
@@ -1199,7 +1199,7 @@ static const struct adreno_reglist a730_hwcg[] = {
{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
- { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+ { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22220222 },
{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
@@ -1454,7 +1454,7 @@ DECLARE_ADRENO_REGLIST_PIPE_LIST(a7xx_dyn_pwrup_reglist);
static const struct adreno_info a7xx_gpus[] = {
{
- .chip_ids = ADRENO_CHIP_IDS(0x07000200),
+ .chip_ids = ADRENO_CHIP_IDS(0x07000200, 0x07000400),
.family = ADRENO_6XX_GEN1, /* NOT a mistake! */
.fw = {
[ADRENO_FW_SQE] = "a702_sqe.fw",
@@ -1501,6 +1501,40 @@ static const struct adreno_info a7xx_gpus[] = {
},
.preempt_record_size = 2860 * SZ_1K,
}, {
+ .chip_ids = ADRENO_CHIP_IDS(0x43020100),
+ .family = ADRENO_7XX_GEN1,
+ .fw = {
+ [ADRENO_FW_SQE] = "qcom/gen71700_sqe.fw",
+ [ADRENO_FW_GMU] = "qcom/gen71700_gmu.bin",
+ },
+ .gmem = SZ_1M,
+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+ .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+ ADRENO_QUIRK_HAS_HW_APRIV |
+ ADRENO_QUIRK_PREEMPTION,
+ .funcs = &a7xx_gpu_funcs,
+ .a6xx = &(const struct a6xx_info) {
+ .hwcg = a730_hwcg,
+ .protect = &a730_protect,
+ .pwrup_reglist = &a7xx_pwrup_reglist,
+ .dyn_pwrup_reglist = &a7xx_dyn_pwrup_reglist,
+ .gbif_cx = a640_gbif,
+ .gmu_chipid = 0x07110000,
+ .gmu_cgc_mode = 0x00020000,
+ .bcms = (const struct a6xx_bcm[]) {
+ { .name = "SH0", .buswidth = 16 },
+ { .name = "MC0", .buswidth = 4 },
+ {
+ .name = "ACV",
+ .fixed = true,
+ .perfmode = BIT(3),
+ .perfmode_bw = 16500000,
+ },
+ { /* sentinel */ },
+ },
+ },
+ .preempt_record_size = 1536 * SZ_1K,
+ }, {
.chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */
.family = ADRENO_7XX_GEN2,
.fw = {
@@ -2180,7 +2214,7 @@ static const struct adreno_reglist a840_gbif[] = {
{ REG_A6XX_GBIF_QSB_SIDE1, 0x00071e20 },
{ REG_A6XX_GBIF_QSB_SIDE2, 0x00071e20 },
{ REG_A6XX_GBIF_QSB_SIDE3, 0x00071e20 },
- { REG_A8XX_GBIF_CX_CONFIG, 0x20023000 },
+ { REG_A6XX_GBIF_CX_CONFIG, 0x20023000 },
{ },
};
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 2e5d7b53a0c3..27cac853975f 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -642,7 +642,7 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu)
int ret;
u32 val;
- if (test_and_clear_bit(GMU_STATUS_FW_START, &gmu->status))
+ if (!test_and_clear_bit(GMU_STATUS_FW_START, &gmu->status))
return;
if (adreno_is_a840(adreno_gpu))
@@ -710,7 +710,8 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4,
- adreno_is_a740_family(adreno_gpu) ? 0x80000021 : 0x80000000);
+ (adreno_is_a740_family(adreno_gpu) ||
+ adreno_is_a722(adreno_gpu)) ? 0x80000021 : 0x80000000);
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
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)
gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
/* The second spin of A7xx GPUs messed with some register offsets.. */
- if (adreno_is_a740_family(adreno_gpu))
+ if (adreno_is_a740_family(adreno_gpu) || adreno_is_a722(adreno_gpu))
seqmem0_drv0_reg = REG_A7XX_RSCC_SEQ_MEM_0_DRV0_A740;
/* 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)
gpu_write(gpu, gbif_cx[i].offset, gbif_cx[i].value);
if (adreno_is_a8xx(adreno_gpu)) {
- gpu_write(gpu, REG_A8XX_GBIF_CX_CONFIG, 0x20023000);
+ gpu_write(gpu, REG_A6XX_GBIF_CX_CONFIG, 0x20023000);
gmu_write(gmu, REG_A6XX_GMU_MRC_GBIF_QOS_CTRL, 0x33);
- }
+ } else if (adreno_is_a722(adreno_gpu))
+ gpu_rmw(gpu, REG_A6XX_GBIF_CX_CONFIG, GENMASK(31, 29),
+ FIELD_PREP(GENMASK(31, 29), 2));
/* Set up the lowest idle level on the GMU */
a6xx_gmu_power_config(gmu);
@@ -1087,7 +1090,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)
u32 val, seqmem_off = 0;
/* The second spin of A7xx GPUs messed with some register offsets.. */
- if (adreno_is_a740_family(adreno_gpu) || adreno_is_a8xx(adreno_gpu))
+ if (adreno_is_a740_family(adreno_gpu) || adreno_is_a722(adreno_gpu) ||
+ adreno_is_a8xx(adreno_gpu))
seqmem_off = 4;
/* Make sure there are no outstanding RPMh votes */
@@ -1100,7 +1104,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)
gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS + seqmem_off,
val, (val & 1), 100, 1000);
- if (!adreno_is_a740_family(adreno_gpu) && !adreno_is_a8xx(adreno_gpu))
+ if (!adreno_is_a740_family(adreno_gpu) && !adreno_is_a722(adreno_gpu) &&
+ !adreno_is_a8xx(adreno_gpu))
return;
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)
/* Stop the interrupts and mask the hardware */
a6xx_gmu_irq_disable(gmu);
+ /* Halt the gmu cm3 core */
+ gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
+
/* Tell RPMh to power off the GPU */
a6xx_rpmh_stop(gmu);
@@ -1546,7 +1554,7 @@ static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo,
flags |= MSM_BO_MAP_PRIV;
}
- bo->obj = msm_gem_new(dev, size, flags);
+ bo->obj = msm_gem_new(dev, size, flags, NULL);
if (IS_ERR(bo->obj))
return PTR_ERR(bo->obj);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 8b3bb2fd433b..f9de9329dee3 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -229,7 +229,7 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
{
bool sysprof = msm_gpu_sysprof_no_perfcntr_zap(&a6xx_gpu->base.base);
struct msm_context *ctx = submit->queue->ctx;
- struct drm_gpuvm *vm = msm_context_vm(submit->dev, ctx);
+ struct drm_gpuvm *vm = ctx->vm;
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
phys_addr_t ttbr;
u32 asid;
@@ -1273,7 +1273,8 @@ static int hw_init(struct msm_gpu *gpu)
if (!(adreno_is_a650_family(adreno_gpu) ||
adreno_is_a702(adreno_gpu) ||
adreno_is_a730(adreno_gpu))) {
- gmem_range_min = adreno_is_a740_family(adreno_gpu) ? SZ_16M : SZ_1M;
+ gmem_range_min = (adreno_is_a740_family(adreno_gpu) ||
+ adreno_is_a722(adreno_gpu)) ? SZ_16M : SZ_1M;
/* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */
gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN, gmem_range_min);
@@ -1338,6 +1339,7 @@ static int hw_init(struct msm_gpu *gpu)
/* Enable fault detection */
if (adreno_is_a612(adreno_gpu) ||
+ adreno_is_a722(adreno_gpu) ||
adreno_is_a730(adreno_gpu) ||
adreno_is_a740_family(adreno_gpu))
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)
gpu_write(gpu, REG_A6XX_RBBM_INT_CLEAR_CMD, status);
- if (priv->disable_err_irq)
+ if (priv->disable_err_irq) {
+ /* Turn off interrupts to avoid interrupt storm */
+ gpu_write(gpu, REG_A6XX_RBBM_INT_0_MASK, A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS);
status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;
+ }
if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)
a6xx_fault_detect_irq(gpu);
@@ -2770,8 +2775,9 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
adreno_gpu->ubwc_config = qcom_ubwc_config_get_data();
if (IS_ERR(adreno_gpu->ubwc_config)) {
+ ret = PTR_ERR(adreno_gpu->ubwc_config);
a6xx_destroy(&(a6xx_gpu->base.base));
- return ERR_CAST(adreno_gpu->ubwc_config);
+ return ERR_PTR(ret);
}
/* Set up the preemption specific bits and pieces for each ringbuffer */
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
index 166365359fa6..26c17861cd5d 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
@@ -11,12 +11,14 @@
static const unsigned int *gen7_0_0_external_core_regs[] __always_unused;
static const unsigned int *gen7_2_0_external_core_regs[] __always_unused;
static const unsigned int *gen7_9_0_external_core_regs[] __always_unused;
+static const unsigned int *gen7_17_0_external_core_regs[] __always_unused;
static const struct gen7_sptp_cluster_registers gen7_9_0_sptp_clusters[] __always_unused;
static const u32 gen7_9_0_cx_debugbus_blocks[] __always_unused;
#include "adreno_gen7_0_0_snapshot.h"
#include "adreno_gen7_2_0_snapshot.h"
#include "adreno_gen7_9_0_snapshot.h"
+#include "adreno_gen7_17_0_snapshot.h"
struct a6xx_gpu_state_obj {
const void *handle;
@@ -404,8 +406,13 @@ static void a7xx_get_debugbus_blocks(struct msm_gpu *gpu,
int i;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- debugbus_blocks = gen7_0_0_debugbus_blocks;
- debugbus_blocks_count = ARRAY_SIZE(gen7_0_0_debugbus_blocks);
+ if (adreno_is_a722(adreno_gpu)) {
+ debugbus_blocks = gen7_17_0_debugbus_blocks;
+ debugbus_blocks_count = ARRAY_SIZE(gen7_17_0_debugbus_blocks);
+ } else {
+ debugbus_blocks = gen7_0_0_debugbus_blocks;
+ debugbus_blocks_count = ARRAY_SIZE(gen7_0_0_debugbus_blocks);
+ }
gbif_debugbus_blocks = a7xx_gbif_debugbus_blocks;
gbif_debugbus_blocks_count = ARRAY_SIZE(a7xx_gbif_debugbus_blocks);
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
@@ -678,8 +685,13 @@ static void a7xx_get_dbgahb_clusters(struct msm_gpu *gpu,
unsigned dbgahb_clusters_size;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- dbgahb_clusters = gen7_0_0_sptp_clusters;
- dbgahb_clusters_size = ARRAY_SIZE(gen7_0_0_sptp_clusters);
+ if (adreno_is_a722(adreno_gpu)) {
+ dbgahb_clusters = gen7_17_0_sptp_clusters;
+ dbgahb_clusters_size = ARRAY_SIZE(gen7_17_0_sptp_clusters);
+ } else {
+ dbgahb_clusters = gen7_0_0_sptp_clusters;
+ dbgahb_clusters_size = ARRAY_SIZE(gen7_0_0_sptp_clusters);
+ }
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
dbgahb_clusters = gen7_2_0_sptp_clusters;
dbgahb_clusters_size = ARRAY_SIZE(gen7_2_0_sptp_clusters);
@@ -839,8 +851,13 @@ static void a7xx_get_clusters(struct msm_gpu *gpu,
unsigned clusters_size;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- clusters = gen7_0_0_clusters;
- clusters_size = ARRAY_SIZE(gen7_0_0_clusters);
+ if (adreno_is_a722(adreno_gpu)) {
+ clusters = gen7_17_0_clusters;
+ clusters_size = ARRAY_SIZE(gen7_17_0_clusters);
+ } else {
+ clusters = gen7_0_0_clusters;
+ clusters_size = ARRAY_SIZE(gen7_0_0_clusters);
+ }
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
clusters = gen7_2_0_clusters;
clusters_size = ARRAY_SIZE(gen7_2_0_clusters);
@@ -977,8 +994,13 @@ static void a7xx_get_shaders(struct msm_gpu *gpu,
int i;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- shader_blocks = gen7_0_0_shader_blocks;
- num_shader_blocks = ARRAY_SIZE(gen7_0_0_shader_blocks);
+ if (adreno_is_a722(adreno_gpu)) {
+ shader_blocks = gen7_17_0_shader_blocks;
+ num_shader_blocks = ARRAY_SIZE(gen7_17_0_shader_blocks);
+ } else {
+ shader_blocks = gen7_0_0_shader_blocks;
+ num_shader_blocks = ARRAY_SIZE(gen7_0_0_shader_blocks);
+ }
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
shader_blocks = gen7_2_0_shader_blocks;
num_shader_blocks = ARRAY_SIZE(gen7_2_0_shader_blocks);
@@ -1244,9 +1266,12 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu,
_a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[1],
&a6xx_state->gmu_registers[1], true);
- if (adreno_is_a621(adreno_gpu) || adreno_is_a623(adreno_gpu))
+ if (adreno_is_a621(adreno_gpu))
_a6xx_get_gmu_registers(gpu, a6xx_state, &a621_gpucc_reg,
&a6xx_state->gmu_registers[2], false);
+ else if (adreno_is_a623(adreno_gpu) || adreno_is_a663(adreno_gpu))
+ _a6xx_get_gmu_registers(gpu, a6xx_state, &a623_gpucc_reg,
+ &a6xx_state->gmu_registers[2], false);
else
_a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gpucc_reg,
&a6xx_state->gmu_registers[2], false);
@@ -1376,8 +1401,13 @@ static void a7xx_get_registers(struct msm_gpu *gpu,
const struct gen7_reg_list *reglist;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- reglist = gen7_0_0_reg_list;
- pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;
+ if (adreno_is_a722(adreno_gpu)) {
+ reglist = gen7_17_0_reg_list;
+ pre_crashdumper_regs = gen7_9_0_pre_crashdumper_gpu_registers;
+ } else {
+ reglist = gen7_0_0_reg_list;
+ pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;
+ }
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
reglist = gen7_2_0_reg_list;
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,
const u32 *regs;
BUG_ON(adreno_gpu->info->family > ADRENO_7XX_GEN3);
- regs = gen7_0_0_post_crashdumper_registers;
+ regs = adreno_is_a722(adreno_gpu) ?
+ gen7_17_0_post_crashdumper_registers :
+ gen7_0_0_post_crashdumper_registers;
a7xx_get_ahb_gpu_registers(gpu,
a6xx_state, regs,
@@ -1540,19 +1572,35 @@ static void a7xx_get_indexed_registers(struct msm_gpu *gpu,
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
const struct a6xx_indexed_registers *indexed_regs;
+ const struct a6xx_indexed_registers *mempool_regs;
int i, indexed_count, mempool_count;
+ bool concurrent_binning;
- if (adreno_gpu->info->family <= ADRENO_7XX_GEN2) {
+ if (adreno_is_a722(adreno_gpu)) {
+ /*
+ * Eliza has no BV or LPAC SQE — skip the BV/LPAC indexed
+ * registers and the BV mempool
+ */
+ indexed_regs = gen7_17_0_cp_indexed_reglist;
+ indexed_count = ARRAY_SIZE(gen7_17_0_cp_indexed_reglist);
+ mempool_regs = a7xx_cp_mempool_indexed;
+ mempool_count = ARRAY_SIZE(a7xx_cp_mempool_indexed);
+ concurrent_binning = false;
+ } else if (adreno_gpu->info->family <= ADRENO_7XX_GEN2) {
indexed_regs = a7xx_indexed_reglist;
indexed_count = ARRAY_SIZE(a7xx_indexed_reglist);
+ mempool_regs = a7xx_cp_bv_mempool_indexed;
+ mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
+ concurrent_binning = true;
} else {
BUG_ON(adreno_gpu->info->family != ADRENO_7XX_GEN3);
indexed_regs = gen7_9_0_cp_indexed_reg_list;
indexed_count = ARRAY_SIZE(gen7_9_0_cp_indexed_reg_list);
+ mempool_regs = a7xx_cp_bv_mempool_indexed;
+ mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
+ concurrent_binning = true;
}
- mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
-
a6xx_state->indexed_regs = state_kcalloc(a6xx_state,
indexed_count + mempool_count,
sizeof(*a6xx_state->indexed_regs));
@@ -1567,15 +1615,17 @@ static void a7xx_get_indexed_registers(struct msm_gpu *gpu,
&a6xx_state->indexed_regs[i]);
gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, 0, BIT(2));
- gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, 0, BIT(2));
+ if (concurrent_binning)
+ gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, 0, BIT(2));
/* Get the contents of the CP_BV mempool */
for (i = 0; i < mempool_count; i++)
- a6xx_get_indexed_regs(gpu, a6xx_state, &a7xx_cp_bv_mempool_indexed[i],
+ a6xx_get_indexed_regs(gpu, a6xx_state, &mempool_regs[i],
&a6xx_state->indexed_regs[indexed_count + i]);
gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(2), 0);
- gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, BIT(2), 0);
+ if (concurrent_binning)
+ gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, BIT(2), 0);
return;
}
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
index b49d8427b59e..6f592394f866 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
@@ -378,6 +378,17 @@ static const u32 a6xx_gmu_gpucc_registers[] = {
static const u32 a621_gmu_gpucc_registers[] = {
/* GPU CC */
+ 0x24000, 0x2400e, 0x24400, 0x2440e, 0x24800, 0x24805, 0x24c00, 0x24cff,
+ 0x25800, 0x25804, 0x25c00, 0x25c04, 0x26000, 0x26004, 0x26400, 0x26405,
+ 0x26414, 0x2641d, 0x2642a, 0x26430, 0x26432, 0x26432, 0x26441, 0x26455,
+ 0x26466, 0x26468, 0x26478, 0x2647a, 0x26489, 0x2648a, 0x2649c, 0x2649e,
+ 0x264a0, 0x264a3, 0x264b3, 0x264b5, 0x264c5, 0x264c7, 0x264d6, 0x264d8,
+ 0x264e8, 0x264e9, 0x264f9, 0x264fc, 0x2650b, 0x2650c, 0x2651c, 0x2651e,
+ 0x26540, 0x26570, 0x26600, 0x26616, 0x26620, 0x2662d,
+};
+
+static const u32 a623_gmu_gpucc_registers[] = {
+ /* GPU CC */
0x24000, 0x2400e, 0x24400, 0x2440e, 0x25800, 0x25804, 0x25c00, 0x25c04,
0x26000, 0x26004, 0x26400, 0x26405, 0x26414, 0x2641d, 0x2642a, 0x26430,
0x26432, 0x26432, 0x26441, 0x26455, 0x26466, 0x26468, 0x26478, 0x2647a,
@@ -402,6 +413,7 @@ static const struct a6xx_registers a6xx_gmu_reglist[] = {
static const struct a6xx_registers a6xx_gpucc_reg = REGS(a6xx_gmu_gpucc_registers, 0, 0);
static const struct a6xx_registers a621_gpucc_reg = REGS(a621_gmu_gpucc_registers, 0, 0);
+static const struct a6xx_registers a623_gpucc_reg = REGS(a623_gmu_gpucc_registers, 0, 0);
static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu);
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[] = {
REG_A7XX_CP_BV_MEM_POOL_DBG_DATA, 0x2200, NULL },
};
+static const struct a6xx_indexed_registers a7xx_cp_mempool_indexed[] = {
+ { "CP_MEM_POOL_DBG", REG_A6XX_CP_MEM_POOL_DBG_ADDR,
+ REG_A6XX_CP_MEM_POOL_DBG_DATA, 0x2200, NULL },
+};
+
#define DEBUGBUS(_id, _count) { .id = _id, .name = #_id, .count = _count }
static const struct a6xx_debugbus_block {
diff --git a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
index 9e44fd1ae634..add93c1fa039 100644
--- a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
@@ -228,7 +228,7 @@ static void a8xx_set_hwcg(struct msm_gpu *gpu, bool state)
* GMU enables clk gating in GBIF during boot up. So,
* override that here when hwcg feature is disabled
*/
- gpu_rmw(gpu, REG_A8XX_GBIF_CX_CONFIG, BIT(0), 0);
+ gpu_rmw(gpu, REG_A6XX_GBIF_CX_CONFIG, BIT(0), 0);
}
}
@@ -1211,8 +1211,11 @@ irqreturn_t a8xx_irq(struct msm_gpu *gpu)
gpu_write(gpu, REG_A8XX_RBBM_INT_CLEAR_CMD, status);
- if (priv->disable_err_irq)
+ if (priv->disable_err_irq) {
+ /* Turn off interrupts to avoid interrupt storm */
+ gpu_write(gpu, REG_A8XX_RBBM_INT_0_MASK, A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS);
status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;
+ }
if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)
a8xx_fault_detect_irq(gpu);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h b/drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h
new file mode 100644
index 000000000000..00a4a0fc97d2
--- /dev/null
+++ b/drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h
@@ -0,0 +1,428 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef __ADRENO_GEN7_17_0_SNAPSHOT_H
+#define __ADRENO_GEN7_17_0_SNAPSHOT_H
+
+#include "a6xx_gpu_state.h"
+
+/*
+ * Snapshot tables for Adreno A722 (Eliza).
+ * Cluster sub-arrays that are identical to A730 reference gen7_0_0_*
+ * symbols; adreno_gen7_0_0_snapshot.h is included first in the TU.
+ */
+
+static const u32 gen7_17_0_rscc_registers[] = {
+ 0x14000, 0x14034, 0x14036, 0x14036, 0x14040, 0x14042, 0x14044, 0x14045,
+ 0x14047, 0x14047, 0x14080, 0x14084, 0x14089, 0x1408c, 0x14091, 0x14094,
+ 0x14099, 0x1409c, 0x140a1, 0x140a4, 0x140a9, 0x140ac, 0x140b1, 0x140b4,
+ 0x140b9, 0x140bc, 0x14100, 0x14104, 0x14114, 0x14119, 0x14124, 0x14132,
+ 0x14154, 0x1416b, 0x14340, 0x14341, 0x14344, 0x14344, 0x14346, 0x1437c,
+ 0x143f0, 0x143f8, 0x143fa, 0x143fe, 0x14400, 0x14404, 0x14406, 0x1440a,
+ 0x1440c, 0x14410, 0x14412, 0x14416, 0x14418, 0x1441c, 0x1441e, 0x14422,
+ 0x14424, 0x14424, 0x14498, 0x144a0, 0x144a2, 0x144a6, 0x144a8, 0x144ac,
+ 0x144ae, 0x144b2, 0x144b4, 0x144b8, 0x144ba, 0x144be, 0x144c0, 0x144c4,
+ 0x144c6, 0x144ca, 0x144cc, 0x144cc, 0x14540, 0x14548, 0x1454a, 0x1454e,
+ 0x14550, 0x14554, 0x14556, 0x1455a, 0x1455c, 0x14560, 0x14562, 0x14566,
+ 0x14568, 0x1456c, 0x1456e, 0x14572, 0x14574, 0x14574, 0x145e8, 0x145f0,
+ 0x145f2, 0x145f6, 0x145f8, 0x145fc, 0x145fe, 0x14602, 0x14604, 0x14608,
+ 0x1460a, 0x1460e, 0x14610, 0x14614, 0x14616, 0x1461a, 0x1461c, 0x1461c,
+ 0x14690, 0x14698, 0x1469a, 0x1469e, 0x146a0, 0x146a4, 0x146a6, 0x146aa,
+ 0x146ac, 0x146b0, 0x146b2, 0x146b6, 0x146b8, 0x146bc, 0x146be, 0x146c2,
+ 0x146c4, 0x146c4, 0x14738, 0x14740, 0x14742, 0x14746, 0x14748, 0x1474c,
+ 0x1474e, 0x14752, 0x14754, 0x14758, 0x1475a, 0x1475e, 0x14760, 0x14764,
+ 0x14766, 0x1476a, 0x1476c, 0x1476c, 0x147e0, 0x147e8, 0x147ea, 0x147ee,
+ 0x147f0, 0x147f4, 0x147f6, 0x147fa, 0x147fc, 0x14800, 0x14802, 0x14806,
+ 0x14808, 0x1480c, 0x1480e, 0x14812, 0x14814, 0x14814, 0x14888, 0x14890,
+ 0x14892, 0x14896, 0x14898, 0x1489c, 0x1489e, 0x148a2, 0x148a4, 0x148a8,
+ 0x148aa, 0x148ae, 0x148b0, 0x148b4, 0x148b6, 0x148ba, 0x148bc, 0x148bc,
+ 0x14930, 0x14938, 0x1493a, 0x1493e, 0x14940, 0x14944, 0x14946, 0x1494a,
+ 0x1494c, 0x14950, 0x14952, 0x14956, 0x14958, 0x1495c, 0x1495e, 0x14962,
+ 0x14964, 0x14964,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_rscc_registers), 8));
+
+static const u32 gen7_17_0_cpr_registers[] = {
+ 0x26800, 0x26805, 0x26808, 0x2680c, 0x26814, 0x26814, 0x2681c, 0x2681c,
+ 0x26820, 0x26838, 0x26840, 0x26840, 0x26848, 0x26848, 0x26850, 0x26850,
+ 0x26880, 0x2688e, 0x26980, 0x269b0, 0x269c0, 0x269c2, 0x269c6, 0x269c8,
+ 0x269e0, 0x269ee, 0x269fb, 0x269ff, 0x26a02, 0x26a07, 0x26a09, 0x26a0b,
+ 0x26a10, 0x26b0f, 0x27440, 0x27441, 0x27444, 0x27444, 0x27480, 0x274a2,
+ 0x274ac, 0x274c4, 0x274c8, 0x274da,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_cpr_registers), 8));
+
+static const u32 gen7_17_0_gpucc_registers[] = {
+ 0x24000, 0x2400f, 0x24400, 0x2440f, 0x24800, 0x24805, 0x24c00, 0x24cff,
+ 0x25400, 0x25404, 0x25800, 0x25804, 0x25c00, 0x25c04, 0x26000, 0x26004,
+ 0x26400, 0x26405, 0x26414, 0x2641d, 0x2642a, 0x2642c, 0x2642e, 0x26432,
+ 0x26434, 0x26434, 0x26443, 0x26457, 0x26459, 0x2645d, 0x2645f, 0x26464,
+ 0x26477, 0x26479, 0x26489, 0x2648b, 0x2649a, 0x2649b, 0x264ad, 0x264af,
+ 0x264b1, 0x264b5, 0x264d6, 0x264d8, 0x264e7, 0x264e9, 0x264f9, 0x264fa,
+ 0x2650a, 0x2650d, 0x2651f, 0x26520, 0x2652d, 0x2652f, 0x2653e, 0x2653e,
+ 0x26540, 0x2654e, 0x26554, 0x26573, 0x26576, 0x26576, 0x26593, 0x26593,
+ 0x26600, 0x26616, 0x26620, 0x2662d, 0x26630, 0x26631, 0x26635, 0x26635,
+ 0x26637, 0x26637, 0x2663a, 0x2663a, 0x26642, 0x26642, 0x26656, 0x26658,
+ 0x2665b, 0x2665d, 0x2665f, 0x26662,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_gpucc_registers), 8));
+
+static const u32 *gen7_17_0_external_core_regs[] = {
+ gen7_17_0_gpucc_registers,
+ gen7_17_0_cpr_registers,
+};
+
+static const u32 gen7_17_0_debugbus_blocks[] = {
+ A7XX_DBGBUS_CP_0_0,
+ A7XX_DBGBUS_CP_0_1,
+ A7XX_DBGBUS_RBBM,
+ A7XX_DBGBUS_HLSQ,
+ A7XX_DBGBUS_UCHE_0,
+ A7XX_DBGBUS_TESS_BR,
+ A7XX_DBGBUS_PC_BR,
+ A7XX_DBGBUS_VFDP_BR,
+ A7XX_DBGBUS_VPC_BR,
+ A7XX_DBGBUS_TSE_BR,
+ A7XX_DBGBUS_RAS_BR,
+ A7XX_DBGBUS_VSC,
+ A7XX_DBGBUS_COM_0,
+ A7XX_DBGBUS_LRZ_BR,
+ A7XX_DBGBUS_UFC_0,
+ A7XX_DBGBUS_UFC_1,
+ A7XX_DBGBUS_GMU_GX,
+ A7XX_DBGBUS_DBGC,
+ A7XX_DBGBUS_GPC_BR,
+ A7XX_DBGBUS_LARC,
+ A7XX_DBGBUS_HLSQ_SPTP,
+ A7XX_DBGBUS_RB_0,
+ A7XX_DBGBUS_RB_1,
+ A7XX_DBGBUS_UCHE_WRAPPER,
+ A7XX_DBGBUS_CCU_0,
+ A7XX_DBGBUS_CCU_1,
+ A7XX_DBGBUS_VFD_BR_0,
+ A7XX_DBGBUS_VFD_BR_1,
+ A7XX_DBGBUS_VFD_BR_2,
+ A7XX_DBGBUS_VFD_BR_3,
+ A7XX_DBGBUS_USP_0,
+ A7XX_DBGBUS_USP_1,
+ A7XX_DBGBUS_TP_0,
+ A7XX_DBGBUS_TP_1,
+ A7XX_DBGBUS_TP_2,
+ A7XX_DBGBUS_TP_3,
+ A7XX_DBGBUS_USPTP_0,
+ A7XX_DBGBUS_USPTP_1,
+ A7XX_DBGBUS_USPTP_2,
+ A7XX_DBGBUS_USPTP_3,
+};
+
+static const struct gen7_sel_reg gen7_17_0_rb_rac_sel = {
+ .host_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_HOST,
+ .cd_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_CD,
+ .val = 0x0,
+};
+
+static const struct gen7_sel_reg gen7_17_0_rb_rbp_sel = {
+ .host_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_HOST,
+ .cd_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_CD,
+ .val = 0x9,
+};
+
+static const u32 gen7_17_0_post_crashdumper_registers[] = {
+ 0x00535, 0x00535,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_post_crashdumper_registers), 8));
+
+static const u32 gen7_17_0_gpu_registers[] = {
+ 0x00000, 0x00000, 0x00002, 0x00002, 0x00011, 0x00012, 0x00016, 0x0001b,
+ 0x0001f, 0x00032, 0x00038, 0x0003c, 0x00042, 0x00042, 0x00044, 0x00044,
+ 0x00047, 0x00047, 0x00049, 0x0004a, 0x0004c, 0x0004c, 0x00050, 0x00050,
+ 0x00056, 0x00056, 0x00073, 0x00075, 0x000ad, 0x000ae, 0x000b0, 0x000b0,
+ 0x000b4, 0x000b4, 0x000b8, 0x000b8, 0x000bc, 0x000bc, 0x000c0, 0x000c0,
+ 0x000c4, 0x000c4, 0x000c8, 0x000c8, 0x000cc, 0x000cc, 0x000d0, 0x000d0,
+ 0x000d4, 0x000d4, 0x000d8, 0x000d8, 0x000dc, 0x000dc, 0x000e0, 0x000e0,
+ 0x000e4, 0x000e4, 0x000e8, 0x000e8, 0x000ec, 0x000ec, 0x000f0, 0x000f0,
+ 0x000f4, 0x000f4, 0x000f8, 0x000f8, 0x00100, 0x00100, 0x00104, 0x0010b,
+ 0x0010f, 0x0011d, 0x0012f, 0x0012f, 0x00200, 0x0020d, 0x00215, 0x00243,
+ 0x00260, 0x00268, 0x00272, 0x00274, 0x00286, 0x00286, 0x0028a, 0x0028a,
+ 0x0028c, 0x0028c, 0x00300, 0x00401, 0x00500, 0x00500, 0x00507, 0x0050b,
+ 0x0050f, 0x0050f, 0x00511, 0x00511, 0x00533, 0x00534, 0x00540, 0x00555,
+ 0x00564, 0x00567, 0x00800, 0x00808, 0x00810, 0x00813, 0x00820, 0x00821,
+ 0x00823, 0x00827, 0x00830, 0x00834, 0x00840, 0x00841, 0x00843, 0x00847,
+ 0x0084f, 0x00886, 0x008a0, 0x008ab, 0x008c0, 0x008c0, 0x008c4, 0x008c5,
+ 0x008d0, 0x008dd, 0x008f0, 0x008f3, 0x00900, 0x00903, 0x00908, 0x00911,
+ 0x00928, 0x0093e, 0x00942, 0x0094d, 0x00980, 0x00984, 0x0098d, 0x0098f,
+ 0x009b0, 0x009b4, 0x009c2, 0x009c9, 0x009ce, 0x009d7, 0x00a00, 0x00a00,
+ 0x00a02, 0x00a03, 0x00a10, 0x00a4f, 0x00a67, 0x00a6c, 0x00a9c, 0x00a9f,
+ 0x00c00, 0x00c00, 0x00c02, 0x00c04, 0x00c06, 0x00c06, 0x00c10, 0x00cd9,
+ 0x00ce0, 0x00d0c, 0x00df0, 0x00df4, 0x00e01, 0x00e02, 0x00e07, 0x00e0e,
+ 0x00e10, 0x00e12, 0x00e17, 0x00e17, 0x00e19, 0x00e19, 0x00e1b, 0x00e2b,
+ 0x00e30, 0x00e32, 0x00e38, 0x00e3c,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_gpu_registers), 8));
+
+static const u32 gen7_17_0_dbgc_registers[] = {
+ 0x00600, 0x0061c, 0x0061e, 0x00634, 0x00640, 0x0065a, 0x00679, 0x0067a,
+ 0x00699, 0x00699, 0x0069b, 0x0069e, 0x18400, 0x1841c, 0x1841e, 0x18434,
+ 0x18440, 0x1845c, 0x18479, 0x1847c, 0x18580, 0x18581,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_dbgc_registers), 8));
+
+static const u32 gen7_17_0_noncontext_pipe_br_registers[] = {
+ 0x00887, 0x0088c, 0x08600, 0x08600, 0x08602, 0x08602, 0x08610, 0x0861b,
+ 0x08620, 0x08620, 0x08630, 0x08630, 0x08637, 0x08639, 0x08640, 0x08640,
+ 0x09600, 0x09600, 0x09602, 0x09603, 0x0960a, 0x09616, 0x09624, 0x0963a,
+ 0x09640, 0x09640, 0x09e00, 0x09e00, 0x09e02, 0x09e07, 0x09e0a, 0x09e16,
+ 0x09e19, 0x09e19, 0x09e1c, 0x09e1c, 0x09e20, 0x09e25, 0x09e30, 0x09e31,
+ 0x09e40, 0x09e51, 0x09e64, 0x09e64, 0x09e70, 0x09e72, 0x09e78, 0x09e79,
+ 0x09e80, 0x09fff, 0x0a600, 0x0a600, 0x0a603, 0x0a603, 0x0a610, 0x0a61f,
+ 0x0a630, 0x0a631, 0x0a638, 0x0a638,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_pipe_br_registers), 8));
+
+static const u32 gen7_17_0_noncontext_rb_rac_pipe_br_registers[] = {
+ 0x08e10, 0x08e1c, 0x08e20, 0x08e25, 0x08e51, 0x08e54,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_rb_rac_pipe_br_registers), 8));
+
+static const u32 gen7_17_0_noncontext_rb_rbp_pipe_br_registers[] = {
+ 0x08e01, 0x08e01, 0x08e04, 0x08e04, 0x08e06, 0x08e09, 0x08e0c, 0x08e0c,
+ 0x08e28, 0x08e28, 0x08e2c, 0x08e35, 0x08e3b, 0x08e3f, 0x08e50, 0x08e50,
+ 0x08e5b, 0x08e5d, 0x08e5f, 0x08e5f, 0x08e61, 0x08e61, 0x08e63, 0x08e65,
+ 0x08e68, 0x08e68, 0x08e70, 0x08e79, 0x08e80, 0x08e8f,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_rb_rbp_pipe_br_registers), 8));
+
+static const u32 gen7_17_0_pc_cluster_fe_pipe_br_registers[] = {
+ 0x09800, 0x09804, 0x09806, 0x0980a, 0x09810, 0x09811, 0x09884, 0x09886,
+ 0x09970, 0x09972, 0x09b00, 0x09b08,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_pc_cluster_fe_pipe_br_registers), 8));
+
+static const u32 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers[] = {
+ 0x0aa40, 0x0aabf,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers), 8));
+
+static const u32 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers[] = {
+ 0x0aa40, 0x0aabf,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers), 8));
+
+static const u32 gen7_17_0_non_context_tpl1_pipe_none_usptp_registers[] = {
+ 0x0b602, 0x0b602, 0x0b604, 0x0b604, 0x0b608, 0x0b60c, 0x0b60f, 0x0b621,
+ 0x0b630, 0x0b633,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_non_context_tpl1_pipe_none_usptp_registers), 8));
+
+static const u32 gen7_17_0_non_context_tpl1_pipe_br_usptp_registers[] = {
+ 0x0b600, 0x0b600,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_non_context_tpl1_pipe_br_usptp_registers), 8));
+
+static const u32 gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers[] = {
+ 0x0b300, 0x0b307, 0x0b309, 0x0b309, 0x0b310, 0x0b310,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers), 8));
+
+static const u32 gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers[] = {
+ 0x0b180, 0x0b183, 0x0b190, 0x0b195, 0x0b2c0, 0x0b2d5, 0x0b300, 0x0b307,
+ 0x0b309, 0x0b309, 0x0b310, 0x0b310,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers), 8));
+
+/* No BV pipe — gen7_0_0_* sub-arrays are shared from adreno_gen7_0_0_snapshot.h */
+static struct gen7_cluster_registers gen7_17_0_clusters[] = {
+ { A7XX_CLUSTER_NONE, PIPE_BR, STATE_NON_CONTEXT,
+ gen7_17_0_noncontext_pipe_br_registers, },
+ { A7XX_CLUSTER_NONE, PIPE_BR, STATE_NON_CONTEXT,
+ gen7_17_0_noncontext_rb_rac_pipe_br_registers, &gen7_17_0_rb_rac_sel, },
+ { A7XX_CLUSTER_NONE, PIPE_BR, STATE_NON_CONTEXT,
+ gen7_17_0_noncontext_rb_rbp_pipe_br_registers, &gen7_17_0_rb_rbp_sel, },
+ { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_rb_rac_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rac_sel, },
+ { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_rb_rac_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rac_sel, },
+ { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_rb_rbp_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rbp_sel, },
+ { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_rb_rbp_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rbp_sel, },
+ { A7XX_CLUSTER_GRAS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_gras_cluster_gras_pipe_br_registers, },
+ { A7XX_CLUSTER_GRAS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_gras_cluster_gras_pipe_br_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_17_0_pc_cluster_fe_pipe_br_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_17_0_pc_cluster_fe_pipe_br_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_vfd_cluster_fe_pipe_bv_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_vfd_cluster_fe_pipe_bv_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_vpc_cluster_fe_pipe_br_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_vpc_cluster_fe_pipe_br_registers, },
+ { A7XX_CLUSTER_PC_VS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_vpc_cluster_pc_vs_pipe_br_registers, },
+ { A7XX_CLUSTER_PC_VS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_vpc_cluster_pc_vs_pipe_br_registers, },
+ { A7XX_CLUSTER_VPC_PS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_vpc_cluster_vpc_ps_pipe_br_registers, },
+ { A7XX_CLUSTER_VPC_PS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_vpc_cluster_vpc_ps_pipe_br_registers, },
+};
+
+/* No BV pipe; 2 SPs, 2 USPTPs */
+static struct gen7_sptp_cluster_registers gen7_17_0_sptp_clusters[] = {
+ { A7XX_CLUSTER_NONE, A7XX_SP_NCTX_REG, PIPE_BR, 0, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_noncontext_pipe_br_hlsq_state_registers, 0xae00 },
+ { A7XX_CLUSTER_NONE, A7XX_SP_NCTX_REG, PIPE_BR, 0, A7XX_SP_TOP,
+ gen7_0_0_sp_noncontext_pipe_br_sp_top_registers, 0xae00 },
+ { A7XX_CLUSTER_NONE, A7XX_SP_NCTX_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_0_0_sp_noncontext_pipe_br_usptp_registers, 0xae00 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_HLSQ_DP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_LPAC, 0, A7XX_HLSQ_STATE,
+ gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_LPAC, 0, A7XX_USPTP,
+ gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_HLSQ_DP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_HLSQ_DP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_HLSQ_DP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_NONE, A7XX_TP0_NCTX_REG, PIPE_NONE, 0, A7XX_USPTP,
+ gen7_17_0_non_context_tpl1_pipe_none_usptp_registers, 0xb600 },
+ { A7XX_CLUSTER_NONE, A7XX_TP0_NCTX_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_17_0_non_context_tpl1_pipe_br_usptp_registers, 0xb600 },
+ { A7XX_CLUSTER_SP_VS, A7XX_TP0_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_VS, A7XX_TP0_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
+};
+
+static struct gen7_shader_block gen7_17_0_shader_blocks[] = {
+ { A7XX_TP0_TMO_DATA, 0x0200, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_TP0_SMO_DATA, 0x0080, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_TP0_MIPMAP_BASE_DATA, 0x03c0, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_INST_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_INST_DATA_1, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_0_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_1_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_2_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_3_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_4_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_5_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_CB_RAM, 0x0390, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_INST_TAG, 0x0090, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_TMO_TAG, 0x0080, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_SMO_TAG, 0x0080, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_STATE_DATA, 0x0040, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_HWAVE_RAM, 0x0100, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_L0_INST_BUF, 0x0050, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_HLSQ_CVS_BE_CTXT_BUF_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CPS_BE_CTXT_BUF_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CVS_BE_CTXT_BUF_RAM, 0x0300, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CPS_BE_CTXT_BUF_RAM, 0x0300, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CHUNK_CVS_RAM, 0x01c0, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CHUNK_CPS_RAM, 0x0300, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CHUNK_CVS_RAM_TAG, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CHUNK_CPS_RAM_TAG, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_ICB_CVS_CB_BASE_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_ICB_CPS_CB_BASE_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CVS_MISC_RAM, 0x0280, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CPS_MISC_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CPS_MISC_RAM_1, 0x0200, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_INST_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CVS_CONST_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CPS_CONST_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CVS_MISC_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CPS_MISC_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_INST_RAM_TAG, 0x0080, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CVS_CONST_RAM_TAG, 0x0064, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CPS_CONST_RAM_TAG, 0x0064, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_INST_RAM_1, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_STPROC_META, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_BV_BE_META, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_DATAPATH_META, 0x0020, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_FRONTEND_META, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_INDIRECT_META, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_BACKEND_META, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+};
+
+static struct gen7_reg_list gen7_17_0_reg_list[] = {
+ { gen7_17_0_gpu_registers, NULL },
+ { gen7_17_0_dbgc_registers, NULL },
+ { NULL, NULL },
+};
+
+static const struct a6xx_indexed_registers gen7_17_0_cp_indexed_reglist[] = {
+ { "CP_SQE_STAT", REG_A6XX_CP_SQE_STAT_ADDR,
+ REG_A6XX_CP_SQE_STAT_DATA, 0x40, NULL },
+ { "CP_DRAW_STATE", REG_A6XX_CP_DRAW_STATE_ADDR,
+ REG_A6XX_CP_DRAW_STATE_DATA, 0x100, NULL },
+ { "CP_SQE_UCODE_DBG", REG_A6XX_CP_SQE_UCODE_DBG_ADDR,
+ REG_A6XX_CP_SQE_UCODE_DBG_DATA, 0x8000, NULL },
+ { "CP_ROQ_DBG", REG_A6XX_CP_ROQ_DBG_ADDR,
+ REG_A6XX_CP_ROQ_DBG_DATA, 0, a7xx_get_cp_roq_size },
+};
+
+#endif /* __ADRENO_GEN7_17_0_SNAPSHOT_H */
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index c62c45bb0ddb..3370cd44382f 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -356,6 +356,12 @@ int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags,
return 0;
}
+static bool
+valid_per_process_vm(struct msm_gpu *gpu, struct drm_gpuvm *vm)
+{
+ return vm && (vm != gpu->vm);
+}
+
int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx,
uint32_t param, uint64_t *value, uint32_t *len)
{
@@ -414,12 +420,12 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx,
*value = gpu->suspend_count;
return 0;
case MSM_PARAM_VA_START:
- if (vm == gpu->vm)
+ if (!valid_per_process_vm(gpu, vm))
return UERR(EINVAL, drm, "requires per-process pgtables");
*value = vm->mm_start;
return 0;
case MSM_PARAM_VA_SIZE:
- if (vm == gpu->vm)
+ if (!valid_per_process_vm(gpu, vm))
return UERR(EINVAL, drm, "requires per-process pgtables");
*value = vm->mm_range;
return 0;
@@ -503,9 +509,11 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_context *ctx,
if (!perfmon_capable())
return UERR(EPERM, drm, "invalid permissions");
return msm_context_set_sysprof(ctx, gpu, value);
- case MSM_PARAM_EN_VM_BIND:
+ case MSM_PARAM_EN_VM_BIND: {
+ guard(rwsem_read)(&ctx->ctxlock);
+
/* We can only support VM_BIND with per-process pgtables: */
- if (ctx->vm == gpu->vm)
+ if (!gpu->funcs->create_private_vm)
return UERR(EINVAL, drm, "requires per-process pgtables");
/*
@@ -518,6 +526,7 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_context *ctx,
ctx->userspace_managed_vm = value;
return 0;
+ }
default:
return UERR(EINVAL, drm, "%s: invalid param: %u", gpu->name, param);
}
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 1f201322cb6e..114a40f79ef3 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -562,6 +562,11 @@ static inline int adreno_is_x185(struct adreno_gpu *gpu)
return gpu->info->chip_ids[0] == 0x43050c01;
}
+static inline int adreno_is_a722(struct adreno_gpu *gpu)
+{
+ return gpu->info->chip_ids[0] == 0x43020100;
+}
+
static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
{
if (WARN_ON_ONCE(!gpu->info))
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_13_0_kaanapali.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_13_0_kaanapali.h
index 06da1583fb1e..85f455a9f29c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_13_0_kaanapali.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_13_0_kaanapali.h
@@ -86,42 +86,42 @@ static const struct dpu_sspp_cfg kaanapali_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x97000, .len = 0x84,
.features = DMA_SDM845_MASK_SDMA,
- .sblk = &dpu_dma_sblk,
+ .sblk = &dpu_dma_sblk_v13,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
}, {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0xa0000, .len = 0x84,
.features = DMA_SDM845_MASK_SDMA,
- .sblk = &dpu_dma_sblk,
+ .sblk = &dpu_dma_sblk_v13,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
}, {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0xa9000, .len = 0x84,
.features = DMA_SDM845_MASK_SDMA,
- .sblk = &dpu_dma_sblk,
+ .sblk = &dpu_dma_sblk_v13,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
}, {
.name = "sspp_11", .id = SSPP_DMA3,
.base = 0xb2000, .len = 0x84,
.features = DMA_SDM845_MASK_SDMA,
- .sblk = &dpu_dma_sblk,
+ .sblk = &dpu_dma_sblk_v13,
.xin_id = 13,
.type = SSPP_TYPE_DMA,
}, {
.name = "sspp_12", .id = SSPP_DMA4,
.base = 0xbb000, .len = 0x84,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
- .sblk = &dpu_dma_sblk,
+ .sblk = &dpu_dma_sblk_v13,
.xin_id = 14,
.type = SSPP_TYPE_DMA,
}, {
.name = "sspp_13", .id = SSPP_DMA5,
.base = 0xc4000, .len = 0x84,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
- .sblk = &dpu_dma_sblk,
+ .sblk = &dpu_dma_sblk_v13,
.xin_id = 15,
.type = SSPP_TYPE_DMA,
},
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index 13cc658065c5..fea173e37464 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -34,7 +34,7 @@ enum dpu_perf_mode {
/**
* dpu_core_perf_adjusted_mode_clk - Adjust given mode clock rate according to
* the perf clock factor.
- * @crtc_clk_rate - Unadjusted mode clock rate
+ * @mode_clk_rate: unadjusted mode clock rate
* @perf_cfg: performance configuration
*/
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,
trace_dpu_core_perf_update_clk(kms->dev, !crtc->enabled, clk_rate);
+ /* If we're going offline, PM callbacks will disable the clocks instead */
+ if (!clk_rate)
+ return 0;
+
clk_rate = min(clk_rate, kms->perf.max_core_clk_rate);
ret = dev_pm_opp_set_rate(&kms->pdev->dev, clk_rate);
if (ret) {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 778e231d4967..1f20695f81e3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -710,8 +710,7 @@ void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
topology->num_cdm++;
} else if (disp_info->intf_type == INTF_DP) {
- if (msm_dp_is_yuv_420_enabled(priv->kms->dp[disp_info->h_tile_instance[0]],
- adj_mode))
+ if (drm_mode_is_420_only(&connector->display_info, adj_mode))
topology->num_cdm++;
}
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 2e10add84fd7..9a993cdfab85 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -303,6 +303,16 @@ static const u32 wb2_formats_rgb_yuv[] = {
.num_formats = ARRAY_SIZE(plane_formats), \
}
+#define _DMA_SBLK_V13() \
+ { \
+ .sspp_rec0_blk = {.name = "sspp_rec0", \
+ .base = 0x1000, .len = 0x180,}, \
+ .sspp_rec1_blk = {.name = "sspp_rec1", \
+ .base = 0x3000, .len = 0x180,}, \
+ .format_list = plane_formats, \
+ .num_formats = ARRAY_SIZE(plane_formats), \
+ }
+
static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = {
.rot_maxheight = 1088,
.rot_num_formats = ARRAY_SIZE(rotation_v2_formats),
@@ -353,6 +363,8 @@ static const struct dpu_sspp_sub_blks dpu_rgb_sblk = _RGB_SBLK();
static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK();
+static const struct dpu_sspp_sub_blks dpu_dma_sblk_v13 = _DMA_SBLK_V13();
+
/*************************************************************
* MIXER sub blocks config
*************************************************************/
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
index 7726edb0d4ed..9b1d1982e683 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
@@ -398,7 +398,7 @@ static int mdp4_kms_init(struct drm_device *dev)
ret = mdp_kms_init(&mdp4_kms->base, &kms_funcs);
if (ret) {
DRM_DEV_ERROR(dev->dev, "failed to init kms\n");
- goto fail;
+ return ret;
}
kms = priv->kms;
@@ -409,7 +409,7 @@ static int mdp4_kms_init(struct drm_device *dev)
ret = regulator_enable(mdp4_kms->vdd);
if (ret) {
DRM_DEV_ERROR(dev->dev, "failed to enable regulator vdd: %d\n", ret);
- goto fail;
+ return ret;
}
}
@@ -421,7 +421,7 @@ static int mdp4_kms_init(struct drm_device *dev)
DRM_DEV_ERROR(dev->dev, "unexpected MDP version: v%d.%d\n",
major, minor);
ret = -ENXIO;
- goto fail;
+ return ret;
}
mdp4_kms->rev = minor;
@@ -430,7 +430,7 @@ static int mdp4_kms_init(struct drm_device *dev)
if (!mdp4_kms->lut_clk) {
DRM_DEV_ERROR(dev->dev, "failed to get lut_clk\n");
ret = -ENODEV;
- goto fail;
+ return ret;
}
clk_set_rate(mdp4_kms->lut_clk, max_clk);
}
@@ -452,7 +452,7 @@ static int mdp4_kms_init(struct drm_device *dev)
vm = msm_kms_init_vm(mdp4_kms->dev, NULL);
if (IS_ERR(vm)) {
ret = PTR_ERR(vm);
- goto fail;
+ return ret;
}
kms->vm = vm;
@@ -460,22 +460,22 @@ static int mdp4_kms_init(struct drm_device *dev)
ret = modeset_init(mdp4_kms);
if (ret) {
DRM_DEV_ERROR(dev->dev, "modeset_init failed: %d\n", ret);
- goto fail;
+ return ret;
}
- mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC | MSM_BO_SCANOUT);
+ mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC | MSM_BO_SCANOUT, NULL);
if (IS_ERR(mdp4_kms->blank_cursor_bo)) {
ret = PTR_ERR(mdp4_kms->blank_cursor_bo);
DRM_DEV_ERROR(dev->dev, "could not allocate blank-cursor bo: %d\n", ret);
mdp4_kms->blank_cursor_bo = NULL;
- goto fail;
+ return ret;
}
ret = msm_gem_get_and_pin_iova(mdp4_kms->blank_cursor_bo, kms->vm,
&mdp4_kms->blank_cursor_iova);
if (ret) {
DRM_DEV_ERROR(dev->dev, "could not pin blank-cursor bo: %d\n", ret);
- goto fail;
+ return ret;
}
dev->mode_config.min_width = 0;
@@ -484,12 +484,6 @@ static int mdp4_kms_init(struct drm_device *dev)
dev->mode_config.max_height = 2048;
return 0;
-
-fail:
- if (kms)
- mdp4_destroy(kms);
-
- return ret;
}
static const struct dev_pm_ops mdp4_pm_ops = {
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index 0a004ab9fc85..3934cd060b27 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -517,7 +517,7 @@ static int mdp5_kms_init(struct drm_device *dev)
ret = mdp_kms_init(&mdp5_kms->base, &kms_funcs);
if (ret) {
DRM_DEV_ERROR(&pdev->dev, "failed to init kms\n");
- goto fail;
+ return ret;
}
config = mdp5_cfg_get_config(mdp5_kms->cfg);
@@ -540,7 +540,7 @@ static int mdp5_kms_init(struct drm_device *dev)
vm = msm_kms_init_vm(mdp5_kms->dev, pdev->dev.parent);
if (IS_ERR(vm)) {
ret = PTR_ERR(vm);
- goto fail;
+ return ret;
}
kms->vm = vm;
@@ -550,7 +550,7 @@ static int mdp5_kms_init(struct drm_device *dev)
ret = modeset_init(mdp5_kms);
if (ret) {
DRM_DEV_ERROR(&pdev->dev, "modeset_init failed: %d\n", ret);
- goto fail;
+ return ret;
}
dev->mode_config.min_width = 0;
@@ -562,11 +562,6 @@ static int mdp5_kms_init(struct drm_device *dev)
dev->vblank_disable_immediate = true;
return 0;
-fail:
- if (kms)
- mdp5_kms_destroy(kms);
-
- return ret;
}
static void mdp5_destroy(struct mdp5_kms *mdp5_kms)
diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c
index 41018e82efa1..df222943ae57 100644
--- a/drivers/gpu/drm/msm/dp/dp_audio.c
+++ b/drivers/gpu/drm/msm/dp/dp_audio.c
@@ -284,10 +284,8 @@ int msm_dp_audio_prepare(struct drm_bridge *bridge,
* such cases check for connection status and bail out if not
* connected.
*/
- if (!msm_dp_display->power_on) {
- rc = -EINVAL;
+ if (!msm_dp_display->power_on)
goto end;
- }
audio = msm_dp_audio_get_data(msm_dp_display);
if (IS_ERR(audio)) {
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 86ef8c89ad44..59070f399e2d 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -114,7 +114,6 @@ struct msm_dp_ctrl_private {
struct drm_device *drm_dev;
struct device *dev;
struct drm_dp_aux *aux;
- struct msm_dp_panel *panel;
struct msm_dp_link *link;
void __iomem *ahb_base;
void __iomem *link_base;
@@ -202,7 +201,8 @@ static int msm_dp_aux_link_configure(struct drm_dp_aux *aux,
/*
* NOTE: resetting DP controller will also clear any pending HPD related interrupts
*/
-void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl)
+void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel)
{
struct msm_dp_ctrl_private *ctrl =
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)
sw_reset &= ~DP_SW_RESET;
msm_dp_write_ahb(ctrl, REG_DP_SW_RESET, sw_reset);
- if (!ctrl->hw_revision) {
+ if (!ctrl->hw_revision)
ctrl->hw_revision = msm_dp_read_ahb(ctrl, REG_DP_HW_VERSION);
- ctrl->panel->hw_revision = ctrl->hw_revision;
- }
+ panel->hw_revision = ctrl->hw_revision;
}
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)
drm_dbg_dp(ctrl->drm_dev, "mainlink off\n");
}
-static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl)
+static void msm_dp_ctrl_config_ctrl_streams(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *msm_dp_panel)
{
u32 config = 0, tbd;
- const u8 *dpcd = ctrl->panel->dpcd;
- /* Default-> LSCLK DIV: 1/4 LCLK */
- config |= (2 << DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT);
+ /*
+ * RMW: called from atomic_enable(), serialized by the DRM atomic framework.
+ * Clear stream-specific fields before OR-ing to avoid bit accumulation.
+ */
+ config = msm_dp_read_link(ctrl, REG_DP_CONFIGURATION_CTRL);
+ config &= ~(DP_CONFIGURATION_CTRL_RGB_YUV_MASK |
+ DP_CONFIGURATION_CTRL_BPC_MASK |
+ DP_CONFIGURATION_CTRL_SEND_VSC);
- if (ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)
+ if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
config |= DP_CONFIGURATION_CTRL_RGB_YUV; /* YUV420 */
- /* Scrambler reset enable */
- if (drm_dp_alternate_scrambler_reset_cap(dpcd))
- config |= DP_CONFIGURATION_CTRL_ASSR;
-
tbd = msm_dp_link_get_test_bits_depth(ctrl->link,
- ctrl->panel->msm_dp_mode.bpp);
+ msm_dp_panel->msm_dp_mode.bpp);
config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT;
+ if (msm_dp_panel->psr_cap.version)
+ config |= DP_CONFIGURATION_CTRL_SEND_VSC;
+
+ drm_dbg_dp(ctrl->drm_dev, "stream DP_CONFIGURATION_CTRL=0x%x\n", config);
+
+ msm_dp_write_link(ctrl, REG_DP_CONFIGURATION_CTRL, config);
+}
+
+static void msm_dp_ctrl_config_ctrl_link(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
+{
+ u32 config = 0;
+ const u8 *dpcd = panel->dpcd;
+
+ /* Default-> LSCLK DIV: 1/4 LCLK */
+ config |= (2 << DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT);
+
+ /* Scrambler reset enable */
+ if (drm_dp_alternate_scrambler_reset_cap(dpcd))
+ config |= DP_CONFIGURATION_CTRL_ASSR;
+
/* Num of Lanes */
config |= ((ctrl->link->link_params.num_lanes - 1)
<< DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT);
@@ -421,10 +443,7 @@ static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl)
config |= DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN;
config |= DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK;
- if (ctrl->panel->psr_cap.version)
- config |= DP_CONFIGURATION_CTRL_SEND_VSC;
-
- drm_dbg_dp(ctrl->drm_dev, "DP_CONFIGURATION_CTRL=0x%x\n", config);
+ drm_dbg_dp(ctrl->drm_dev, "link DP_CONFIGURATION_CTRL=0x%x\n", config);
msm_dp_write_link(ctrl, REG_DP_CONFIGURATION_CTRL, config);
}
@@ -443,16 +462,13 @@ static void msm_dp_ctrl_lane_mapping(struct msm_dp_ctrl_private *ctrl)
ln_mapping);
}
-static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl)
+static void msm_dp_ctrl_config_misc1_misc0(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *msm_dp_panel)
{
u32 colorimetry_cfg, test_bits_depth, misc_val;
- msm_dp_ctrl_lane_mapping(ctrl);
- msm_dp_setup_peripheral_flush(ctrl);
-
- msm_dp_ctrl_config_ctrl(ctrl);
-
- test_bits_depth = msm_dp_link_get_test_bits_depth(ctrl->link, ctrl->panel->msm_dp_mode.bpp);
+ test_bits_depth = msm_dp_link_get_test_bits_depth(ctrl->link,
+ msm_dp_panel->msm_dp_mode.bpp);
colorimetry_cfg = msm_dp_link_get_colorimetry_config(ctrl->link);
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
drm_dbg_dp(ctrl->drm_dev, "misc settings = 0x%x\n", misc_val);
msm_dp_write_link(ctrl, REG_DP_MISC1_MISC0, misc_val);
+}
- msm_dp_panel_timing_cfg(ctrl->panel, ctrl->msm_dp_ctrl.wide_bus_en);
+static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
+{
+ msm_dp_ctrl_config_ctrl_streams(ctrl, panel);
+
+ msm_dp_ctrl_config_misc1_misc0(ctrl, panel);
+
+ msm_dp_panel_timing_cfg(panel, ctrl->msm_dp_ctrl.wide_bus_en);
}
/*
@@ -1237,20 +1261,21 @@ tu_size_calc:
}
static void msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel,
struct msm_dp_vc_tu_mapping_table *tu_table)
{
struct msm_dp_tu_calc_input in;
- struct drm_display_mode *drm_mode;
+ const struct drm_display_mode *drm_mode;
- drm_mode = &ctrl->panel->msm_dp_mode.drm_mode;
+ drm_mode = &panel->msm_dp_mode.drm_mode;
in.lclk = ctrl->link->link_params.rate / 1000;
in.pclk_khz = drm_mode->clock;
in.hactive = drm_mode->hdisplay;
in.hporch = drm_mode->htotal - drm_mode->hdisplay;
in.nlanes = ctrl->link->link_params.num_lanes;
- in.bpp = ctrl->panel->msm_dp_mode.bpp;
- in.pixel_enc = ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420 ? 420 : 444;
+ in.bpp = panel->msm_dp_mode.bpp;
+ in.pixel_enc = panel->msm_dp_mode.out_fmt_is_yuv_420 ? 420 : 444;
in.dsc_en = 0;
in.async_en = 0;
in.fec_en = 0;
@@ -1260,14 +1285,15 @@ static void msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private *ctrl,
_dp_ctrl_calc_tu(ctrl, &in, tu_table);
}
-static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl)
+static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
{
u32 msm_dp_tu = 0x0;
u32 valid_boundary = 0x0;
u32 valid_boundary2 = 0x0;
struct msm_dp_vc_tu_mapping_table tu_calc_table;
- msm_dp_ctrl_calc_tu_parameters(ctrl, &tu_calc_table);
+ msm_dp_ctrl_calc_tu_parameters(ctrl, panel, &tu_calc_table);
msm_dp_tu |= tu_calc_table.tu_size_minus1;
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,
}
static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel,
int *training_step, enum drm_dp_phy dp_phy)
{
int delay_us;
@@ -1427,7 +1454,7 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
int const maximum_retries = 4;
delay_us = drm_dp_read_clock_recovery_delay(ctrl->aux,
- ctrl->panel->dpcd, dp_phy, false);
+ panel->dpcd, dp_phy, false);
msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
@@ -1513,14 +1540,15 @@ static int msm_dp_ctrl_link_rate_down_shift(struct msm_dp_ctrl_private *ctrl)
return ret;
}
-static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
{
if (ctrl->link->link_params.num_lanes == 1)
return -1;
ctrl->link->link_params.num_lanes /= 2;
- ctrl->link->link_params.rate = ctrl->panel->link_info.rate;
+ ctrl->link->link_params.rate = panel->link_info.rate;
ctrl->link->phy_params.p_level = 0;
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)
}
static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel,
enum drm_dp_phy dp_phy)
{
int delay_us;
@@ -1536,11 +1565,12 @@ static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl,
msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE, dp_phy);
delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
- ctrl->panel->dpcd, dp_phy, false);
+ panel->dpcd, dp_phy, false);
fsleep(delay_us);
}
static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel,
int *training_step, enum drm_dp_phy dp_phy)
{
int delay_us;
@@ -1551,16 +1581,16 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
u8 link_status[DP_LINK_STATUS_SIZE];
delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
- ctrl->panel->dpcd, dp_phy, false);
+ panel->dpcd, dp_phy, false);
msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, 0);
*training_step = DP_TRAINING_2;
- if (drm_dp_tps4_supported(ctrl->panel->dpcd)) {
+ if (drm_dp_tps4_supported(panel->dpcd)) {
pattern = DP_TRAINING_PATTERN_4;
state_ctrl_bit = 4;
- } else if (drm_dp_tps3_supported(ctrl->panel->dpcd)) {
+ } else if (drm_dp_tps3_supported(panel->dpcd)) {
pattern = DP_TRAINING_PATTERN_3;
state_ctrl_bit = 3;
} else {
@@ -1597,18 +1627,19 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
}
static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel,
int *training_step, enum drm_dp_phy dp_phy)
{
int ret;
- ret = msm_dp_ctrl_link_train_1(ctrl, training_step, dp_phy);
+ ret = msm_dp_ctrl_link_train_1(ctrl, panel, training_step, dp_phy);
if (ret) {
DRM_ERROR("link training #1 on phy %d failed. ret=%d\n", dp_phy, ret);
return ret;
}
drm_dbg_dp(ctrl->drm_dev, "link training #1 on phy %d successful\n", dp_phy);
- ret = msm_dp_ctrl_link_train_2(ctrl, training_step, dp_phy);
+ ret = msm_dp_ctrl_link_train_2(ctrl, panel, training_step, dp_phy);
if (ret) {
DRM_ERROR("link training #2 on phy %d failed. ret=%d\n", dp_phy, ret);
return ret;
@@ -1619,16 +1650,18 @@ static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl,
}
static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel,
int *training_step)
{
int i;
int ret = 0;
- const u8 *dpcd = ctrl->panel->dpcd;
+ const u8 *dpcd = panel->dpcd;
u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
u8 assr;
struct msm_dp_link_info link_info = {0};
- msm_dp_ctrl_config_ctrl(ctrl);
+ msm_dp_ctrl_config_ctrl_link(ctrl, panel);
+ msm_dp_ctrl_config_ctrl_streams(ctrl, panel);
link_info.num_lanes = ctrl->link->link_params.num_lanes;
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,
for (i = ctrl->link->lttpr_count - 1; i >= 0; i--) {
enum drm_dp_phy dp_phy = DP_PHY_LTTPR(i);
- ret = msm_dp_ctrl_link_train_1_2(ctrl, training_step, dp_phy);
- msm_dp_ctrl_clear_training_pattern(ctrl, dp_phy);
+ ret = msm_dp_ctrl_link_train_1_2(ctrl, panel, training_step, dp_phy);
+ msm_dp_ctrl_clear_training_pattern(ctrl, panel, dp_phy);
if (ret)
break;
@@ -1663,7 +1696,7 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
goto end;
}
- ret = msm_dp_ctrl_link_train_1_2(ctrl, training_step, DP_PHY_DPRX);
+ ret = msm_dp_ctrl_link_train_1_2(ctrl, panel, training_step, DP_PHY_DPRX);
if (ret) {
DRM_ERROR("link training on sink failed. ret=%d\n", ret);
goto end;
@@ -1676,6 +1709,7 @@ end:
}
static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel,
int *training_step)
{
int ret = 0;
@@ -1691,7 +1725,7 @@ static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl,
* a link training pattern, we have to first do soft reset.
*/
- ret = msm_dp_ctrl_link_train(ctrl, training_step);
+ ret = msm_dp_ctrl_link_train(ctrl, panel, training_step);
return ret;
}
@@ -1790,11 +1824,12 @@ static void msm_dp_ctrl_link_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl)
str_on_off(ctrl->core_clks_on));
}
-static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
{
int ret = 0;
struct phy *phy = ctrl->phy;
- const u8 *dpcd = ctrl->panel->dpcd;
+ const u8 *dpcd = panel->dpcd;
ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
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)
msm_dp_write_link(ctrl, REG_PSR_CMD, cmd);
}
-void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl)
+void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel)
{
struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
struct msm_dp_ctrl_private, msm_dp_ctrl);
u32 cfg;
- if (!ctrl->panel->psr_cap.version)
+ if (!panel->psr_cap.version)
return;
/* enable PSR1 function */
@@ -1867,12 +1903,13 @@ void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl)
drm_dp_dpcd_write(ctrl->aux, DP_PSR_EN_CFG, &cfg, 1);
}
-void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enter)
+void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel, bool enter)
{
struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
struct msm_dp_ctrl_private, msm_dp_ctrl);
- if (!ctrl->panel->psr_cap.version)
+ if (!panel->psr_cap.version)
return;
/*
@@ -1942,7 +1979,8 @@ void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl)
phy_exit(phy);
}
-static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
{
struct phy *phy = ctrl->phy;
int ret = 0;
@@ -1950,20 +1988,19 @@ static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
msm_dp_ctrl_mainlink_disable(ctrl);
ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
phy_configure(phy, &ctrl->phy_opts);
+
/*
* Disable and re-enable the mainlink clock since the
* link clock might have been adjusted as part of the
* link maintenance.
*/
- dev_pm_opp_set_rate(ctrl->dev, 0);
-
msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
phy_power_off(phy);
/* hw recommended delay before re-enabling clocks */
msleep(20);
- ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
+ ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
if (ret) {
DRM_ERROR("Failed to enable mainlink clks. ret=%d\n", ret);
return ret;
@@ -1972,7 +2009,8 @@ static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
return ret;
}
-static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
{
struct phy *phy;
@@ -1980,9 +2018,8 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
msm_dp_ctrl_mainlink_disable(ctrl);
- msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);
+ msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl, panel);
- dev_pm_opp_set_rate(ctrl->dev, 0);
msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
phy_power_off(phy);
@@ -1994,7 +2031,8 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
return 0;
}
-static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
{
int ret = 0;
int training_step = DP_TRAINING_NONE;
@@ -2004,11 +2042,11 @@ static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl)
ctrl->link->phy_params.p_level = 0;
ctrl->link->phy_params.v_level = 0;
- ret = msm_dp_ctrl_setup_main_link(ctrl, &training_step);
+ ret = msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
if (ret)
goto end;
- msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
+ msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
@@ -2152,7 +2190,43 @@ static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl)
return success;
}
-static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_on_pixel_clk(struct msm_dp_ctrl_private *ctrl, unsigned long pixel_rate)
+{
+ int ret;
+
+ ret = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
+ if (ret) {
+ DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
+ return ret;
+ }
+
+ if (WARN_ON_ONCE(ctrl->stream_clks_on))
+ return 0;
+
+ ret = clk_prepare_enable(ctrl->pixel_clk);
+ if (ret) {
+ DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
+ return ret;
+ }
+ ctrl->stream_clks_on = true;
+
+ return ret;
+}
+
+void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+ struct msm_dp_ctrl_private *ctrl;
+
+ ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+ if (ctrl->stream_clks_on) {
+ clk_disable_unprepare(ctrl->pixel_clk);
+ ctrl->stream_clks_on = false;
+ }
+}
+
+static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
{
int ret;
unsigned long pixel_rate;
@@ -2168,38 +2242,27 @@ static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl
* running. Add the global reset just before disabling the
* link clocks and core clocks.
*/
- msm_dp_ctrl_off(&ctrl->msm_dp_ctrl);
+ msm_dp_ctrl_off_pixel_clk(&ctrl->msm_dp_ctrl);
+ msm_dp_ctrl_off_link(&ctrl->msm_dp_ctrl, panel);
- ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl);
+ ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl, panel);
if (ret) {
DRM_ERROR("failed to enable DP link controller\n");
return ret;
}
- pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock;
- ret = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
- if (ret) {
- DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
+ pixel_rate = panel->msm_dp_mode.drm_mode.clock;
+ ret = msm_dp_ctrl_on_pixel_clk(ctrl, pixel_rate);
+ if (ret)
return ret;
- }
-
- if (ctrl->stream_clks_on) {
- drm_dbg_dp(ctrl->drm_dev, "pixel clks already enabled\n");
- } else {
- ret = clk_prepare_enable(ctrl->pixel_clk);
- if (ret) {
- DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
- return ret;
- }
- ctrl->stream_clks_on = true;
- }
msm_dp_ctrl_send_phy_test_pattern(ctrl);
return 0;
}
-void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl)
+void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel)
{
struct msm_dp_ctrl_private *ctrl;
u32 sink_request = 0x0;
@@ -2214,14 +2277,14 @@ void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl)
if (sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
drm_dbg_dp(ctrl->drm_dev, "PHY_TEST_PATTERN request\n");
- if (msm_dp_ctrl_process_phy_test_request(ctrl)) {
+ if (msm_dp_ctrl_process_phy_test_request(ctrl, panel)) {
DRM_ERROR("process phy_test_req failed\n");
return;
}
}
if (sink_request & DP_LINK_STATUS_UPDATED) {
- if (msm_dp_ctrl_link_maintenance(ctrl)) {
+ if (msm_dp_ctrl_link_maintenance(ctrl, panel)) {
DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
return;
}
@@ -2229,7 +2292,7 @@ void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl)
if (sink_request & DP_TEST_LINK_TRAINING) {
msm_dp_link_send_test_response(ctrl->link);
- if (msm_dp_ctrl_link_maintenance(ctrl)) {
+ if (msm_dp_ctrl_link_maintenance(ctrl, panel)) {
DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
return;
}
@@ -2265,7 +2328,8 @@ static bool msm_dp_ctrl_channel_eq_ok(struct msm_dp_ctrl_private *ctrl)
return drm_dp_channel_eq_ok(link_status, num_lanes);
}
-int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
+int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel)
{
int rc = 0;
struct msm_dp_ctrl_private *ctrl;
@@ -2281,8 +2345,8 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
- rate = ctrl->panel->link_info.rate;
- pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock;
+ rate = panel->link_info.rate;
+ pixel_rate = panel->msm_dp_mode.drm_mode.clock;
msm_dp_ctrl_core_clk_enable(&ctrl->msm_dp_ctrl);
@@ -2294,8 +2358,8 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
} else {
ctrl->link->link_params.rate = rate;
ctrl->link->link_params.num_lanes =
- ctrl->panel->link_info.num_lanes;
- if (ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)
+ panel->link_info.num_lanes;
+ if (panel->msm_dp_mode.out_fmt_is_yuv_420)
pixel_rate >>= 1;
}
@@ -2303,13 +2367,13 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes,
pixel_rate);
- rc = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
+ rc = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
if (rc)
return rc;
while (--link_train_max_retries) {
training_step = DP_TRAINING_NONE;
- rc = msm_dp_ctrl_setup_main_link(ctrl, &training_step);
+ rc = msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
if (rc == 0) {
/* training completed successfully */
break;
@@ -2328,7 +2392,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
* some lanes are ready,
* reduce lane number
*/
- rc = msm_dp_ctrl_link_lane_down_shift(ctrl);
+ rc = msm_dp_ctrl_link_lane_down_shift(ctrl, panel);
if (rc < 0) { /* lane == 1 already */
/* end with failure */
break;
@@ -2349,7 +2413,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
ctrl->link->link_params.num_lanes))
rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
else
- rc = msm_dp_ctrl_link_lane_down_shift(ctrl);
+ rc = msm_dp_ctrl_link_lane_down_shift(ctrl, panel);
if (rc < 0) {
/* end with failure */
@@ -2357,10 +2421,10 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
}
/* stop link training before start re training */
- msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
+ msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
}
- rc = msm_dp_ctrl_reinitialize_mainlink(ctrl);
+ rc = msm_dp_ctrl_reinitialize_mainlink(ctrl, panel);
if (rc) {
DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", rc);
break;
@@ -2381,20 +2445,21 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
* link training failed
* end txing train pattern here
*/
- msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
+ msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
- msm_dp_ctrl_deinitialize_mainlink(ctrl);
+ msm_dp_ctrl_deinitialize_mainlink(ctrl, panel);
rc = -ECONNRESET;
}
return rc;
}
-static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl,
+ struct msm_dp_panel *panel)
{
int training_step = DP_TRAINING_NONE;
- return msm_dp_ctrl_setup_main_link(ctrl, &training_step);
+ return msm_dp_ctrl_setup_main_link(ctrl, panel, &training_step);
}
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,
msm_dp_write_link(ctrl, REG_DP_SOFTWARE_NVID, nvid);
}
-int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train)
+int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel,
+ bool force_link_train)
{
int ret = 0;
- bool mainlink_ready = false;
struct msm_dp_ctrl_private *ctrl;
- unsigned long pixel_rate;
- unsigned long pixel_rate_orig;
if (!msm_dp_ctrl)
return -EINVAL;
ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
- pixel_rate = pixel_rate_orig = ctrl->panel->msm_dp_mode.drm_mode.clock;
-
- if (msm_dp_ctrl->wide_bus_en || ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)
- pixel_rate >>= 1;
-
- drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d, pixel_rate=%lu\n",
- ctrl->link->link_params.rate,
- ctrl->link->link_params.num_lanes, pixel_rate);
+ drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d\n",
+ ctrl->link->link_params.rate,
+ ctrl->link->link_params.num_lanes);
drm_dbg_dp(ctrl->drm_dev,
"core_clk_on=%d link_clk_on=%d stream_clk_on=%d\n",
ctrl->core_clks_on, ctrl->link_clks_on, ctrl->stream_clks_on);
if (!ctrl->link_clks_on) { /* link clk is off */
- ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
+ ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl, panel);
if (ret) {
DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);
- goto end;
- }
- }
-
- ret = clk_set_rate(ctrl->pixel_clk, pixel_rate * 1000);
- if (ret) {
- DRM_ERROR("Failed to set pixel clock rate. ret=%d\n", ret);
- goto end;
- }
-
- if (ctrl->stream_clks_on) {
- drm_dbg_dp(ctrl->drm_dev, "pixel clks already enabled\n");
- } else {
- ret = clk_prepare_enable(ctrl->pixel_clk);
- if (ret) {
- DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
- goto end;
+ return ret;
}
- ctrl->stream_clks_on = true;
}
if (force_link_train || !msm_dp_ctrl_channel_eq_ok(ctrl))
- msm_dp_ctrl_link_retrain(ctrl);
+ msm_dp_ctrl_link_retrain(ctrl, panel);
/* stop txing train pattern to end link training */
- msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
+ msm_dp_ctrl_clear_training_pattern(ctrl, panel, DP_PHY_DPRX);
+
+ return ret;
+}
+
+int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel)
+{
+ int ret = 0;
+ bool mainlink_ready = false;
+ struct msm_dp_ctrl_private *ctrl;
+ unsigned long pixel_rate;
+ unsigned long pixel_rate_orig;
+
+ if (!msm_dp_ctrl)
+ return -EINVAL;
+
+ ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+ pixel_rate_orig = panel->msm_dp_mode.drm_mode.clock;
+ pixel_rate = pixel_rate_orig;
+
+ if (msm_dp_ctrl->wide_bus_en || panel->msm_dp_mode.out_fmt_is_yuv_420)
+ pixel_rate >>= 1;
+
+ drm_dbg_dp(ctrl->drm_dev, "pixel_rate=%lu\n", pixel_rate);
+
+ ret = msm_dp_ctrl_on_pixel_clk(ctrl, pixel_rate);
+ if (ret)
+ return ret;
/*
* 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
*/
reinit_completion(&ctrl->video_comp);
- msm_dp_ctrl_configure_source_params(ctrl);
+ msm_dp_ctrl_lane_mapping(ctrl);
+ msm_dp_setup_peripheral_flush(ctrl);
+ msm_dp_ctrl_config_ctrl_link(ctrl, panel);
+
+ msm_dp_ctrl_configure_source_params(ctrl, panel);
msm_dp_ctrl_config_msa(ctrl,
ctrl->link->link_params.rate,
pixel_rate_orig,
- ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420);
+ panel->msm_dp_mode.out_fmt_is_yuv_420);
- msm_dp_panel_clear_dsc_dto(ctrl->panel);
+ msm_dp_panel_clear_dsc_dto(panel);
- msm_dp_ctrl_setup_tr_unit(ctrl);
+ msm_dp_ctrl_setup_tr_unit(ctrl, panel);
msm_dp_write_link(ctrl, REG_DP_STATE_CTRL, DP_STATE_CTRL_SEND_VIDEO);
@@ -2549,11 +2623,10 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train
drm_dbg_dp(ctrl->drm_dev,
"mainlink %s\n", mainlink_ready ? "READY" : "NOT READY");
-end:
return ret;
}
-void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl)
+void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl)
{
struct msm_dp_ctrl_private *ctrl;
struct phy *phy;
@@ -2561,29 +2634,13 @@ void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl)
ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
phy = ctrl->phy;
- msm_dp_panel_disable_vsc_sdp(ctrl->panel);
-
- /* set dongle to D3 (power off) mode */
- msm_dp_link_psm_config(ctrl->link, &ctrl->panel->link_info, true);
-
- msm_dp_ctrl_mainlink_disable(ctrl);
-
- if (ctrl->stream_clks_on) {
- clk_disable_unprepare(ctrl->pixel_clk);
- ctrl->stream_clks_on = false;
- }
-
- dev_pm_opp_set_rate(ctrl->dev, 0);
- msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
-
- phy_power_off(phy);
-
/* aux channel down, reinit phy */
phy_exit(phy);
phy_init(phy);
}
-void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)
+void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel)
{
struct msm_dp_ctrl_private *ctrl;
struct phy *phy;
@@ -2591,24 +2648,19 @@ void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)
ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
phy = ctrl->phy;
- msm_dp_panel_disable_vsc_sdp(ctrl->panel);
+ msm_dp_panel_disable_vsc_sdp(panel);
msm_dp_ctrl_mainlink_disable(ctrl);
- msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);
-
- if (ctrl->stream_clks_on) {
- clk_disable_unprepare(ctrl->pixel_clk);
- ctrl->stream_clks_on = false;
- }
+ msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl, panel);
- dev_pm_opp_set_rate(ctrl->dev, 0);
msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
phy_power_off(phy);
}
-irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
+irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel)
{
struct msm_dp_ctrl_private *ctrl;
u32 isr;
@@ -2619,7 +2671,7 @@ irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
- if (ctrl->panel->psr_cap.version) {
+ if (panel->psr_cap.version) {
isr = msm_dp_ctrl_get_psr_interrupt(ctrl);
if (isr)
@@ -2708,7 +2760,7 @@ static int msm_dp_ctrl_clk_init(struct msm_dp_ctrl *msm_dp_ctrl)
}
struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link,
- struct msm_dp_panel *panel, struct drm_dp_aux *aux,
+ struct drm_dp_aux *aux,
struct phy *phy,
void __iomem *ahb_base,
void __iomem *link_base)
@@ -2716,7 +2768,7 @@ struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link
struct msm_dp_ctrl_private *ctrl;
int ret;
- if (!dev || !panel || !aux || !link) {
+ if (!dev || !aux || !link) {
DRM_ERROR("invalid input\n");
return ERR_PTR(-EINVAL);
}
@@ -2744,7 +2796,6 @@ struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link
init_completion(&ctrl->video_comp);
/* in parameters */
- ctrl->panel = panel;
ctrl->aux = aux;
ctrl->link = link;
ctrl->dev = dev;
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h
index f68bee62713f..5902cf7e746a 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.h
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h
@@ -16,28 +16,37 @@ struct msm_dp_ctrl {
struct phy;
-int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl);
-int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train);
-void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl);
-void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl);
+int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel);
+int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *panel);
+int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel,
+ bool force_link_train);
+void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel);
+void msm_dp_ctrl_off_pixel_clk(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl);
-irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl);
-void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl);
+irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel);
+void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel);
struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev,
struct msm_dp_link *link,
- struct msm_dp_panel *panel,
struct drm_dp_aux *aux,
struct phy *phy,
void __iomem *ahb_base,
void __iomem *link_base);
-void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel);
void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_irq_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
-void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enable);
-void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel, bool enable);
+void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl,
+ struct msm_dp_panel *panel);
int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl);
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);
void msm_dp_ctrl_enable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_disable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl);
#endif /* _DP_CTRL_H_ */
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index dc6f33809ca5..bc646d172abe 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -63,7 +63,6 @@ struct msm_dp_display_private {
struct msm_dp_panel *panel;
struct msm_dp_ctrl *ctrl;
- struct msm_dp_display_mode msm_dp_mode;
struct msm_dp msm_dp_display;
/* wait for audio signaling */
@@ -269,6 +268,7 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
const struct drm_display_info *info = &connector->display_info;
int rc = 0;
u8 dpcd[DP_RECEIVER_CAP_SIZE];
+ const struct drm_edid *drm_edid = NULL;
rc = drm_dp_read_dpcd_caps(dp->aux, dpcd);
if (rc)
@@ -276,10 +276,20 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
dp->link->lttpr_count = msm_dp_display_lttpr_init(dp, dpcd);
- rc = msm_dp_panel_read_sink_caps(dp->panel, connector);
+ rc = msm_dp_panel_read_link_caps(dp->panel, connector);
if (rc)
goto end;
+ drm_edid = drm_edid_read_ddc(connector, &dp->aux->ddc);
+ drm_edid_connector_update(connector, drm_edid);
+
+ if (!drm_edid) {
+ DRM_ERROR("panel edid read failed\n");
+ /* check edid read fail is due to unplug */
+ if (!msm_dp_aux_is_link_connected(dp->aux))
+ return -ETIMEDOUT;
+ }
+
msm_dp_link_process_request(dp->link);
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)
dp->msm_dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
dp->audio_supported = info->has_audio;
- msm_dp_panel_handle_sink_request(dp->panel);
+ msm_dp_panel_handle_sink_request(dp->panel, drm_edid);
/*
* 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)
msm_dp_link_reset_phy_params_vx_px(dp->link);
end:
+ drm_edid_free(drm_edid);
return rc;
}
@@ -348,7 +359,7 @@ static void msm_dp_display_host_init(struct msm_dp_display_private *dp)
dp->phy_initialized);
msm_dp_ctrl_core_clk_enable(dp->ctrl);
- msm_dp_ctrl_reset(dp->ctrl);
+ msm_dp_ctrl_reset(dp->ctrl, dp->panel);
msm_dp_ctrl_enable_irq(dp->ctrl);
msm_dp_aux_init(dp->aux);
dp->core_initialized = true;
@@ -360,7 +371,7 @@ static void msm_dp_display_host_deinit(struct msm_dp_display_private *dp)
dp->msm_dp_display.connector_type, dp->core_initialized,
dp->phy_initialized);
- msm_dp_ctrl_reset(dp->ctrl);
+ msm_dp_ctrl_reset(dp->ctrl, dp->panel);
msm_dp_ctrl_disable_irq(dp->ctrl);
msm_dp_aux_deinit(dp->aux);
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)
drm_dbg_dp(dp->drm_dev, "%d\n", sink_request);
- msm_dp_ctrl_handle_sink_request(dp->ctrl);
+ msm_dp_ctrl_handle_sink_request(dp->ctrl, dp->panel);
if (sink_request & DP_TEST_LINK_VIDEO_PATTERN)
msm_dp_display_handle_video_request(dp);
@@ -453,7 +464,7 @@ static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp)
/* Don't forget modes for eDP */
if (!dp->msm_dp_display.is_edp)
- msm_dp_panel_unplugged(dp->panel, dp->msm_dp_display.connector);
+ drm_edid_connector_update(dp->msm_dp_display.connector, NULL);
/* triggered by irq_hdp with sink_count = 0 */
if (dp->link->sink_count == 0)
@@ -515,7 +526,6 @@ static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp)
static void msm_dp_display_deinit_sub_modules(struct msm_dp_display_private *dp)
{
msm_dp_audio_put(dp->audio);
- msm_dp_panel_put(dp->panel);
msm_dp_aux_put(dp->aux);
}
@@ -560,13 +570,13 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
goto error_link;
}
- dp->ctrl = msm_dp_ctrl_get(dev, dp->link, dp->panel, dp->aux,
- phy, dp->ahb_base, dp->link_base);
+ dp->ctrl = msm_dp_ctrl_get(dev, dp->link, dp->aux,
+ phy, dp->ahb_base, dp->link_base);
if (IS_ERR(dp->ctrl)) {
rc = PTR_ERR(dp->ctrl);
DRM_ERROR("failed to initialize ctrl, rc = %d\n", rc);
dp->ctrl = NULL;
- goto error_ctrl;
+ goto error_link;
}
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)
rc = PTR_ERR(dp->audio);
pr_err("failed to initialize audio, rc = %d\n", rc);
dp->audio = NULL;
- goto error_ctrl;
+ goto error_link;
}
return rc;
-error_ctrl:
- msm_dp_panel_put(dp->panel);
error_link:
msm_dp_aux_put(dp->aux);
error:
@@ -588,20 +596,64 @@ error:
}
static int msm_dp_display_set_mode(struct msm_dp *msm_dp_display,
- struct msm_dp_display_mode *mode)
+ const struct drm_display_mode *adjusted_mode,
+ struct msm_dp_panel *msm_dp_panel)
{
struct msm_dp_display_private *dp;
+ u32 bpp;
dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
- drm_mode_copy(&dp->panel->msm_dp_mode.drm_mode, &mode->drm_mode);
- dp->panel->msm_dp_mode.bpp = mode->bpp;
- dp->panel->msm_dp_mode.out_fmt_is_yuv_420 = mode->out_fmt_is_yuv_420;
- msm_dp_panel_init_panel_info(dp->panel);
+ if (msm_dp_display_check_video_test(msm_dp_display))
+ bpp = msm_dp_display_get_test_bpp(msm_dp_display);
+ else
+ bpp = msm_dp_panel->connector->display_info.bpc * 3;
+
+ msm_dp_panel_init_panel_info(msm_dp_panel, adjusted_mode, bpp ? bpp : 24);
+
+ /* populate wide_bus_support to different layers */
+ dp->ctrl->wide_bus_en =
+ msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 ? false : dp->wide_bus_supported;
return 0;
}
-static int msm_dp_display_enable(struct msm_dp_display_private *dp, bool force_link_train)
+static int msm_dp_display_prepare_link(struct msm_dp_display_private *dp)
+{
+ struct msm_dp *msm_dp_display = &dp->msm_dp_display;
+ int rc = 0;
+ bool force_link_train = false;
+
+ drm_dbg_dp(dp->drm_dev, "sink_count=%d\n", dp->link->sink_count);
+
+ if (msm_dp_display->is_edp)
+ msm_dp_hpd_plug_handle(dp);
+
+ rc = pm_runtime_resume_and_get(&msm_dp_display->pdev->dev);
+ if (rc) {
+ DRM_ERROR("failed to pm_runtime_resume\n");
+ return rc;
+ }
+
+ if (dp->link->sink_count == 0)
+ return -ENOTCONN;
+
+ if (!msm_dp_display->power_on) {
+ msm_dp_display_host_phy_init(dp);
+ force_link_train = true;
+ }
+
+ rc = msm_dp_ctrl_on_link(dp->ctrl, dp->panel);
+ if (rc) {
+ DRM_ERROR("Failed link training (rc=%d)\n", rc);
+ // TODO: schedule drm_connector_set_link_status_property()
+ return rc;
+ }
+
+ return msm_dp_ctrl_prepare_stream_on(dp->ctrl, dp->panel, force_link_train);
+}
+
+static int msm_dp_display_enable(struct msm_dp_display_private *dp,
+ struct msm_dp_panel *msm_dp_panel)
{
int rc = 0;
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
return 0;
}
- rc = msm_dp_ctrl_on_stream(dp->ctrl, force_link_train);
+ rc = msm_dp_ctrl_on_stream(dp->ctrl, msm_dp_panel);
if (!rc)
msm_dp_display->power_on = true;
@@ -637,18 +689,15 @@ static int msm_dp_display_post_enable(struct msm_dp *msm_dp_display)
msm_dp_display_handle_plugged_change(msm_dp_display, true);
if (msm_dp_display->psr_supported)
- msm_dp_ctrl_config_psr(dp->ctrl);
+ msm_dp_ctrl_config_psr(dp->ctrl, dp->panel);
return 0;
}
-static int msm_dp_display_disable(struct msm_dp_display_private *dp)
+static void msm_dp_display_audio_notify_disable(struct msm_dp_display_private *dp)
{
struct msm_dp *msm_dp_display = &dp->msm_dp_display;
- if (!msm_dp_display->power_on)
- return 0;
-
/* wait only if audio was enabled */
if (msm_dp_display->audio_enabled) {
/* signal the disconnect event */
@@ -659,21 +708,31 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp)
}
msm_dp_display->audio_enabled = false;
+}
- if (dp->link->sink_count == 0) {
- /*
- * irq_hpd with sink_count = 0
- * hdmi unplugged out of dongle
- */
- msm_dp_ctrl_off_link_stream(dp->ctrl);
- } else {
- /*
- * unplugged interrupt
- * dongle unplugged out of DUT
- */
- msm_dp_ctrl_off(dp->ctrl);
+static int msm_dp_display_disable(struct msm_dp_display_private *dp,
+ struct msm_dp_panel *msm_dp_panel)
+{
+ struct msm_dp *msm_dp_display = &dp->msm_dp_display;
+
+ if (!msm_dp_display->power_on)
+ return 0;
+
+ msm_dp_panel_disable_vsc_sdp(msm_dp_panel);
+
+ msm_dp_ctrl_off_pixel_clk(dp->ctrl);
+
+ /* dongle is still connected but sinks are disconnected */
+ if (dp->link->sink_count == 0)
+ msm_dp_link_psm_config(dp->link, &msm_dp_panel->link_info, true);
+
+ msm_dp_ctrl_off_link(dp->ctrl, msm_dp_panel);
+
+ if (dp->link->sink_count == 0)
+ /* re-init the PHY so that we can listen to Dongle disconnect */
+ msm_dp_ctrl_reinit_phy(dp->ctrl);
+ else
msm_dp_display_host_phy_exit(dp);
- }
msm_dp_display->power_on = false;
@@ -682,24 +741,22 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp)
}
/**
- * msm_dp_bridge_mode_valid - callback to determine if specified mode is valid
- * @bridge: Pointer to drm bridge structure
+ * msm_dp_display_mode_valid - callback to determine if specified mode is valid
+ * @dp: Pointer to dp display structure
* @info: display info
* @mode: Pointer to drm mode structure
* Returns: Validity status for specified mode
*/
-enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *bridge,
- const struct drm_display_info *info,
- const struct drm_display_mode *mode)
+enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
+ const struct drm_display_info *info,
+ const struct drm_display_mode *mode)
{
const u32 num_components = 3, default_bpp = 24;
struct msm_dp_display_private *msm_dp_display;
struct msm_dp_link_info *link_info;
u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
- struct msm_dp *dp;
int mode_pclk_khz = mode->clock;
-
- dp = to_dp_bridge(bridge)->msm_dp_display;
+ bool is_yuv_420;
if (!dp || !mode_pclk_khz || !dp->connector) {
DRM_ERROR("invalid params\n");
@@ -709,9 +766,16 @@ enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *bridge,
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
link_info = &msm_dp_display->panel->link_info;
- if ((drm_mode_is_420_only(&dp->connector->display_info, mode) &&
- msm_dp_display->panel->vsc_sdp_supported) ||
- msm_dp_wide_bus_available(dp))
+ is_yuv_420 = drm_mode_is_420_only(&dp->connector->display_info, mode);
+
+ /*
+ * YUV 420 is carried over DP by signalling the colorimetry through a
+ * VSC SDP, so a 420-only mode cannot be driven without VSC SDP support.
+ */
+ if (is_yuv_420 && !msm_dp_display->panel->vsc_sdp_supported)
+ return MODE_NO_420;
+
+ if (is_yuv_420 || msm_dp_display->wide_bus_supported)
mode_pclk_khz /= 2;
if (mode_pclk_khz > DP_MAX_PIXEL_CLK_KHZ)
@@ -744,8 +808,7 @@ int msm_dp_display_get_modes(struct msm_dp *dp)
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
- return msm_dp_panel_get_modes(msm_dp_display->panel,
- dp->connector);
+ return drm_edid_connector_add_modes(msm_dp_display->panel->connector);
}
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)
}
dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
- msm_dp_ctrl_set_psr(dp->ctrl, enter);
+ msm_dp_ctrl_set_psr(dp->ctrl, dp->panel, enter);
}
/**
@@ -918,7 +981,7 @@ static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
}
/* DP controller isr */
- ret |= msm_dp_ctrl_isr(dp->ctrl);
+ ret |= msm_dp_ctrl_isr(dp->ctrl, dp->panel);
return ret;
}
@@ -1277,22 +1340,10 @@ void __exit msm_dp_unregister(void)
platform_driver_unregister(&msm_dp_display_driver);
}
-bool msm_dp_is_yuv_420_enabled(const struct msm_dp *msm_dp_display,
- const struct drm_display_mode *mode)
-{
- struct msm_dp_display_private *dp;
- const struct drm_display_info *info;
-
- dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
- info = &msm_dp_display->connector->display_info;
-
- return dp->panel->vsc_sdp_supported && drm_mode_is_420_only(info, mode);
-}
-
bool msm_dp_needs_periph_flush(const struct msm_dp *msm_dp_display,
const struct drm_display_mode *mode)
{
- return msm_dp_is_yuv_420_enabled(msm_dp_display, mode);
+ return drm_mode_is_420_only(&msm_dp_display->connector->display_info, mode);
}
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)
dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
- if (dp->msm_dp_mode.out_fmt_is_yuv_420)
+ if (dp->panel->msm_dp_mode.out_fmt_is_yuv_420)
return false;
return dp->wide_bus_supported;
@@ -1352,66 +1403,57 @@ int msm_dp_modeset_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
return 0;
}
-void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
- struct drm_atomic_commit *state)
+void msm_dp_display_atomic_pre_enable(struct msm_dp *msm_dp_display,
+ struct drm_atomic_commit *state)
{
- struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
- struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
- int rc = 0;
- struct msm_dp_display_private *msm_dp_display;
- bool force_link_train = false;
-
- msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
- if (!msm_dp_display->msm_dp_mode.drm_mode.clock) {
- DRM_ERROR("invalid params\n");
- return;
- }
+ struct msm_dp_display_private *dp;
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *crtc_state;
- if (dp->is_edp)
- msm_dp_hpd_plug_handle(msm_dp_display);
+ dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
- if (pm_runtime_resume_and_get(&dp->pdev->dev)) {
- DRM_ERROR("failed to pm_runtime_resume\n");
+ crtc = drm_atomic_get_new_crtc_for_encoder(state, msm_dp_display->bridge->encoder);
+ if (!crtc)
return;
- }
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
- if (msm_dp_display->link->sink_count == 0)
- return;
+ /*
+ * The DPU encoder's .atomic_enable() reads the mode's YUV420 / wide bus
+ * state and runs before the bridge's .atomic_enable(), so the mode must
+ * be programmed here, in .atomic_pre_enable().
+ */
+ msm_dp_display_set_mode(msm_dp_display, &crtc_state->adjusted_mode, dp->panel);
+}
- rc = msm_dp_display_set_mode(dp, &msm_dp_display->msm_dp_mode);
- if (rc) {
- DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
- return;
- }
+void msm_dp_display_atomic_enable(struct msm_dp *msm_dp_display,
+ struct drm_atomic_commit *state)
+{
+ int rc = 0;
+ struct msm_dp_display_private *dp;
- if (!dp->power_on) {
- msm_dp_display_host_phy_init(msm_dp_display);
- force_link_train = true;
- }
+ dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
- rc = msm_dp_ctrl_on_link(msm_dp_display->ctrl);
+ rc = msm_dp_display_prepare_link(dp);
if (rc) {
- DRM_ERROR("Failed link training (rc=%d)\n", rc);
- // TODO: schedule drm_connector_set_link_status_property()
+ DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
return;
}
- msm_dp_display_enable(msm_dp_display, force_link_train);
+ rc = msm_dp_display_enable(dp, dp->panel);
+ if (rc)
+ DRM_ERROR("DP display enable failed, rc=%d\n", rc);
- rc = msm_dp_display_post_enable(dp);
+ rc = msm_dp_display_post_enable(msm_dp_display);
if (rc) {
DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
- msm_dp_display_disable(msm_dp_display);
+ msm_dp_display_disable(dp, dp->panel);
}
- drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
+ drm_dbg_dp(msm_dp_display->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
}
-void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
- struct drm_atomic_commit *state)
+void msm_dp_display_atomic_disable(struct msm_dp *dp)
{
- struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
- struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
struct msm_dp_display_private *msm_dp_display;
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,
msm_dp_ctrl_push_idle(msm_dp_display->ctrl);
}
-void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
- struct drm_atomic_commit *state)
+static void msm_dp_display_unprepare(struct msm_dp_display_private *dp)
{
- struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
- struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
- struct msm_dp_display_private *msm_dp_display;
-
- msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
-
- if (dp->is_edp)
- msm_dp_hpd_unplug_handle(msm_dp_display);
-
- msm_dp_display_disable(msm_dp_display);
+ struct msm_dp *msm_dp_display = &dp->msm_dp_display;
- drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
+ pm_runtime_put_sync(&msm_dp_display->pdev->dev);
- pm_runtime_put_sync(&dp->pdev->dev);
+ drm_dbg_dp(dp->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
}
-void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,
- const struct drm_display_mode *mode,
- const struct drm_display_mode *adjusted_mode)
+void msm_dp_display_atomic_post_disable(struct msm_dp *dp)
{
- struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
- struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
struct msm_dp_display_private *msm_dp_display;
- struct msm_dp_panel *msm_dp_panel;
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
- msm_dp_panel = msm_dp_display->panel;
- memset(&msm_dp_display->msm_dp_mode, 0x0, sizeof(struct msm_dp_display_mode));
-
- if (msm_dp_display_check_video_test(dp))
- msm_dp_display->msm_dp_mode.bpp = msm_dp_display_get_test_bpp(dp);
- else /* Default num_components per pixel = 3 */
- msm_dp_display->msm_dp_mode.bpp = dp->connector->display_info.bpc * 3;
-
- if (!msm_dp_display->msm_dp_mode.bpp)
- msm_dp_display->msm_dp_mode.bpp = 24; /* Default bpp */
-
- drm_mode_copy(&msm_dp_display->msm_dp_mode.drm_mode, adjusted_mode);
-
- msm_dp_display->msm_dp_mode.v_active_low =
- !!(msm_dp_display->msm_dp_mode.drm_mode.flags & DRM_MODE_FLAG_NVSYNC);
+ if (dp->is_edp)
+ msm_dp_hpd_unplug_handle(msm_dp_display);
- msm_dp_display->msm_dp_mode.h_active_low =
- !!(msm_dp_display->msm_dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);
+ msm_dp_display_audio_notify_disable(msm_dp_display);
- msm_dp_display->msm_dp_mode.out_fmt_is_yuv_420 =
- drm_mode_is_420_only(&dp->connector->display_info, adjusted_mode) &&
- msm_dp_panel->vsc_sdp_supported;
+ msm_dp_display_disable(msm_dp_display, msm_dp_display->panel);
- /* populate wide_bus_support to different layers */
- msm_dp_display->ctrl->wide_bus_en =
- msm_dp_display->msm_dp_mode.out_fmt_is_yuv_420 ? false : msm_dp_display->wide_bus_supported;
+ msm_dp_display_unprepare(msm_dp_display);
}
void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index 0b65e16c790d..83117e7619f3 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -33,5 +33,14 @@ void msm_dp_display_signal_audio_start(struct msm_dp *msm_dp_display);
void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display);
void msm_dp_display_set_psr(struct msm_dp *dp, bool enter);
void msm_dp_display_debugfs_init(struct msm_dp *msm_dp_display, struct dentry *dentry, bool is_edp);
+void msm_dp_display_atomic_post_disable(struct msm_dp *dp_display);
+void msm_dp_display_atomic_disable(struct msm_dp *dp_display);
+void msm_dp_display_atomic_pre_enable(struct msm_dp *dp_display,
+ struct drm_atomic_commit *state);
+void msm_dp_display_atomic_enable(struct msm_dp *dp_display,
+ struct drm_atomic_commit *state);
+enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
+ const struct drm_display_info *info,
+ const struct drm_display_mode *mode);
#endif /* _DP_DISPLAY_H_ */
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 06881bfd6181..c1e4147bfef1 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -49,14 +49,60 @@ static void msm_dp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry
msm_dp_display_debugfs_init(dp, root, false);
}
+static void msm_dp_bridge_atomic_pre_enable(struct drm_bridge *drm_bridge,
+ struct drm_atomic_commit *state)
+{
+ struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+ struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+ msm_dp_display_atomic_pre_enable(dp, state);
+}
+
+static void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
+ struct drm_atomic_commit *state)
+{
+ struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+ struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+ msm_dp_display_atomic_enable(dp, state);
+}
+
+static void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
+ struct drm_atomic_commit *state)
+{
+ struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+ struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+ msm_dp_display_atomic_disable(dp);
+}
+
+static void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
+ struct drm_atomic_commit *state)
+{
+ struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+ struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+ msm_dp_display_atomic_post_disable(dp);
+}
+
+static enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *drm_bridge,
+ const struct drm_display_info *info,
+ const struct drm_display_mode *mode)
+{
+ struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+ struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+ return msm_dp_display_mode_valid(dp, info, mode);
+}
+
static const struct drm_bridge_funcs msm_dp_bridge_ops = {
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
.atomic_create_state = drm_atomic_helper_bridge_create_state,
+ .atomic_pre_enable = msm_dp_bridge_atomic_pre_enable,
.atomic_enable = msm_dp_bridge_atomic_enable,
.atomic_disable = msm_dp_bridge_atomic_disable,
.atomic_post_disable = msm_dp_bridge_atomic_post_disable,
- .mode_set = msm_dp_bridge_mode_set,
.mode_valid = msm_dp_bridge_mode_valid,
.get_modes = msm_dp_bridge_get_modes,
.detect = msm_dp_bridge_detect,
@@ -116,7 +162,7 @@ static void msm_edp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
return;
}
- msm_dp_bridge_atomic_enable(drm_bridge, state);
+ msm_dp_display_atomic_enable(dp, state);
}
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
}
static const struct drm_bridge_funcs msm_edp_bridge_ops = {
+ .atomic_pre_enable = msm_dp_bridge_atomic_pre_enable,
.atomic_enable = msm_edp_bridge_atomic_enable,
.atomic_disable = msm_edp_bridge_atomic_disable,
.atomic_post_disable = msm_edp_bridge_atomic_post_disable,
- .mode_set = msm_dp_bridge_mode_set,
.mode_valid = msm_edp_bridge_mode_valid,
.atomic_create_state = drm_atomic_helper_bridge_create_state,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index 041aa026ae2e..da412c788503 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -27,18 +27,6 @@ int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge,
struct drm_connector *connector);
-void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
- struct drm_atomic_commit *state);
-void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
- struct drm_atomic_commit *state);
-void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
- struct drm_atomic_commit *state);
-enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *bridge,
- const struct drm_display_info *info,
- const struct drm_display_mode *mode);
-void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,
- const struct drm_display_mode *mode,
- const struct drm_display_mode *adjusted_mode);
void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge);
void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge);
void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 6bb021820d7c..e76dad0f6663 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -232,8 +232,8 @@ static u32 msm_dp_panel_get_supported_bpp(struct msm_dp_panel *msm_dp_panel,
return min_supported_bpp;
}
-int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
- struct drm_connector *connector)
+int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
+ struct drm_connector *connector)
{
int rc, bw_code;
int count;
@@ -271,36 +271,9 @@ int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
rc = drm_dp_read_downstream_info(panel->aux, msm_dp_panel->dpcd,
msm_dp_panel->downstream_ports);
- if (rc)
- return rc;
-
- drm_edid_free(msm_dp_panel->drm_edid);
-
- msm_dp_panel->drm_edid = drm_edid_read_ddc(connector, &panel->aux->ddc);
-
- drm_edid_connector_update(connector, msm_dp_panel->drm_edid);
-
- if (!msm_dp_panel->drm_edid) {
- DRM_ERROR("panel edid read failed\n");
- /* check edid read fail is due to unplug */
- if (!msm_dp_aux_is_link_connected(panel->aux)) {
- rc = -ETIMEDOUT;
- goto end;
- }
- }
-
-end:
return rc;
}
-void msm_dp_panel_unplugged(struct msm_dp_panel *msm_dp_panel,
- struct drm_connector *connector)
-{
- drm_edid_connector_update(connector, NULL);
- drm_edid_free(msm_dp_panel->drm_edid);
- msm_dp_panel->drm_edid = NULL;
-}
-
u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
u32 mode_edid_bpp, u32 mode_pclk_khz)
{
@@ -324,20 +297,6 @@ u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
return bpp;
}
-int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
- struct drm_connector *connector)
-{
- if (!msm_dp_panel) {
- DRM_ERROR("invalid input\n");
- return -EINVAL;
- }
-
- if (msm_dp_panel->drm_edid)
- return drm_edid_connector_add_modes(connector);
-
- return 0;
-}
-
static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)
{
edid += edid->extensions;
@@ -345,7 +304,8 @@ static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)
return edid->checksum;
}
-void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)
+void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel,
+ const struct drm_edid *drm_edid)
{
struct msm_dp_panel_private *panel;
@@ -358,7 +318,7 @@ void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)
if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) {
/* FIXME: get rid of drm_edid_raw() */
- const struct edid *edid = drm_edid_raw(msm_dp_panel->drm_edid);
+ const struct edid *edid = drm_edid_raw(drm_edid);
u8 checksum;
if (edid)
@@ -687,15 +647,27 @@ int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel, bool wide_bus_en)
return 0;
}
-int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel)
+int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel,
+ const struct drm_display_mode *adjusted_mode,
+ u32 bpp)
{
struct drm_display_mode *drm_mode;
struct msm_dp_panel_private *panel;
- drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
-
panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+ drm_mode_copy(&msm_dp_panel->msm_dp_mode.drm_mode, adjusted_mode);
+ msm_dp_panel->msm_dp_mode.bpp = bpp;
+ msm_dp_panel->msm_dp_mode.v_active_low =
+ !!(adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC);
+ msm_dp_panel->msm_dp_mode.h_active_low =
+ !!(adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC);
+ msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 =
+ drm_mode_is_420_only(&msm_dp_panel->connector->display_info, adjusted_mode) &&
+ msm_dp_panel->vsc_sdp_supported;
+
+ drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
+
/*
* print resolution info as this is a result
* 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
return msm_dp_panel;
}
-void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel)
-{
- if (!msm_dp_panel)
- return;
-
- drm_edid_free(msm_dp_panel->drm_edid);
-}
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
index 9173e90a5053..4519ac374220 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -33,7 +33,6 @@ struct msm_dp_panel {
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
struct msm_dp_link_info link_info;
- const struct drm_edid *drm_edid;
struct drm_connector *connector;
struct msm_dp_display_mode msm_dp_mode;
struct msm_dp_panel_psr psr_cap;
@@ -44,18 +43,17 @@ struct msm_dp_panel {
u32 max_bw_code;
};
-int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel);
+int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel,
+ const struct drm_display_mode *adjusted_mode,
+ u32 bpp);
int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel);
int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel, bool wide_bus_en);
-int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
- struct drm_connector *connector);
-void msm_dp_panel_unplugged(struct msm_dp_panel *msm_dp_panel,
- struct drm_connector *connector);
+int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
+ struct drm_connector *connector);
u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp,
u32 mode_pclk_khz);
-int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
- struct drm_connector *connector);
-void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel);
+void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel,
+ const struct drm_edid *drm_edid);
void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable);
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
struct msm_dp_link *link,
void __iomem *link_base,
void __iomem *p0_base);
-void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel);
#endif /* _DP_PANEL_H_ */
diff --git a/drivers/gpu/drm/msm/dp/dp_reg.h b/drivers/gpu/drm/msm/dp/dp_reg.h
index 3689642b7fc0..dda4b642c81b 100644
--- a/drivers/gpu/drm/msm/dp/dp_reg.h
+++ b/drivers/gpu/drm/msm/dp/dp_reg.h
@@ -149,8 +149,10 @@
#define DP_CONFIGURATION_CTRL_ENHANCED_FRAMING (0x00000040)
#define DP_CONFIGURATION_CTRL_SEND_VSC (0x00000080)
#define DP_CONFIGURATION_CTRL_BPC (0x00000100)
+#define DP_CONFIGURATION_CTRL_BPC_MASK GENMASK(9, 8)
#define DP_CONFIGURATION_CTRL_ASSR (0x00000400)
#define DP_CONFIGURATION_CTRL_RGB_YUV (0x00000800)
+#define DP_CONFIGURATION_CTRL_RGB_YUV_MASK GENMASK(12, 11)
#define DP_CONFIGURATION_CTRL_LSCLK_DIV (0x00002000)
#define DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT (0x04)
#define DP_CONFIGURATION_CTRL_BPC_SHIFT (0x08)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index de1ba11987fc..7e4e3718b536 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -550,8 +550,6 @@ error:
void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
{
- /* Drop the performance state vote */
- dev_pm_opp_set_rate(&msm_host->pdev->dev, 0);
clk_disable_unprepare(msm_host->esc_clk);
clk_disable_unprepare(msm_host->pixel_clk);
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)
int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
{
+ long rounded_byte_clk_rate;
+
if (!msm_host->mode) {
pr_err("%s: mode not set\n", __func__);
return -EINVAL;
}
dsi_calc_pclk(msm_host, is_bonded_dsi);
+
+ rounded_byte_clk_rate = clk_round_rate(msm_host->byte_clk,
+ msm_host->byte_clk_rate);
+ if (rounded_byte_clk_rate < 0) {
+ pr_err("%s: failed to round byte clock rate, %ld\n",
+ __func__, rounded_byte_clk_rate);
+ return rounded_byte_clk_rate;
+ }
+
+ msm_host->byte_clk_rate = rounded_byte_clk_rate;
msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
return 0;
}
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
index 21a59d66e8dc..f5d3e806f8fd 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
@@ -111,6 +111,7 @@ struct msm_dsi_phy {
struct msm_dsi_dphy_timing timing;
const struct msm_dsi_phy_cfg *cfg;
void *tuning_cfg;
+ void *pll_data;
enum msm_dsi_phy_usecase usecase;
bool regulator_ldo_mode;
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
index 984a66085dfb..5d805a797abd 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
@@ -426,8 +426,11 @@ static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)
u32 data;
spin_lock_irqsave(&pll->pll_enable_lock, flags);
- pll->pll_enable_cnt++;
- WARN_ON(pll->pll_enable_cnt == INT_MAX);
+ if (pll->pll_enable_cnt++) {
+ spin_unlock_irqrestore(&pll->pll_enable_lock, flags);
+ WARN_ON(pll->pll_enable_cnt == INT_MAX);
+ return;
+ }
data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
data |= DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB;
@@ -873,6 +876,7 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy)
spin_lock_init(&pll_7nm->pll_enable_lock);
pll_7nm->phy = phy;
+ phy->pll_data = pll_7nm;
ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);
if (ret) {
@@ -961,8 +965,10 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
u32 const delay_us = 5;
u32 const timeout_us = 1000;
struct msm_dsi_dphy_timing *timing = &phy->timing;
+ struct dsi_pll_7nm *pll = phy->pll_data;
void __iomem *base = phy->base;
bool less_than_1500_mhz;
+ unsigned long flags;
u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;
u32 glbl_pemph_ctrl_0;
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,
glbl_rescode_bot_ctrl = 0x3c;
}
+ spin_lock_irqsave(&pll->pll_enable_lock, flags);
+ pll->pll_enable_cnt = 1;
/* de-assert digital and pll power down */
data = DSI_7nm_PHY_CMN_CTRL_0_DIGTOP_PWRDN_B |
DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB;
writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);
+ spin_unlock_irqrestore(&pll->pll_enable_lock, flags);
/* Assert PLL core reset */
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)
static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)
{
+ struct dsi_pll_7nm *pll = phy->pll_data;
void __iomem *base = phy->base;
+ unsigned long flags;
u32 data;
DBG("");
@@ -1227,8 +1238,11 @@ static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)
writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);
writel(0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0);
+ spin_lock_irqsave(&pll->pll_enable_lock, flags);
+ pll->pll_enable_cnt = 0;
/* Turn off all PHY blocks */
writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_0);
+ spin_unlock_irqrestore(&pll->pll_enable_lock, flags);
/* make sure phy is turned off */
wmb();
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 49433f7727c3..436d4f9fe346 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -112,6 +112,25 @@ static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg)
return readl(hdmi->mmio + reg);
}
+static inline void hdmi_clear_bits(struct hdmi *hdmi, u32 reg, u32 mask)
+{
+ u32 val;
+
+ val = hdmi_read(hdmi, reg);
+ val &= ~mask;
+ hdmi_write(hdmi, reg, val);
+}
+
+static inline void hdmi_update_bits(struct hdmi *hdmi, u32 reg, u32 mask, u32 data)
+{
+ u32 val;
+
+ val = hdmi_read(hdmi, reg);
+ val &= ~mask;
+ val |= data & mask;
+ hdmi_write(hdmi, reg, val);
+}
+
static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg)
{
return readl(hdmi->qfprom_mmio + reg);
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 7abb9243dba5..157f19bd90b4 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -58,16 +58,13 @@ static int msm_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge)
{
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
- u32 val;
- val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
- val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND |
- HDMI_INFOFRAME_CTRL0_AVI_CONT);
- hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
+ hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0,
+ HDMI_INFOFRAME_CTRL0_AVI_SEND |
+ HDMI_INFOFRAME_CTRL0_AVI_CONT);
- val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
- val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK;
- hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
+ hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL1,
+ HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK);
return 0;
}
@@ -76,18 +73,15 @@ static int msm_hdmi_bridge_clear_audio_infoframe(struct drm_bridge *bridge)
{
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
- u32 val;
- val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
- val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
- HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
- HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
- HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE);
- hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
+ hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0,
+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE);
- val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
- val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK;
- hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
+ hdmi_clear_bits(hdmi, REG_HDMI_INFOFRAME_CTRL1,
+ HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK);
return 0;
}
@@ -96,13 +90,11 @@ static int msm_hdmi_bridge_clear_spd_infoframe(struct drm_bridge *bridge)
{
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
- u32 val;
- val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
- val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
- HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
- HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK);
- hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
+ hdmi_clear_bits(hdmi, REG_HDMI_GEN_PKT_CTRL,
+ HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
+ HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
+ HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK);
return 0;
}
@@ -111,14 +103,12 @@ static int msm_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge)
{
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
- u32 val;
- val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
- val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
- HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
- HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
- HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK);
- hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
+ hdmi_clear_bits(hdmi, REG_HDMI_GEN_PKT_CTRL,
+ HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
+ HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
+ HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
+ HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK);
return 0;
}
@@ -129,7 +119,6 @@ static int msm_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge,
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
u32 buf[4] = {};
- u32 val;
int i;
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,
for (i = 0; i < ARRAY_SIZE(buf); i++)
hdmi_write(hdmi, REG_HDMI_AVI_INFO(i), buf[i]);
- val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
- val |= HDMI_INFOFRAME_CTRL0_AVI_SEND |
- HDMI_INFOFRAME_CTRL0_AVI_CONT;
- hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
+ hdmi_update_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0,
+ HDMI_INFOFRAME_CTRL0_AVI_SEND | HDMI_INFOFRAME_CTRL0_AVI_CONT,
+ HDMI_INFOFRAME_CTRL0_AVI_SEND | HDMI_INFOFRAME_CTRL0_AVI_CONT);
- val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
- val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK;
- val |= HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER);
- hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
+ hdmi_update_bits(hdmi, REG_HDMI_INFOFRAME_CTRL1,
+ HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK,
+ HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER));
return 0;
}
@@ -193,12 +180,11 @@ static int msm_hdmi_bridge_write_audio_infoframe(struct drm_bridge *bridge,
buffer[9] << 16 |
buffer[10] << 24);
- val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
- val |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
- HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
- HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
- HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
- hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
+ val = HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
+ HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
+ hdmi_update_bits(hdmi, REG_HDMI_INFOFRAME_CTRL0, val, val);
return 0;
}
@@ -231,11 +217,10 @@ static int msm_hdmi_bridge_write_spd_infoframe(struct drm_bridge *bridge,
for (i = 0; i < ARRAY_SIZE(buf); i++)
hdmi_write(hdmi, REG_HDMI_GENERIC1(i), buf[i]);
- val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
- val |= HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
- HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
- HDMI_GEN_PKT_CTRL_GENERIC1_LINE(SPD_IFRAME_LINE_NUMBER);
- hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
+ val = HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
+ HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
+ HDMI_GEN_PKT_CTRL_GENERIC1_LINE(SPD_IFRAME_LINE_NUMBER);
+ hdmi_update_bits(hdmi, REG_HDMI_GEN_PKT_CTRL, val, val);
return 0;
}
@@ -269,12 +254,11 @@ static int msm_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge,
for (i = 0; i < ARRAY_SIZE(buf); i++)
hdmi_write(hdmi, REG_HDMI_GENERIC0(i), buf[i]);
- val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
- val |= HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
- HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
- HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
- HDMI_GEN_PKT_CTRL_GENERIC0_LINE(VENSPEC_IFRAME_LINE_NUMBER);
- hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
+ val = HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
+ HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
+ HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
+ HDMI_GEN_PKT_CTRL_GENERIC0_LINE(VENSPEC_IFRAME_LINE_NUMBER);
+ hdmi_update_bits(hdmi, REG_HDMI_GEN_PKT_CTRL, val, val);
return 0;
}
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c b/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c
index 8fb5497aac9f..7862bd67d154 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c
@@ -306,9 +306,9 @@ static int msm_reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl)
HDMI_HDCP_DDC_CTRL_0_DISABLE);
/* ACK the Failure to Clear it */
- reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_CTRL_1);
- reg_val |= HDMI_HDCP_DDC_CTRL_1_FAILED_ACK;
- hdmi_write(hdmi, REG_HDMI_HDCP_DDC_CTRL_1, reg_val);
+ hdmi_update_bits(hdmi, REG_HDMI_HDCP_DDC_CTRL_1,
+ HDMI_HDCP_DDC_CTRL_1_FAILED_ACK,
+ HDMI_HDCP_DDC_CTRL_1_FAILED_ACK);
/* Check if the FAILURE got Cleared */
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)
DBG("Before: HDMI_DDC_SW_STATUS=0x%08x",
hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
/* Reset HDMI DDC software status */
- reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
- reg_val |= HDMI_DDC_CTRL_SW_STATUS_RESET;
- hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
+ hdmi_update_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SW_STATUS_RESET,
+ HDMI_DDC_CTRL_SW_STATUS_RESET);
rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
- reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
- reg_val &= ~HDMI_DDC_CTRL_SW_STATUS_RESET;
- hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SW_STATUS_RESET);
/* Reset HDMI DDC Controller */
- reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
- reg_val |= HDMI_DDC_CTRL_SOFT_RESET;
- hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
+ hdmi_update_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SOFT_RESET,
+ HDMI_DDC_CTRL_SOFT_RESET);
/* If previous msleep is aborted, skip this msleep */
if (!rc)
rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
- reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
- reg_val &= ~HDMI_DDC_CTRL_SOFT_RESET;
- hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_DDC_CTRL, HDMI_DDC_CTRL_SOFT_RESET);
DBG("After: HDMI_DDC_SW_STATUS=0x%08x",
hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
}
@@ -399,7 +393,6 @@ static void msm_hdmi_hdcp_reauth_work(struct work_struct *work)
struct hdmi_hdcp_ctrl, hdcp_reauth_work);
struct hdmi *hdmi = hdcp_ctrl->hdmi;
unsigned long flags;
- u32 reg_val;
DBG("HDCP REAUTH WORK");
/*
@@ -409,9 +402,7 @@ static void msm_hdmi_hdcp_reauth_work(struct work_struct *work)
* AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
*/
spin_lock_irqsave(&hdmi->reg_lock, flags);
- reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
- reg_val &= ~HDMI_HPD_CTRL_ENABLE;
- hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE);
/* Disable HDCP interrupts */
hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL, 0);
@@ -431,9 +422,8 @@ static void msm_hdmi_hdcp_reauth_work(struct work_struct *work)
/* Enable HPD circuitry */
spin_lock_irqsave(&hdmi->reg_lock, flags);
- reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
- reg_val |= HDMI_HPD_CTRL_ENABLE;
- hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
+ hdmi_update_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE,
+ HDMI_HPD_CTRL_ENABLE);
spin_unlock_irqrestore(&hdmi->reg_lock, flags);
/*
@@ -456,7 +446,6 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
struct hdmi *hdmi = hdcp_ctrl->hdmi;
u32 link0_status;
- u32 reg_val;
unsigned long flags;
int rc;
@@ -472,14 +461,11 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl)
spin_lock_irqsave(&hdmi->reg_lock, flags);
/* disable HDMI Encrypt */
- reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
- reg_val &= ~HDMI_CTRL_ENCRYPTED;
- hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
/* Enabling Software DDC */
- reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);
- reg_val &= ~HDMI_DDC_ARBITRATION_HW_ARBITRATION;
- hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_DDC_ARBITRATION,
+ HDMI_DDC_ARBITRATION_HW_ARBITRATION);
spin_unlock_irqrestore(&hdmi->reg_lock, flags);
/*
@@ -498,9 +484,8 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl)
hdmi_write(hdmi, REG_HDMI_HDCP_ENTROPY_CTRL1, 0xF00DFACE);
/* Disable the RngCipher state */
- reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL);
- reg_val &= ~HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER;
- hdmi_write(hdmi, REG_HDMI_HDCP_DEBUG_CTRL, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_HDCP_DEBUG_CTRL,
+ HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER);
DBG("HDCP_DEBUG_CTRL=0x%08x",
hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL));
@@ -537,15 +522,12 @@ static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl)
static void msm_hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
struct hdmi *hdmi = hdcp_ctrl->hdmi;
- u32 reg_val;
unsigned long flags;
DBG("hdcp auth failed, queue reauth work");
/* clear HDMI Encrypt */
spin_lock_irqsave(&hdmi->reg_lock, flags);
- reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
- reg_val &= ~HDMI_CTRL_ENCRYPTED;
- hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
spin_unlock_irqrestore(&hdmi->reg_lock, flags);
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)
static void msm_hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
struct hdmi *hdmi = hdcp_ctrl->hdmi;
- u32 reg_val;
unsigned long flags;
/*
@@ -563,16 +544,15 @@ static void msm_hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl)
* there is no Arbitration between software and hardware for DDC
*/
spin_lock_irqsave(&hdmi->reg_lock, flags);
- reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);
- reg_val |= HDMI_DDC_ARBITRATION_HW_ARBITRATION;
- hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);
+ hdmi_update_bits(hdmi, REG_HDMI_DDC_ARBITRATION,
+ HDMI_DDC_ARBITRATION_HW_ARBITRATION,
+ HDMI_DDC_ARBITRATION_HW_ARBITRATION);
spin_unlock_irqrestore(&hdmi->reg_lock, flags);
/* enable HDMI Encrypt */
spin_lock_irqsave(&hdmi->reg_lock, flags);
- reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
- reg_val |= HDMI_CTRL_ENCRYPTED;
- hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+ hdmi_update_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED,
+ HDMI_CTRL_ENCRYPTED);
spin_unlock_irqrestore(&hdmi->reg_lock, flags);
hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATED;
@@ -1304,7 +1284,6 @@ end:
void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
struct hdmi *hdmi = hdcp_ctrl->hdmi;
- u32 reg_val;
unsigned long flags;
if ((HDCP_STATE_INACTIVE != hdcp_ctrl->hdcp_state) ||
@@ -1315,9 +1294,7 @@ void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl)
/* clear HDMI Encrypt */
spin_lock_irqsave(&hdmi->reg_lock, flags);
- reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
- reg_val &= ~HDMI_CTRL_ENCRYPTED;
- hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
spin_unlock_irqrestore(&hdmi->reg_lock, flags);
hdcp_ctrl->auth_event = 0;
@@ -1330,7 +1307,6 @@ void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
struct hdmi *hdmi = hdcp_ctrl->hdmi;
unsigned long flags;
- u32 reg_val;
if ((HDCP_STATE_INACTIVE == hdcp_ctrl->hdcp_state) ||
(HDCP_STATE_NO_AKSV == hdcp_ctrl->hdcp_state)) {
@@ -1345,9 +1321,7 @@ void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl)
* AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
*/
spin_lock_irqsave(&hdmi->reg_lock, flags);
- reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
- reg_val &= ~HDMI_HPD_CTRL_ENABLE;
- hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE);
/*
* Disable HDCP interrupts.
@@ -1375,14 +1349,11 @@ void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl)
hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, 0);
spin_lock_irqsave(&hdmi->reg_lock, flags);
- reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
- reg_val &= ~HDMI_CTRL_ENCRYPTED;
- hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+ hdmi_clear_bits(hdmi, REG_HDMI_CTRL, HDMI_CTRL_ENCRYPTED);
/* Enable HPD circuitry */
- reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
- reg_val |= HDMI_HPD_CTRL_ENABLE;
- hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
+ hdmi_update_bits(hdmi, REG_HDMI_HPD_CTRL, HDMI_HPD_CTRL_ENABLE,
+ HDMI_HPD_CTRL_ENABLE);
spin_unlock_irqrestore(&hdmi->reg_lock, flags);
hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index ac86b427c0e5..db1b655dd055 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -222,20 +222,21 @@ static void load_gpu(struct drm_device *dev)
*/
struct drm_gpuvm *msm_context_vm(struct drm_device *dev, struct msm_context *ctx)
{
- static DEFINE_MUTEX(init_lock);
struct msm_drm_private *priv = dev->dev_private;
+ struct drm_gpuvm *vm = smp_load_acquire(&ctx->vm);
/* Once ctx->vm is created it is valid for the lifetime of the context: */
- if (ctx->vm)
- return ctx->vm;
+ if (vm)
+ return vm;
+
+ guard(rwsem_write)(&ctx->ctxlock);
- mutex_lock(&init_lock);
if (!ctx->vm) {
- ctx->vm = msm_gpu_create_private_vm(
+ vm = msm_gpu_create_private_vm(
priv->gpu, current, !ctx->userspace_managed_vm);
-
+ if (!IS_ERR_OR_NULL(vm))
+ smp_store_release(&ctx->vm, vm);
}
- mutex_unlock(&init_lock);
return ctx->vm;
}
@@ -250,7 +251,7 @@ static int context_init(struct drm_device *dev, struct drm_file *file)
return -ENOMEM;
INIT_LIST_HEAD(&ctx->submitqueues);
- rwlock_init(&ctx->queuelock);
+ init_rwsem(&ctx->ctxlock);
kref_init(&ctx->ref);
msm_submitqueue_init(dev, ctx);
@@ -422,10 +423,14 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev,
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_context *ctx = file->driver_priv;
+ struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
if (!priv->gpu)
return -EINVAL;
+ if (!vm)
+ return UERR(ENOMEM, dev, "no VM");
+
if (msm_context_is_vmbind(ctx))
return UERR(EINVAL, dev, "VM_BIND is enabled");
@@ -436,7 +441,7 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev,
* Don't pin the memory here - just get an address so that userspace can
* be productive
*/
- return msm_gem_get_iova(obj, msm_context_vm(dev, ctx), iova);
+ return msm_gem_get_iova(obj, vm, iova);
}
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,
if (!priv->gpu)
return -EINVAL;
+ if (!vm)
+ return UERR(ENOMEM, dev, "no VM");
+
if (msm_context_is_vmbind(ctx))
return UERR(EINVAL, dev, "VM_BIND is enabled");
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 3787db8770ad..eb4bbae8557b 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -261,8 +261,6 @@ const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
struct drm_file *file, const struct drm_format_info *info,
const struct drm_mode_fb_cmd2 *mode_cmd);
-struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
- int w, int h, int p, uint32_t format);
#ifdef CONFIG_DRM_MSM_KMS_FBDEV
int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
@@ -356,8 +354,6 @@ void __exit msm_dp_unregister(void);
int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
struct drm_encoder *encoder, bool yuv_supported);
void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);
-bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,
- const struct drm_display_mode *mode);
bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
const struct drm_display_mode *mode);
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
{
}
-static inline bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,
- const struct drm_display_mode *mode)
-{
- return false;
-}
-
static inline bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
const struct drm_display_mode *mode)
{
@@ -503,13 +493,6 @@ void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
-static inline int align_pitch(int width, int bpp)
-{
- int bytespp = (bpp + 7) / 8;
- /* adreno needs pitch aligned to 32 pixels: */
- return bytespp * ALIGN(width, 32);
-}
-
/* for the generated headers: */
#define INVALID_IDX(idx) ({BUG(); 0;})
#define fui(x) ({BUG(); 0;})
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index 9b681e144c07..60c108d35d2a 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -6,7 +6,6 @@
#include <drm/drm_crtc.h>
#include <drm/drm_damage_helper.h>
-#include <drm/drm_file.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_framebuffer_helper.h>
@@ -29,10 +28,6 @@ struct msm_framebuffer {
};
#define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
-static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
- const struct drm_format_info *info,
- const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
-
static int msm_framebuffer_dirtyfb(struct drm_framebuffer *fb,
struct drm_file *file_priv, unsigned int flags,
unsigned int color, struct drm_clip_rect *clips,
@@ -139,39 +134,10 @@ const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb)
return msm_fb->format;
}
-struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
- struct drm_file *file, const struct drm_format_info *info,
- const struct drm_mode_fb_cmd2 *mode_cmd)
-{
- struct drm_gem_object *bos[4] = {0};
- struct drm_framebuffer *fb;
- int ret, i, n = info->num_planes;
-
- for (i = 0; i < n; i++) {
- bos[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
- if (!bos[i]) {
- ret = -ENXIO;
- goto out_unref;
- }
- }
-
- fb = msm_framebuffer_init(dev, info, mode_cmd, bos);
- if (IS_ERR(fb)) {
- ret = PTR_ERR(fb);
- goto out_unref;
- }
-
- return fb;
-
-out_unref:
- for (i = 0; i < n; i++)
- drm_gem_object_put(bos[i]);
- return ERR_PTR(ret);
-}
-
-static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
- const struct drm_format_info *info,
- const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
+static struct drm_framebuffer *
+msm_framebuffer_init(struct drm_device *dev, const struct drm_format_info *info,
+ const struct drm_mode_fb_cmd2 *mode_cmd,
+ struct drm_gem_object **bos)
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
@@ -251,47 +217,33 @@ fail:
return ERR_PTR(ret);
}
-struct drm_framebuffer *
-msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format)
+struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
+ struct drm_file *file,
+ const struct drm_format_info *info,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
{
- struct drm_mode_fb_cmd2 mode_cmd = {
- .pixel_format = format,
- .width = w,
- .height = h,
- .pitches = { p },
- };
- struct drm_gem_object *bo;
+ struct drm_gem_object *bos[4] = {0};
struct drm_framebuffer *fb;
- int size;
-
- /* allocate backing bo */
- size = mode_cmd.pitches[0] * mode_cmd.height;
- DBG("allocating %d bytes for fb %d", size, dev->primary->index);
- bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN);
- if (IS_ERR(bo)) {
- dev_warn(dev->dev, "could not allocate stolen bo\n");
- /* try regular bo: */
- bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC);
- }
- if (IS_ERR(bo)) {
- DRM_DEV_ERROR(dev->dev, "failed to allocate buffer object\n");
- return ERR_CAST(bo);
- }
+ int ret, i, n = info->num_planes;
- msm_gem_object_set_name(bo, "stolenfb");
+ for (i = 0; i < n; i++) {
+ bos[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
+ if (!bos[i]) {
+ ret = -ENXIO;
+ goto out_unref;
+ }
+ }
- fb = msm_framebuffer_init(dev,
- drm_get_format_info(dev, mode_cmd.pixel_format,
- mode_cmd.modifier[0]),
- &mode_cmd, &bo);
+ fb = msm_framebuffer_init(dev, info, mode_cmd, bos);
if (IS_ERR(fb)) {
- DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");
- /* note: if fb creation failed, we can't rely on fb destroy
- * to unref the bo:
- */
- drm_gem_object_put(bo);
- return ERR_CAST(fb);
+ ret = PTR_ERR(fb);
+ goto out_unref;
}
return fb;
+
+out_unref:
+ for (i = 0; i < n; i++)
+ drm_gem_object_put(bos[i]);
+ return ERR_PTR(ret);
}
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index fd19995b12b5..89ca9da3e1f2 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -9,6 +9,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
+#include <drm/drm_file.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_prime.h>
@@ -40,17 +41,15 @@ static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
static void msm_fbdev_fb_destroy(struct fb_info *info)
{
struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
- struct drm_framebuffer *fb = helper->fb;
- struct drm_gem_object *bo = msm_framebuffer_bo(fb, 0);
+ struct drm_gem_object *bo = msm_framebuffer_bo(helper->fb, 0);
DBG();
drm_fb_helper_fini(helper);
- /* this will free the backing object */
msm_gem_put_vaddr(bo);
- drm_framebuffer_remove(fb);
+ drm_client_buffer_delete(helper->buffer);
drm_client_release(&helper->client);
}
@@ -89,31 +88,54 @@ static const struct drm_fb_helper_funcs msm_fbdev_helper_funcs = {
int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
- struct drm_device *dev = helper->dev;
+ struct drm_client_dev *client = &helper->client;
+ struct drm_device *dev = client->dev;
+ struct drm_file *file = client->file;
struct msm_drm_private *priv = dev->dev_private;
struct fb_info *fbi = helper->info;
- struct drm_framebuffer *fb = NULL;
+ const struct drm_format_info *format;
+ u32 fourcc, pitch, handle;
+ u64 size;
struct drm_gem_object *bo;
+ struct drm_client_buffer *buffer;
uint64_t paddr;
- uint32_t format;
- int ret, pitch;
-
- format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
+ int ret;
DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
sizes->surface_height, sizes->surface_bpp,
sizes->fb_width, sizes->fb_height);
- pitch = align_pitch(sizes->surface_width, sizes->surface_bpp);
- fb = msm_alloc_stolen_fb(dev, sizes->surface_width,
- sizes->surface_height, pitch, format);
-
- if (IS_ERR(fb)) {
- DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");
- return PTR_ERR(fb);
+ fourcc = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
+ format = drm_get_format_info(dev, fourcc, DRM_FORMAT_MOD_LINEAR);
+ /* adreno needs pitch aligned to 32 pixels: */
+ pitch = drm_format_info_min_pitch(format, 0, ALIGN(sizes->surface_width, 32));
+ size = ALIGN(pitch * sizes->surface_height, PAGE_SIZE);
+
+ /* allocate backing bo */
+ DBG("allocating %llu bytes for fb %d", size, dev->primary->index);
+ bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN, NULL);
+ if (IS_ERR(bo)) {
+ drm_warn(dev, "could not allocate stolen bo\n");
+ /* try regular bo: */
+ bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC, NULL);
+ if (IS_ERR(bo)) {
+ drm_err(dev, "failed to allocate buffer object\n");
+ return PTR_ERR(bo);
+ }
}
- bo = msm_framebuffer_bo(fb, 0);
+ msm_gem_object_set_name(bo, "stolenfb");
+
+ ret = drm_gem_handle_create(file, bo, &handle);
+ if (ret)
+ goto err_drm_gem_object_put;
+
+ buffer = drm_client_buffer_create(client, sizes->surface_width, sizes->surface_height,
+ fourcc, handle, pitch);
+ if (IS_ERR(buffer)) {
+ ret = PTR_ERR(buffer);
+ goto err_drm_gem_handle_delete;
+ }
/*
* 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,
*/
ret = msm_gem_get_and_pin_iova(bo, priv->kms->vm, &paddr);
if (ret) {
- DRM_DEV_ERROR(dev->dev, "failed to get buffer obj iova: %d\n", ret);
- goto fail;
+ drm_err(dev, "failed to get buffer obj iova: %d\n", ret);
+ goto err_drm_client_buffer_delete;
}
DBG("fbi=%p, dev=%p", fbi, dev);
helper->funcs = &msm_fbdev_helper_funcs;
- helper->fb = fb;
+ helper->buffer = buffer;
+ helper->fb = buffer->fb;
fbi->fbops = &msm_fb_ops;
@@ -138,18 +161,31 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
fbi->screen_buffer = msm_gem_get_vaddr(bo);
if (IS_ERR(fbi->screen_buffer)) {
ret = PTR_ERR(fbi->screen_buffer);
- goto fail;
+ goto err_msm_gem_unpin;
}
fbi->screen_size = bo->size;
fbi->fix.smem_start = paddr;
fbi->fix.smem_len = bo->size;
DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
- DBG("allocated %dx%d fb", fb->width, fb->height);
+ DBG("allocated %dx%d fb", buffer->fb->width, buffer->fb->height);
+
+ /* The handle is only needed for creating the framebuffer. */
+ drm_gem_handle_delete(file, handle);
+
+ /* The framebuffer still holds a reference on the GEM object. */
+ drm_gem_object_put(bo);
return 0;
-fail:
- drm_framebuffer_remove(fb);
+err_msm_gem_unpin:
+ msm_gem_unpin_iova(bo, priv->kms->vm);
+ msm_gem_vma_put(bo);
+err_drm_client_buffer_delete:
+ drm_client_buffer_delete(buffer);
+err_drm_gem_handle_delete:
+ drm_gem_handle_delete(file, handle);
+err_drm_gem_object_put:
+ drm_gem_object_put(bo);
return ret;
}
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index efd3d3c9a449..de4e60e28a71 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -1093,7 +1093,9 @@ static void msm_gem_free_object(struct drm_gem_object *obj)
*/
kvfree(msm_obj->pages);
- drm_prime_gem_destroy(obj, msm_obj->sgt);
+ /* In msm_gem_import() error path, sgt won't be set yet: */
+ if (msm_obj->sgt)
+ drm_prime_gem_destroy(obj, msm_obj->sgt);
} else {
msm_gem_vunmap(obj);
put_pages(obj);
@@ -1134,10 +1136,21 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
size_t size, uint32_t flags, uint32_t *handle,
char *name)
{
- struct drm_gem_object *obj;
+ struct drm_gem_object *obj, *r_obj = NULL;
int ret;
- obj = msm_gem_new(dev, size, flags);
+ if (flags & MSM_BO_NO_SHARE) {
+ struct msm_drm_private *priv = dev->dev_private;
+ struct msm_context *ctx = file->driver_priv;
+ struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
+
+ if (!priv->gpu || !vm)
+ return UERR(EINVAL, dev, "not supported with shared VM");
+
+ r_obj = drm_gpuvm_resv_obj(vm);
+ }
+
+ obj = msm_gem_new(dev, size, flags, r_obj);
if (IS_ERR(obj))
return PTR_ERR(obj);
@@ -1145,15 +1158,6 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
if (name)
msm_gem_object_set_name(obj, "%s", name);
- if (flags & MSM_BO_NO_SHARE) {
- struct msm_context *ctx = file->driver_priv;
- struct drm_gem_object *r_obj = drm_gpuvm_resv_obj(ctx->vm);
-
- drm_gem_object_get(r_obj);
-
- obj->resv = r_obj->resv;
- }
-
ret = drm_gem_handle_create(file, obj, handle);
/* 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,
return 0;
}
-struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, uint32_t flags)
+static int msm_gem_init_bookkeeping(struct drm_gem_object *obj)
+{
+ struct msm_drm_private *priv = obj->dev->dev_private;
+
+ if (drm_gem_is_imported(obj)) {
+ drm_gem_lru_move_tail(&priv->lru.pinned, obj);
+ } else {
+ drm_gem_lru_move_tail(&priv->lru.unbacked, obj);
+ }
+
+ mutex_lock(&priv->obj_lock);
+ list_add_tail(&to_msm_bo(obj)->node, &priv->objects);
+ mutex_unlock(&priv->obj_lock);
+
+ return drm_gem_create_mmap_offset(obj);
+}
+
+struct drm_gem_object *
+msm_gem_new(struct drm_device *dev, size_t size, uint32_t flags,
+ struct drm_gem_object *r_obj)
{
- struct msm_drm_private *priv = dev->dev_private;
- struct msm_gem_object *msm_obj;
struct drm_gem_object *obj = NULL;
int ret;
@@ -1251,7 +1272,10 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, uint32_t
if (ret)
return ERR_PTR(ret);
- msm_obj = to_msm_bo(obj);
+ if (flags & MSM_BO_NO_SHARE) {
+ drm_gem_object_get(r_obj);
+ obj->resv = r_obj->resv;
+ }
ret = drm_gem_object_init(dev, obj, size);
if (ret)
@@ -1264,13 +1288,7 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, uint32_t
*/
mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER);
- drm_gem_lru_move_tail(&priv->lru.unbacked, obj);
-
- mutex_lock(&priv->obj_lock);
- list_add_tail(&msm_obj->node, &priv->objects);
- mutex_unlock(&priv->obj_lock);
-
- ret = drm_gem_create_mmap_offset(obj);
+ ret = msm_gem_init_bookkeeping(obj);
if (ret)
goto fail;
@@ -1282,11 +1300,12 @@ fail:
}
struct drm_gem_object *msm_gem_import(struct drm_device *dev,
- struct dma_buf *dmabuf, struct sg_table *sgt)
+ struct dma_buf_attachment *attach,
+ struct sg_table *sgt)
{
- struct msm_drm_private *priv = dev->dev_private;
struct msm_gem_object *msm_obj;
struct drm_gem_object *obj;
+ struct dma_buf *dmabuf = attach->dmabuf;
size_t size, npages;
int ret;
@@ -1296,38 +1315,35 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev,
if (ret)
return ERR_PTR(ret);
+ /*
+ * Set import_attach here in case we hit an error path that ends
+ * up in drm_gem_object_put() -> msm_gem_free_object()
+ */
+ obj->import_attach = attach;
+ obj->resv = dmabuf->resv;
drm_gem_private_object_init(dev, obj, size);
npages = size / PAGE_SIZE;
msm_obj = to_msm_bo(obj);
- msm_gem_lock(obj);
- msm_obj->sgt = sgt;
msm_obj->pages = kvmalloc_objs(struct page *, npages);
if (!msm_obj->pages) {
- msm_gem_unlock(obj);
ret = -ENOMEM;
goto fail;
}
ret = drm_prime_sg_to_page_array(sgt, msm_obj->pages, npages);
if (ret) {
- msm_gem_unlock(obj);
goto fail;
}
- msm_gem_unlock(obj);
-
- drm_gem_lru_move_tail(&priv->lru.pinned, obj);
-
- mutex_lock(&priv->obj_lock);
- list_add_tail(&msm_obj->node, &priv->objects);
- mutex_unlock(&priv->obj_lock);
-
- ret = drm_gem_create_mmap_offset(obj);
+ ret = msm_gem_init_bookkeeping(obj);
if (ret)
goto fail;
+ /* Now that we are past potential failure points, set sgt: */
+ msm_obj->sgt = sgt;
+
return obj;
fail:
@@ -1340,7 +1356,7 @@ void *msm_gem_kernel_new(struct drm_device *dev, size_t size, uint32_t flags,
uint64_t *iova)
{
void *vaddr;
- struct drm_gem_object *obj = msm_gem_new(dev, size, flags);
+ struct drm_gem_object *obj = msm_gem_new(dev, size, flags, NULL);
int ret;
if (IS_ERR(obj))
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 762e546d25ef..dff60cbc9d95 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -296,13 +296,14 @@ int msm_gem_cpu_fini(struct drm_gem_object *obj);
int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
size_t size, uint32_t flags, uint32_t *handle, char *name);
struct drm_gem_object *msm_gem_new(struct drm_device *dev,
- size_t size, uint32_t flags);
+ size_t size, uint32_t flags, struct drm_gem_object *r_obj);
void *msm_gem_kernel_new(struct drm_device *dev, size_t size, uint32_t flags,
struct drm_gpuvm *vm, struct drm_gem_object **bo,
uint64_t *iova);
void msm_gem_kernel_put(struct drm_gem_object *bo, struct drm_gpuvm *vm);
struct drm_gem_object *msm_gem_import(struct drm_device *dev,
- struct dma_buf *dmabuf, struct sg_table *sgt);
+ struct dma_buf_attachment *attach,
+ struct sg_table *sgt);
__printf(2, 3)
void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...);
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c
index 036d34c674d9..beb7f22fd694 100644
--- a/drivers/gpu/drm/msm/msm_gem_prime.c
+++ b/drivers/gpu/drm/msm/msm_gem_prime.c
@@ -83,7 +83,7 @@ struct drm_gem_object *msm_gem_prime_import(struct drm_device *dev,
struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach, struct sg_table *sg)
{
- return msm_gem_import(dev, attach->dmabuf, sg);
+ return msm_gem_import(dev, attach, sg);
}
struct dma_buf *msm_gem_prime_export(struct drm_gem_object *obj, int flags)
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 3c6bc90c3d48..5862db05297a 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -30,20 +30,17 @@
*/
static struct msm_gem_submit *submit_create(struct drm_device *dev,
- struct msm_gpu *gpu,
+ struct msm_gpu *gpu, struct drm_gpuvm *vm,
struct msm_gpu_submitqueue *queue, uint32_t nr_bos,
uint32_t nr_cmds, u64 drm_client_id)
{
static atomic_t ident = ATOMIC_INIT(0);
struct msm_gem_submit *submit;
- uint64_t sz;
+ size_t sz;
int ret;
- sz = struct_size(submit, bos, nr_bos) +
- ((u64)nr_cmds * sizeof(submit->cmd[0]));
-
- if (sz > SIZE_MAX)
- return ERR_PTR(-ENOMEM);
+ sz = size_add(struct_size(submit, bos, nr_bos),
+ array_size(sizeof(submit->cmd[0]), nr_cmds));
submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN);
if (!submit)
@@ -66,7 +63,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
kref_init(&submit->ref);
submit->dev = dev;
- submit->vm = msm_context_vm(dev, queue->ctx);
+ submit->vm = vm;
submit->gpu = gpu;
submit->cmd = (void *)&submit->bos[nr_bos];
submit->queue = queue;
@@ -250,16 +247,14 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit,
sz = array_size(submit_cmd.nr_relocs,
sizeof(struct drm_msm_gem_submit_reloc));
- /* check for overflow: */
- if (sz == SIZE_MAX) {
- ret = -ENOMEM;
- goto out;
- }
submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN);
if (!submit->cmd[i].relocs) {
ret = -ENOMEM;
goto out;
}
+
+ submit->nr_cmds = i + 1;
+
ret = copy_from_user(submit->cmd[i].relocs, userptr, sz);
if (ret) {
ret = -EFAULT;
@@ -554,6 +549,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
struct msm_drm_private *priv = dev->dev_private;
struct drm_msm_gem_submit *args = data;
struct msm_context *ctx = file->driver_priv;
+ struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
struct msm_gem_submit *submit = NULL;
struct msm_gpu *gpu = priv->gpu;
struct msm_gpu_submitqueue *queue;
@@ -569,10 +565,13 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
if (!gpu)
return -ENXIO;
+ if (!vm)
+ return UERR(ENOMEM, dev, "no VM");
+
if (args->pad)
return -EINVAL;
- if (to_msm_vm(ctx->vm)->unusable)
+ if (to_msm_vm(vm)->unusable)
return UERR(EPIPE, dev, "context is unusable");
/* 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,
}
}
- submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds,
+ submit = submit_create(dev, gpu, vm, queue, args->nr_bos, args->nr_cmds,
file->client_id);
if (IS_ERR(submit)) {
ret = PTR_ERR(submit);
@@ -719,8 +718,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
goto out;
}
- submit->nr_cmds = args->nr_cmds;
-
idr_preload(GFP_KERNEL);
spin_lock(&queue->idr_lock);
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index c4cfe036066b..c11d021581e0 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -458,6 +458,8 @@ msm_gem_vm_bo_validate(struct drm_gpuvm_bo *vm_bo, struct drm_exec *exec)
return ret;
}
+ drm_gpuvm_bo_evict(vm_bo, false);
+
return 0;
}
@@ -955,7 +957,7 @@ msm_gem_vm_close(struct drm_gpuvm *gpuvm)
static struct msm_vm_bind_job *
-vm_bind_job_create(struct drm_device *dev, struct drm_file *file,
+vm_bind_job_create(struct drm_device *dev, struct drm_file *file, struct drm_gpuvm *vm,
struct msm_gpu_submitqueue *queue, uint32_t nr_ops)
{
struct msm_vm_bind_job *job;
@@ -972,7 +974,7 @@ vm_bind_job_create(struct drm_device *dev, struct drm_file *file,
return ERR_PTR(ret);
}
- job->vm = msm_context_vm(dev, queue->ctx);
+ job->vm = vm;
job->queue = queue;
INIT_LIST_HEAD(&job->vm_ops);
@@ -1431,6 +1433,7 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file)
struct msm_drm_private *priv = dev->dev_private;
struct drm_msm_vm_bind *args = data;
struct msm_context *ctx = file->driver_priv;
+ struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
struct msm_vm_bind_job *job = NULL;
struct msm_gpu *gpu = priv->gpu;
struct msm_gpu_submitqueue *queue;
@@ -1445,11 +1448,14 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file)
if (!gpu)
return -ENXIO;
+ if (!vm)
+ return UERR(ENOMEM, dev, "no VM");
+
/*
* Maybe we could allow just UNMAP ops? OTOH userspace should just
* immediately close the device file and all will be torn down.
*/
- if (to_msm_vm(msm_context_vm(dev, ctx))->unusable)
+ if (to_msm_vm(vm)->unusable)
return UERR(EPIPE, dev, "context is unusable");
/*
@@ -1480,7 +1486,7 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file)
}
}
- job = vm_bind_job_create(dev, file, queue, args->nr_ops);
+ job = vm_bind_job_create(dev, file, vm, queue, args->nr_ops);
if (IS_ERR(job)) {
ret = PTR_ERR(job);
goto out_post_unlock;
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 18ed00e5f143..0c2c35636251 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -505,6 +505,8 @@ static void recover_worker(struct kthread_work *work)
*/
if (!vm->managed)
msm_gem_vm_unusable(submit->vm);
+
+ put_task_struct(task);
}
noreclaim_flag = memalloc_noreclaim_save();
@@ -552,11 +554,13 @@ static void recover_worker(struct kthread_work *work)
msm_update_fence(ring->fctx, fence);
}
- /* retire completed submits, plus the one that hung: */
- retire_submits(gpu);
+ priv->disable_err_irq = false;
gpu->funcs->recover(gpu);
+ /* retire completed submits, plus the one that hung: */
+ retire_submits(gpu);
+
/*
* Replay all remaining submits starting with highest priority
* ring
@@ -875,7 +879,7 @@ msm_gpu_create_private_vm(struct msm_gpu *gpu, struct task_struct *task,
to_msm_vm(vm)->pid = get_pid(task_pid(task));
}
- if (IS_ERR_OR_NULL(vm))
+ if (IS_ERR_OR_NULL(vm) && kernel_managed)
vm = drm_gpuvm_get(gpu->vm);
return vm;
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 6c83b8cbbb90..d27d54bdb7a7 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -392,8 +392,8 @@ msm_gpu_sysprof_no_ifpc(struct msm_gpu *gpu)
* struct msm_context - per-drm_file context
*/
struct msm_context {
- /** @queuelock: synchronizes access to submitqueues list */
- rwlock_t queuelock;
+ /** @ctxlock: synchronizes access to submitqueues list, etc */
+ struct rw_semaphore ctxlock;
/** @submitqueues: list of &msm_gpu_submitqueue created by userspace */
struct list_head submitqueues;
/**
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 897e42c8d5c8..da6782fca6bd 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -7,6 +7,15 @@
#include <linux/adreno-smmu-priv.h>
#include <linux/io-pgtable.h>
#include <linux/kmemleak.h>
+
+#if defined(CONFIG_ARM_DMA_USE_IOMMU)
+#include <asm/dma-iommu.h>
+#else
+#define arm_iommu_detach_device(...) ({ })
+#define arm_iommu_release_mapping(...) ({ })
+#define to_dma_iommu_mapping(dev) NULL
+#endif
+
#include "msm_drv.h"
#include "msm_gpu_trace.h"
#include "msm_mmu.h"
@@ -749,6 +758,19 @@ struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks)
mutex_init(&iommu->init_lock);
+ /*
+ * ARM32 attaches a DMA mapping domain to every IOMMU-backed device,
+ * which would make attaching our own domain fail with -EBUSY.
+ */
+ if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
+ struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
+
+ if (mapping) {
+ arm_iommu_detach_device(dev);
+ arm_iommu_release_mapping(mapping);
+ }
+ }
+
ret = iommu_attach_device(iommu->domain, dev);
if (ret) {
iommu_domain_free(domain);
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c
index 2d6b930b766e..59c69aa75649 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.c
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
@@ -109,9 +109,9 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
ring->memptrs_iova = memptrs_iova;
ret = drm_sched_init(&ring->sched, &args);
- if (ret) {
+ if (ret)
goto fail;
- }
+ ring->sched_initialized = true;
INIT_LIST_HEAD(&ring->submits);
spin_lock_init(&ring->submit_lock);
@@ -133,7 +133,8 @@ void msm_ringbuffer_destroy(struct msm_ringbuffer *ring)
if (IS_ERR_OR_NULL(ring))
return;
- drm_sched_fini(&ring->sched);
+ if (ring->sched_initialized)
+ drm_sched_fini(&ring->sched);
msm_fence_context_free(ring->fctx);
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h
index 28ca8c9f7463..3631ec283c6e 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.h
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.h
@@ -56,6 +56,7 @@ struct msm_ringbuffer {
* The job scheduler for this ring.
*/
struct drm_gpu_scheduler sched;
+ bool sched_initialized;
/*
* List of in-flight submits on this ring. Protected by submit_lock.
diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c
index 1a5a77b28016..d307cdd17d90 100644
--- a/drivers/gpu/drm/msm/msm_submitqueue.c
+++ b/drivers/gpu/drm/msm/msm_submitqueue.c
@@ -9,6 +9,8 @@
int msm_context_set_sysprof(struct msm_context *ctx, struct msm_gpu *gpu, int sysprof)
{
+ guard(rwsem_write)(&ctx->ctxlock);
+
/*
* Since pm_runtime and sysprof_active are both refcounts, we
* 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,
if (!ctx)
return NULL;
- read_lock(&ctx->queuelock);
+ guard(rwsem_read)(&ctx->ctxlock);
list_for_each_entry(entry, &ctx->submitqueues, node) {
if (entry->id == id) {
kref_get(&entry->ref);
- read_unlock(&ctx->queuelock);
-
return entry;
}
}
- read_unlock(&ctx->queuelock);
return NULL;
}
@@ -175,6 +174,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx,
struct msm_drm_private *priv = drm->dev_private;
struct msm_gpu_submitqueue *queue;
enum drm_sched_priority sched_prio;
+ struct drm_gpuvm *vm = NULL;
unsigned ring_nr;
int ret;
@@ -187,6 +187,11 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx,
if (flags & MSM_SUBMITQUEUE_VM_BIND) {
unsigned sz;
+ vm = msm_context_vm(drm, ctx);
+
+ if (!vm)
+ return UERR(ENOMEM, drm, "no VM");
+
/* Not allowed for kernel managed VMs (ie. kernel allocs VA) */
if (!msm_context_is_vmbind(ctx))
return -EINVAL;
@@ -218,7 +223,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx,
queue->flags = flags;
if (flags & MSM_SUBMITQUEUE_VM_BIND) {
- struct drm_gpu_scheduler *sched = &to_msm_vm(msm_context_vm(drm, ctx))->sched;
+ struct drm_gpu_scheduler *sched = &to_msm_vm(vm)->sched;
queue->entity = &queue->_vm_bind_entity[0];
@@ -237,7 +242,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx,
return ret;
}
- write_lock(&ctx->queuelock);
+ guard(rwsem_write)(&ctx->ctxlock);
queue->ctx = msm_context_get(ctx);
queue->id = ctx->queueid++;
@@ -251,8 +256,6 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx,
list_add_tail(&queue->node, &ctx->submitqueues);
- write_unlock(&ctx->queuelock);
-
return 0;
}
@@ -335,19 +338,16 @@ int msm_submitqueue_remove(struct msm_context *ctx, u32 id)
if (!id)
return -ENOENT;
- write_lock(&ctx->queuelock);
+ guard(rwsem_write)(&ctx->ctxlock);
list_for_each_entry(entry, &ctx->submitqueues, node) {
if (entry->id == id) {
list_del(&entry->node);
- write_unlock(&ctx->queuelock);
-
msm_submitqueue_put(entry);
return 0;
}
}
- write_unlock(&ctx->queuelock);
return -ENOENT;
}
diff --git a/drivers/gpu/drm/msm/registers/adreno/a3xx.xml b/drivers/gpu/drm/msm/registers/adreno/a3xx.xml
index 09c9606fc3e1..21b00a17ef3e 100644
--- a/drivers/gpu/drm/msm/registers/adreno/a3xx.xml
+++ b/drivers/gpu/drm/msm/registers/adreno/a3xx.xml
@@ -1495,6 +1495,8 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
<reg32 offset="0x3058" name="VBIF_OUT_AXI_AMEMTYPE_CONF0"/>
<reg32 offset="0x305e" name="VBIF_OUT_AXI_AOOO_EN"/>
<reg32 offset="0x305f" name="VBIF_OUT_AXI_AOOO"/>
+ <reg32 offset="0x3080" name="VBIF_XIN_HALT_CTRL0"/>
+ <reg32 offset="0x3081" name="VBIF_XIN_HALT_CTRL1"/>
<bitset name="a3xx_vbif_perf_cnt" inline="yes">
<bitfield name="CNT0" pos="0" type="boolean"/>
diff --git a/drivers/gpu/drm/msm/registers/adreno/a6xx.xml b/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
index 3349c01646e1..69dd0446f8d2 100644
--- a/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
+++ b/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
@@ -1268,7 +1268,7 @@ by a particular renderpass/blit.
<reg32 offset="0x3119" name="VBIF_PERF_PWR_CNT_HIGH1" variants="A6XX"/>
<reg32 offset="0x311a" name="VBIF_PERF_PWR_CNT_HIGH2" variants="A6XX"/>
- <reg32 offset="0x3c00" name="GBIF_CX_CONFIG" variants="A8XX-"/>
+ <reg32 offset="0x3c00" name="GBIF_CX_CONFIG" variants="A6XX-"/>
<reg32 offset="0x3c01" name="GBIF_SCACHE_CNTL0"/>
<reg32 offset="0x3c02" name="GBIF_SCACHE_CNTL1"/>
<reg32 offset="0x3c03" name="GBIF_QSB_SIDE0"/>
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 7f2e594be4eb..3d363f12f66a 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -228,7 +228,7 @@ struct drm_msm_gem_cpu_fini {
struct drm_msm_syncobj {
__u32 handle; /* in, syncobj handle. */
- __u32 flags; /* in, from MSM_SUBMIT_SYNCOBJ_FLAGS */
+ __u32 flags; /* in, from MSM_SYNCOBJ_FLAGS */
__u64 point; /* in, timepoint for timeline syncobjs. */
};
@@ -393,9 +393,9 @@ struct drm_msm_vm_bind {
__s32 fence_fd;
/** @queue_id: in, submitqueue id */
__u32 queue_id;
- /** @in_syncobjs: in, ptr to array of drm_msm_gem_syncobj */
+ /** @in_syncobjs: in, ptr to array of drm_msm_syncobj */
__u64 in_syncobjs;
- /** @out_syncobjs: in, ptr to array of drm_msm_gem_syncobj */
+ /** @out_syncobjs: in, ptr to array of drm_msm_syncobj */
__u64 out_syncobjs;
/** @nr_in_syncobjs: in, number of entries in in_syncobj */
__u32 nr_in_syncobjs;