diff mbox series

[v2,5/7] drm/msm/adreno: Add A702 support

Message ID 20240219-topic-rb1_gpu-v2-5-2d3d6a0db040@linaro.org (mailing list archive)
State New, archived
Headers show
Series A702 support | expand

Commit Message

Konrad Dybcio Feb. 23, 2024, 9:21 p.m. UTC
The A702 is a weird mix of 600 and 700 series.. Perhaps even a
testing ground for some A7xx features with good ol' A6xx silicon.
It's basically A610 that's been beefed up with some new registers
and hw features (like APRIV!), that was then cut back in size,
memory bus and some other ways.

Add support for it, tested with QCM2290 / RB1.

Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 92 +++++++++++++++++++++++++++---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 18 ++++++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h    | 16 +++++-
 3 files changed, 117 insertions(+), 9 deletions(-)

Comments

Connor Abbott May 23, 2024, 12:14 p.m. UTC | #1
On Fri, Feb 23, 2024 at 9:28 PM Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
>
> The A702 is a weird mix of 600 and 700 series.. Perhaps even a
> testing ground for some A7xx features with good ol' A6xx silicon.
> It's basically A610 that's been beefed up with some new registers
> and hw features (like APRIV!), that was then cut back in size,
> memory bus and some other ways.
>
> Add support for it, tested with QCM2290 / RB1.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 92 +++++++++++++++++++++++++++---
>  drivers/gpu/drm/msm/adreno/adreno_device.c | 18 ++++++
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h    | 16 +++++-
>  3 files changed, 117 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index c9c55e2ea584..2a491a486ca1 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -837,6 +837,65 @@ const struct adreno_reglist a690_hwcg[] = {
>         {}
>  };
>
> +const struct adreno_reglist a702_hwcg[] = {
> +       { REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
> +       { REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
> +       { REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
> +       { REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
> +       { REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222 },
> +       { REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002 },
> +       { REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002 },
> +       { REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
> +       { REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
> +       { REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_FCHE, 0x00000222 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_FCHE, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_FCHE, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_GLC, 0x00222222 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_GLC, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_GLC, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_CNTL_MHUB, 0x00000002 },
> +       { REG_A6XX_RBBM_CLOCK_DELAY_MHUB, 0x00000000 },
> +       { REG_A6XX_RBBM_CLOCK_HYST_MHUB, 0x00000000 },
> +       {}
> +};
> +
>  const struct adreno_reglist a730_hwcg[] = {
>         { REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
>         { REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022222 },
> @@ -968,6 +1027,8 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>                 clock_cntl_on = 0x8aa8aa02;
>         else if (adreno_is_a610(adreno_gpu))
>                 clock_cntl_on = 0xaaa8aa82;
> +       else if (adreno_is_a702(adreno_gpu))
> +               clock_cntl_on = 0xaaaaaa82;
>         else
>                 clock_cntl_on = 0x8aa8aa82;
>
> @@ -989,14 +1050,14 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
>                 return;
>
>         /* Disable SP clock before programming HWCG registers */
> -       if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
> +       if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
>                 gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0);
>
>         for (i = 0; (reg = &adreno_gpu->info->hwcg[i], reg->offset); i++)
>                 gpu_write(gpu, reg->offset, state ? reg->value : 0);
>
>         /* Enable SP clock */
> -       if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
> +       if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
>                 gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1);
>
>         gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0);
> @@ -1224,7 +1285,7 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
>         const u32 *regs = a6xx_protect;
>         unsigned i, count, count_max;
>
> -       if (adreno_is_a650(adreno_gpu)) {
> +       if (adreno_is_a650(adreno_gpu) || adreno_is_a702(adreno_gpu)) {
>                 regs = a650_protect;
>                 count = ARRAY_SIZE(a650_protect);
>                 count_max = 48;
> @@ -1320,6 +1381,12 @@ static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
>                 gpu->ubwc_config.rgb565_predicator = 1;
>                 gpu->ubwc_config.uavflagprd_inv = 2;
>         }
> +
> +       if (adreno_is_a702(gpu)) {
> +               gpu->ubwc_config.highest_bank_bit = 14;
> +               gpu->ubwc_config.min_acc_len = 1;
> +               gpu->ubwc_config.ubwc_mode = 2;

I just noticed, but this is wrong. ubwc_mode is a 1 bit field and what
this is actually doing is overwriting hbb_lo, making the highest bank
bit 15 instead of 14.

> +       }
>  }
>
>  static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
> @@ -1453,7 +1520,7 @@ static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
>                 return false;
>
>         /* A7xx is safe! */
> -       if (adreno_is_a7xx(adreno_gpu))
> +       if (adreno_is_a7xx(adreno_gpu) || adreno_is_a702(adreno_gpu))
>                 return true;
>
>         /*
> @@ -1671,7 +1738,7 @@ static int hw_init(struct msm_gpu *gpu)
>         a6xx_set_hwcg(gpu, true);
>
>         /* VBIF/GBIF start*/
> -       if (adreno_is_a610(adreno_gpu) ||
> +       if (adreno_is_a610_family(adreno_gpu) ||
>             adreno_is_a640_family(adreno_gpu) ||
>             adreno_is_a650_family(adreno_gpu) ||
>             adreno_is_a7xx(adreno_gpu)) {
> @@ -1705,6 +1772,7 @@ 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;
>
> @@ -1725,7 +1793,7 @@ static int hw_init(struct msm_gpu *gpu)
>         if (adreno_is_a640_family(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) {
>                 gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
>                 gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
> -       } else if (adreno_is_a610(adreno_gpu)) {
> +       } else if (adreno_is_a610_family(adreno_gpu)) {
>                 gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x00800060);
>                 gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x40201b16);
>         } else if (!adreno_is_a7xx(adreno_gpu)) {
> @@ -1740,13 +1808,18 @@ static int hw_init(struct msm_gpu *gpu)
>         if (adreno_is_a610(adreno_gpu)) {
>                 gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 48);
>                 gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 47);
> +       } else if (adreno_is_a702(adreno_gpu)) {
> +               gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 64);
> +               gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 63);
>         } else if (!adreno_is_a7xx(adreno_gpu))
>                 gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
>
>         /* Setting the primFifo thresholds default values,
>          * and vccCacheSkipDis=1 bit (0x200) for A640 and newer
>         */
> -       if (adreno_is_a690(adreno_gpu))
> +       if (adreno_is_a702(adreno_gpu))
> +               gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x0000c000);
> +       else if (adreno_is_a690(adreno_gpu))
>                 gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00800200);
>         else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
>                 gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
> @@ -1786,7 +1859,7 @@ static int hw_init(struct msm_gpu *gpu)
>                 gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4fffff);
>         else if (adreno_is_a619(adreno_gpu))
>                 gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff);
> -       else if (adreno_is_a610(adreno_gpu))
> +       else if (adreno_is_a610(adreno_gpu) || adreno_is_a702(adreno_gpu))
>                 gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3ffff);
>         else
>                 gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff);
> @@ -1822,6 +1895,9 @@ static int hw_init(struct msm_gpu *gpu)
>                 else
>                         gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1);
>                 gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0);
> +       } else if (adreno_is_a702(adreno_gpu)) {
> +               /* Something to do with the HLSQ cluster */
> +               gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(24));
>         }
>
>         if (adreno_is_a690(adreno_gpu))
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
> index 2ce7d7b1690d..b121abc71338 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
> @@ -492,6 +492,24 @@ static const struct adreno_info gpulist[] = {
>                 .zapfw = "a690_zap.mdt",
>                 .hwcg = a690_hwcg,
>                 .address_space_size = SZ_16G,
> +       }, {
> +               .chip_ids = ADRENO_CHIP_IDS(0x07000200),
> +               .family = ADRENO_6XX_GEN1, /* NOT a mistake! */
> +               .fw = {
> +                       [ADRENO_FW_SQE] = "a702_sqe.fw",
> +               },
> +               .gmem = SZ_128K,
> +               .inactive_period = DRM_MSM_INACTIVE_PERIOD,
> +               .quirks = ADRENO_QUIRK_HAS_HW_APRIV,
> +               .init = a6xx_gpu_init,
> +               .zapfw = "a702_zap.mbn",
> +               .hwcg = a702_hwcg,
> +               .speedbins = ADRENO_SPEEDBINS(
> +                       { 0,   0 },
> +                       { 236, 1 },
> +                       { 178, 2 },
> +                       { 142, 3 },
> +               ),
>         }, {
>                 .chip_ids = ADRENO_CHIP_IDS(0x07030001),
>                 .family = ADRENO_7XX_GEN1,
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> index bc14df96feb0..f451881a6ddf 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
> @@ -77,7 +77,7 @@ struct adreno_reglist {
>  };
>
>  extern const struct adreno_reglist a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[];
> -extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a730_hwcg[], a740_hwcg[];
> +extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a702_hwcg[], a730_hwcg[], a740_hwcg[];
>
>  struct adreno_speedbin {
>         uint16_t fuse;
> @@ -382,6 +382,20 @@ static inline int adreno_is_a690(const struct adreno_gpu *gpu)
>         return gpu->info->chip_ids[0] == 0x06090000;
>  }
>
> +static inline int adreno_is_a702(const struct adreno_gpu *gpu)
> +{
> +       return gpu->info->chip_ids[0] == 0x07000200;
> +}
> +
> +static inline int adreno_is_a610_family(const struct adreno_gpu *gpu)
> +{
> +       if (WARN_ON_ONCE(!gpu->info))
> +               return false;
> +
> +       /* TODO: A612 */
> +       return adreno_is_a610(gpu) || adreno_is_a702(gpu);
> +}
> +
>  /* check for a615, a616, a618, a619 or any a630 derivatives */
>  static inline int adreno_is_a630_family(const struct adreno_gpu *gpu)
>  {
>
> --
> 2.43.2
>
Konrad Dybcio June 6, 2024, 9:27 a.m. UTC | #2
On 23.05.2024 2:14 PM, Connor Abbott wrote:
> On Fri, Feb 23, 2024 at 9:28 PM Konrad Dybcio <konrad.dybcio@linaro.org> wrote:
>>
>> The A702 is a weird mix of 600 and 700 series.. Perhaps even a
>> testing ground for some A7xx features with good ol' A6xx silicon.
>> It's basically A610 that's been beefed up with some new registers
>> and hw features (like APRIV!), that was then cut back in size,
>> memory bus and some other ways.
>>
>> Add support for it, tested with QCM2290 / RB1.
>>
>> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
>> ---

[...]

>> +
>> +       if (adreno_is_a702(gpu)) {
>> +               gpu->ubwc_config.highest_bank_bit = 14;
>> +               gpu->ubwc_config.min_acc_len = 1;
>> +               gpu->ubwc_config.ubwc_mode = 2;
> 
> I just noticed, but this is wrong. ubwc_mode is a 1 bit field and what
> this is actually doing is overwriting hbb_lo, making the highest bank
> bit 15 instead of 14.

You're right, this should be a 0. Thanks!

Konrad
diff mbox series

Patch

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c9c55e2ea584..2a491a486ca1 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -837,6 +837,65 @@  const struct adreno_reglist a690_hwcg[] = {
 	{}
 };
 
+const struct adreno_reglist a702_hwcg[] = {
+	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002 },
+	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
+	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_FCHE, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GLC, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_MHUB, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_MHUB, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_MHUB, 0x00000000 },
+	{}
+};
+
 const struct adreno_reglist a730_hwcg[] = {
 	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
 	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022222 },
@@ -968,6 +1027,8 @@  static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 		clock_cntl_on = 0x8aa8aa02;
 	else if (adreno_is_a610(adreno_gpu))
 		clock_cntl_on = 0xaaa8aa82;
+	else if (adreno_is_a702(adreno_gpu))
+		clock_cntl_on = 0xaaaaaa82;
 	else
 		clock_cntl_on = 0x8aa8aa82;
 
@@ -989,14 +1050,14 @@  static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 		return;
 
 	/* Disable SP clock before programming HWCG registers */
-	if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
 		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0);
 
 	for (i = 0; (reg = &adreno_gpu->info->hwcg[i], reg->offset); i++)
 		gpu_write(gpu, reg->offset, state ? reg->value : 0);
 
 	/* Enable SP clock */
