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@xxxxxxxxxxxxxx> > --- > 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 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html