Skip to content

Commit 06cfbca

Browse files
akhilpo-qcomRob Clark
authored andcommitted
drm/msm/a6xx: Share dependency vote table with GMU
A8x GMU firmwares expect a separate vote table which describes the relationship between the Gx rail and MxA rail (and possibly Cx rail). Create this new vote table and implement the new HFI message which allows passing vote tables to send this data to GMU. Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com> Patchwork: https://patchwork.freedesktop.org/patch/689016/ Message-ID: <20251118-kaana-gpu-support-v4-13-86eeb8e93fb6@oss.qualcomm.com> Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
1 parent ca04ce7 commit 06cfbca

4 files changed

Lines changed: 125 additions & 0 deletions

File tree

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,57 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes,
16161616
return 0;
16171617
}
16181618

1619+
static int a6xx_gmu_rpmh_dep_votes_init(struct device *dev, u32 *votes,
1620+
unsigned long *freqs, int freqs_count)
1621+
{
1622+
const u16 *mx;
1623+
size_t count;
1624+
1625+
mx = cmd_db_read_aux_data("mx.lvl", &count);
1626+
if (IS_ERR(mx))
1627+
return PTR_ERR(mx);
1628+
/*
1629+
* The data comes back as an array of unsigned shorts so adjust the
1630+
* count accordingly
1631+
*/
1632+
count >>= 1;
1633+
if (!count)
1634+
return -EINVAL;
1635+
1636+
/* Fix the vote for zero frequency */
1637+
votes[0] = 0xffffffff;
1638+
1639+
/* Construct a vote for rest of the corners */
1640+
for (int i = 1; i < freqs_count; i++) {
1641+
unsigned int level = a6xx_gmu_get_arc_level(dev, freqs[i]);
1642+
u8 j, index = 0;
1643+
1644+
/* Get the primary index that matches the arc level */
1645+
for (j = 0; j < count; j++) {
1646+
if (mx[j] >= level) {
1647+
index = j;
1648+
break;
1649+
}
1650+
}
1651+
1652+
if (j == count) {
1653+
DRM_DEV_ERROR(dev,
1654+
"Mx Level %u not found in the RPMh list\n",
1655+
level);
1656+
DRM_DEV_ERROR(dev, "Available levels:\n");
1657+
for (j = 0; j < count; j++)
1658+
DRM_DEV_ERROR(dev, " %u\n", mx[j]);
1659+
1660+
return -EINVAL;
1661+
}
1662+
1663+
/* Construct the vote */
1664+
votes[i] = (0x3fff << 14) | (index << 8) | (0xff);
1665+
}
1666+
1667+
return 0;
1668+
}
1669+
16191670
/*
16201671
* The GMU votes with the RPMh for itself and on behalf of the GPU but we need
16211672
* to construct the list of votes on the CPU and send it over. Query the RPMh
@@ -1649,6 +1700,9 @@ static int a6xx_gmu_rpmh_votes_init(struct a6xx_gmu *gmu)
16491700
ret |= a6xx_gmu_rpmh_arc_votes_init(gmu->dev, gmu->cx_arc_votes,
16501701
gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl", "mx.lvl");
16511702

1703+
ret |= a6xx_gmu_rpmh_dep_votes_init(gmu->dev, gmu->dep_arc_votes,
1704+
gmu->gpu_freqs, gmu->nr_gpu_freqs);
1705+
16521706
/* Build the interconnect votes */
16531707
if (info->bcms && gmu->nr_gpu_bws > 1)
16541708
ret |= a6xx_gmu_rpmh_bw_votes_init(adreno_gpu, info, gmu);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ struct a6xx_gmu {
9797
int nr_gpu_freqs;
9898
unsigned long gpu_freqs[GMU_MAX_GX_FREQS];
9999
u32 gx_arc_votes[GMU_MAX_GX_FREQS];
100+
u32 dep_arc_votes[GMU_MAX_GX_FREQS];
100101
struct a6xx_hfi_acd_table acd_table;
101102

102103
int nr_gpu_bws;

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static const char * const a6xx_hfi_msg_id[] = {
2323
HFI_MSG_ID(HFI_H2F_MSG_START),
2424
HFI_MSG_ID(HFI_H2F_FEATURE_CTRL),
2525
HFI_MSG_ID(HFI_H2F_MSG_CORE_FW_START),
26+
HFI_MSG_ID(HFI_H2F_MSG_TABLE),
2627
HFI_MSG_ID(HFI_H2F_MSG_GX_BW_PERF_VOTE),
2728
HFI_MSG_ID(HFI_H2F_MSG_PREPARE_SLUMBER),
2829
};
@@ -270,11 +271,63 @@ static int a6xx_hfi_send_perf_table_v1(struct a6xx_gmu *gmu)
270271
NULL, 0);
271272
}
272273

