diff options
Diffstat (limited to 'drivers/soc/mediatek/mtk-svs.c')
-rw-r--r-- | drivers/soc/mediatek/mtk-svs.c | 87 |
1 files changed, 40 insertions, 47 deletions
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index 517a27c58888..e7df3a577b4c 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -372,7 +372,6 @@ struct svs_fusemap { * @base: svs platform register base * @dev: svs platform device * @main_clk: main clock for svs bank - * @pbank: svs bank pointer needing to be protected by spin_lock section * @banks: svs banks that svs platform supports * @rst: svs platform reset control * @efuse_max: total number of svs efuse @@ -387,7 +386,6 @@ struct svs_platform { void __iomem *base; struct device *dev; struct clk *main_clk; - struct svs_bank *pbank; struct svs_bank *banks; struct reset_control *rst; size_t efuse_max; @@ -483,8 +481,8 @@ struct svs_bank { struct regulator *buck; struct thermal_zone_device *tzd; struct mutex lock; /* lock to protect voltage update process */ - void (*set_freq_pct)(struct svs_platform *svsp); - void (*get_volts)(struct svs_platform *svsp); + void (*set_freq_pct)(struct svs_platform *svsp, struct svs_bank *svsb); + void (*get_volts)(struct svs_platform *svsp, struct svs_bank *svsb); char *name; char *buck_name; char *tzone_name; @@ -555,10 +553,8 @@ static void svs_writel_relaxed(struct svs_platform *svsp, u32 val, writel_relaxed(val, svsp->base + svsp->regs[rg_i]); } -static void svs_switch_bank(struct svs_platform *svsp) +static void svs_switch_bank(struct svs_platform *svsp, struct svs_bank *svsb) { - struct svs_bank *svsb = svsp->pbank; - svs_writel_relaxed(svsp, svsb->core_sel, CORESEL); } @@ -693,8 +689,7 @@ static void svs_bank_disable_and_restore_default_volts(struct svs_platform *svsp return; spin_lock_irqsave(&svs_lock, flags); - svsp->pbank = svsb; - svs_switch_bank(svsp); + svs_switch_bank(svsp, svsb); svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN); svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS); spin_unlock_irqrestore(&svs_lock, flags); @@ -926,9 +921,8 @@ static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx) return DIV_ROUND_UP(vx, 100); } -static void svs_get_bank_volts_v3(struct svs_platform *svsp) +static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *svsb) { - struct svs_bank *svsb = svsp->pbank; u32 i, j, *vop, vop74, vop30, turn_pt = svsb->turn_pt; u32 b_sft, shift_byte = 0, opp_start = 0, opp_stop = 0; u32 middle_index = (svsb->opp_count / 2); @@ -1041,9 +1035,8 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp) } } -static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp) +static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp, struct svs_bank *svsb) { - struct svs_bank *svsb = svsp->pbank; u32 i, j, *freq_pct, freq_pct74 = 0, freq_pct30 = 0; u32 b_sft, shift_byte = 0, turn_pt; u32 middle_index = (svsb->opp_count / 2); @@ -1124,9 +1117,8 @@ static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp) svs_writel_relaxed(svsp, freq_pct30, FREQPCT30); } -static void svs_get_bank_volts_v2(struct svs_platform *svsp) +static void svs_get_bank_volts_v2(struct svs_platform *svsp, struct svs_bank *svsb) { - struct svs_bank *svsb = svsp->pbank; u32 temp, i; temp = svs_readl_relaxed(svsp, VOP74); @@ -1181,9 +1173,8 @@ static void svs_get_bank_volts_v2(struct svs_platform *svsp) } } -static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp) +static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp, struct svs_bank *svsb) { - struct svs_bank *svsb = svsp->pbank; u32 freqpct74_val, freqpct30_val; freqpct74_val = FIELD_PREP(SVSB_FREQPCTS_FLD_PCT0_4, svsb->freq_pct[8]) | @@ -1201,12 +1192,13 @@ static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp) } static void svs_set_bank_phase(struct svs_platform *svsp, + unsigned int bank_idx, enum svsb_phase target_phase) { - struct svs_bank *svsb = svsp->pbank; + struct svs_bank *svsb = &svsp->banks[bank_idx]; u32 des_char, temp_char, det_char, limit_vals, init2vals, ts_calcs; - svs_switch_bank(svsp); + svs_switch_bank(svsp, svsb); des_char = FIELD_PREP(SVSB_DESCHAR_FLD_BDES, svsb->bdes) | FIELD_PREP(SVSB_DESCHAR_FLD_MDES, svsb->mdes); @@ -1225,7 +1217,7 @@ static void svs_set_bank_phase(struct svs_platform *svsp, svs_writel_relaxed(svsp, svsb->age_config, AGECONFIG); svs_writel_relaxed(svsp, SVSB_RUNCONFIG_DEFAULT, RUNCONFIG); - svsb->set_freq_pct(svsp); + svsb->set_freq_pct(svsp, svsb); limit_vals = FIELD_PREP(SVSB_LIMITVALS_FLD_DTLO, SVSB_VAL_DTLO) | FIELD_PREP(SVSB_LIMITVALS_FLD_DTHI, SVSB_VAL_DTHI) | @@ -1267,18 +1259,20 @@ static void svs_set_bank_phase(struct svs_platform *svsp, } static inline void svs_save_bank_register_data(struct svs_platform *svsp, + unsigned short bank_idx, enum svsb_phase phase) { - struct svs_bank *svsb = svsp->pbank; + struct svs_bank *svsb = &svsp->banks[bank_idx]; enum svs_reg_index rg_i; for (rg_i = DESCHAR; rg_i < SVS_REG_MAX; rg_i++) svsb->reg_data[phase][rg_i] = svs_readl_relaxed(svsp, rg_i); } -static inline void svs_error_isr_handler(struct svs_platform *svsp) +static inline void svs_error_isr_handler(struct svs_platform *svsp, + unsigned short bank_idx) { - struct svs_bank *svsb = svsp->pbank; + struct svs_bank *svsb = &svsp->banks[bank_idx]; dev_err(svsb->dev, "%s: CORESEL = 0x%08x\n", __func__, svs_readl_relaxed(svsp, CORESEL)); @@ -1290,16 +1284,17 @@ static inline void svs_error_isr_handler(struct svs_platform *svsp) svs_readl_relaxed(svsp, SMSTATE1)); dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl_relaxed(svsp, TEMP)); - svs_save_bank_register_data(svsp, SVSB_PHASE_ERROR); + svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_ERROR); svsb->phase = SVSB_PHASE_ERROR; svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN); svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS); } -static inline void svs_init01_isr_handler(struct svs_platform *svsp) +static inline void svs_init01_isr_handler(struct svs_platform *svsp, + unsigned short bank_idx) { - struct svs_bank *svsb = svsp->pbank; + struct svs_bank *svsb = &svsp->banks[bank_idx]; u32 val; dev_info(svsb->dev, "%s: VDN74~30:0x%08x~0x%08x, DC:0x%08x\n", @@ -1307,7 +1302,7 @@ static inline void svs_init01_isr_handler(struct svs_platform *svsp) svs_readl_relaxed(svsp, VDESIGN30), svs_readl_relaxed(svsp, DCVALUES)); - svs_save_bank_register_data(svsp, SVSB_PHASE_INIT01); + svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_INIT01); svsb->phase = SVSB_PHASE_INIT01; val = ~(svs_readl_relaxed(svsp, DCVALUES) & GENMASK(15, 0)) + 1; @@ -1325,32 +1320,34 @@ static inline void svs_init01_isr_handler(struct svs_platform *svsp) svsb->core_sel &= ~SVSB_DET_CLK_EN; } -static inline void svs_init02_isr_handler(struct svs_platform *svsp) +static inline void svs_init02_isr_handler(struct svs_platform *svsp, + unsigned short bank_idx) { - struct svs_bank *svsb = svsp->pbank; + struct svs_bank *svsb = &svsp->banks[bank_idx]; dev_info(svsb->dev, "%s: VOP74~30:0x%08x~0x%08x, DC:0x%08x\n", __func__, svs_readl_relaxed(svsp, VOP74), svs_readl_relaxed(svsp, VOP30), svs_readl_relaxed(svsp, DCVALUES)); - svs_save_bank_register_data(svsp, SVSB_PHASE_INIT02); + svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_INIT02); svsb->phase = SVSB_PHASE_INIT02; - svsb->get_volts(svsp); + svsb->get_volts(svsp, svsb); svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN); svs_writel_relaxed(svsp, SVSB_INTSTS_F0_COMPLETE, INTSTS); } -static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp) +static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp, + unsigned short bank_idx) { - struct svs_bank *svsb = svsp->pbank; + struct svs_bank *svsb = &svsp->banks[bank_idx]; - svs_save_bank_register_data(svsp, SVSB_PHASE_MON); + svs_save_bank_register_data(svsp, bank_idx, SVSB_PHASE_MON); svsb->phase = SVSB_PHASE_MON; - svsb->get_volts(svsp); + svsb->get_volts(svsp, svsb); svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0); svs_writel_relaxed(svsp, SVSB_INTSTS_FLD_MONVOP, INTSTS); @@ -1368,7 +1365,6 @@ static irqreturn_t svs_isr(int irq, void *data) WARN(!svsb, "%s: svsb(%s) is null", __func__, svsb->name); spin_lock_irqsave(&svs_lock, flags); - svsp->pbank = svsb; /* Find out which svs bank fires interrupt */ if (svsb->int_st & svs_readl_relaxed(svsp, INTST)) { @@ -1376,20 +1372,20 @@ static irqreturn_t svs_isr(int irq, void *data) continue; } - svs_switch_bank(svsp); + svs_switch_bank(svsp, svsb); int_sts = svs_readl_relaxed(svsp, INTSTS); svs_en = svs_readl_relaxed(svsp, SVSEN); if (int_sts == SVSB_INTSTS_F0_COMPLETE && svs_en == SVSB_PTPEN_INIT01) - svs_init01_isr_handler(svsp); + svs_init01_isr_handler(svsp, idx); else if (int_sts == SVSB_INTSTS_F0_COMPLETE && svs_en == SVSB_PTPEN_INIT02) - svs_init02_isr_handler(svsp); + svs_init02_isr_handler(svsp, idx); else if (int_sts & SVSB_INTSTS_FLD_MONVOP) - svs_mon_mode_isr_handler(svsp); + svs_mon_mode_isr_handler(svsp, idx); else - svs_error_isr_handler(svsp); + svs_error_isr_handler(svsp, idx); spin_unlock_irqrestore(&svs_lock, flags); break; @@ -1518,8 +1514,7 @@ static int svs_init01(struct svs_platform *svsp) } spin_lock_irqsave(&svs_lock, flags); - svsp->pbank = svsb; - svs_set_bank_phase(svsp, SVSB_PHASE_INIT01); + svs_set_bank_phase(svsp, idx, SVSB_PHASE_INIT01); spin_unlock_irqrestore(&svs_lock, flags); time_left = wait_for_completion_timeout(&svsb->init_completion, @@ -1588,8 +1583,7 @@ static int svs_init02(struct svs_platform *svsp) reinit_completion(&svsb->init_completion); spin_lock_irqsave(&svs_lock, flags); - svsp->pbank = svsb; - svs_set_bank_phase(svsp, SVSB_PHASE_INIT02); + svs_set_bank_phase(svsp, idx, SVSB_PHASE_INIT02); spin_unlock_irqrestore(&svs_lock, flags); time_left = wait_for_completion_timeout(&svsb->init_completion, @@ -1645,8 +1639,7 @@ static void svs_mon_mode(struct svs_platform *svsp) continue; spin_lock_irqsave(&svs_lock, flags); - svsp->pbank = svsb; - svs_set_bank_phase(svsp, SVSB_PHASE_MON); + svs_set_bank_phase(svsp, idx, SVSB_PHASE_MON); spin_unlock_irqrestore(&svs_lock, flags); } } |