-	if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
 		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1);
 
 	gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0);
@@ -1224,7 +1285,7 @@  static void a6xx_set_cp_protect(struct msm_gpu *gpu)
 	const u32 *regs = a6xx_protect;
 	unsigned i, count, count_max;
 
-	if (adreno_is_a650(adreno_gpu)) {
+	if (adreno_is_a650(adreno_gpu) || adreno_is_a702(adreno_gpu)) {
 		regs = a650_protect;
 		count = ARRAY_SIZE(a650_protect);
 		count_max = 48;
@@ -1320,6 +1381,12 @@  static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
 		gpu->ubwc_config.rgb565_predicator = 1;
 		gpu->ubwc_config.uavflagprd_inv = 2;
 	}
+
+	if (adreno_is_a702(gpu)) {
+		gpu->ubwc_config.highest_bank_bit = 14;
+		gpu->ubwc_config.min_acc_len = 1;
+		gpu->ubwc_config.ubwc_mode = 2;
+	}
 }
 
 static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
@@ -1453,7 +1520,7 @@  static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
 		return false;
 
 	/* A7xx is safe! */
-	if (adreno_is_a7xx(adreno_gpu))
+	if (adreno_is_a7xx(adreno_gpu) || adreno_is_a702(adreno_gpu))
 		return true;
 
 	/*
@@ -1671,7 +1738,7 @@  static int hw_init(struct msm_gpu *gpu)
 	a6xx_set_hwcg(gpu, true);
 
 	/* VBIF/GBIF start*/
