[Freedreno] [PATCH v2 9/9] drm/msm/a6xx: update a6xx_hw_init for A640 and A650

2020-04-21 Thread Jonathan Marek
Adreno 640 and 650 GPUs need some registers set differently.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/adreno/a6xx.xml.h | 14 +++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 56 ++-
 2 files changed, 61 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h 
b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
index ed78fee2a262..47840b73cdda 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
@@ -1047,6 +1047,8 @@ enum a6xx_tex_type {
 
 #define REG_A6XX_CP_MISC_CNTL  0x0840
 
+#define REG_A6XX_CP_APRIV_CNTL 0x0844
+
 #define REG_A6XX_CP_ROQ_THRESHOLDS_1   0x08c1
 
 #define REG_A6XX_CP_ROQ_THRESHOLDS_2   0x08c2
@@ -1764,6 +1766,8 @@ static inline uint32_t 
A6XX_CP_PROTECT_REG_MASK_LEN(uint32_t val)
 
 #define REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL 0x0010
 
+#define REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL 0x0011
+
 #define REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL  0x001f
 
 #define REG_A6XX_RBBM_INT_CLEAR_CMD0x0037
@@ -2418,6 +2422,16 @@ static inline uint32_t 
A6XX_UCHE_CLIENT_PF_PERFSEL(uint32_t val)
 
 #define REG_A6XX_TPL1_NC_MODE_CNTL 0xb604
 
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0  0xb608
+
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1  0xb609
+
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_2  0xb60a
+
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_3  0xb60b
+
+#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_4  0xb60c
+
 #define REG_A6XX_TPL1_PERFCTR_TP_SEL_0 0xb610
 
 #define REG_A6XX_TPL1_PERFCTR_TP_SEL_1 0xb611
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index a860d4970e10..e1eb34fa3a99 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -414,7 +414,17 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
a6xx_set_hwcg(gpu, true);
 
/* VBIF/GBIF start*/
-   gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
+   if (adreno_is_a640(adreno_gpu) || adreno_is_a650(adreno_gpu)) {
+   gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE0, 0x00071620);
+   gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE1, 0x00071620);
+   gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE2, 0x00071620);
+   gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
+   gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
+   gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x3);
+   } else {
+   gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
+   }
+
if (adreno_is_a630(adreno_gpu))
gpu_write(gpu, REG_A6XX_VBIF_GATE_OFF_WRREQ_EN, 0x0009);
 
@@ -429,25 +439,35 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_LO, 0xf000);
gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_HI, 0x0001);
 
-   /* Set the GMEM VA range [0x10:0x10 + gpu->gmem - 1] */
-   gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN_LO,
-   REG_A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x0010);
+   if (!adreno_is_a650(adreno_gpu)) {
+   /* Set the GMEM VA range [0x10:0x10 + gpu->gmem - 1] */
+   gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN_LO,
+   REG_A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x0010);
 
-   gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX_LO,
-   REG_A6XX_UCHE_GMEM_RANGE_MAX_HI,
-   0x0010 + adreno_gpu->gmem - 1);
+   gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX_LO,
+   REG_A6XX_UCHE_GMEM_RANGE_MAX_HI,
+   0x0010 + adreno_gpu->gmem - 1);
+   }
 
gpu_write(gpu, REG_A6XX_UCHE_FILTER_CNTL, 0x804);
gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, 0x4);
 
-   gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x01c0);
+   if (adreno_is_a640(adreno_gpu) || adreno_is_a650(adreno_gpu))
+   gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
+   else
+   gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x01c0);
gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
 
/* Setting the mem pool size */
gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
 
/* Setting the primFifo thresholds default values */
-   gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, (0x300 << 11));
+   if (adreno_is_a650(adreno_gpu))
+   gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x0030);
+   else if (adreno_is_a640(adreno_gpu))
+   gpu_write(gpu, 

[Freedreno] [PATCH v2 8/9] drm/msm/a6xx: enable GMU log

2020-04-21 Thread Jonathan Marek
This is required for a650 to work.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 15 +++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  1 +
 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h |  4 
 3 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 60ed5360fd8a..f24e436daafe 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -201,6 +201,12 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu)
u32 val;
 
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
+
+   /* Set the log wptr index
+* note: downstream saves the value in poweroff and restores it here
+*/
+   gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP, 0);
+
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);
 
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val,
@@ -740,6 +746,9 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned 
int state)
 
gmu_write(gmu, REG_A6XX_GMU_HFI_SFR_ADDR, chipid);
 
+   gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG,
+ gmu->log.iova | (gmu->log.size / SZ_4K - 1));
+
/* Set up the lowest idle level on the GMU */
a6xx_gmu_power_config(gmu);
 
@@ -1046,6 +1055,7 @@ static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu)
msm_gem_kernel_put(gmu->icache.obj, gmu->aspace, false);
msm_gem_kernel_put(gmu->dcache.obj, gmu->aspace, false);
msm_gem_kernel_put(gmu->dummy.obj, gmu->aspace, false);
+   msm_gem_kernel_put(gmu->log.obj, gmu->aspace, false);
 
gmu->aspace->mmu->funcs->detach(gmu->aspace->mmu);
msm_gem_address_space_put(gmu->aspace);
@@ -1450,6 +1460,11 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct 
device_node *node)
if (ret)
goto err_memory;
 
+   /* Allocate memory for the GMU log region */
+   ret = a6xx_gmu_memory_alloc(gmu, >log, SZ_4K, 0);
+   if (ret)
+   goto err_memory;
+
/* Map the GMU registers */
gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");
if (IS_ERR(gmu->mmio)) {
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
index aed02b2b7659..be65720f32cf 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
@@ -61,6 +61,7 @@ struct a6xx_gmu {
struct a6xx_gmu_bo icache;
struct a6xx_gmu_bo dcache;
struct a6xx_gmu_bo dummy;
+   struct a6xx_gmu_bo log;
 
int nr_clocks;
struct clk_bulk_data *clocks;
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
index b4357ea550ec..176ae94d9fe6 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
@@ -205,6 +205,10 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t 
val)
 
 #define REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF0x50f0
 
+#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG 0x5100
+
+#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP
0x5101
+
 #define REG_A6XX_GMU_BOOT_KMD_LM_HANDSHAKE 0x51f0
 
 #define REG_A6XX_GMU_LLM_GLM_SLEEP_CTRL
0x5157
-- 
2.26.1

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 5/9] drm/msm/a6xx: HFI v2 for A640 and A650

2020-04-21 Thread Jonathan Marek
Add HFI v2 code paths required by Adreno 640 and 650 GPUs.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  66 ---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h |   7 ++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c |   6 +-
 drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 117 --
 drivers/gpu/drm/msm/adreno/a6xx_hfi.h |  50 ++-
 5 files changed, 222 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index c9fd0470a321..b22a69e2f4b0 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -129,8 +129,6 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int 
index)
if (ret)
dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
 
