Skip to content

Commit 8c1b945

Browse files
superna9999robclark
authored andcommitted
drm/msm: adreno: dynamically generate GMU bw table
The Adreno GPU Management Unit (GMU) can also scale the ddr bandwidth along the frequency and power domain level, but for now we statically fill the bw_table with values from the downstream driver. Only the first entry is used, which is a disable vote, so we currently rely on scaling via the linux interconnect paths. Let's dynamically generate the bw_table with the vote values previously calculated from the OPPs. Those entries will then be used by the GMU when passing the appropriate bandwidth level while voting for a gpu frequency. Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Akhil P Oommen <quic_akhilpo@quicinc.com> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Patchwork: https://patchwork.freedesktop.org/patch/629396/ Signed-off-by: Rob Clark <robdclark@chromium.org>
1 parent ff4a7f6 commit 8c1b945

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

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

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/list.h>
77

88
#include <soc/qcom/cmd-db.h>
9+
#include <soc/qcom/tcs.h>
910

1011
#include "a6xx_gmu.h"
1112
#include "a6xx_gmu.xml.h"
@@ -259,6 +260,48 @@ static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu)
259260
NULL, 0);
260261
}
261262

263+
static void a6xx_generate_bw_table(const struct a6xx_info *info, struct a6xx_gmu *gmu,
264+
struct a6xx_hfi_msg_bw_table *msg)
265+
{
266+
unsigned int i, j;
267+
268+
for (i = 0; i < GMU_MAX_BCMS; i++) {
269+
if (!info->bcms[i].name)
270+
break;
271+
msg->ddr_cmds_addrs[i] = cmd_db_read_addr(info->bcms[i].name);
272+
}
273+
msg->ddr_cmds_num = i;
274+
275+
for (i = 0; i < gmu->nr_gpu_bws; ++i)
276+
for (j = 0; j < msg->ddr_cmds_num; j++)
277+
msg->ddr_cmds_data[i][j] = gmu->gpu_ib_votes[i][j];
278+
msg->bw_level_num = gmu->nr_gpu_bws;
279+
280+
/* Compute the wait bitmask with each BCM having the commit bit */
281+
msg->ddr_wait_bitmask = 0;
282+
for (j = 0; j < msg->ddr_cmds_num; j++)
283+
if (msg->ddr_cmds_data[0][j] & BCM_TCS_CMD_COMMIT_MASK)
284+
msg->ddr_wait_bitmask |= BIT(j);
285+
286+
/*
287+
* These are the CX (CNOC) votes - these are used by the GMU
288+
* The 'CN0' BCM is used on all targets, and votes are basically
289+
* 'off' and 'on' states with first bit to enable the path.
290+
*/
291+
292+
msg->cnoc_cmds_addrs[0] = cmd_db_read_addr("CN0");
293+
msg->cnoc_cmds_num = 1;
294+
295+
msg->cnoc_cmds_data[0][0] = BCM_TCS_CMD(true, false, 0, 0);
296+
msg->cnoc_cmds_data[1][0] = BCM_TCS_CMD(true, true, 0, BIT(0));
297+
298+
/* Compute the wait bitmask with each BCM having the commit bit */
299+
msg->cnoc_wait_bitmask = 0;
300+
for (j = 0; j < msg->cnoc_cmds_num; j++)
301+
if (msg->cnoc_cmds_data[0][j] & BCM_TCS_CMD_COMMIT_MASK)
302+
msg->cnoc_wait_bitmask |= BIT(j);
303+
}
304+
262305
static void a618_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
263306
{
264307
/* Send a single "off" entry since the 618 GMU doesn't do bus scaling */
@@ -664,6 +707,7 @@ static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu)
664707
struct a6xx_hfi_msg_bw_table *msg;
665708
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
666709
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
710+
const struct a6xx_info *info = adreno_gpu->info->a6xx;
667711

668712
if (gmu->bw_table)
669713
goto send;
@@ -672,7 +716,9 @@ static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu)
672716
if (!msg)
673717
return -ENOMEM;
674718

675-
if (adreno_is_a618(adreno_gpu))
719+
if (info->bcms && gmu->nr_gpu_bws > 1)
720+
a6xx_generate_bw_table(info, gmu, msg);
721+
else if (adreno_is_a618(adreno_gpu))
676722
a618_build_bw_table(msg);
677723
else if (adreno_is_a619(adreno_gpu))
678724
a619_build_bw_table(msg);

0 commit comments

Comments
 (0)