mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 10:31:33 -04:00
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
This commit is contained in:
@@ -47,6 +47,10 @@ properties:
|
||||
- qcom,sm8650-dsi-ctrl
|
||||
- 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
@@ -1500,6 +1500,40 @@ static const struct adreno_info a7xx_gpus[] = {
|
||||
.gmu_cgc_mode = 0x00020000,
|
||||
},
|
||||
.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,
|
||||
@@ -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 },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -377,6 +377,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,
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
428
drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h
Normal file
428
drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h
Normal file
@@ -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 */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*************************************************************/
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
/*
|
||||
* 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 (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
|
||||
config |= DP_CONFIGURATION_CTRL_RGB_YUV; /* YUV420 */
|
||||
|
||||
tbd = msm_dp_link_get_test_bits_depth(ctrl->link,
|
||||
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);
|
||||
|
||||
if (ctrl->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);
|
||||
|
||||
config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT;
|
||||
|
||||
/* 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 @@ static void _dp_ctrl_calc_tu(struct msm_dp_ctrl_private *ctrl,
|
||||
}
|
||||
|
||||
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 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
|
||||
}
|
||||
|
||||
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,7 +2530,44 @@ 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;
|
||||
struct msm_dp_ctrl_private *ctrl;
|
||||
|
||||
if (!msm_dp_ctrl)
|
||||
return -EINVAL;
|
||||
|
||||
ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
|
||||
|
||||
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, panel);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (force_link_train || !msm_dp_ctrl_channel_eq_ok(ctrl))
|
||||
msm_dp_ctrl_link_retrain(ctrl, panel);
|
||||
|
||||
/* stop txing train pattern to end link training */
|
||||
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;
|
||||
@@ -2478,49 +2580,17 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train
|
||||
|
||||
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;
|
||||
pixel_rate_orig = panel->msm_dp_mode.drm_mode.clock;
|
||||
pixel_rate = pixel_rate_orig;
|
||||
|
||||
if (msm_dp_ctrl->wide_bus_en || ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)
|
||||
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, "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, "pixel_rate=%lu\n", pixel_rate);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
ctrl->stream_clks_on = true;
|
||||
}
|
||||
|
||||
if (force_link_train || !msm_dp_ctrl_channel_eq_ok(ctrl))
|
||||
msm_dp_ctrl_link_retrain(ctrl);
|
||||
|
||||
/* stop txing train pattern to end link training */
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
|
||||
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);
|
||||
msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl, panel);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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 @@ static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
|
||||
}
|
||||
|
||||
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;
|
||||
struct msm_dp_display_private *dp;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
|
||||
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");
|
||||
dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
|
||||
|
||||
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 (dp->is_edp)
|
||||
msm_dp_hpd_plug_handle(msm_dp_display);
|
||||
|
||||
if (pm_runtime_resume_and_get(&dp->pdev->dev)) {
|
||||
DRM_ERROR("failed to pm_runtime_resume\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (msm_dp_display->link->sink_count == 0)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!dp->power_on) {
|
||||
msm_dp_display_host_phy_init(msm_dp_display);
|
||||
force_link_train = true;
|
||||
}
|
||||
|
||||
rc = msm_dp_ctrl_on_link(msm_dp_display->ctrl);
|
||||
if (rc) {
|
||||
DRM_ERROR("Failed link training (rc=%d)\n", rc);
|
||||
// TODO: schedule drm_connector_set_link_status_property()
|
||||
return;
|
||||
}
|
||||
|
||||
msm_dp_display_enable(msm_dp_display, force_link_train);
|
||||
|
||||
rc = msm_dp_display_post_enable(dp);
|
||||
if (rc) {
|
||||
DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
|
||||
msm_dp_display_disable(msm_dp_display);
|
||||
}
|
||||
|
||||
drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
|
||||
void msm_dp_display_atomic_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 *dp;
|
||||
|
||||
dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
|
||||
|
||||
rc = msm_dp_display_prepare_link(dp);
|
||||
if (rc) {
|
||||
DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
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(msm_dp_display);
|
||||
if (rc) {
|
||||
DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
|
||||
msm_dp_display_disable(dp, dp->panel);
|
||||
}
|
||||
|
||||
drm_dbg_dp(msm_dp_display->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
|
||||
}
|
||||
|
||||
void msm_dp_display_atomic_disable(struct msm_dp *dp)
|
||||
{
|
||||
struct msm_dp_display_private *msm_dp_display;
|
||||
|
||||
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
|
||||
@@ -1419,11 +1461,17 @@ 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 *msm_dp_display = &dp->msm_dp_display;
|
||||
|
||||
pm_runtime_put_sync(&msm_dp_display->pdev->dev);
|
||||
|
||||
drm_dbg_dp(dp->drm_dev, "type=%d Done\n", msm_dp_display->connector_type);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
|
||||
@@ -1431,50 +1479,11 @@ void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
|
||||
if (dp->is_edp)
|
||||
msm_dp_hpd_unplug_handle(msm_dp_display);
|
||||
|
||||
msm_dp_display_disable(msm_dp_display);
|
||||
msm_dp_display_audio_notify_disable(msm_dp_display);
|
||||
|
||||
drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
|
||||
msm_dp_display_disable(msm_dp_display, msm_dp_display->panel);
|
||||
|
||||
pm_runtime_put_sync(&dp->pdev->dev);
|
||||
}
|
||||
|
||||
void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,
|
||||
const struct drm_display_mode *mode,
|
||||
const struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
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);
|
||||
|
||||
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->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;
|
||||
|
||||
/* 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)
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -550,8 +550,6 @@ int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 @@ static void msm_hdmi_hdcp_auth_work(struct work_struct *work)
|
||||
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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;})
|
||||
|
||||
@@ -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 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
|
||||
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;
|
||||
int ret, i, n = info->num_planes;
|
||||
|
||||
/* 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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
msm_gem_object_set_name(bo, "stolenfb");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
|
||||
if (IS_ERR(fb)) {
|
||||
DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");
|
||||
return PTR_ERR(fb);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -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 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, uint32_t
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
@@ -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, ...);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user