-   gmu->freq = gmu->gpu_freqs[index];
-
/*
 * Eventually we will want to scale the path vote with the frequency but
 * for now leave it at max so that the performance is nominal.
@@ -154,7 +152,12 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long 
freq)
 
gmu->current_perf_index = perf_index;
 
-   __a6xx_gmu_set_freq(gmu, perf_index);
+   if (gmu->legacy)
+   __a6xx_gmu_set_freq(gmu, perf_index);
+   else
+   a6xx_hfi_set_freq(gmu, perf_index);
+
+   gmu->freq = gmu->gpu_freqs[perf_index];
 }
 
 unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)
@@ -234,8 +237,13 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
a6xx_gmu_oob_state state)
 
switch (state) {
case GMU_OOB_GPU_SET:
-   request = GMU_OOB_GPU_SET_REQUEST;
-   ack = GMU_OOB_GPU_SET_ACK;
+   if (gmu->legacy) {
+   request = GMU_OOB_GPU_SET_REQUEST;
+   ack = GMU_OOB_GPU_SET_ACK;
+   } else {
+   request = GMU_OOB_GPU_SET_REQUEST_NEW;
+   ack = GMU_OOB_GPU_SET_ACK_NEW;
+   }
name = "GPU_SET";
break;
case GMU_OOB_BOOT_SLUMBER:
@@ -274,6 +282,13 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
a6xx_gmu_oob_state state)
 /* Clear a pending OOB state in the GMU */
 void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
 {
+   if (!gmu->legacy) {
+   WARN_ON(state != GMU_OOB_GPU_SET);
+   gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
+   1 << GMU_OOB_GPU_SET_CLEAR_NEW);
+   return;
+   }
+
switch (state) {
case GMU_OOB_GPU_SET:
gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
@@ -296,6 +311,9 @@ static int a6xx_sptprac_enable(struct a6xx_gmu *gmu)
int ret;
u32 val;
 
+   if (!gmu->legacy)
+   return 0;
+
gmu_write(gmu, REG_A6XX_GMU_GX_SPTPRAC_POWER_CONTROL, 0x778000);
 
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, val,
@@ -315,6 +333,9 @@ static void a6xx_sptprac_disable(struct a6xx_gmu *gmu)
u32 val;
int ret;
 
+   if (!gmu->legacy)
+   return;
+
/* Make sure retention is on */
gmu_rmw(gmu, REG_A6XX_GPU_CC_GX_GDSCR, 0, (1 << 11));
 
@@ -358,6 +379,11 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu)
if (gmu->idle_level < GMU_IDLE_STATE_SPTP)
a6xx_sptprac_disable(gmu);
 
+   if (!gmu->legacy) {
+   ret = a6xx_hfi_send_prep_slumber(gmu);
+   goto out;
+   }
+
/* Tell the GMU to get ready to slumber */
gmu_write(gmu, REG_A6XX_GMU_BOOT_SLUMBER_OPTION, 1);
 
@@ -373,6 +399,7 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu)
}
}
 
+out:
/* Put fence into allow mode */
gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0);
return ret;
@@ -642,9 +669,11 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, 
unsigned int state)
if (ret)
return ret;
 
-   ret = a6xx_gmu_gfx_rail_on(gmu);
-   if (ret)
-   return ret;
+   if (gmu->legacy) {
+   ret = a6xx_gmu_gfx_rail_on(gmu);
+   if (ret)
+   return ret;
+   }
 
/* Enable SPTP_PC if the CPU is responsible for it */
if (gmu->idle_level < GMU_IDLE_STATE_SPTP) {
@@ -763,7 +792,10 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
enable_irq(gmu->hfi_irq);
 
/* Set the GPU to the current freq */
-   __a6xx_gmu_set_freq(gmu, gmu->current_perf_index);
+   if (gmu->legacy)
+   __a6xx_gmu_set_freq(gmu, gmu->current_perf_index);
+   else
+   a6xx_hfi_set_freq(gmu, gmu->current_perf_index);
 
/*
 * "enable" the GX power domain which won't actually do anything but it
@@ -1262,6 +1294,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
 
 int a6xx_gmu_init(struct a6xx_gpu 

[Freedreno] [PATCH v2 4/9] drm/msm/a6xx: add A640/A650 to gpulist

2020-04-21 Thread Jonathan Marek
Add Adreno 640 and 650 GPU info to the gpulist.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 24 ++
 drivers/gpu/drm/msm/adreno/adreno_gpu.c|  2 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.h| 10 +
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index cb3a6e597d76..1156f72532a4 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -189,6 +189,30 @@ static const struct adreno_info gpulist[] = {
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a6xx_gpu_init,
.zapfw = "a630_zap.mdt",
+   }, {
+   .rev = ADRENO_REV(6, 4, 0, ANY_ID),
+   .revn = 640,
+   .name = "A640",
+   .fw = {
+   [ADRENO_FW_SQE] = "a630_sqe.fw",
+   [ADRENO_FW_GMU] = "a640_gmu.bin",
+   },
+   .gmem = SZ_1M,
+   .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+   .init = a6xx_gpu_init,
+   .zapfw = "a640_zap.mdt",
+   }, {
+   .rev = ADRENO_REV(6, 5, 0, ANY_ID),
+   .revn = 650,
+   .name = "A650",
+   .fw = {
+   [ADRENO_FW_SQE] = "a650_sqe.fw",
+   [ADRENO_FW_GMU] = "a650_gmu.bin",
+   },
+   .gmem = SZ_1M + SZ_128K,
+   .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+   .init = a6xx_gpu_init,
+   .zapfw = "a650_zap.mdt",
},
 };
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 1d5c43c22269..a7647eaacc7a 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -197,7 +197,7 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, 
uint64_t *value)
*value = adreno_gpu->gmem;
return 0;
case MSM_PARAM_GMEM_BASE:
-   *value = 0x10;
+   *value = !adreno_is_a650(adreno_gpu) ? 0x10 : 0;
return 0;
case MSM_PARAM_CHIP_ID:
*value = adreno_gpu->rev.patchid |
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 9ff4e550e7bd..88ae1b2813ef 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -237,6 +237,16 @@ static inline int adreno_is_a630(struct adreno_gpu *gpu)
return gpu->revn == 630;
 }
 
+static inline int adreno_is_a640(struct adreno_gpu *gpu)
+{
+   return gpu->revn == 640;
+}
+
+static inline int adreno_is_a650(struct adreno_gpu *gpu)
+{
+   return gpu->revn == 650;
+}
+
 int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value);
 const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu,
const char *fwname);
-- 
2.26.1

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 7/9] drm/msm/a6xx: update pdc/rscc GMU registers for A640/A650

2020-04-21 Thread Jonathan Marek
Update the gmu_pdc registers for A640 and A650.

Some of the RSCC registers on A650 are in a separate region.

Note this also changes the address of these registers:

RSCC_TCS1_DRV0_STATUS
RSCC_TCS2_DRV0_STATUS
RSCC_TCS3_DRV0_STATUS

Based on the values in msm-4.14 and msm-4.19 kernels.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 90 ++-
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 10 +++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h | 38 +-
 3 files changed, 85 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 4aef5fe985d6..60ed5360fd8a 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -421,7 +421,7 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu)
return ret;
}
 
-   ret = gmu_poll_timeout(gmu, REG_A6XX_RSCC_SEQ_BUSY_DRV0, val,
+   ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_SEQ_BUSY_DRV0, val,
!val, 100, 1);
 
if (ret) {
@@ -447,7 +447,7 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu)
 
gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1);
 
-   ret = gmu_poll_timeout(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0,
+   ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0,
val, val & (1 << 16), 100, 1);
if (ret)
DRM_DEV_ERROR(gmu->dev, "Unable to power off the GPU RSC\n");
@@ -470,32 +470,48 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
struct platform_device *pdev = to_platform_device(gmu->dev);
void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc");
void __iomem *seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
+   uint32_t pdc_address_offset;
 
if (!pdcptr || !seqptr)
goto err;
 
+   if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu))
+   pdc_address_offset = 0x30090;
+   else if (adreno_is_a650(adreno_gpu))
+   pdc_address_offset = 0x300a0;
+   else
+   pdc_address_offset = 0x30080;
+
/* Disable SDE clock gating */
-   gmu_write(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
+   gmu_write_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
 
/* Setup RSC PDC handshake for sleep and wakeup */
-   gmu_write(gmu, REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0, 1);
-   gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA, 0);
-   gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0);
-   gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
-   gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
-   gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4, 0x8000);
-   gmu_write(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
-   gmu_write(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
-   gmu_write(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);
-   gmu_write(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510);
-   gmu_write(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0, 1);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA, 0);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0);
+   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, 0x8000);
+   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);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
 
