drm/msm: Refactor UBWC config setting
authorConnor Abbott <cwabbott0@gmail.com>
Thu, 7 Dec 2023 21:30:47 +0000 (21:30 +0000)
committerRob Clark <robdclark@chromium.org>
Sun, 10 Dec 2023 18:19:18 +0000 (10:19 -0800)
Split up calculating configuration parameters and programming them, so
that we can expose them to userspace.

Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
Patchwork: https://patchwork.freedesktop.org/patch/571180/
Signed-off-by: Rob Clark <robdclark@chromium.org>
drivers/gpu/drm/msm/adreno/a5xx_gpu.c
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
drivers/gpu/drm/msm/adreno/adreno_gpu.h

index e5916c106796796045eaa1342036a27c4be4e0b1..c003f970189b06972d5ceef173d85816479a911b 100644 (file)
@@ -684,7 +684,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 {
        struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
        struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
-       u32 regbit;
+       u32 hbb;
        int ret;
 
        gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
@@ -820,18 +820,15 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 
        gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
 
-       /* Set the highest bank bit */
-       if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
-               regbit = 2;
-       else
-               regbit = 1;
+       BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
+       hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
 
-       gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, regbit << 7);
-       gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, regbit << 1);
+       gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, hbb << 7);
+       gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, hbb << 1);
 
        if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) ||
            adreno_is_a540(adreno_gpu))
-               gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, regbit);
+               gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, hbb);
 
        /* Disable All flat shading optimization (ALLFLATOPTDIS) */
        gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, (1 << 10));
@@ -1785,5 +1782,11 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
        /* Set up the preemption specific bits and pieces for each ringbuffer */
        a5xx_preempt_init(gpu);
 
+       /* Set the highest bank bit */
+       if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
+               adreno_gpu->ubwc_config.highest_bank_bit = 15;
+       else
+               adreno_gpu->ubwc_config.highest_bank_bit = 14;
+
        return gpu;
 }
index 723f9b97734da063bd4628e2b7cacb9e6a69382f..c0bc924cd3025dc21939e2e75548f273a90fd620 100644 (file)
@@ -1270,81 +1270,92 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
        gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]);
 }
 
