Skip to content

Commit e7fc939

Browse files
konradybciorobclark
authored andcommitted
drm/msm/a6xx: Add A610 support
A610 is one of (if not the) lowest-tier SKUs in the A6XX family. It features no GMU, as it's implemented solely on SoCs with SMD_RPM. What's more interesting is that it does not feature a VDDGX line either, being powered solely by VDDCX and has an unfortunate hardware quirk that makes its reset line broken - after a couple of assert/ deassert cycles, it will hang for good and will not wake up again. This GPU requires mesa changes for proper rendering, and lots of them at that. The command streams are quite far away from any other A6XX GPU and hence it needs special care. This patch was validated both by running an (incomplete) downstream mesa with some hacks (frames rendered correctly, though some instructions made the GPU hangcheck which is expected - garbage in, garbage out) and by replaying RD traces captured with the downstream KGSL driver - no crashes there, ever. Add support for this GPU on the kernel side, which comes down to pretty simply adding A612 HWCG tables, altering a few values and adding a special case for handling the reset line. Reviewed-by: Dmitry Baryshkov <[email protected]> Signed-off-by: Konrad Dybcio <[email protected]> Patchwork: https://patchwork.freedesktop.org/patch/542779/ Signed-off-by: Rob Clark <[email protected]>
1 parent 8296ff0 commit e7fc939

File tree

3 files changed

+107
-12
lines changed

3 files changed

+107
-12
lines changed

drivers/gpu/drm/msm/adreno/a6xx_gpu.c

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,56 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
252252
a6xx_flush(gpu, ring);
253253
}
254254