/* Load RSC sequencer uCode for sleep and wakeup */
-   gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0);
-   gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xa1e6a6e7);
-   gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e081e1);
-   gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xe9a982e2);
-   gmu_write(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8);
+   if (adreno_is_a650(adreno_gpu)) {
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xeaaae5a0);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 
0xe1a1ebab);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 
0xa2e0a581);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 
0xecac82e2);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 
0x0020edad);
+   } else {
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0);
+   gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 
0xa1e6a6e7);
+   gmu_write_rscc(gmu, 

[Freedreno] [PATCH v2 1/9] drm/msm: add msm_gem_get_and_pin_iova_range

2020-04-21 Thread Jonathan Marek
This function allows pinning iova to a specific page range (for a6xx GMU).

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/msm_drv.h |  6 +-
 drivers/gpu/drm/msm/msm_gem.c | 28 +---
 drivers/gpu/drm/msm/msm_gem_vma.c |  6 --
 3 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 194d900a460e..966fd9068c94 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -236,7 +236,8 @@ int msm_crtc_enable_vblank(struct drm_crtc *crtc);
 void msm_crtc_disable_vblank(struct drm_crtc *crtc);
 
 int msm_gem_init_vma(struct msm_gem_address_space *aspace,
-   struct msm_gem_vma *vma, int npages);
+   struct msm_gem_vma *vma, int npages,
+   u64 range_start, u64 range_end);
 void msm_gem_purge_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma);
 void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
@@ -276,6 +277,9 @@ vm_fault_t msm_gem_fault(struct vm_fault *vmf);
 uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
 int msm_gem_get_iova(struct drm_gem_object *obj,
struct msm_gem_address_space *aspace, uint64_t *iova);
+int msm_gem_get_and_pin_iova_range(struct drm_gem_object *obj,
+   struct msm_gem_address_space *aspace, uint64_t *iova,
+   u64 range_start, u64 range_end);
 int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
struct msm_gem_address_space *aspace, uint64_t *iova);
 uint64_t msm_gem_iova(struct drm_gem_object *obj,
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5a6a79fbc9d6..d8f56a34c117 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -389,7 +389,8 @@ put_iova(struct drm_gem_object *obj)
 }
 
 static int msm_gem_get_iova_locked(struct drm_gem_object *obj,
-   struct msm_gem_address_space *aspace, uint64_t *iova)
+   struct msm_gem_address_space *aspace, uint64_t *iova,
+   u64 range_start, u64 range_end)
 {
struct msm_gem_object *msm_obj = to_msm_bo(obj);
struct msm_gem_vma *vma;
@@ -404,7 +405,8 @@ static int msm_gem_get_iova_locked(struct drm_gem_object 
*obj,
if (IS_ERR(vma))
return PTR_ERR(vma);
 
-   ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT);
+   ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT,
+   range_start, range_end);
if (ret) {
del_vma(vma);
return ret;
@@ -443,9 +445,13 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj,
msm_obj->sgt, obj->size >> PAGE_SHIFT);
 }
 
-/* get iova and pin it. Should have a matching put */
-int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
-   struct msm_gem_address_space *aspace, uint64_t *iova)
+/*
+ * get iova and pin it. Should have a matching put
+ * limits iova to specified range (in pages)
+ */
+int msm_gem_get_and_pin_iova_range(struct drm_gem_object *obj,
+   struct msm_gem_address_space *aspace, uint64_t *iova,
+   u64 range_start, u64 range_end)
 {
struct msm_gem_object *msm_obj = to_msm_bo(obj);
u64 local;
@@ -453,7 +459,8 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
 
mutex_lock(_obj->lock);
 
-   ret = msm_gem_get_iova_locked(obj, aspace, );
+   ret = msm_gem_get_iova_locked(obj, aspace, ,
+   range_start, range_end);
 
if (!ret)
ret = msm_gem_pin_iova(obj, aspace);
@@ -465,6 +472,13 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
return ret;
 }
 
+/* get iova and pin it. Should have a matching put */
+int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
+   struct msm_gem_address_space *aspace, uint64_t *iova)
+{
+   return msm_gem_get_and_pin_iova_range(obj, aspace, iova, 0, U64_MAX);
+}
+
 /*
  * Get an iova but don't pin it. Doesn't need a put because iovas are currently
  * valid for the life of the object
@@ -476,7 +490,7 @@ int msm_gem_get_iova(struct drm_gem_object *obj,
int ret;
 
mutex_lock(_obj->lock);
-   ret = msm_gem_get_iova_locked(obj, aspace, iova);
+   ret = msm_gem_get_iova_locked(obj, aspace, iova, 0, U64_MAX);
mutex_unlock(_obj->lock);
 
return ret;
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
b/drivers/gpu/drm/msm/msm_gem_vma.c
index 1af5354bcd46..407b7ab82818 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -103,7 +103,8 @@ void msm_gem_close_vma(struct msm_gem_address_space *aspace,
 
 /* Initialize a new vma and allocate an iova for it */
 int msm_gem_init_vma(struct msm_gem_address_space *aspace,
-   struct msm_gem_vma *vma, int npages)
+   

[Freedreno] [PATCH v2 3/9] drm/msm/a6xx: use msm_gem for GMU memory objects

2020-04-21 Thread Jonathan Marek
This gives more fine-grained control over how memory is allocated over the
DMA api. In particular, it allows using an address range or pinning to
a fixed address.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 115 ++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h |   9 +-
 drivers/gpu/drm/msm/adreno/a6xx_hfi.c |   6 +-
 3 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index c4e71abbdd53..c9fd0470a321 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -2,14 +2,16 @@
 /* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. */
 
 #include 
-#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "a6xx_gpu.h"
 #include "a6xx_gmu.xml.h"
+#include "msm_gem.h"
+#include "msm_mmu.h"
 
 static void a6xx_gmu_fault(struct a6xx_gmu *gmu)
 {
@@ -620,7 +622,7 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned 
int state)
gmu_write(gmu, REG_A6XX_GMU_CM3_BOOT_CONFIG, 0x02);
 
