Message ID | 20200526032514.22198-1-jonathan@marek.ca (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/msm/a6xx: set ubwc config for A640 and A650 | expand |
On Mon, May 25, 2020 at 11:25:13PM -0400, Jonathan Marek wrote: > This is required for A640 and A650 to be able to share UBWC-compressed > images with other HW such as display, which expect this configuration. > Signed-off-by: Jonathan Marek <jonathan@marek.ca> > --- > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 38 ++++++++++++++++++++++----- > 1 file changed, 32 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > index 6f335ae179c8..aa004a261277 100644 > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > @@ -289,6 +289,37 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state) > gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? 0x8aa8aa02 : 0); > } > > +static void a6xx_set_ubwc_config(struct msm_gpu *gpu) > +{ > + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); > + u32 lower_bit = 2; > + u32 amsbc = 0; > + u32 rgb565_predicator = 0; > + u32 uavflagprd_inv = 0; > + This hardware design has the amazing ability to make me sad every time I see it. > + /* a618 is using the hw default values */ > + if (adreno_is_a618(adreno_gpu)) > + return; > + I've been a recent convert to the cult of <linux/bitfields.h> and FIELD_PREP() could help, maybe? if (adreno_is_a640(adreno_gpu)) { rb_ncmode = FIELD_PREP(REG_A6XX_RB_NC_MODE_CNTL_AMSBC, 1); rb_ncmode |= FIELD_PREP(REG_A6XX_RB_NC_MODE_CNTL_HBB, 2); tpl1_ncmode = FIELD_PREP(REG_A6XX_TPL1_NC_MODE_HBB, 2); sp_ncmode = FIELD_PREP(REG_A6XX_TPL1_NC_MODE_HBB, 2); uchemode = FIELD_PREP(REG_A6XX_UCHE_MODE_CNTL_HBB, 2); } else if adreno_is_a650(adreno_gpu)) { rb_ncmode = FIELD_PREP(REG_A6XX_RB_NC_MODE_CNTL_AMSBC, 1); rb_ncmode |= FIELD_PREP(REG_A6XX_RB_NC_MODE_CNTL_HBB, 3); rb_ncmode |= FIELD_PREP(REG_A6XX_RB_NC_MODE_CNTL_RGB565, 1); tpl1_ncmode = FIELD_PREP(REG_A6XX_TPL1_NC_MODE_HBB, 3); sp_ncmode = FIELD_PREP(REG_A6XX_TPL1_NC_MODE_HBB, 3); sp_ncmode |= FIELD_PREP(REG_A6XX_TPL1_NC_MODE_UAVFLAGPRD_INV, 2); uchemode = FIELD_PREP(REG_A6XX_UCHE_MODE_CNTL_HBB, 2); } I'm not sure if that is any clearer or not. Perhaps this is a problem for the next person to add a new target. Regardless the code is programming the hardware correctly so... Reviewed-by: Jordan Crouse <jcrouse@codeaurora.org> > + if (adreno_is_a640(adreno_gpu)) > + amsbc = 1; > + > + if (adreno_is_a650(adreno_gpu)) { > + /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */ > + lower_bit = 3; > + amsbc = 1; > + rgb565_predicator = 1; > + uavflagprd_inv = 2; > + } > + > + gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, > + rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); > + gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); > + gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, > + uavflagprd_inv >> 4 | lower_bit << 1); > + gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, lower_bit << 21); > +} > + > static int a6xx_cp_init(struct msm_gpu *gpu) > { > struct msm_ringbuffer *ring = gpu->rb[0]; > @@ -478,12 +509,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu) > /* Select CP0 to always count cycles */ > gpu_write(gpu, REG_A6XX_CP_PERFCTR_CP_SEL_0, PERF_CP_ALWAYS_COUNT); > > - if (adreno_is_a630(adreno_gpu)) { > - gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, 2 << 1); > - gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, 2 << 1); > - gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, 2 << 1); > - gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, 2 << 21); > - } > + a6xx_set_ubwc_config(gpu); > > /* Enable fault detection */ > gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, > -- > 2.26.1 >
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 6f335ae179c8..aa004a261277 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -289,6 +289,37 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state) gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? 0x8aa8aa02 : 0); } +static void a6xx_set_ubwc_config(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + u32 lower_bit = 2; + u32 amsbc = 0; + u32 rgb565_predicator = 0; + u32 uavflagprd_inv = 0; + + /* a618 is using the hw default values */ + if (adreno_is_a618(adreno_gpu)) + return; + + if (adreno_is_a640(adreno_gpu)) + amsbc = 1; + + if (adreno_is_a650(adreno_gpu)) { + /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */ + lower_bit = 3; + amsbc = 1; + rgb565_predicator = 1; + uavflagprd_inv = 2; + } + + gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, + rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); + gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); + gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, + uavflagprd_inv >> 4 | lower_bit << 1); + gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, lower_bit << 21); +} + static int a6xx_cp_init(struct msm_gpu *gpu) { struct msm_ringbuffer *ring = gpu->rb[0]; @@ -478,12 +509,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu) /* Select CP0 to always count cycles */ gpu_write(gpu, REG_A6XX_CP_PERFCTR_CP_SEL_0, PERF_CP_ALWAYS_COUNT); - if (adreno_is_a630(adreno_gpu)) { - gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, 2 << 1); - gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, 2 << 1); - gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, 2 << 1); - gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, 2 << 21); - } + a6xx_set_ubwc_config(gpu); /* Enable fault detection */ gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL,
This is required for A640 and A650 to be able to share UBWC-compressed images with other HW such as display, which expect this configuration. Signed-off-by: Jonathan Marek <jonathan@marek.ca> --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 38 ++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-)