-static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
+static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
 {
-       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
        /* Unknown, introduced with A650 family, related to UBWC mode/ver 4 */
-       u32 rgb565_predicator = 0;
+       gpu->ubwc_config.rgb565_predicator = 0;
        /* Unknown, introduced with A650 family */
-       u32 uavflagprd_inv = 0;
+       gpu->ubwc_config.uavflagprd_inv = 0;
        /* Whether the minimum access length is 64 bits */
-       u32 min_acc_len = 0;
+       gpu->ubwc_config.min_acc_len = 0;
        /* Entirely magic, per-GPU-gen value */
-       u32 ubwc_mode = 0;
+       gpu->ubwc_config.ubwc_mode = 0;
        /*
         * The Highest Bank Bit value represents the bit of the highest DDR bank.
-        * We then subtract 13 from it (13 is the minimum value allowed by hw) and
-        * write the lowest two bits of the remaining value as hbb_lo and the
-        * one above it as hbb_hi to the hardware. This should ideally use DRAM
-        * type detection.
+        * This should ideally use DRAM type detection.
         */
-       u32 hbb_hi = 0;
-       u32 hbb_lo = 2;
-       /* Unknown, introduced with A640/680 */
-       u32 amsbc = 0;
+       gpu->ubwc_config.highest_bank_bit = 15;
 
-       if (adreno_is_a610(adreno_gpu)) {
-               /* HBB = 14 */
-               hbb_lo = 1;
-               min_acc_len = 1;
-               ubwc_mode = 1;
+       if (adreno_is_a610(gpu)) {
+               gpu->ubwc_config.highest_bank_bit = 14;
+               gpu->ubwc_config.min_acc_len = 1;
+               gpu->ubwc_config.ubwc_mode = 1;
        }
 
        /* a618 is using the hw default values */
-       if (adreno_is_a618(adreno_gpu))
+       if (adreno_is_a618(gpu))
                return;
 
-       if (adreno_is_a619_holi(adreno_gpu))
-               hbb_lo = 0;
+       if (adreno_is_a619_holi(gpu))
+               gpu->ubwc_config.highest_bank_bit = 13;
 
-       if (adreno_is_a640_family(adreno_gpu))
-               amsbc = 1;
+       if (adreno_is_a640_family(gpu))
+               gpu->ubwc_config.amsbc = 1;
 
-       if (adreno_is_a650(adreno_gpu) ||
-           adreno_is_a660(adreno_gpu) ||
-           adreno_is_a690(adreno_gpu) ||
-           adreno_is_a730(adreno_gpu) ||
-           adreno_is_a740_family(adreno_gpu)) {
+       if (adreno_is_a650(gpu) ||
+           adreno_is_a660(gpu) ||
+           adreno_is_a690(gpu) ||
+           adreno_is_a730(gpu) ||
+           adreno_is_a740_family(gpu)) {
                /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */
-               hbb_lo = 3;
-               amsbc = 1;
-               rgb565_predicator = 1;
-               uavflagprd_inv = 2;
+               gpu->ubwc_config.highest_bank_bit = 16;
+               gpu->ubwc_config.amsbc = 1;
+               gpu->ubwc_config.rgb565_predicator = 1;
+               gpu->ubwc_config.uavflagprd_inv = 2;
        }
 
-       if (adreno_is_7c3(adreno_gpu)) {
-               hbb_lo = 1;
-               amsbc = 1;
-               rgb565_predicator = 1;
-               uavflagprd_inv = 2;
+       if (adreno_is_7c3(gpu)) {
+               gpu->ubwc_config.highest_bank_bit = 14;
+               gpu->ubwc_config.amsbc = 1;
+               gpu->ubwc_config.rgb565_predicator = 1;
+               gpu->ubwc_config.uavflagprd_inv = 2;
        }
+}
+
+static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       /*
+        * We subtract 13 from the highest bank bit (13 is the minimum value
+        * allowed by hw) and write the lowest two bits of the remaining value
+        * as hbb_lo and the one above it as hbb_hi to the hardware.
+        */
+       BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
+       u32 hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
+       u32 hbb_hi = hbb >> 2;
+       u32 hbb_lo = hbb & 3;
 
        gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL,
-                 rgb565_predicator << 11 | hbb_hi << 10 | amsbc << 4 |
-                 min_acc_len << 3 | hbb_lo << 1 | ubwc_mode);
+                 adreno_gpu->ubwc_config.rgb565_predicator << 11 |
+                 hbb_hi << 10 | adreno_gpu->ubwc_config.amsbc << 4 |
+                 adreno_gpu->ubwc_config.min_acc_len << 3 |
+                 hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
 
        gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, hbb_hi << 4 |
-                 min_acc_len << 3 | hbb_lo << 1 | ubwc_mode);
+                 adreno_gpu->ubwc_config.min_acc_len << 3 |
+                 hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
 
        gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 |
-                 uavflagprd_inv << 4 | min_acc_len << 3 |
-                 hbb_lo << 1 | ubwc_mode);
+                 adreno_gpu->ubwc_config.uavflagprd_inv << 4 |
+                 adreno_gpu->ubwc_config.min_acc_len << 3 |
+                 hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
 
        if (adreno_is_a7xx(adreno_gpu))
                gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL,
                          FIELD_PREP(GENMASK(8, 5), hbb_lo));
 
-       gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, min_acc_len << 23 | hbb_lo << 21);
+       gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL,
+                 adreno_gpu->ubwc_config.min_acc_len << 23 | hbb_lo << 21);
 }
 
 static int a6xx_cp_init(struct msm_gpu *gpu)
@@ -2911,5 +2922,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
                msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
                                a6xx_fault_handler);
 
+       a6xx_calc_ubwc_config(adreno_gpu);
+
        return gpu;
 }
index 80b3f6312116eead9bb9d3b1eb2eded560fffc0b..bc14df96feb013a9592c203aab2ab59b7b61e336 100644 (file)
@@ -165,6 +165,15 @@ struct adreno_gpu {
        /* firmware: */
        const struct firmware *fw[ADRENO_FW_MAX];
 
+       struct {
+               u32 rgb565_predicator;
+               u32 uavflagprd_inv;
+               u32 min_acc_len;
+               u32 ubwc_mode;
+               u32 highest_bank_bit;
+               u32 amsbc;
+       } ubwc_config;
+
        /*
         * Register offsets are different between some GPUs.
         * GPU specific offsets will be exported by GPU specific