/* Write the iova of the HFI table */
-   gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_ADDR, gmu->hfi->iova);
+   gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_ADDR, gmu->hfi.iova);
gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_INFO, 1);
 
gmu_write(gmu, REG_A6XX_GMU_AHB_FENCE_RANGE_0,
@@ -919,34 +921,77 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
return 0;
 }
 
-static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo)
+static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu)
 {
-   if (IS_ERR_OR_NULL(bo))
-   return;
+   msm_gem_kernel_put(gmu->hfi.obj, gmu->aspace, false);
+   msm_gem_kernel_put(gmu->debug.obj, gmu->aspace, false);
+
+   gmu->aspace->mmu->funcs->detach(gmu->aspace->mmu);
+   msm_gem_address_space_put(gmu->aspace);
+}
+
+static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo,
+   size_t size, u64 iova)
+{
+   struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+   struct drm_device *dev = a6xx_gpu->base.base.dev;
+   uint32_t flags = MSM_BO_WC;
+   u64 range_start, range_end;
+   int ret;
+
+   size = PAGE_ALIGN(size);
+   if (!iova) {
+   /* no fixed address - use GMU's uncached range */
+   range_start = 0x6000;
+   range_end = 0x8000;
+   } else {
+   /* range for fixed address */
+   range_start = iova;
+   range_end = iova + size;
+   }
+
+   bo->obj = msm_gem_new(dev, size, flags);
+   if (IS_ERR(bo->obj))
+   return PTR_ERR(bo->obj);
 
-   dma_free_wc(gmu->dev, bo->size, bo->virt, bo->iova);
-   kfree(bo);
+   ret = msm_gem_get_and_pin_iova_range(bo->obj, gmu->aspace, >iova,
+   range_start >> PAGE_SHIFT, range_end >> PAGE_SHIFT);
+   if (ret) {
+   drm_gem_object_put(bo->obj);
+   return ret;
+   }
+
+   bo->virt = msm_gem_get_vaddr(bo->obj);
+   bo->size = size;
+
+   return 0;
 }
 
-static struct a6xx_gmu_bo *a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu,
-   size_t size)
+static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu)
 {
-   struct a6xx_gmu_bo *bo;
+   struct iommu_domain *domain;
+   int ret;
 
-   bo = kzalloc(sizeof(*bo), GFP_KERNEL);
-   if (!bo)
-   return ERR_PTR(-ENOMEM);
+   domain = iommu_domain_alloc(_bus_type);
+   if (!domain)
+   return -ENODEV;
 
-   bo->size = PAGE_ALIGN(size);
+   domain->geometry.aperture_start = 0x;
+   domain->geometry.aperture_end = 0x7fff;
 
-   bo->virt = dma_alloc_wc(gmu->dev, bo->size, >iova, GFP_KERNEL);
+   gmu->aspace = msm_gem_address_space_create(gmu->dev, domain, "gmu");
+   if (IS_ERR(gmu->aspace)) {
+   iommu_domain_free(domain);
+   return PTR_ERR(gmu->aspace);
+   }
 
-   if (!bo->virt) {
-   kfree(bo);
-   return ERR_PTR(-ENOMEM);
+   ret = gmu->aspace->mmu->funcs->attach(gmu->aspace->mmu);
+   if (ret) {
+   msm_gem_address_space_put(gmu->aspace);
+   return ret;
}
 
-   return bo;
+   return 0;
 }
 
 /* Return the 'arc-level' for the given frequency */
@@ -1204,7 +1249,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
iounmap(gmu->mmio);
gmu->mmio = NULL;
 
-   a6xx_gmu_memory_free(gmu, gmu->hfi);
+   a6xx_gmu_memory_free(gmu);
 
free_irq(gmu->gmu_irq, gmu);
free_irq(gmu->hfi_irq, gmu);
@@ -1226,15 +1271,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct 
device_node *node)
 
gmu->dev = >dev;
 
-   /* Pass force_dma false to require the DT to set the dma region */
-   ret = of_dma_configure(gmu->dev, node, false);
-   if (ret)
-  

[Freedreno] [PATCH v2 0/9] Add support for A640 and A650

2020-04-21 Thread Jonathan Marek
This series adds support for A640 and A650 GPUs.

Missing bus scaling, hwcg, and UBWC config, but GPU works without those.

Changes in V2:
Use msm_gem for allocations (first 3 patches are new)
Squashed pdc/rscc patches together
Removed unnecessary "WARN_ON"s in "HFI v2 for A640 and A650"

Jonathan Marek (9):
  drm/msm: add msm_gem_get_and_pin_iova_range
  drm/msm: add internal MSM_BO_MAP_PRIV flag
  drm/msm/a6xx: use msm_gem for GMU memory objects
  drm/msm/a6xx: add A640/A650 to gpulist
  drm/msm/a6xx: HFI v2 for A640 and A650
  drm/msm/a6xx: A640/A650 GMU firmware path
  drm/msm/a6xx: update pdc/rscc GMU registers for A640/A650
  drm/msm/a6xx: enable GMU log
  drm/msm/a6xx: update a6xx_hw_init for A640 and A650

 drivers/gpu/drm/msm/adreno/a6xx.xml.h  |  14 +
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c  | 409 -
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h  |  38 +-
 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h  |  48 ++-
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c  |  62 +++-
 drivers/gpu/drm/msm/adreno/a6xx_hfi.c  | 123 ++-
 drivers/gpu/drm/msm/adreno/a6xx_hfi.h  |  50 ++-
 drivers/gpu/drm/msm/adreno/adreno_device.c |  24 ++
 drivers/gpu/drm/msm/adreno/adreno_gpu.c|   2 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.h|  10 +
 drivers/gpu/drm/msm/msm_drv.h  |   6 +-
 drivers/gpu/drm/msm/msm_gem.c  |  31 +-
 drivers/gpu/drm/msm/msm_gem.h  |   1 +
 drivers/gpu/drm/msm/msm_gem_vma.c  |   6 +-
 14 files changed, 675 insertions(+), 149 deletions(-)

-- 
2.26.1

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 6/9] drm/msm/a6xx: A640/A650 GMU firmware path

2020-04-21 Thread Jonathan Marek
Newer GPUs have different GMU firmware path.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 135 +++---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  11 ++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h |   6 +
 3 files changed, 136 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index b22a69e2f4b0..4aef5fe985d6 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -571,6 +571,8 @@ static void a6xx_gmu_power_config(struct a6xx_gmu *gmu)
 {
/* Disable GMU WB/RB buffer */
gmu_write(gmu, REG_A6XX_GMU_SYS_BUS_CONFIG, 0x1);
+   gmu_write(gmu, REG_A6XX_GMU_ICACHE_CONFIG, 0x1);
+   gmu_write(gmu, REG_A6XX_GMU_DCACHE_CONFIG, 0x1);
 
gmu_write(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0x9c40400);
 
@@ -600,14 +602,91 @@ static void a6xx_gmu_power_config(struct a6xx_gmu *gmu)
A6XX_GMU_RPMH_CTRL_GFX_VOTE_ENABLE);
 }
 
