clk: renesas: cpg-mssr: Add register pointers into struct cpg_mssr_priv

To support other register layouts in the future, add register pointers
of {control,status,reset,reset_clear}_regs into struct cpg_mssr_priv.
After that, we can remove unused macros like MSTPSR().  No behavioral
changes.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Link: https://lore.kernel.org/r/1599810232-29035-3-git-send-email-yoshihiro.shimoda.uh@renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
This commit is contained in:
Yoshihiro Shimoda 2020-09-11 16:43:50 +09:00 committed by Geert Uytterhoeven
parent ffbf9cf3f9
commit 8b652aa8a1
1 changed files with 47 additions and 35 deletions

View File

@ -57,9 +57,6 @@ static const u16 mstpsr[] = {
0x9A0, 0x9A4, 0x9A8, 0x9AC,
};
#define MSTPSR(i) mstpsr[i]
/*
* System Module Stop Control Register offsets
*/
@ -69,8 +66,6 @@ static const u16 smstpcr[] = {
0x990, 0x994, 0x998, 0x99C,
};
#define SMSTPCR(i) smstpcr[i]
/*
* Standby Control Register offsets (RZ/A)
* Base address is FRQCR register
@ -81,8 +76,6 @@ static const u16 stbcr[] = {
0x424, 0x428, 0x42C,
};
#define STBCR(i) stbcr[i]
/*
* Software Reset Register offsets
*/
@ -92,9 +85,6 @@ static const u16 srcr[] = {
0x920, 0x924, 0x928, 0x92C,
};
#define SRCR(i) srcr[i]
/* Realtime Module Stop Control Register offsets */
#define RMSTPCR(i) (smstpcr[i] - 0x20)
@ -102,8 +92,11 @@ static const u16 srcr[] = {
#define MMSTPCR(i) (smstpcr[i] + 0x20)
/* Software Reset Clearing Register offsets */
#define SRSTCLR(i) (0x940 + (i) * 4)
static const u16 srstclr[] = {
0x940, 0x944, 0x948, 0x94C, 0x950, 0x954, 0x958, 0x95C,
0x960, 0x964, 0x968, 0x96C,
};
/**
* Clock Pulse Generator / Module Standby and Software Reset Private Data
@ -118,6 +111,10 @@ static const u16 srcr[] = {
* @num_mod_clks: Number of Module Clocks in clks[]
* @last_dt_core_clk: ID of the last Core Clock exported to DT
* @notifiers: Notifier chain to save/restore clock state for system resume
* @status_regs: Pointer to status registers array
* @control_regs: Pointer to control registers array
* @reset_regs: Pointer to reset registers array
* @reset_clear_regs: Pointer to reset clearing registers array
* @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control
* @smstpcr_saved[].val: Saved values of SMSTPCR[]
* @clks: Array containing all Core and Module Clocks
@ -137,6 +134,10 @@ struct cpg_mssr_priv {
unsigned int last_dt_core_clk;
struct raw_notifier_head notifiers;
const u16 *status_regs;
const u16 *control_regs;
const u16 *reset_regs;
const u16 *reset_clear_regs;
struct {
u32 mask;
u32 val;
@ -178,23 +179,23 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
spin_lock_irqsave(&priv->rmw_lock, flags);
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
value = readb(priv->base + STBCR(reg));
value = readb(priv->base + priv->control_regs[reg]);
if (enable)
value &= ~bitmask;
else
value |= bitmask;
writeb(value, priv->base + STBCR(reg));
writeb(value, priv->base + priv->control_regs[reg]);
/* dummy read to ensure write has completed */
readb(priv->base + STBCR(reg));
barrier_data(priv->base + STBCR(reg));
readb(priv->base + priv->control_regs[reg]);
barrier_data(priv->base + priv->control_regs[reg]);
} else {
value = readl(priv->base + SMSTPCR(reg));
value = readl(priv->base + priv->control_regs[reg]);
if (enable)
value &= ~bitmask;
else
value |= bitmask;
writel(value, priv->base + SMSTPCR(reg));
writel(value, priv->base + priv->control_regs[reg]);
}
spin_unlock_irqrestore(&priv->rmw_lock, flags);
@ -203,14 +204,14 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
return 0;
for (i = 1000; i > 0; --i) {
if (!(readl(priv->base + MSTPSR(reg)) & bitmask))
if (!(readl(priv->base + priv->status_regs[reg]) & bitmask))
break;
cpu_relax();
}
if (!i) {
dev_err(dev, "Failed to enable SMSTP %p[%d]\n",
priv->base + SMSTPCR(reg), bit);
priv->base + priv->control_regs[reg], bit);
return -ETIMEDOUT;
}
@ -234,9 +235,9 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
u32 value;
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
value = readb(priv->base + STBCR(clock->index / 32));
value = readb(priv->base + priv->control_regs[clock->index / 32]);
else
value = readl(priv->base + MSTPSR(clock->index / 32));
value = readl(priv->base + priv->status_regs[clock->index / 32]);
return !(value & BIT(clock->index % 32));
}
@ -578,13 +579,13 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
/* Reset module */
writel(bitmask, priv->base + SRCR(reg));
writel(bitmask, priv->base + priv->reset_regs[reg]);
/* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
udelay(35);
/* Release module from reset state */
writel(bitmask, priv->base + SRSTCLR(reg));
writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
return 0;
}
@ -598,7 +599,7 @@ static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
writel(bitmask, priv->base + SRCR(reg));
writel(bitmask, priv->base + priv->reset_regs[reg]);
return 0;
}
@ -612,7 +613,7 @@ static int cpg_mssr_deassert(struct reset_controller_dev *rcdev,
dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
writel(bitmask, priv->base + SRSTCLR(reg));
writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
return 0;
}
@ -624,7 +625,7 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev,
unsigned int bit = id % 32;
u32 bitmask = BIT(bit);
return !!(readl(priv->base + SRCR(reg)) & bitmask);
return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask);
}
static const struct reset_control_ops cpg_mssr_reset_ops = {
@ -827,8 +828,8 @@ static int cpg_mssr_suspend_noirq(struct device *dev)
if (priv->smstpcr_saved[reg].mask)
priv->smstpcr_saved[reg].val =
priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
readb(priv->base + STBCR(reg)) :
readl(priv->base + SMSTPCR(reg));
readb(priv->base + priv->control_regs[reg]) :
readl(priv->base + priv->control_regs[reg]);
}
/* Save core clocks */
@ -857,22 +858,22 @@ static int cpg_mssr_resume_noirq(struct device *dev)
continue;
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
oldval = readb(priv->base + STBCR(reg));
oldval = readb(priv->base + priv->control_regs[reg]);
else
oldval = readl(priv->base + SMSTPCR(reg));
oldval = readl(priv->base + priv->control_regs[reg]);
newval = oldval & ~mask;
newval |= priv->smstpcr_saved[reg].val & mask;
if (newval == oldval)
continue;
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
writeb(newval, priv->base + STBCR(reg));
writeb(newval, priv->base + priv->control_regs[reg]);
/* dummy read to ensure write has completed */
readb(priv->base + STBCR(reg));
barrier_data(priv->base + STBCR(reg));
readb(priv->base + priv->control_regs[reg]);
barrier_data(priv->base + priv->control_regs[reg]);
continue;
} else
writel(newval, priv->base + SMSTPCR(reg));
writel(newval, priv->base + priv->control_regs[reg]);
/* Wait until enabled clocks are really enabled */
mask &= ~priv->smstpcr_saved[reg].val;
@ -880,7 +881,7 @@ static int cpg_mssr_resume_noirq(struct device *dev)
continue;
for (i = 1000; i > 0; --i) {
oldval = readl(priv->base + MSTPSR(reg));
oldval = readl(priv->base + priv->status_regs[reg]);
if (!(oldval & mask))
break;
cpu_relax();
@ -939,6 +940,17 @@ static int __init cpg_mssr_common_init(struct device *dev,
priv->last_dt_core_clk = info->last_dt_core_clk;
RAW_INIT_NOTIFIER_HEAD(&priv->notifiers);
priv->reg_layout = info->reg_layout;
if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
priv->status_regs = mstpsr;
priv->control_regs = smstpcr;
priv->reset_regs = srcr;
priv->reset_clear_regs = srstclr;
} else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
priv->control_regs = stbcr;
} else {
error = -EINVAL;
goto out_err;
}
for (i = 0; i < nclks; i++)
priv->clks[i] = ERR_PTR(-ENOENT);