274+
static int a8xx_hfi_send_perf_table(struct a6xx_gmu *gmu)
275+
{
276+
unsigned int num_gx_votes = 3, num_cx_votes = 2;
277+
struct a6xx_hfi_table_entry *entry;
278+
struct a6xx_hfi_table *tbl;
279+
int ret, i;
280+
u32 size;
281+
282+
size = sizeof(*tbl) + (2 * sizeof(tbl->entry[0])) +
283+
(gmu->nr_gpu_freqs * num_gx_votes * sizeof(gmu->gx_arc_votes[0])) +
284+
(gmu->nr_gmu_freqs * num_cx_votes * sizeof(gmu->cx_arc_votes[0]));
285+
tbl = kzalloc(size, GFP_KERNEL);
286+
tbl->type = HFI_TABLE_GPU_PERF;
287+
288+
/* First fill GX votes */
289+
entry = &tbl->entry[0];
290+
entry->count = gmu->nr_gpu_freqs;
291+
entry->stride = num_gx_votes;
292+
293+
for (i = 0; i < gmu->nr_gpu_freqs; i++) {
294+
unsigned int base = i * entry->stride;
295+
296+
entry->data[base+0] = gmu->gx_arc_votes[i];
297+
entry->data[base+1] = gmu->dep_arc_votes[i];
298+
entry->data[base+2] = gmu->gpu_freqs[i] / 1000;
299+
}
300+
301+
/* Then fill CX votes */
302+
entry = (struct a6xx_hfi_table_entry *)
303+
&tbl->entry[0].data[gmu->nr_gpu_freqs * num_gx_votes];
304+
305+
entry->count = gmu->nr_gmu_freqs;
306+
entry->stride = num_cx_votes;
307+
308+
for (i = 0; i < gmu->nr_gmu_freqs; i++) {
309+
unsigned int base = i * entry->stride;
310+
311+
entry->data[base] = gmu->cx_arc_votes[i];
312+
entry->data[base+1] = gmu->gmu_freqs[i] / 1000;
313+
}
314+
315+
ret = a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_TABLE, tbl, size, NULL, 0);
316+
317+
kfree(tbl);
318+
return ret;
319+
}
320+
273321
static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu)
274322
{
323+
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
324+
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
275325
struct a6xx_hfi_msg_perf_table msg = { 0 };
276326
int i;
277327

328+
if (adreno_is_a8xx(adreno_gpu))
329+
return a8xx_hfi_send_perf_table(gmu);
330+
278331
msg.num_gpu_levels = gmu->nr_gpu_freqs;
279332
msg.num_gmu_levels = gmu->nr_gmu_freqs;
280333

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,23 @@ struct a6xx_hfi_msg_core_fw_start {
185185
u32 handle;
186186
};
187187

188+
#define HFI_H2F_MSG_TABLE 15
189+
190+
struct a6xx_hfi_table_entry {
191+
u32 count;
192+
u32 stride;
193+
u32 data[];
194+
};
195+
196+
struct a6xx_hfi_table {
197+
u32 header;
198+
u32 version;
199+
u32 type;
200+
#define HFI_TABLE_BW_VOTE 0
201+
#define HFI_TABLE_GPU_PERF 1
202+
struct a6xx_hfi_table_entry entry[];
203+
};
204+
188205
#define HFI_H2F_MSG_GX_BW_PERF_VOTE 30
189206

190207
struct a6xx_hfi_gx_bw_perf_vote_cmd {

0 commit comments

Comments
 (0)