+static int in_range(u32 addr, u32 start, u32 size)
+{
+   return addr >= start && addr < start + size;
+}
+
+static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu)
+{
+   struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+   struct adreno_gpu *adreno_gpu = _gpu->base;
+   const struct firmware *fw_image = adreno_gpu->fw[ADRENO_FW_GMU];
+   const struct block_header {
+   u32 addr;
+   u32 size;
+   u32 type;
+   u32 value;
+   u32 data[];
+   } *blk;
+   struct a6xx_gmu_bo *mem;
+   u32 reg;
+
+   u32 itcm_base = 0x;
+   u32 dtcm_base = 0x0004;
+
+   if (adreno_is_a650(adreno_gpu))
+   dtcm_base = 0x10004000;
+
+   if (gmu->legacy) {
+   /* Sanity check the size of the firmware that was loaded */
+   if (fw_image->size > 0x8000) {
+   DRM_DEV_ERROR(gmu->dev,
+   "GMU firmware is bigger than the available 
region\n");
+   return -EINVAL;
+   }
+
+   gmu_write_bulk(gmu, REG_A6XX_GMU_CM3_ITCM_START,
+  (u32*) fw_image->data, fw_image->size >> 2);
+   return 0;
+   }
+
+
+   for (blk = (const struct block_header *) fw_image->data;
+(const u8*) blk < fw_image->data + fw_image->size;
+blk = (const struct block_header *) >data[blk->size >> 2]) {
+   if (blk->size == 0)
+   continue;
+
+   reg = 0;
+   mem = NULL;
+
+   if (in_range(blk->addr, itcm_base, SZ_16K))
+   reg = REG_A6XX_GMU_CM3_ITCM_START + ((blk->addr - 
itcm_base) >> 2);
+   else if (in_range(blk->addr, dtcm_base, SZ_16K))
+   reg = REG_A6XX_GMU_CM3_DTCM_START + ((blk->addr - 
dtcm_base) >> 2);
+   else if (in_range(blk->addr, gmu->icache.iova, 
gmu->icache.size))
+   mem = >icache;
+   else if (in_range(blk->addr, gmu->dcache.iova, 
gmu->dcache.size))
+   mem = >dcache;
+   else if (in_range(blk->addr, gmu->dummy.iova, gmu->dummy.size))
+   mem = >dummy;
+   else {
+   DRM_DEV_ERROR(gmu->dev,
+   "failed to match fw block (addr=%.8x size=%d 
data[0]=%.8x)\n",
+   blk->addr, blk->size, blk->data[0]);
+   }
+
+   if (reg)
+   gmu_write_bulk(gmu, reg, blk->data, blk->size >> 2);
+
+   if (mem)
+   memcpy(mem->virt + blk->addr - mem->iova, blk->data, 
blk->size);
+   }
+
+   return 0;
+}
+
 static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
 {
static bool rpmh_init;
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
struct adreno_gpu *adreno_gpu = _gpu->base;
-   int i, ret;
+   int ret;
u32 chipid;
-   u32 *image;
+
+   if (adreno_is_a650(adreno_gpu))
+   gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF, 1);
 
if (state == GMU_WARM_BOOT) {
ret = a6xx_rpmh_start(gmu);
@@ -618,13 +697,6 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, 
unsigned int state)
"GMU firmware is not loaded\n"))
return -ENOENT;
 
-   /* Sanity check the size of the firmware that was loaded */
-   if (adreno_gpu->fw[ADRENO_FW_GMU]->size > 0x8000) {
-   DRM_DEV_ERROR(gmu->dev,
-   "GMU firmware is bigger than the available 
region\n");
-   return -EINVAL;
-   }
-
/* Turn on register retention */
gmu_write(gmu, REG_A6XX_GMU_GENERAL_7, 1);
 
@@ -638,11 

[Freedreno] [PATCH v2 2/9] drm/msm: add internal MSM_BO_MAP_PRIV flag

2020-04-21 Thread Jonathan Marek
This flag sets IOMMU_PRIV, which is required for some a6xx GMU objects.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/msm_gem.c | 3 +++
 drivers/gpu/drm/msm/msm_gem.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index d8f56a34c117..6277fde13df9 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -428,6 +428,9 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj,
if (!(msm_obj->flags & MSM_BO_GPU_READONLY))
prot |= IOMMU_WRITE;
 
+   if (msm_obj->flags & MSM_BO_MAP_PRIV)
+   prot |= IOMMU_PRIV;
+
WARN_ON(!mutex_is_locked(_obj->lock));
 
if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED))
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 30584eaf8cc8..972490b14ba5 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -13,6 +13,7 @@
 
 /* Additional internal-use only BO flags: */
 #define MSM_BO_STOLEN0x1000/* try to use stolen/splash memory 
*/
+#define MSM_BO_MAP_PRIV  0x2000/* use IOMMU_PRIV when mapping */
 
 struct msm_gem_address_space {
const char *name;
-- 
2.26.1

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v11 1/2] drm/panel: add support for rm69299 visionox panel driver

2020-04-21 Thread Matthias Kaehlcke
Hi,

On Tue, Apr 21, 2020 at 10:25:07AM +0530, Harigovindan P wrote:
> Add support for Visionox panel driver.
> 
> Signed-off-by: Harigovindan P 

Please keep tags from previous versions (like my Reviewed-by from v7)
when making minimal changes.

Also there is no need to keep sending the bindings patch, it already
landed in drm-misc.

> diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c 
> b/drivers/gpu/drm/panel/panel-visionox-rm69299.c
> new file mode 100644
> index ..3ef4cc80044a
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c

...

> +MODULE_DESCRIPTION("Visionox RM69299 DSI Panel Driver");
> -- 
> 2.25.1

The last two lines break the patch:

git am 
/tmp/v11-1-2-drm-panel-add-support-for-rm69299-visionox-panel-driver.patch
Applying: drm/panel: add support for rm69299 visionox panel driver
error: corrupt patch at line 379
Patch failed at 0001 drm/panel: add support for rm69299 visionox panel driver

Besides the broken format:

Reviewed-by: Matthias Kaehlcke 
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 4/9] drm/msm/a6xx: HFI v2 for A640 and A650

2020-04-21 Thread Jonathan Marek

On 4/21/20 12:30 PM, Jordan Crouse wrote:

On Mon, Apr 20, 2020 at 10:03:08AM -0400, Jonathan Marek wrote:

Signed-off-by: Jonathan Marek 
---
  drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  68 ---
  drivers/gpu/drm/msm/adreno/a6xx_gmu.h |   7 ++
  drivers/gpu/drm/msm/adreno/a6xx_gpu.c |   6 +-
  drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 117 --
  drivers/gpu/drm/msm/adreno/a6xx_hfi.h |  50 ++-
  5 files changed, 224 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index c6ecb3189ec5..dc2d69837110 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -126,8 +126,6 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int 
index)
if (ret)
dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
  
-	gmu->freq = gmu->gpu_freqs[index];