-	if (adreno_is_a610(adreno_gpu) ||
+	if (adreno_is_a610_family(adreno_gpu) ||
 	    adreno_is_a640_family(adreno_gpu) ||
 	    adreno_is_a650_family(adreno_gpu) ||
 	    adreno_is_a7xx(adreno_gpu)) {
@@ -1705,6 +1772,7 @@  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;
 
@@ -1725,7 +1793,7 @@  static int hw_init(struct msm_gpu *gpu)
 	if (adreno_is_a640_family(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
-	} else if (adreno_is_a610(adreno_gpu)) {
+	} else if (adreno_is_a610_family(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x00800060);
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x40201b16);
 	} else if (!adreno_is_a7xx(adreno_gpu)) {
@@ -1740,13 +1808,18 @@  static int hw_init(struct msm_gpu *gpu)
 	if (adreno_is_a610(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 48);
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 47);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 64);
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 63);
 	} else if (!adreno_is_a7xx(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
 
 	/* Setting the primFifo thresholds default values,
 	 * and vccCacheSkipDis=1 bit (0x200) for A640 and newer
 	*/
-	if (adreno_is_a690(adreno_gpu))
+	if (adreno_is_a702(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x0000c000);
+	else if (adreno_is_a690(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00800200);
 	else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
@@ -1786,7 +1859,7 @@  static int hw_init(struct msm_gpu *gpu)
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4fffff);
 	else if (adreno_is_a619(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff);
-	else if (adreno_is_a610(adreno_gpu))
+	else if (adreno_is_a610(adreno_gpu) || adreno_is_a702(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3ffff);
 	else
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff);
@@ -1822,6 +1895,9 @@  static int hw_init(struct msm_gpu *gpu)
 		else
 			gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1);
 		gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		/* Something to do with the HLSQ cluster */
+		gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(24));
 	}
 
 	if (adreno_is_a690(adreno_gpu))
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 2ce7d7b1690d..b121abc71338 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -492,6 +492,24 @@  static const struct adreno_info gpulist[] = {
 		.zapfw = "a690_zap.mdt",
 		.hwcg = a690_hwcg,
 		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x07000200),
+		.family = ADRENO_6XX_GEN1, /* NOT a mistake! */
+		.fw = {
+			[ADRENO_FW_SQE] = "a702_sqe.fw",
+		},
+		.gmem = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a702_zap.mbn",
+		.hwcg = a702_hwcg,
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 236, 1 },
+			{ 178, 2 },
+			{ 142, 3 },
+		),
 	}, {
 		.chip_ids = ADRENO_CHIP_IDS(0x07030001),
 		.family = ADRENO_7XX_GEN1,
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index bc14df96feb0..f451881a6ddf 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -77,7 +77,7 @@  struct adreno_reglist {
 };
 
 extern const struct adreno_reglist a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[];
-extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a730_hwcg[], a740_hwcg[];
+extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a702_hwcg[], a730_hwcg[], a740_hwcg[];
 
 struct adreno_speedbin {
 	uint16_t fuse;
@@ -382,6 +382,20 @@  static inline int adreno_is_a690(const struct adreno_gpu *gpu)
 	return gpu->info->chip_ids[0] == 0x06090000;
 }
 
+static inline int adreno_is_a702(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x07000200;
+}
+
+static inline int adreno_is_a610_family(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+
+	/* TODO: A612 */
+	return adreno_is_a610(gpu) || adreno_is_a702(gpu);
+}
+
 /* check for a615, a616, a618, a619 or any a630 derivatives */
 static inline int adreno_is_a630_family(const struct adreno_gpu *gpu)
 {