drm/msm/adreno: support for adreno 430.
authorCraig Stout <cstout@chromium.org>
Fri, 19 Feb 2016 00:50:00 +0000 (16:50 -0800)
committerRob Clark <robdclark@gmail.com>
Thu, 3 Mar 2016 16:55:27 +0000 (11:55 -0500)
Signed-off-by: Craig Stout <cstout@chromium.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/adreno/a4xx_gpu.c
drivers/gpu/drm/msm/adreno/adreno_device.c
drivers/gpu/drm/msm/adreno/adreno_gpu.c
drivers/gpu/drm/msm/adreno/adreno_gpu.h

index a53f1be05f75fbcd9c99e9980f16ef4987595410..84066cbf0e10243899bc025977c09156c37a95ef 100644 (file)
@@ -102,11 +102,17 @@ static void a4xx_enable_hwcg(struct msm_gpu *gpu)
        gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00000222);
        gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_HLSQ , 0x00000000);
        gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000);
-       gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ, 0x00020000);
-       gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL, 0xAAAAAAAA);
+       gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ, 0x00220000);
+       /* Early A430's have a timing issue with SP/TP power collapse;
+          disabling HW clock gating prevents it. */
+       if (adreno_is_a430(adreno_gpu) && adreno_gpu->rev.patchid < 2)
+               gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL, 0);
+       else
+               gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL, 0xAAAAAAAA);
        gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2, 0);
 }
 
+
 static void a4xx_me_init(struct msm_gpu *gpu)
 {
        struct msm_ringbuffer *ring = gpu->rb;
@@ -141,7 +147,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
        uint32_t *ptr, len;
        int i, ret;
 
-       if (adreno_is_a4xx(adreno_gpu)) {
+       if (adreno_is_a420(adreno_gpu)) {
                gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT, 0x0001001F);
                gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
                gpu_write(gpu, REG_A4XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000001);
@@ -150,6 +156,13 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
                gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF0, 0x18181818);
                gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF1, 0x00000018);
                gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
+       } else if (adreno_is_a430(adreno_gpu)) {
+               gpu_write(gpu, REG_A4XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000001);
+               gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF0, 0x18181818);
+               gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF1, 0x00000018);
+               gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF0, 0x18181818);
+               gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF1, 0x00000018);
+               gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
        } else {
                BUG();
        }
@@ -161,6 +174,10 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
        gpu_write(gpu, REG_A4XX_RBBM_SP_HYST_CNT, 0x10);
        gpu_write(gpu, REG_A4XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10);
 
+       if (adreno_is_a430(adreno_gpu)) {
+               gpu_write(gpu, REG_A4XX_RBBM_WAIT_IDLE_CLOCKS_CTL2, 0x30);
+       }
+
         /* Enable the RBBM error reporting bits */
        gpu_write(gpu, REG_A4XX_RBBM_AHB_CTL0, 0x00000001);
 
@@ -183,6 +200,9 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
        /* Turn on performance counters: */
        gpu_write(gpu, REG_A4XX_RBBM_PERFCTR_CTL, 0x01);
 
+       if (adreno_is_a430(adreno_gpu))
+               gpu_write(gpu, REG_A4XX_UCHE_CACHE_WAYS_VFD, 0x07);
+
        /* Disable L2 bypass to avoid UCHE out of bounds errors */
        gpu_write(gpu, REG_A4XX_UCHE_TRAP_BASE_LO, 0xffff0000);
        gpu_write(gpu, REG_A4XX_UCHE_TRAP_BASE_HI, 0xffff0000);
@@ -190,6 +210,15 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
        gpu_write(gpu, REG_A4XX_CP_DEBUG, (1 << 25) |
                        (adreno_is_a420(adreno_gpu) ? (1 << 29) : 0));
 
+       /* On A430 enable SP regfile sleep for power savings */
+       /* TODO downstream does this for !420, so maybe applies for 405 too? */
+       if (!adreno_is_a420(adreno_gpu)) {
+               gpu_write(gpu, REG_A4XX_RBBM_SP_REGFILE_SLEEP_CNTL_0,
+                       0x00000441);
+               gpu_write(gpu, REG_A4XX_RBBM_SP_REGFILE_SLEEP_CNTL_1,
+                       0x00000441);
+       }
+
        a4xx_enable_hwcg(gpu);
 
        /*
@@ -204,9 +233,11 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
                gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ, val);
        }
 
-       ret = adreno_hw_init(gpu);
-       if (ret)
-               return ret;
+       if (!adreno_is_a430(adreno_gpu)) {
+               ret = adreno_hw_init(gpu);
+               if (ret)
+                       return ret;
+       }
 
        /* setup access protection: */
        gpu_write(gpu, REG_A4XX_CP_PROTECT_CTRL, 0x00000007);
index 950d27d26b30e07aef548fa6f1ee416baa4ce4b9..5127b75dbf40cbbac1955e5e4d8b3e4201133dd8 100644 (file)
@@ -69,6 +69,14 @@ static const struct adreno_info gpulist[] = {
                .pfpfw = "a420_pfp.fw",
                .gmem  = (SZ_1M + SZ_512K),
                .init  = a4xx_gpu_init,
+       }, {
+               .rev   = ADRENO_REV(4, 3, 0, ANY_ID),
+               .revn  = 430,
+               .name  = "A430",
+               .pm4fw = "a420_pm4.fw",
+               .pfpfw = "a420_pfp.fw",
+               .gmem  = (SZ_1M + SZ_512K),
+               .init  = a4xx_gpu_init,
        },
 };
 
index 0e1d0c57cd3d10e7a745e67df24adb0a09a3f2d5..e696c54df2db294ec68fe1864f8eab65aa0c8839 100644 (file)
@@ -140,7 +140,8 @@ int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
                        if (priv->lastctx == ctx)
                                break;
                case MSM_SUBMIT_CMD_BUF:
-                       OUT_PKT3(ring, CP_INDIRECT_BUFFER_PFD, 2);
+                       OUT_PKT3(ring, adreno_is_a430(adreno_gpu) ?
+                               CP_INDIRECT_BUFFER_PFE : CP_INDIRECT_BUFFER_PFD, 2);
                        OUT_RING(ring, submit->cmd[i].iova);
                        OUT_RING(ring, submit->cmd[i].size);
                        ibs++;
index 0a312e9d3afd3264380367184650084f402f99e9..c26aea13df6d660295c14ace5f69a071c28304d5 100644 (file)
@@ -228,6 +228,11 @@ static inline int adreno_is_a420(struct adreno_gpu *gpu)
        return gpu->revn == 420;
 }
 
+static inline int adreno_is_a430(struct adreno_gpu *gpu)
+{
+       return gpu->revn == 430;
+}
+
 int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value);
 int adreno_hw_init(struct msm_gpu *gpu);
 uint32_t adreno_last_fence(struct msm_gpu *gpu);