-
/*
 * Eventually we will want to scale the path vote with the frequency but
 * for now leave it at max so that the performance is nominal.
@@ -151,7 +149,12 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long 
freq)
  
  	gmu->current_perf_index = perf_index;
  
-	__a6xx_gmu_set_freq(gmu, perf_index);

+   if (gmu->legacy)
+   __a6xx_gmu_set_freq(gmu, perf_index);
+   else
+   a6xx_hfi_set_freq(gmu, perf_index);


Welcome to the first great GMU schism. There are going to be a lot of these if()
statements and my guess is that it won't get any cleaner in the future.

The best option in my opinion would be to make two separate GMU implementations
and select the probe either from the gpu list or the compatible string and use
function pointers for the functions that are called from a6xx_gpu.c and
a6xx_gpu_state.c.

We _could_ make the gmu->legacy thing work but if someday there is a another
schism we would be sad that we didn't do the ground work now.

We could also do the same for HFI, but I think there is a bit less of a delta
there and there isn't a harm in having a _v1 function or two laying around.



I don't think it makes sense to have two separate GMU implementations at 
this point, most of the code is still sharable. There's "only" 10 of 
these gmu->legacy if()s in the final version, and they are very small if()s.



+
+   gmu->freq = gmu->gpu_freqs[perf_index];
  }
  
  unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)

@@ -231,19 +234,26 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
a6xx_gmu_oob_state state)
  
  	switch (state) {

case GMU_OOB_GPU_SET:
-   request = GMU_OOB_GPU_SET_REQUEST;
-   ack = GMU_OOB_GPU_SET_ACK;
+   if (gmu->legacy) {
+   request = GMU_OOB_GPU_SET_REQUEST;
+   ack = GMU_OOB_GPU_SET_ACK;
+   } else {
+   request = GMU_OOB_GPU_SET_REQUEST_NEW;
+   ack = GMU_OOB_GPU_SET_ACK_NEW;
+   }
name = "GPU_SET";
break;
case GMU_OOB_BOOT_SLUMBER:
request = GMU_OOB_BOOT_SLUMBER_REQUEST;
ack = GMU_OOB_BOOT_SLUMBER_ACK;
name = "BOOT_SLUMBER";
+   WARN_ON(!gmu->legacy);


This is unlikely to be the case - these should only be called from within the
GMU code and we should be able to control it.



These are called from a6xx_gpu.c too, not just from within a6xx_gmu.c. 
IMO the warnings might be useful to catch errors in the future, but they 
not absolutely necessary either.



break;
case GMU_OOB_DCVS_SET:
request = GMU_OOB_DCVS_REQUEST;
ack = GMU_OOB_DCVS_ACK;
name = "GPU_DCVS";
+   WARN_ON(!gmu->legacy);


Same.


break;
default:
return -EINVAL;
@@ -271,6 +281,13 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
a6xx_gmu_oob_state state)
  /* Clear a pending OOB state in the GMU */
  void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
  {
+   if (!gmu->legacy) {
+   WARN_ON(state != GMU_OOB_GPU_SET);
+   gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
+   1 << GMU_OOB_GPU_SET_CLEAR_NEW);
+   return;
+   }


A good example of the usefulness of per-implementation functions.



I wouldn't say its a great example, the function is effectively the 
same, just with a different shift value. It was just simple enough that 
it felt better to do it this way.



+
switch (state) {
case GMU_OOB_GPU_SET:
gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
@@ -293,6 +310,9 @@ static int a6xx_sptprac_enable(struct a6xx_gmu *gmu)
int ret;
u32 val;
  
+	if (!gmu->legacy)

+   return 0;
+
gmu_write(gmu, REG_A6XX_GMU_GX_SPTPRAC_POWER_CONTROL, 0x778000);
  
  	ret = gmu_poll_timeout(gmu, 

Re: [Freedreno] [PATCH 9/9] drm/msm/a6xx: update a6xx_hw_init for A640 and A650

2020-04-21 Thread Jordan Crouse
On Mon, Apr 20, 2020 at 10:03:13AM -0400, Jonathan Marek wrote:
> Adreno 640 and 650 GPUs need some registers set differently.

> Signed-off-by: Jonathan Marek 
> ---
>  drivers/gpu/drm/msm/adreno/a6xx.xml.h | 14 +++
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 56 ++-
>  2 files changed, 61 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h 
> b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
> index ed78fee2a262..47840b73cdda 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h
> +++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
> @@ -1047,6 +1047,8 @@ enum a6xx_tex_type {
>  
>  #define REG_A6XX_CP_MISC_CNTL
> 0x0840
>  
> +#define REG_A6XX_CP_APRIV_CNTL   
> 0x0844
> +
>  #define REG_A6XX_CP_ROQ_THRESHOLDS_1 0x08c1
>  
>  #define REG_A6XX_CP_ROQ_THRESHOLDS_2 0x08c2
> @@ -1764,6 +1766,8 @@ static inline uint32_t 
> A6XX_CP_PROTECT_REG_MASK_LEN(uint32_t val)
>  
>  #define REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL   0x0010
>  
> +#define REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL   0x0011
> +
>  #define REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL
> 0x001f
>  
>  #define REG_A6XX_RBBM_INT_CLEAR_CMD  0x0037
> @@ -2418,6 +2422,16 @@ static inline uint32_t 
> A6XX_UCHE_CLIENT_PF_PERFSEL(uint32_t val)
>  
>  #define REG_A6XX_TPL1_NC_MODE_CNTL   0xb604
>  
> +#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0
> 0xb608
> +
> +#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1
> 0xb609
> +
> +#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_2
> 0xb60a
> +
> +#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_3
> 0xb60b
> +
> +#define REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_4
> 0xb60c
> +
>  #define REG_A6XX_TPL1_PERFCTR_TP_SEL_0   
> 0xb610
>  
>  #define REG_A6XX_TPL1_PERFCTR_TP_SEL_1   
> 0xb611
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index a860d4970e10..e1eb34fa3a99 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -414,7 +414,17 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
>   a6xx_set_hwcg(gpu, true);
>  
>   /* VBIF/GBIF start*/
> - gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);

Oops, this should have been changed for 618 too.  Only 630 had the VBIF
so you can invert this if statement.

> + if (adreno_is_a640(adreno_gpu) || adreno_is_a650(adreno_gpu)) {
> + gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE0, 0x00071620);
> + gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE1, 0x00071620);
> + gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE2, 0x00071620);
> + gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
> + gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
> + gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x3);
> + } else {
> + gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
> + }
> +
>   if (adreno_is_a630(adreno_gpu))
>   gpu_write(gpu, REG_A6XX_VBIF_GATE_OFF_WRREQ_EN, 0x0009);
>  
> @@ -429,25 +439,35 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
>   gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_LO, 0xf000);
>   gpu_write(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE_HI, 0x0001);
>  
> - /* Set the GMEM VA range [0x10:0x10 + gpu->gmem - 1] */
> - gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN_LO,
> - REG_A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x0010);
> + if (!adreno_is_a650(adreno_gpu)) {
> + /* Set the GMEM VA range [0x10:0x10 + gpu->gmem - 1] */
> + gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN_LO,
> + REG_A6XX_UCHE_GMEM_RANGE_MIN_HI, 0x0010);
>  
> - gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX_LO,
> - REG_A6XX_UCHE_GMEM_RANGE_MAX_HI,
> - 0x0010 + adreno_gpu->gmem - 1);
> + gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX_LO,
> + REG_A6XX_UCHE_GMEM_RANGE_MAX_HI,
> + 0x0010 + adreno_gpu->gmem - 1);
> + }
>  
>   gpu_write(gpu, REG_A6XX_UCHE_FILTER_CNTL, 0x804);
>   gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, 0x4);
>  
> - gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x01c0);
> + if (adreno_is_a640(adreno_gpu) || adreno_is_a650(adreno_gpu))
> + gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
> + else
> + gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x01c0);
>   gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
>  
>   /* Setting the mem pool size */

