drm/msm: Refactor UBWC config setting
Split up calculating configuration parameters and programming them, so that we can expose them to userspace. Signed-off-by: Connor Abbott <cwabbott0@gmail.com> Patchwork: https://patchwork.freedesktop.org/patch/571180/ Signed-off-by: Rob Clark <robdclark@chromium.org>
This commit is contained in:
parent
cbaf84e738
commit
8814455a0e
3 changed files with 78 additions and 53 deletions
|
@ -684,7 +684,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
|
||||||
{
|
{
|
||||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||||
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
|
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
|
||||||
u32 regbit;
|
u32 hbb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
|
gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
|
||||||
|
@ -820,18 +820,15 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
|
||||||
|
|
||||||
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
|
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
|
||||||
|
|
||||||
/* Set the highest bank bit */
|
BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
|
||||||
if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
|
hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
|
||||||
regbit = 2;
|
|
||||||
else
|
|
||||||
regbit = 1;
|
|
||||||
|
|
||||||
gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, regbit << 7);
|
gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, hbb << 7);
|
||||||
gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, regbit << 1);
|
gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, hbb << 1);
|
||||||
|
|
||||||
if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) ||
|
if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) ||
|
||||||
adreno_is_a540(adreno_gpu))
|
adreno_is_a540(adreno_gpu))
|
||||||
gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, regbit);
|
gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, hbb);
|
||||||
|
|
||||||
/* Disable All flat shading optimization (ALLFLATOPTDIS) */
|
/* Disable All flat shading optimization (ALLFLATOPTDIS) */
|
||||||
gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, (1 << 10));
|
gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, (1 << 10));
|
||||||
|
@ -1785,5 +1782,11 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
|
||||||
/* Set up the preemption specific bits and pieces for each ringbuffer */
|
/* Set up the preemption specific bits and pieces for each ringbuffer */
|
||||||
a5xx_preempt_init(gpu);
|
a5xx_preempt_init(gpu);
|
||||||
|
|
||||||
|
/* Set the highest bank bit */
|
||||||
|
if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
|
||||||
|
adreno_gpu->ubwc_config.highest_bank_bit = 15;
|
||||||
|
else
|
||||||
|
adreno_gpu->ubwc_config.highest_bank_bit = 14;
|
||||||
|
|
||||||
return gpu;
|
return gpu;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1270,81 +1270,92 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
|
||||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]);
|
gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
|
static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
|
||||||
{
|
{
|
||||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
|
||||||
/* Unknown, introduced with A650 family, related to UBWC mode/ver 4 */
|
/* Unknown, introduced with A650 family, related to UBWC mode/ver 4 */
|
||||||
u32 rgb565_predicator = 0;
|
gpu->ubwc_config.rgb565_predicator = 0;
|
||||||
/* Unknown, introduced with A650 family */
|
/* Unknown, introduced with A650 family */
|
||||||
u32 uavflagprd_inv = 0;
|
gpu->ubwc_config.uavflagprd_inv = 0;
|
||||||
/* Whether the minimum access length is 64 bits */
|
/* Whether the minimum access length is 64 bits */
|
||||||
u32 min_acc_len = 0;
|
gpu->ubwc_config.min_acc_len = 0;
|
||||||
/* Entirely magic, per-GPU-gen value */
|
/* Entirely magic, per-GPU-gen value */
|
||||||
u32 ubwc_mode = 0;
|
gpu->ubwc_config.ubwc_mode = 0;
|
||||||
/*
|
/*
|
||||||
* The Highest Bank Bit value represents the bit of the highest DDR bank.
|
* The Highest Bank Bit value represents the bit of the highest DDR bank.
|
||||||
* We then subtract 13 from it (13 is the minimum value allowed by hw) and
|
* This should ideally use DRAM type detection.
|
||||||
* write the lowest two bits of the remaining value as hbb_lo and the
|
|
||||||
* one above it as hbb_hi to the hardware. This should ideally use DRAM
|
|
||||||
* type detection.
|
|
||||||
*/
|
*/
|
||||||
u32 hbb_hi = 0;
|
gpu->ubwc_config.highest_bank_bit = 15;
|
||||||
u32 hbb_lo = 2;
|
|
||||||
/* Unknown, introduced with A640/680 */
|
|
||||||
u32 amsbc = 0;
|
|
||||||
|
|
||||||
if (adreno_is_a610(adreno_gpu)) {
|
if (adreno_is_a610(gpu)) {
|
||||||
/* HBB = 14 */
|
gpu->ubwc_config.highest_bank_bit = 14;
|
||||||
hbb_lo = 1;
|
gpu->ubwc_config.min_acc_len = 1;
|
||||||
min_acc_len = 1;
|
gpu->ubwc_config.ubwc_mode = 1;
|
||||||
ubwc_mode = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a618 is using the hw default values */
|
/* a618 is using the hw default values */
|
||||||
if (adreno_is_a618(adreno_gpu))
|
if (adreno_is_a618(gpu))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (adreno_is_a619_holi(adreno_gpu))
|
if (adreno_is_a619_holi(gpu))
|
||||||
hbb_lo = 0;
|
gpu->ubwc_config.highest_bank_bit = 13;
|
||||||
|
|
||||||
if (adreno_is_a640_family(adreno_gpu))
|
if (adreno_is_a640_family(gpu))
|
||||||
amsbc = 1;
|
gpu->ubwc_config.amsbc = 1;
|
||||||
|
|
||||||
if (adreno_is_a650(adreno_gpu) ||
|
if (adreno_is_a650(gpu) ||
|
||||||
adreno_is_a660(adreno_gpu) ||
|
adreno_is_a660(gpu) ||
|
||||||
adreno_is_a690(adreno_gpu) ||
|
adreno_is_a690(gpu) ||
|
||||||
adreno_is_a730(adreno_gpu) ||
|
adreno_is_a730(gpu) ||
|
||||||
adreno_is_a740_family(adreno_gpu)) {
|
adreno_is_a740_family(gpu)) {
|
||||||
/* TODO: get ddr type from bootloader and use 2 for LPDDR4 */
|
/* TODO: get ddr type from bootloader and use 2 for LPDDR4 */
|
||||||
hbb_lo = 3;
|
gpu->ubwc_config.highest_bank_bit = 16;
|
||||||
amsbc = 1;
|
gpu->ubwc_config.amsbc = 1;
|
||||||
rgb565_predicator = 1;
|
gpu->ubwc_config.rgb565_predicator = 1;
|
||||||
uavflagprd_inv = 2;
|
gpu->ubwc_config.uavflagprd_inv = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adreno_is_7c3(adreno_gpu)) {
|
if (adreno_is_7c3(gpu)) {
|
||||||
hbb_lo = 1;
|
gpu->ubwc_config.highest_bank_bit = 14;
|
||||||
amsbc = 1;
|
gpu->ubwc_config.amsbc = 1;
|
||||||
rgb565_predicator = 1;
|
gpu->ubwc_config.rgb565_predicator = 1;
|
||||||
uavflagprd_inv = 2;
|
gpu->ubwc_config.uavflagprd_inv = 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
|
||||||
|
{
|
||||||
|
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||||
|
/*
|
||||||
|
* We subtract 13 from the highest bank bit (13 is the minimum value
|
||||||
|
* allowed by hw) and write the lowest two bits of the remaining value
|
||||||
|
* as hbb_lo and the one above it as hbb_hi to the hardware.
|
||||||
|
*/
|
||||||
|
BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
|
||||||
|
u32 hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
|
||||||
|
u32 hbb_hi = hbb >> 2;
|
||||||
|
u32 hbb_lo = hbb & 3;
|
||||||
|
|
||||||
gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL,
|
gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL,
|
||||||
rgb565_predicator << 11 | hbb_hi << 10 | amsbc << 4 |
|
adreno_gpu->ubwc_config.rgb565_predicator << 11 |
|
||||||
min_acc_len << 3 | hbb_lo << 1 | ubwc_mode);
|
hbb_hi << 10 | adreno_gpu->ubwc_config.amsbc << 4 |
|
||||||
|
adreno_gpu->ubwc_config.min_acc_len << 3 |
|
||||||
|
hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
|
||||||
|
|
||||||
gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, hbb_hi << 4 |
|
gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, hbb_hi << 4 |
|
||||||
min_acc_len << 3 | hbb_lo << 1 | ubwc_mode);
|
adreno_gpu->ubwc_config.min_acc_len << 3 |
|
||||||
|
hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
|
||||||
|
|
||||||
gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 |
|
gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 |
|
||||||
uavflagprd_inv << 4 | min_acc_len << 3 |
|
adreno_gpu->ubwc_config.uavflagprd_inv << 4 |
|
||||||
hbb_lo << 1 | ubwc_mode);
|
adreno_gpu->ubwc_config.min_acc_len << 3 |
|
||||||
|
hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
|
||||||
|
|
||||||
if (adreno_is_a7xx(adreno_gpu))
|
if (adreno_is_a7xx(adreno_gpu))
|
||||||
gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL,
|
gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL,
|
||||||
FIELD_PREP(GENMASK(8, 5), hbb_lo));
|
FIELD_PREP(GENMASK(8, 5), hbb_lo));
|
||||||
|
|
||||||
gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, min_acc_len << 23 | hbb_lo << 21);
|
gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL,
|
||||||
|
adreno_gpu->ubwc_config.min_acc_len << 23 | hbb_lo << 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int a6xx_cp_init(struct msm_gpu *gpu)
|
static int a6xx_cp_init(struct msm_gpu *gpu)
|
||||||
|
@ -2911,5 +2922,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
|
||||||
msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
|
msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
|
||||||
a6xx_fault_handler);
|
a6xx_fault_handler);
|
||||||
|
|
||||||
|
a6xx_calc_ubwc_config(adreno_gpu);
|
||||||
|
|
||||||
return gpu;
|
return gpu;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,6 +165,15 @@ struct adreno_gpu {
|
||||||
/* firmware: */
|
/* firmware: */
|
||||||
const struct firmware *fw[ADRENO_FW_MAX];
|
const struct firmware *fw[ADRENO_FW_MAX];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u32 rgb565_predicator;
|
||||||
|
u32 uavflagprd_inv;
|
||||||
|
u32 min_acc_len;
|
||||||
|
u32 ubwc_mode;
|
||||||
|
u32 highest_bank_bit;
|
||||||
|
u32 amsbc;
|
||||||
|
} ubwc_config;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register offsets are different between some GPUs.
|
* Register offsets are different between some GPUs.
|
||||||
* GPU specific offsets will be exported by GPU specific
|
* GPU specific offsets will be exported by GPU specific
|
||||||
|
|
Loading…
Add table
Reference in a new issue