255+
const struct adreno_reglist a612_hwcg[] = {
256+
{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
257+
{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
258+
{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081},
259+
{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf},
260+
{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
261+
{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
262+
{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
263+
{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
264+
{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
265+
{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
266+
{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
267+
{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
268+
{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
269+
{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
270+
{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
271+
{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
272+
{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
273+
{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222},
274+
{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
275+
{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00},
276+
{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022},
277+
{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
278+
{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
279+
{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
280+
{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
281+
{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
282+
{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
283+
{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
284+
{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
285+
{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
286+
{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
287+
{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
288+
{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
289+
{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
290+
{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
291+
{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
292+
{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
293+
{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
294+
{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
295+
{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
296+
{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
297+
{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
298+
{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
299+
{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
300+
{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
301+
{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
302+
{},
303+
};
304+
255305
/* For a615 family (a615, a616, a618 and a619) */
256306
const struct adreno_reglist a615_hwcg[] = {
257307
{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
@@ -659,6 +709,8 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
659709

660710
if (adreno_is_a630(adreno_gpu))
661711
clock_cntl_on = 0x8aa8aa02;
712+
else if (adreno_is_a610(adreno_gpu))
713+
clock_cntl_on = 0xaaa8aa82;
662714
else
663715
clock_cntl_on = 0x8aa8aa82;
664716

@@ -669,13 +721,15 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
669721
return;
670722

671723
/* Disable SP clock before programming HWCG registers */
672-
gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0);
724+
if (!adreno_is_a610(adreno_gpu))
725+
gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0);
673726

674727
for (i = 0; (reg = &adreno_gpu->info->hwcg[i], reg->offset); i++)
675728
gpu_write(gpu, reg->offset, state ? reg->value : 0);
676729

677730
/* Enable SP clock */
678-
gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1);
731+
if (!adreno_is_a610(adreno_gpu))
732+
gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1);
679733

680734
gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0);
681735
}
@@ -907,6 +961,13 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
907961
/* Unknown, introduced with A640/680 */
908962
u32 amsbc = 0;
909963

964+
if (adreno_is_a610(adreno_gpu)) {
965+
/* HBB = 14 */
966+
hbb_lo = 1;
967+
min_acc_len = 1;
968+
ubwc_mode = 1;
969+
}
970+
910971
/* a618 is using the hw default values */
911972
if (adreno_is_a618(adreno_gpu))
912973
return;
@@ -1181,13 +1242,13 @@ static int hw_init(struct msm_gpu *gpu)
11811242
a6xx_set_hwcg(gpu, true);
11821243

11831244
/* VBIF/GBIF start*/
1184-
if (adreno_is_a640_family(adreno_gpu) ||
1245+
if (adreno_is_a610(adreno_gpu) ||
1246+
adreno_is_a640_family(adreno_gpu) ||
11851247
adreno_is_a650_family(adreno_gpu)) {
11861248
gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE0, 0x00071620);
11871249
gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE1, 0x00071620);
11881250
gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE2, 0x00071620);
11891251
gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
1190-
gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
11911252
gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x3);
11921253
} else {
11931254
gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
@@ -1215,18 +1276,26 @@ static int hw_init(struct msm_gpu *gpu)
12151276
gpu_write(gpu, REG_A6XX_UCHE_FILTER_CNTL, 0x804);
12161277
gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, 0x4);
12171278

1218-
if (adreno_is_a640_family(adreno_gpu) ||
1219-
adreno_is_a650_family(adreno_gpu))
1279+
if (adreno_is_a640_family(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) {
12201280
gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
1221-
else
1281+
gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
1282+
} else if (adreno_is_a610(adreno_gpu)) {
1283+
gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x00800060);
1284+
gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x40201b16);
1285+
} else {
12221286
gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x010000c0);
1223-
gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
1287+
gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
1288+
}
12241289

12251290
if (adreno_is_a660_family(adreno_gpu))
12261291
gpu_write(gpu, REG_A6XX_CP_LPAC_PROG_FIFO_SIZE, 0x00000020);
12271292

12281293
/* Setting the mem pool size */
1229-
gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
1294+
if (adreno_is_a610(adreno_gpu)) {
1295+
gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 48);
1296+
gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 47);
1297+
} else
1298+
gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
12301299

12311300
/* Setting the primFifo thresholds default values,
12321301
* and vccCacheSkipDis=1 bit (0x200) for A640 and newer
@@ -1237,6 +1306,8 @@ static int hw_init(struct msm_gpu *gpu)
12371306
gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200);
12381307
else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
12391308
gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
1309+
else if (adreno_is_a610(adreno_gpu))
1310+
gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00080000);
12401311
else
12411312
gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00180000);
12421313

@@ -1252,8 +1323,10 @@ static int hw_init(struct msm_gpu *gpu)
12521323
a6xx_set_ubwc_config(gpu);
12531324

12541325
/* Enable fault detection */
1255-
gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL,
1256-
(1 << 30) | 0x1fffff);
1326+
if (adreno_is_a610(adreno_gpu))
1327+
gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3ffff);
1328+
else
1329+
gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff);
12571330

12581331
gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, 1);
12591332

@@ -1813,6 +1886,10 @@ void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_
18131886

18141887
void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert)
18151888
{
1889+
/* 11nm chips (e.g. ones with A610) have hw issues with the reset line! */
1890+
if (adreno_is_a610(to_adreno_gpu(gpu)))
1891+
return;
1892+
18161893
gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, assert);
18171894
/* Perform a bogus read and add a brief delay to ensure ordering. */
18181895
gpu_read(gpu, REG_A6XX_RBBM_SW_RESET_CMD);

drivers/gpu/drm/msm/adreno/adreno_device.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,18 @@ static const struct adreno_info gpulist[] = {
253253
.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
254254
.init = a5xx_gpu_init,
255255
.zapfw = "a540_zap.mdt",
256+
}, {
257+
.rev = ADRENO_REV(6, 1, 0, ANY_ID),
258+
.revn = 610,
259+
.name = "A610",
260+
.fw = {
261+
[ADRENO_FW_SQE] = "a630_sqe.fw",
262+
},
263+
.gmem = (SZ_128K + SZ_4K),
264+
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
265+
.init = a6xx_gpu_init,
266+
.zapfw = "a610_zap.mdt",
267+
.hwcg = a612_hwcg,
256268
}, {
257269
.rev = ADRENO_REV(6, 1, 8, ANY_ID),
258270
.revn = 618,

drivers/gpu/drm/msm/adreno/adreno_gpu.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ struct adreno_reglist {
5555
u32 value;
5656
};
5757

58-
extern const struct adreno_reglist a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[], a660_hwcg[], a690_hwcg[];
58+
extern const struct adreno_reglist a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[];
59+
extern const struct adreno_reglist a660_hwcg[], a690_hwcg[];
5960

6061
struct adreno_info {
6162
struct adreno_rev rev;
@@ -253,6 +254,11 @@ static inline int adreno_is_a540(const struct adreno_gpu *gpu)
253254
return adreno_is_revn(gpu, 540);
254255
}
255256

257+
static inline int adreno_is_a610(const struct adreno_gpu *gpu)
258+
{
259+
return adreno_is_revn(gpu, 610);
260+
}
261+
256262
static inline int adreno_is_a618(const struct adreno_gpu *gpu)
257263
{
258264
return adreno_is_revn(gpu, 618);

0 commit comments

Comments
 (0)