Re: [Freedreno] [PATCH 8/9] drm/msm/a6xx: enable GMU log

2020-04-21 Thread Jordan Crouse
On Mon, Apr 20, 2020 at 10:03:12AM -0400, Jonathan Marek wrote:
> This is required for a650 to work.
> 
> Signed-off-by: Jonathan Marek 
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 16 
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  1 +
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h |  4 
>  3 files changed, 21 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> index b583bf6e293b..1cdb7c832b87 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> @@ -198,6 +198,12 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu)
>   u32 val;
>  
>   gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
> +
> + /* Set the log wptr index
> +  * note: downstream saves the value in poweroff and restores it here
> +  */
> + gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP, 0);
> +
>   gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);
>  
>   ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val,
> @@ -739,6 +745,9 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, 
> unsigned int state)
>  
>   gmu_write(gmu, REG_A6XX_GMU_HFI_SFR_ADDR, chipid);
>  
> + gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG,
> +   gmu->log->iova | (gmu->log->size / SZ_4K - 1));
> +
>   /* Set up the lowest idle level on the GMU */
>   a6xx_gmu_power_config(gmu);
>  
> @@ -1416,6 +1425,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
>   a6xx_gmu_memory_free(gmu, gmu->dcache);
>   a6xx_gmu_memory_free(gmu, gmu->dummy);
>   a6xx_gmu_memory_free(gmu, gmu->debug);
> + a6xx_gmu_memory_free(gmu, gmu->log);
>   a6xx_gmu_memory_free(gmu, gmu->hfi);
>  
>   iommu_detach_device(gmu->domain, gmu->dev);
> @@ -1495,6 +1505,11 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct 
> device_node *node)
>   if (IS_ERR(gmu->hfi))
>   goto err_memory;
>  
> + /* Allocate memory for the GMU log region */
> + gmu->log = a6xx_gmu_memory_alloc(gmu, SZ_4K, 0);
> + if (IS_ERR(gmu->log))
> + goto err_memory;
> +
>   /* Map the GMU registers */
>   gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");
>   if (IS_ERR(gmu->mmio))
> @@ -1542,6 +1557,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct 
> device_node *node)
>   a6xx_gmu_memory_free(gmu, gmu->dcache);
>   a6xx_gmu_memory_free(gmu, gmu->dummy);
>   a6xx_gmu_memory_free(gmu, gmu->debug);
> + a6xx_gmu_memory_free(gmu, gmu->log);
>   a6xx_gmu_memory_free(gmu, gmu->hfi);

This is starting to feel like we could use some devres style garbage collection.

>  
>   if (gmu->domain) {
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h 
> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
> index abd425ca6682..589b9b0c348e 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
> @@ -59,6 +59,7 @@ struct a6xx_gmu {
>  
>   struct a6xx_gmu_bo *hfi;
>   struct a6xx_gmu_bo *debug;
> + struct a6xx_gmu_bo *log;
>   struct a6xx_gmu_bo *icache;
>   struct a6xx_gmu_bo *dcache;
>   struct a6xx_gmu_bo *dummy;
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h 
> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
> index b4357ea550ec..176ae94d9fe6 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
> @@ -205,6 +205,10 @@ static inline uint32_t 
> A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val)
>  
>  #define REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF  0x50f0
>  
> +#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG   
> 0x5100
> +
> +#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP  
> 0x5101
> +
>  #define REG_A6XX_GMU_BOOT_KMD_LM_HANDSHAKE   0x51f0
>  
>  #define REG_A6XX_GMU_LLM_GLM_SLEEP_CTRL  
> 0x5157
> -- 
> 2.26.1
> 
> ___
> Freedreno mailing list
> Freedreno@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 7/9] drm/msm/a6xx: gmu_pdc register values for A640 and A650

2020-04-21 Thread Jordan Crouse
On Mon, Apr 20, 2020 at 10:03:11AM -0400, Jonathan Marek wrote:
> Signed-off-by: Jonathan Marek 

I was wondering where this was.  I don't think there is any reason to not squash
this into the previous patch since the GMU won't be operational without it.

> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 22 +++---
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> index 3e51939eb867..b583bf6e293b 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> @@ -469,10 +469,18 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
>   struct platform_device *pdev = to_platform_device(gmu->dev);
>   void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc");
>   void __iomem *seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
> + uint32_t pdc_address_offset;
>  
>   if (!pdcptr || !seqptr)
>   goto err;
>  
> + if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu))
> + pdc_address_offset = 0x30090;
> + else if (adreno_is_a650(adreno_gpu))
> + pdc_address_offset = 0x300a0;
> + else
> + pdc_address_offset = 0x30080;
> +

>   /* Disable SDE clock gating */
>   gmu_write_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
>  
> @@ -523,10 +531,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 4, 0x0);
>  
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 8, 0x10108);
> - if (adreno_is_a618(adreno_gpu))
> - pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 0x30090);
> - else
> - pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 0x30080);
> + pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, 
> pdc_address_offset);
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 8, 0x0);
>  
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD_ENABLE_BANK, 7);
> @@ -538,17 +543,12 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
>  
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108);
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x3);
> - if (adreno_is_a618(adreno_gpu))
> + if (adreno_is_a618(adreno_gpu) || adreno_is_a650(adreno_gpu))
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x2);
>   else
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3);
> -
> -
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 8, 0x10108);
> - if (adreno_is_a618(adreno_gpu))
> - pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, 0x30090);
> - else
> - pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, 0x30080);
> + pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, 
> pdc_address_offset);
>   pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 8, 0x3);
>  
>   /* Setup GPU PDC */
> -- 
> 2.26.1
> 

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 4/9] drm/msm/a6xx: HFI v2 for A640 and A650

