Re: [PATCH v6] drm/msm/a6xx: Add support for an interconnect path

From: Jordan Crouse
Date: Fri Jan 18 2019 - 18:27:56 EST


On Fri, Jan 18, 2019 at 03:04:34PM -0800, Evan Green wrote:
> On Fri, Jan 18, 2019 at 12:24 PM Jordan Crouse <jcrouse@xxxxxxxxxxxxxx> wrote:
> >
> > Try to get the interconnect path for the GPU and vote for the maximum
> > bandwidth to support all frequencies. This is needed for performance.
> > Later we will want to scale the bandwidth based on the frequency to
> > also optimize for power but that will require some device tree
> > infrastructure that does not yet exist.
> >
> > v6: use icc_set_bw() instead of icc_set()
> > v5: Remove hardcoded interconnect name and just use the default
> > v4: Don't use a port string at all to skip the need for names in the DT
> > v3: Use macros and change port string per Georgi Djakov
> >
> > Signed-off-by: Jordan Crouse <jcrouse@xxxxxxxxxxxxxx>
> > ---
> >
> > drivers/gpu/drm/msm/Kconfig | 1 +
> > drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 20 ++++++++++++++++++++
> > drivers/gpu/drm/msm/adreno/adreno_gpu.c | 9 +++++++++
> > drivers/gpu/drm/msm/msm_gpu.h | 3 +++
> > 4 files changed, 33 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
> > index cf549f1..78c9e5a5 100644
> > --- a/drivers/gpu/drm/msm/Kconfig
> > +++ b/drivers/gpu/drm/msm/Kconfig
> > @@ -5,6 +5,7 @@ config DRM_MSM
> > depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST)
> > depends on OF && COMMON_CLK
> > depends on MMU
> > + depends on INTERCONNECT || !INTERCONNECT
> > select QCOM_MDT_LOADER if ARCH_QCOM
> > select REGULATOR
> > select DRM_KMS_HELPER
> > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > index 5beb83d..c48fe46 100644
> > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > @@ -2,6 +2,7 @@
> > /* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. */
> >
> > #include <linux/clk.h>
> > +#include <linux/interconnect.h>
> > #include <linux/pm_opp.h>
> > #include <soc/qcom/cmd-db.h>
> >
> > @@ -84,6 +85,9 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
> >
> > static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
> > {
> > + struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
> > + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
> > + struct msm_gpu *gpu = &adreno_gpu->base;
> > int ret;
> >
> > gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);
> > @@ -106,6 +110,12 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
> > dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
> >
> > gmu->freq = gmu->gpu_freqs[index];
> > +
> > + /*
> > + * Eventually we will want to scale the path vote with the frequency but
> > + * for now leave it at max so that the performance is nominal.
> > + */
> > + icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
> > }
> >
> > void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq)
> > @@ -705,6 +715,8 @@ int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu)
> >
> > int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
> > {
> > + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
> > + struct msm_gpu *gpu = &adreno_gpu->base;
> > struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
> > int status, ret;
> >
> > @@ -720,6 +732,9 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
> > if (ret)
> > goto out;
> >
> > + /* Set the bus quota to a reasonable value for boot */
> > + icc_set_bw(gpu->icc_path, 0, MBps_to_icc(3072));
>
> Does the comment mention boot because this resume call happens during
> init?

Correct. Boot refers to the GMU in this context.

> How come this number is different from the one in __a6xx_gmu_set_freq?

If you never request a bus quota from the kernel the sucker is horribly
painfully slow. I'm not sure if that is just the default reset value of
the registers or if the bootloader is doing something. In any event
the GMU doesn't always initialize if you try to bring it up with the
default bus settings so we set it to a "reasonable" quota for the
init sequence. I admit I didn't come up with these numbers on my own;
some poor anonymous soul debugged this on the downstream kernel and
I just stole the same parameters.

As for _a6xx_gmu_set_freq() eventually we'll agree on a way to communicate
the bus bandwidth in the opp settings and we'll be able to adjust the quota
based on the frequency to save power so that's why the code is organized the way
it is so that a6xx_gmu_set_freq() won't have to be massively changed later.

> Also, you're setting an average bandwidth of 0, I
> guess you don't know really what your average is, and the hardware is
> fine with that setting. Is that true?

Yes, we only set the instantaneous bandwidth.

> -Evan

Jordan

--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project