in mm/cache-l2x0.c [607:679]
static void __init l2c310_enable(void __iomem *base, unsigned num_lock)
{
unsigned rev = readl_relaxed(base + L2X0_CACHE_ID) & L2X0_CACHE_ID_RTL_MASK;
bool cortex_a9 = read_cpuid_part() == ARM_CPU_PART_CORTEX_A9;
u32 aux = l2x0_saved_regs.aux_ctrl;
if (rev >= L310_CACHE_ID_RTL_R2P0) {
if (cortex_a9 && !l2x0_bresp_disable) {
aux |= L310_AUX_CTRL_EARLY_BRESP;
pr_info("L2C-310 enabling early BRESP for Cortex-A9\n");
} else if (aux & L310_AUX_CTRL_EARLY_BRESP) {
pr_warn("L2C-310 early BRESP only supported with Cortex-A9\n");
aux &= ~L310_AUX_CTRL_EARLY_BRESP;
}
}
if (cortex_a9 && !l2x0_flz_disable) {
u32 aux_cur = readl_relaxed(base + L2X0_AUX_CTRL);
u32 acr = get_auxcr();
pr_debug("Cortex-A9 ACR=0x%08x\n", acr);
if (acr & BIT(3) && !(aux_cur & L310_AUX_CTRL_FULL_LINE_ZERO))
pr_err("L2C-310: full line of zeros enabled in Cortex-A9 but not L2C-310 - invalid\n");
if (aux & L310_AUX_CTRL_FULL_LINE_ZERO && !(acr & BIT(3)))
pr_err("L2C-310: enabling full line of zeros but not enabled in Cortex-A9\n");
if (!(aux & L310_AUX_CTRL_FULL_LINE_ZERO) && !outer_cache.write_sec) {
aux |= L310_AUX_CTRL_FULL_LINE_ZERO;
pr_info("L2C-310 full line of zeros enabled for Cortex-A9\n");
}
} else if (aux & (L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP)) {
pr_err("L2C-310: disabling Cortex-A9 specific feature bits\n");
aux &= ~(L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP);
}
/*
* Always enable non-secure access to the lockdown registers -
* we write to them as part of the L2C enable sequence so they
* need to be accessible.
*/
l2x0_saved_regs.aux_ctrl = aux | L310_AUX_CTRL_NS_LOCKDOWN;
l2c_enable(base, num_lock);
/* Read back resulting AUX_CTRL value as it could have been altered. */
aux = readl_relaxed(base + L2X0_AUX_CTRL);
if (aux & (L310_AUX_CTRL_DATA_PREFETCH | L310_AUX_CTRL_INSTR_PREFETCH)) {
u32 prefetch = readl_relaxed(base + L310_PREFETCH_CTRL);
pr_info("L2C-310 %s%s prefetch enabled, offset %u lines\n",
aux & L310_AUX_CTRL_INSTR_PREFETCH ? "I" : "",
aux & L310_AUX_CTRL_DATA_PREFETCH ? "D" : "",
1 + (prefetch & L310_PREFETCH_CTRL_OFFSET_MASK));
}
/* r3p0 or later has power control register */
if (rev >= L310_CACHE_ID_RTL_R3P0) {
u32 power_ctrl;
power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
pr_info("L2C-310 dynamic clock gating %sabled, standby mode %sabled\n",
power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
}
if (aux & L310_AUX_CTRL_FULL_LINE_ZERO)
cpuhp_setup_state(CPUHP_AP_ARM_L2X0_STARTING,
"arm/l2x0:starting", l2c310_starting_cpu,
l2c310_dying_cpu);
}