2020-04-21 Thread Jordan Crouse
On Mon, Apr 20, 2020 at 10:03:08AM -0400, Jonathan Marek wrote:
> Signed-off-by: Jonathan Marek 
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  68 ---
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.h |   7 ++
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c |   6 +-
>  drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 117 --
>  drivers/gpu/drm/msm/adreno/a6xx_hfi.h |  50 ++-
>  5 files changed, 224 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> index c6ecb3189ec5..dc2d69837110 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> @@ -126,8 +126,6 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int 
> index)
>   if (ret)
>   dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
>  
> - gmu->freq = gmu->gpu_freqs[index];
> -
>   /*
>* Eventually we will want to scale the path vote with the frequency but
>* for now leave it at max so that the performance is nominal.
> @@ -151,7 +149,12 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned 
> long freq)
>  
>   gmu->current_perf_index = perf_index;
>  
> - __a6xx_gmu_set_freq(gmu, perf_index);
> + if (gmu->legacy)
> + __a6xx_gmu_set_freq(gmu, perf_index);
> + else
> + a6xx_hfi_set_freq(gmu, perf_index);

Welcome to the first great GMU schism. There are going to be a lot of these if()
statements and my guess is that it won't get any cleaner in the future.

The best option in my opinion would be to make two separate GMU implementations
and select the probe either from the gpu list or the compatible string and use
function pointers for the functions that are called from a6xx_gpu.c and
a6xx_gpu_state.c.

We _could_ make the gmu->legacy thing work but if someday there is a another
schism we would be sad that we didn't do the ground work now.

We could also do the same for HFI, but I think there is a bit less of a delta
there and there isn't a harm in having a _v1 function or two laying around.

> +
> + gmu->freq = gmu->gpu_freqs[perf_index];
>  }
>  
>  unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)
> @@ -231,19 +234,26 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
> a6xx_gmu_oob_state state)
>  
>   switch (state) {
>   case GMU_OOB_GPU_SET:
> - request = GMU_OOB_GPU_SET_REQUEST;
> - ack = GMU_OOB_GPU_SET_ACK;
> + if (gmu->legacy) {
> + request = GMU_OOB_GPU_SET_REQUEST;
> + ack = GMU_OOB_GPU_SET_ACK;
> + } else {
> + request = GMU_OOB_GPU_SET_REQUEST_NEW;
> + ack = GMU_OOB_GPU_SET_ACK_NEW;
> + }
>   name = "GPU_SET";
>   break;
>   case GMU_OOB_BOOT_SLUMBER:
>   request = GMU_OOB_BOOT_SLUMBER_REQUEST;
>   ack = GMU_OOB_BOOT_SLUMBER_ACK;
>   name = "BOOT_SLUMBER";
> + WARN_ON(!gmu->legacy);

This is unlikely to be the case - these should only be called from within the
GMU code and we should be able to control it.

>   break;
>   case GMU_OOB_DCVS_SET:
>   request = GMU_OOB_DCVS_REQUEST;
>   ack = GMU_OOB_DCVS_ACK;
>   name = "GPU_DCVS";
> + WARN_ON(!gmu->legacy);

Same.

>   break;
>   default:
>   return -EINVAL;
> @@ -271,6 +281,13 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum 
> a6xx_gmu_oob_state state)
>  /* Clear a pending OOB state in the GMU */
>  void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
>  {
> + if (!gmu->legacy) {
> + WARN_ON(state != GMU_OOB_GPU_SET);
> + gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
> + 1 << GMU_OOB_GPU_SET_CLEAR_NEW);
> + return;
> + }

A good example of the usefulness of per-implementation functions.

> +
>   switch (state) {
>   case GMU_OOB_GPU_SET:
>   gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
> @@ -293,6 +310,9 @@ static int a6xx_sptprac_enable(struct a6xx_gmu *gmu)
>   int ret;
>   u32 val;
>  
> + if (!gmu->legacy)
> + return 0;
> +
>   gmu_write(gmu, REG_A6XX_GMU_GX_SPTPRAC_POWER_CONTROL, 0x778000);
>  
>   ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, val,
> @@ -312,6 +332,9 @@ static void a6xx_sptprac_disable(struct a6xx_gmu *gmu)
>   u32 val;
>   int ret;
>  
> + if (!gmu->legacy)
> + return;
> +
>   /* Make sure retention is on */
>   gmu_rmw(gmu, REG_A6XX_GPU_CC_GX_GDSCR, 0, (1 << 11));
>  
> @@ -355,6 +378,11 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu)
>   if (gmu->idle_level < GMU_IDLE_STATE_SPTP)
>   a6xx_sptprac_disable(gmu);
>  
> + if (!gmu->legacy) {
> + ret = 

Re: [Freedreno] [PATCH 2/9] Revert "drm/msm/a6xx: Use the DMA API for GMU memory objects"

2020-04-21 Thread Christoph Hellwig
Using VM_IOREMAP outside of ioremap implementations is completely
bogus.  Don't go there, especialy with such a horribly bad commit log.
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH] of_device: removed #include that caused a recursion in included headers

2020-04-21 Thread Hadar Gat


> -Original Message-
> From: Rob Herring 
> Sent: Monday, 20 April 2020 23:37
> 
> On Mon, Apr 13, 2020 at 04:35:53PM +0300, Hadar Gat wrote:
> > Both of_platform.h and of_device.h were included each other.
> > In of_device.h, removed unneeded #include to of_platform.h and added
> > include to of_platform.h in the files that needs it.
> 
> Guess we forgot about that temporary comment!
> 
> Both of these headers have a lot of things we don't want 'normal'
> drivers calling. The most common thing needed from of_device.h is
> of_match_device/of_device_get_match_data. A good number are only for
> ibmebus. Maybe the header should be split or the former just moved to of.h.
> 
> For of_platform.h, it seems we have a bunch of unneeded includes:
> 
> $ git grep 'of_platform\.h' drivers/ | wc
> 5601120   36049
> $ git grep -E 'of_(platform_(pop|def)|find_device)' drivers/ | wc
> 2481215   20630
> 
> Would nice to drop those (or switch to of_device.h?) too.
> 
> Be sure to build on Sparc. It's the oddball.

Hi Rob and thanks for your inputs.
Unfortunately I cannot continue to work on this patch at the moment since it is 
not as small as I expected and I have limited resources for that.
So anyone can take it and continue from here.
Thanks,
Hadar

> > Signed-off-by: Hadar Gat 
> > ---
> >  drivers/base/platform.c   | 1 +
> >  drivers/bus/vexpress-config.c | 1 +
> >  drivers/dma/at_hdmac.c| 1 +
> >  drivers/dma/stm32-dmamux.c| 1 +
> >  drivers/dma/ti/dma-crossbar.c | 1 +
> >  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 1 +
> >  drivers/gpu/drm/msm/hdmi/hdmi.c   | 1 +
> >  drivers/gpu/drm/msm/msm_drv.c | 1 +
> >  drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 1 +
> >  drivers/gpu/drm/sun4i/sun4i_tcon.c| 1 +
> >  drivers/iio/adc/stm32-adc-core.c  | 1 +
> >  drivers/iio/adc/stm32-dfsdm-adc.c | 1 +
> >  drivers/iio/adc/stm32-dfsdm-core.c| 1 +
> >  drivers/iommu/tegra-smmu.c| 1 +
> >  drivers/memory/atmel-ebi.c| 1 +
> >  drivers/mfd/palmas.c  | 1 +
> >  drivers/mfd/ssbi.c| 1 +
> >  drivers/mtd/nand/raw/omap2.c  | 1 +
> >  drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 1 +
> >  drivers/net/ethernet/ti/cpsw.c| 1 +
> >  drivers/phy/tegra/xusb.c  | 1 +
> >  drivers/pinctrl/nomadik/pinctrl-nomadik.c | 1 +
> >  drivers/soc/samsung/exynos-pmu.c  | 1 +
> >  drivers/soc/sunxi/sunxi_sram.c| 1 +
> >  include/linux/of_device.h | 2 --
> >  lib/genalloc.c| 1 +
> >  26 files changed, 25 insertions(+), 2 deletions(-)
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno