[Freedreno] [PATCH 13/16] drm/msm: gpu: Add support for the GPMU

Stanimir Varbanov stanimir.varbanov at linaro.org
Mon Nov 7 12:58:01 UTC 2016


Hi Jordan,

On 11/05/2016 12:44 AM, Jordan Crouse wrote:
> Most 5XX targets have GPMU (Graphics Power Management Unit) that
> handles a lot of the heavy lifting for power management including
> thermal and limits management and dynamic power collapse. While
> the GPMU itself is optional, it is usually nessesary to hit
> aggressive power targets.
> 
> The GPMU firmware needs to be loaded into the GPMU at init time via a
> shared hardware block of registers. Using the GPU to write the microcode
> is more efficient than using the CPU so at first load create an indirect
> buffer that can be executed during subsequent initalization sequences.
> 
> After loading the GPMU gets initalized through a shared register
> interface and then we mostly get out of its way and let it do
> its thing.
> 
> Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
> ---
>  drivers/gpu/drm/msm/Makefile               |   1 +
>  drivers/gpu/drm/msm/adreno/a5xx_gpu.c      |  64 +++++-
>  drivers/gpu/drm/msm/adreno/a5xx_gpu.h      |  23 ++
>  drivers/gpu/drm/msm/adreno/a5xx_power.c    | 341 +++++++++++++++++++++++++++++
>  drivers/gpu/drm/msm/adreno/adreno_device.c |   1 +
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h    |   1 +
>  6 files changed, 428 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/gpu/drm/msm/adreno/a5xx_power.c
> 

<cut>

> +/* Enable the GPMU microcontroller */
> +static int a5xx_gpmu_init(struct msm_gpu *gpu)
> +{
> +	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
> +	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
> +	struct msm_ringbuffer *ring = gpu->rb;
> +
> +	if (!a5xx_gpu->gpmu_dwords)
> +		return 0;
> +
> +	/* Turn off protected mode for this operation */
> +	OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);

This looks wrong, shouldn't it be?

OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 0)

> +	OUT_RING(ring, 0);
> +
> +	/* Kick off the IB to load the GPMU microcode */
> +	OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
> +	OUT_RING(ring, lower_32_bits(a5xx_gpu->gpmu_iova));
> +	OUT_RING(ring, upper_32_bits(a5xx_gpu->gpmu_iova));
> +	OUT_RING(ring, a5xx_gpu->gpmu_dwords);
> +
> +	/* Turn back on protected mode */
> +	OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
> +	OUT_RING(ring, 1);
> +
> +	gpu->funcs->flush(gpu);
> +
> +	if (!gpu->funcs->idle(gpu)) {
> +		DRM_ERROR("%s: Unable to load GPMU firmware. GPMU will not be active\n",
> +			gpu->name);
> +		return -EINVAL;
> +	}
> +
> +	gpu_write(gpu, REG_A5XX_GPMU_WFI_CONFIG, 0x4014);
> +
> +	/* Kick off the GPMU */
> +	gpu_write(gpu, REG_A5XX_GPMU_CM3_SYSRESET, 0x0);
> +
> +	/*
> +	 * Wait for the GPMU to respond. It isn't fatal if it doesn't, we just
> +	 * won't have advanced power collapse.
> +	 */
> +	if (spin_usecs(gpu, 25, REG_A5XX_GPMU_GENERAL_0, 0xFFFFFFFF,
> +		0xBABEFACE))
> +		DRM_ERROR("%s: GPMU firmware initialization timed out\n",
> +			gpu->name);
> +
> +	return 0;
> +}
> +

<cut>


-- 
regards,
Stan


More information about the Freedreno mailing list