in qcom_q6v5_wcss.c [154:236]
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
{
int ret;
u32 val;
int i;
/* Assert resets, stop core */
val = readl(wcss->reg_base + Q6SS_RESET_REG);
val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
writel(val, wcss->reg_base + Q6SS_RESET_REG);
/* BHS require xo cbcr to be enabled */
val = readl(wcss->reg_base + Q6SS_XO_CBCR);
val |= 0x1;
writel(val, wcss->reg_base + Q6SS_XO_CBCR);
/* Read CLKOFF bit to go low indicating CLK is enabled */
ret = readl_poll_timeout(wcss->reg_base + Q6SS_XO_CBCR,
val, !(val & BIT(31)), 1,
HALT_CHECK_MAX_LOOPS);
if (ret) {
dev_err(wcss->dev,
"xo cbcr enabling timed out (rc:%d)\n", ret);
return ret;
}
/* Enable power block headswitch and wait for it to stabilize */
val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG);
val |= Q6SS_BHS_ON;
writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG);
udelay(1);
/* Put LDO in bypass mode */
val |= Q6SS_LDO_BYP;
writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG);
/* Deassert Q6 compiler memory clamp */
val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG);
val &= ~Q6SS_CLAMP_QMC_MEM;
writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG);
/* Deassert memory peripheral sleep and L2 memory standby */
val |= Q6SS_L2DATA_STBY_N | Q6SS_SLP_RET_N;
writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG);
/* Turn on L1, L2, ETB and JU memories 1 at a time */
val = readl(wcss->reg_base + Q6SS_MEM_PWR_CTL);
for (i = MEM_BANKS; i >= 0; i--) {
val |= BIT(i);
writel(val, wcss->reg_base + Q6SS_MEM_PWR_CTL);
/*
* Read back value to ensure the write is done then
* wait for 1us for both memory peripheral and data
* array to turn on.
*/
val |= readl(wcss->reg_base + Q6SS_MEM_PWR_CTL);
udelay(1);
}
/* Remove word line clamp */
val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG);
val &= ~Q6SS_CLAMP_WL;
writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG);
/* Remove IO clamp */
val &= ~Q6SS_CLAMP_IO;
writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG);
/* Bring core out of reset */
val = readl(wcss->reg_base + Q6SS_RESET_REG);
val &= ~Q6SS_CORE_ARES;
writel(val, wcss->reg_base + Q6SS_RESET_REG);
/* Turn on core clock */
val = readl(wcss->reg_base + Q6SS_GFMUX_CTL_REG);
val |= Q6SS_CLK_ENABLE;
writel(val, wcss->reg_base + Q6SS_GFMUX_CTL_REG);
/* Start core execution */
val = readl(wcss->reg_base + Q6SS_RESET_REG);
val &= ~Q6SS_STOP_CORE;
writel(val, wcss->reg_base + Q6SS_RESET_REG);
return 0;
}