From f294a0ea9d12a658ff326bbe0d64137659bc2fc9 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 28 Sep 2021 14:01:32 +0100 Subject: clk: renesas: r9a07g044: Add clock and reset entries for SPI Multi I/O Bus Controller Add clock and reset entries for SPI Multi I/O Bus Controller. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210928130132.15022-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 18 ++++++++++++++++++ drivers/clk/renesas/rzg2l-cpg.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 3c518b56c5a6..1e331cdb13a5 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -29,10 +29,14 @@ enum clk_ids { CLK_PLL2_DIV16, CLK_PLL2_DIV20, CLK_PLL3, + CLK_PLL3_400, + CLK_PLL3_533, CLK_PLL3_DIV2, CLK_PLL3_DIV2_4, CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV4, + CLK_SEL_PLL3_3, + CLK_DIV_PLL3_C, CLK_PLL4, CLK_PLL5, CLK_PLL5_FOUT3, @@ -56,6 +60,7 @@ static const struct clk_div_table dtable_1_32[] = { }; /* Mux clock tables */ +static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" }; static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" }; static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { @@ -68,6 +73,8 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, PLL146_CONF(0)), DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 133, 2), DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 133, 2), + DEF_FIXED(".pll3_400", CLK_PLL3_400, CLK_PLL3, 1, 4), + DEF_FIXED(".pll3_533", CLK_PLL3_533, CLK_PLL3, 1, 3), DEF_FIXED(".pll5", CLK_PLL5, CLK_EXTAL, 125, 1), DEF_FIXED(".pll5_fout3", CLK_PLL5_FOUT3, CLK_PLL5, 1, 6), @@ -82,6 +89,10 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4), DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2), DEF_FIXED(".pll3_div4", CLK_PLL3_DIV4, CLK_PLL3, 1, 4), + DEF_MUX(".sel_pll3_3", CLK_SEL_PLL3_3, SEL_PLL3_3, + sel_pll3_3, ARRAY_SIZE(sel_pll3_3), 0, CLK_MUX_READ_ONLY), + DEF_DIV("divpl3c", CLK_DIV_PLL3_C, CLK_SEL_PLL3_3, + DIVPL3C, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), DEF_FIXED(".pll5_250", CLK_PLL5_250, CLK_PLL5_FOUT3, 1, 2), DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2), @@ -101,6 +112,8 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { DEF_FIXED("ZT", R9A07G044_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1), DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2, sel_pll6_2, ARRAY_SIZE(sel_pll6_2), 0, CLK_MUX_HIWORD_MASK), + DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2), + DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4), }; static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { @@ -114,6 +127,10 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x52c, 0), DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2, 0x52c, 1), + DEF_MOD("spi_clk2", R9A07G044_SPI_CLK2, R9A07G044_CLK_SPI1, + 0x550, 0), + DEF_MOD("spi_clk", R9A07G044_SPI_CLK, R9A07G044_CLK_SPI0, + 0x550, 1), DEF_MOD("ssi0_pclk", R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0, 0x570, 0), DEF_MOD("ssi0_sfr", R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0, @@ -182,6 +199,7 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0), DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1), + DEF_RST(R9A07G044_SPI_RST, 0x850, 0), DEF_RST(R9A07G044_SSI0_RST_M2_REG, 0x870, 0), DEF_RST(R9A07G044_SSI1_RST_M2_REG, 0x870, 1), DEF_RST(R9A07G044_SSI2_RST_M2_REG, 0x870, 2), diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h index 191c403aa52f..dc5b65a4029e 100644 --- a/drivers/clk/renesas/rzg2l-cpg.h +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -11,6 +11,7 @@ #define CPG_PL2_DDIV (0x204) #define CPG_PL3A_DDIV (0x208) +#define CPG_PL3_SSEL (0x408) #define CPG_PL6_ETH_SSEL (0x418) /* n = 0/1/2 for PLL1/4/6 */ @@ -24,10 +25,12 @@ #define DIVPL2A DDIV_PACK(CPG_PL2_DDIV, 0, 3) #define DIVPL3A DDIV_PACK(CPG_PL3A_DDIV, 0, 3) #define DIVPL3B DDIV_PACK(CPG_PL3A_DDIV, 4, 3) +#define DIVPL3C DDIV_PACK(CPG_PL3A_DDIV, 8, 3) #define SEL_PLL_PACK(offset, bitpos, size) \ (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) +#define SEL_PLL3_3 SEL_PLL_PACK(CPG_PL3_SSEL, 8, 1) #define SEL_PLL6_2 SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1) /** -- cgit From 6f21d145b90f3f5769eb6615af601a973e365a64 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 6 Oct 2021 10:58:33 +0200 Subject: clk: renesas: cpg-lib: Move RPC clock registration to the library We want to reuse this code for V3U soon. Because its RPCCKCR register is at a different offset, the moved functions do not use the base register as an argument anymore but the RPCCKCR register itself. Verified that an Eagle board with R-Car V3M still works. Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20211006085836.42155-2-wsa+renesas@sang-engineering.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rcar-cpg-lib.c | 83 ++++++++++++++++++++++++++++++++++ drivers/clk/renesas/rcar-cpg-lib.h | 7 +++ drivers/clk/renesas/rcar-gen3-cpg.c | 89 +------------------------------------ 3 files changed, 92 insertions(+), 87 deletions(-) diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c index 5678768ee1f2..e93f0011eb07 100644 --- a/drivers/clk/renesas/rcar-cpg-lib.c +++ b/drivers/clk/renesas/rcar-cpg-lib.c @@ -267,4 +267,87 @@ free_clock: return clk; } +struct rpc_clock { + struct clk_divider div; + struct clk_gate gate; + /* + * One notifier covers both RPC and RPCD2 clocks as they are both + * controlled by the same RPCCKCR register... + */ + struct cpg_simple_notifier csn; +}; + +static const struct clk_div_table cpg_rpc_div_table[] = { + { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 }, +}; + +struct clk * __init cpg_rpc_clk_register(const char *name, + void __iomem *rpcckcr, const char *parent_name, + struct raw_notifier_head *notifiers) +{ + struct rpc_clock *rpc; + struct clk *clk; + + rpc = kzalloc(sizeof(*rpc), GFP_KERNEL); + if (!rpc) + return ERR_PTR(-ENOMEM); + + rpc->div.reg = rpcckcr; + rpc->div.width = 3; + rpc->div.table = cpg_rpc_div_table; + rpc->div.lock = &cpg_lock; + + rpc->gate.reg = rpcckcr; + rpc->gate.bit_idx = 8; + rpc->gate.flags = CLK_GATE_SET_TO_DISABLE; + rpc->gate.lock = &cpg_lock; + + rpc->csn.reg = rpcckcr; + + clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, + &rpc->div.hw, &clk_divider_ops, + &rpc->gate.hw, &clk_gate_ops, + CLK_SET_RATE_PARENT); + if (IS_ERR(clk)) { + kfree(rpc); + return clk; + } + + cpg_simple_notifier_register(notifiers, &rpc->csn); + return clk; +} + +struct rpcd2_clock { + struct clk_fixed_factor fixed; + struct clk_gate gate; +}; + +struct clk * __init cpg_rpcd2_clk_register(const char *name, + void __iomem *rpcckcr, + const char *parent_name) +{ + struct rpcd2_clock *rpcd2; + struct clk *clk; + + rpcd2 = kzalloc(sizeof(*rpcd2), GFP_KERNEL); + if (!rpcd2) + return ERR_PTR(-ENOMEM); + + rpcd2->fixed.mult = 1; + rpcd2->fixed.div = 2; + + rpcd2->gate.reg = rpcckcr; + rpcd2->gate.bit_idx = 9; + rpcd2->gate.flags = CLK_GATE_SET_TO_DISABLE; + rpcd2->gate.lock = &cpg_lock; + + clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, + &rpcd2->fixed.hw, &clk_fixed_factor_ops, + &rpcd2->gate.hw, &clk_gate_ops, + CLK_SET_RATE_PARENT); + if (IS_ERR(clk)) + kfree(rpcd2); + + return clk; +} diff --git a/drivers/clk/renesas/rcar-cpg-lib.h b/drivers/clk/renesas/rcar-cpg-lib.h index d00c91b116ca..35c0217c2f8b 100644 --- a/drivers/clk/renesas/rcar-cpg-lib.h +++ b/drivers/clk/renesas/rcar-cpg-lib.h @@ -30,4 +30,11 @@ struct clk * __init cpg_sd_clk_register(const char *name, void __iomem *base, unsigned int offset, const char *parent_name, struct raw_notifier_head *notifiers, bool skip_first); +struct clk * __init cpg_rpc_clk_register(const char *name, + void __iomem *rpcckcr, const char *parent_name, + struct raw_notifier_head *notifiers); + +struct clk * __init cpg_rpcd2_clk_register(const char *name, + void __iomem *rpcckcr, + const char *parent_name); #endif diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 558191c99b48..741f6e74bbcf 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -301,95 +301,10 @@ static struct clk * __init cpg_z_clk_register(const char *name, return clk; } -struct rpc_clock { - struct clk_divider div; - struct clk_gate gate; - /* - * One notifier covers both RPC and RPCD2 clocks as they are both - * controlled by the same RPCCKCR register... - */ - struct cpg_simple_notifier csn; -}; - static const struct clk_div_table cpg_rpcsrc_div_table[] = { { 2, 5 }, { 3, 6 }, { 0, 0 }, }; -static const struct clk_div_table cpg_rpc_div_table[] = { - { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 }, -}; - -static struct clk * __init cpg_rpc_clk_register(const char *name, - void __iomem *base, const char *parent_name, - struct raw_notifier_head *notifiers) -{ - struct rpc_clock *rpc; - struct clk *clk; - - rpc = kzalloc(sizeof(*rpc), GFP_KERNEL); - if (!rpc) - return ERR_PTR(-ENOMEM); - - rpc->div.reg = base + CPG_RPCCKCR; - rpc->div.width = 3; - rpc->div.table = cpg_rpc_div_table; - rpc->div.lock = &cpg_lock; - - rpc->gate.reg = base + CPG_RPCCKCR; - rpc->gate.bit_idx = 8; - rpc->gate.flags = CLK_GATE_SET_TO_DISABLE; - rpc->gate.lock = &cpg_lock; - - rpc->csn.reg = base + CPG_RPCCKCR; - - clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, - &rpc->div.hw, &clk_divider_ops, - &rpc->gate.hw, &clk_gate_ops, - CLK_SET_RATE_PARENT); - if (IS_ERR(clk)) { - kfree(rpc); - return clk; - } - - cpg_simple_notifier_register(notifiers, &rpc->csn); - return clk; -} - -struct rpcd2_clock { - struct clk_fixed_factor fixed; - struct clk_gate gate; -}; - -static struct clk * __init cpg_rpcd2_clk_register(const char *name, - void __iomem *base, - const char *parent_name) -{ - struct rpcd2_clock *rpcd2; - struct clk *clk; - - rpcd2 = kzalloc(sizeof(*rpcd2), GFP_KERNEL); - if (!rpcd2) - return ERR_PTR(-ENOMEM); - - rpcd2->fixed.mult = 1; - rpcd2->fixed.div = 2; - - rpcd2->gate.reg = base + CPG_RPCCKCR; - rpcd2->gate.bit_idx = 9; - rpcd2->gate.flags = CLK_GATE_SET_TO_DISABLE; - rpcd2->gate.lock = &cpg_lock; - - clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, - &rpcd2->fixed.hw, &clk_fixed_factor_ops, - &rpcd2->gate.hw, &clk_gate_ops, - CLK_SET_RATE_PARENT); - if (IS_ERR(clk)) - kfree(rpcd2); - - return clk; -} - - static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata; static unsigned int cpg_clk_extalr __initdata; static u32 cpg_mode __initdata; @@ -600,11 +515,11 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, break; case CLK_TYPE_GEN3_RPC: - return cpg_rpc_clk_register(core->name, base, + return cpg_rpc_clk_register(core->name, base + CPG_RPCCKCR, __clk_get_name(parent), notifiers); case CLK_TYPE_GEN3_RPCD2: - return cpg_rpcd2_clk_register(core->name, base, + return cpg_rpcd2_clk_register(core->name, base + CPG_RPCCKCR, __clk_get_name(parent)); default: -- cgit From 27c9d7635d23416f5e791508882f34157dde23f5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 6 Oct 2021 10:58:34 +0200 Subject: clk: renesas: r8a779a0: Add RPC support Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20211006085836.42155-3-wsa+renesas@sang-engineering.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a779a0-cpg-mssr.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index 1ced31b6dbe8..fbd7454f2beb 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -37,6 +37,9 @@ enum rcar_r8a779a0_clk_types { CLK_TYPE_R8A779A0_SD, CLK_TYPE_R8A779A0_MDSEL, /* Select parent/divider using mode pin */ CLK_TYPE_R8A779A0_OSC, /* OSC EXTAL predivider and fixed divider */ + CLK_TYPE_R8A779A0_RPCSRC, + CLK_TYPE_R8A779A0_RPC, + CLK_TYPE_R8A779A0_RPCD2, }; struct rcar_r8a779a0_cpg_pll_config { @@ -125,6 +128,10 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 4, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL5_DIV4, 1, 1), DEF_RATE(".oco", CLK_OCO, 32768), + DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_R8A779A0_RPCSRC, CLK_PLL5), + DEF_BASE("rpc", R8A779A0_CLK_RPC, CLK_TYPE_R8A779A0_RPC, CLK_RPCSRC), + DEF_BASE("rpcd2", R8A779A0_CLK_RPCD2, CLK_TYPE_R8A779A0_RPCD2, + R8A779A0_CLK_RPC), /* Core Clock Outputs */ DEF_Z("z0", R8A779A0_CLK_Z0, CLK_PLL20, 2, 0), @@ -200,6 +207,7 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { DEF_MOD("msi3", 621, R8A779A0_CLK_MSO), DEF_MOD("msi4", 622, R8A779A0_CLK_MSO), DEF_MOD("msi5", 623, R8A779A0_CLK_MSO), + DEF_MOD("rpc-if", 629, R8A779A0_CLK_RPCD2), DEF_MOD("scif0", 702, R8A779A0_CLK_S1D8), DEF_MOD("scif1", 703, R8A779A0_CLK_S1D8), DEF_MOD("scif3", 704, R8A779A0_CLK_S1D8), @@ -414,6 +422,15 @@ static struct clk * __init cpg_z_clk_register(const char *name, return clk; } +/* + * RPC Clocks + */ +#define CPG_RPCCKCR 0x874 + +static const struct clk_div_table cpg_rpcsrc_div_table[] = { + { 0, 4 }, { 1, 6 }, { 2, 5 }, { 3, 6 }, { 0, 0 }, +}; + static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, struct clk **clks, void __iomem *base, @@ -481,6 +498,21 @@ static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev, div = cpg_pll_config->osc_prediv * core->div; break; + case CLK_TYPE_R8A779A0_RPCSRC: + return clk_register_divider_table(NULL, core->name, + __clk_get_name(parent), 0, + base + CPG_RPCCKCR, 3, 2, 0, + cpg_rpcsrc_div_table, + &cpg_lock); + + case CLK_TYPE_R8A779A0_RPC: + return cpg_rpc_clk_register(core->name, base + CPG_RPCCKCR, + __clk_get_name(parent), notifiers); + + case CLK_TYPE_R8A779A0_RPCD2: + return cpg_rpcd2_clk_register(core->name, base + CPG_RPCCKCR, + __clk_get_name(parent)); + default: return ERR_PTR(-EINVAL); } -- cgit From eaff33646f4cb6a541d01013b0a222f03f6dfac3 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 7 Oct 2021 12:14:33 +0100 Subject: clk: renesas: rzg2l: Add SDHI clk mux support Add SDHI clk mux support to select SDHI clock from different clock sources. As per HW manual, direct clock switching from 533MHz to 400MHz and vice versa is not recommended. So added support for handling this in mux. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/20211007111434.8665-2-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/rzg2l-cpg.c | 118 ++++++++++++++++++++++++++++++++++++++++ drivers/clk/renesas/rzg2l-cpg.h | 12 ++++ 2 files changed, 130 insertions(+) diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 1501547a11a3..4021f6cabda4 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,14 @@ #define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff) #define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff) +struct sd_hw_data { + struct clk_hw hw; + u32 conf; + struct rzg2l_cpg_priv *priv; +}; + +#define to_sd_hw_data(_hw) container_of(_hw, struct sd_hw_data, hw) + /** * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data * @@ -150,6 +159,112 @@ rzg2l_cpg_mux_clk_register(const struct cpg_core_clk *core, return clk_hw->clk; } +static int rzg2l_cpg_sd_clk_mux_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + return clk_mux_determine_rate_flags(hw, req, 0); +} + +static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct sd_hw_data *hwdata = to_sd_hw_data(hw); + struct rzg2l_cpg_priv *priv = hwdata->priv; + u32 off = GET_REG_OFFSET(hwdata->conf); + u32 shift = GET_SHIFT(hwdata->conf); + const u32 clk_src_266 = 2; + u32 bitmask; + + /* + * As per the HW manual, we should not directly switch from 533 MHz to + * 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz) + * to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first, + * and then switch to the target setting (2’b01 (533 MHz) or 2’b10 + * (400 MHz)). + * Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock + * switching register is prohibited. + * The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and + * the index to value mapping is done by adding 1 to the index. + */ + bitmask = (GENMASK(GET_WIDTH(hwdata->conf) - 1, 0) << shift) << 16; + if (index != clk_src_266) { + u32 msk, val; + int ret; + + writel(bitmask | ((clk_src_266 + 1) << shift), priv->base + off); + + msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS; + + ret = readl_poll_timeout(priv->base + CPG_CLKSTATUS, val, + !(val & msk), 100, + CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); + if (ret) { + dev_err(priv->dev, "failed to switch clk source\n"); + return ret; + } + } + + writel(bitmask | ((index + 1) << shift), priv->base + off); + + return 0; +} + +static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw) +{ + struct sd_hw_data *hwdata = to_sd_hw_data(hw); + struct rzg2l_cpg_priv *priv = hwdata->priv; + u32 val = readl(priv->base + GET_REG_OFFSET(hwdata->conf)); + + val >>= GET_SHIFT(hwdata->conf); + val &= GENMASK(GET_WIDTH(hwdata->conf) - 1, 0); + if (val) { + val--; + } else { + /* Prohibited clk source, change it to 533 MHz(reset value) */ + rzg2l_cpg_sd_clk_mux_set_parent(hw, 0); + } + + return val; +} + +static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = { + .determine_rate = rzg2l_cpg_sd_clk_mux_determine_rate, + .set_parent = rzg2l_cpg_sd_clk_mux_set_parent, + .get_parent = rzg2l_cpg_sd_clk_mux_get_parent, +}; + +static struct clk * __init +rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core, + void __iomem *base, + struct rzg2l_cpg_priv *priv) +{ + struct sd_hw_data *clk_hw_data; + struct clk_init_data init; + struct clk_hw *clk_hw; + int ret; + + clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); + if (!clk_hw_data) + return ERR_PTR(-ENOMEM); + + clk_hw_data->priv = priv; + clk_hw_data->conf = core->conf; + + init.name = GET_SHIFT(core->conf) ? "sd1" : "sd0"; + init.ops = &rzg2l_cpg_sd_clk_mux_ops; + init.flags = 0; + init.num_parents = core->num_parents; + init.parent_names = core->parent_names; + + clk_hw = &clk_hw_data->hw; + clk_hw->init = &init; + + ret = devm_clk_hw_register(priv->dev, clk_hw); + if (ret) + return ERR_PTR(ret); + + return clk_hw->clk; +} + struct pll_clk { struct clk_hw hw; unsigned int conf; @@ -311,6 +426,9 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, case CLK_TYPE_MUX: clk = rzg2l_cpg_mux_clk_register(core, priv->base, priv); break; + case CLK_TYPE_SD_MUX: + clk = rzg2l_cpg_sd_mux_clk_register(core, priv->base, priv); + break; default: goto fail; } diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h index dc5b65a4029e..952fca98ba71 100644 --- a/drivers/clk/renesas/rzg2l-cpg.h +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -11,9 +11,15 @@ #define CPG_PL2_DDIV (0x204) #define CPG_PL3A_DDIV (0x208) +#define CPG_CLKSTATUS (0x280) #define CPG_PL3_SSEL (0x408) #define CPG_PL6_ETH_SSEL (0x418) +#define CPG_CLKSTATUS_SELSDHI0_STS BIT(28) +#define CPG_CLKSTATUS_SELSDHI1_STS BIT(29) + +#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 20000 + /* n = 0/1/2 for PLL1/4/6 */ #define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n)) #define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n)) @@ -67,6 +73,9 @@ enum clk_types { /* Clock with clock source selector */ CLK_TYPE_MUX, + + /* Clock with SD clock source selector */ + CLK_TYPE_SD_MUX, }; #define DEF_TYPE(_name, _id, _type...) \ @@ -87,6 +96,9 @@ enum clk_types { DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \ .parent_names = _parent_names, .num_parents = _num_parents, \ .flag = _flag, .mux_flags = _mux_flags) +#define DEF_SD_MUX(_name, _id, _conf, _parent_names, _num_parents) \ + DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, \ + .parent_names = _parent_names, .num_parents = _num_parents) /** * struct rzg2l_mod_clk - Module Clocks definitions -- cgit From 373bd6f487562e8727bc842e9983b093d57968cc Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 7 Oct 2021 12:14:34 +0100 Subject: clk: renesas: r9a07g044: Add SDHI clock and reset entries Add SDHI{0,1} mux, clock and reset entries to CPG driver. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/20211007111434.8665-3-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/clk/renesas/rzg2l-cpg.h | 4 ++++ 2 files changed, 40 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 1e331cdb13a5..47c16265fca9 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -44,6 +44,12 @@ enum clk_ids { CLK_PLL6, CLK_PLL6_250, CLK_P1_DIV2, + CLK_PLL2_800, + CLK_PLL2_SDHI_533, + CLK_PLL2_SDHI_400, + CLK_PLL2_SDHI_266, + CLK_SD0_DIV4, + CLK_SD1_DIV4, /* Module Clocks */ MOD_CLK_BASE, @@ -62,6 +68,7 @@ static const struct clk_div_table dtable_1_32[] = { /* Mux clock tables */ static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" }; static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" }; +static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" }; static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { /* External Clock Inputs */ @@ -82,6 +89,11 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { DEF_FIXED(".pll6", CLK_PLL6, CLK_EXTAL, 125, 6), DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2), + DEF_FIXED(".clk_800", CLK_PLL2_800, CLK_PLL2, 1, 2), + DEF_FIXED(".clk_533", CLK_PLL2_SDHI_533, CLK_PLL2, 1, 3), + DEF_FIXED(".clk_400", CLK_PLL2_SDHI_400, CLK_PLL2_800, 1, 2), + DEF_FIXED(".clk_266", CLK_PLL2_SDHI_266, CLK_PLL2_SDHI_533, 1, 2), + DEF_FIXED(".pll2_div16", CLK_PLL2_DIV16, CLK_PLL2, 1, 16), DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20), @@ -114,6 +126,12 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { sel_pll6_2, ARRAY_SIZE(sel_pll6_2), 0, CLK_MUX_HIWORD_MASK), DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2), DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4), + DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, + sel_shdi, ARRAY_SIZE(sel_shdi)), + DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, + sel_shdi, ARRAY_SIZE(sel_shdi)), + DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4), + DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4), }; static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { @@ -131,6 +149,22 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x550, 0), DEF_MOD("spi_clk", R9A07G044_SPI_CLK, R9A07G044_CLK_SPI0, 0x550, 1), + DEF_MOD("sdhi0_imclk", R9A07G044_SDHI0_IMCLK, CLK_SD0_DIV4, + 0x554, 0), + DEF_MOD("sdhi0_imclk2", R9A07G044_SDHI0_IMCLK2, CLK_SD0_DIV4, + 0x554, 1), + DEF_MOD("sdhi0_clk_hs", R9A07G044_SDHI0_CLK_HS, R9A07G044_CLK_SD0, + 0x554, 2), + DEF_MOD("sdhi0_aclk", R9A07G044_SDHI0_ACLK, R9A07G044_CLK_P1, + 0x554, 3), + DEF_MOD("sdhi1_imclk", R9A07G044_SDHI1_IMCLK, CLK_SD1_DIV4, + 0x554, 4), + DEF_MOD("sdhi1_imclk2", R9A07G044_SDHI1_IMCLK2, CLK_SD1_DIV4, + 0x554, 5), + DEF_MOD("sdhi1_clk_hs", R9A07G044_SDHI1_CLK_HS, R9A07G044_CLK_SD1, + 0x554, 6), + DEF_MOD("sdhi1_aclk", R9A07G044_SDHI1_ACLK, R9A07G044_CLK_P1, + 0x554, 7), DEF_MOD("ssi0_pclk", R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0, 0x570, 0), DEF_MOD("ssi0_sfr", R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0, @@ -200,6 +234,8 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0), DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1), DEF_RST(R9A07G044_SPI_RST, 0x850, 0), + DEF_RST(R9A07G044_SDHI0_IXRST, 0x854, 0), + DEF_RST(R9A07G044_SDHI1_IXRST, 0x854, 1), DEF_RST(R9A07G044_SSI0_RST_M2_REG, 0x870, 0), DEF_RST(R9A07G044_SSI1_RST_M2_REG, 0x870, 1), DEF_RST(R9A07G044_SSI2_RST_M2_REG, 0x870, 2), diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h index 952fca98ba71..7fb6b4030f72 100644 --- a/drivers/clk/renesas/rzg2l-cpg.h +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -11,6 +11,7 @@ #define CPG_PL2_DDIV (0x204) #define CPG_PL3A_DDIV (0x208) +#define CPG_PL2SDHI_DSEL (0x218) #define CPG_CLKSTATUS (0x280) #define CPG_PL3_SSEL (0x408) #define CPG_PL6_ETH_SSEL (0x418) @@ -39,6 +40,9 @@ #define SEL_PLL3_3 SEL_PLL_PACK(CPG_PL3_SSEL, 8, 1) #define SEL_PLL6_2 SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1) +#define SEL_SDHI0 DDIV_PACK(CPG_PL2SDHI_DSEL, 0, 2) +#define SEL_SDHI1 DDIV_PACK(CPG_PL2SDHI_DSEL, 4, 2) + /** * Definitions of CPG Core Clocks * -- cgit From 2bd9feed23166f5ab67dec2ca02bd3f74c77b0ba Mon Sep 17 00:00:00 2001 From: Andrey Gusakov Date: Thu, 30 Sep 2021 00:34:32 +0300 Subject: clk: renesas: r8a779[56]x: Add MLP clocks Add clocks for MLP modules on Renesas R-Car H3 and M3-W/N SoCs. Signed-off-by: Andrey Gusakov Signed-off-by: Nikita Yushchenko Link: https://lore.kernel.org/r/20210929213431.5275-1-nikita.yoush@cogentembedded.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 + drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 + drivers/clk/renesas/r8a77965-cpg-mssr.c | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index c32d2c678046..d6b1d0148bfd 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -229,6 +229,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { DEF_MOD("lvds", 727, R8A7795_CLK_S0D4), DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), + DEF_MOD("mlp", 802, R8A7795_CLK_S2D1), DEF_MOD("vin7", 804, R8A7795_CLK_S0D2), DEF_MOD("vin6", 805, R8A7795_CLK_S0D2), DEF_MOD("vin5", 806, R8A7795_CLK_S0D2), diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 41593c126faf..9c22977e42c2 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -207,6 +207,7 @@ static struct mssr_mod_clk r8a7796_mod_clks[] __initdata = { DEF_MOD("du0", 724, R8A7796_CLK_S2D1), DEF_MOD("lvds", 727, R8A7796_CLK_S2D1), DEF_MOD("hdmi0", 729, R8A7796_CLK_HDMI), + DEF_MOD("mlp", 802, R8A7796_CLK_S2D1), DEF_MOD("vin7", 804, R8A7796_CLK_S0D2), DEF_MOD("vin6", 805, R8A7796_CLK_S0D2), DEF_MOD("vin5", 806, R8A7796_CLK_S0D2), diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index bc1be8bcbbe4..7eee45a31b2a 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -205,6 +205,7 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { DEF_MOD("lvds", 727, R8A77965_CLK_S2D1), DEF_MOD("hdmi0", 729, R8A77965_CLK_HDMI), + DEF_MOD("mlp", 802, R8A77965_CLK_S2D1), DEF_MOD("vin7", 804, R8A77965_CLK_S0D2), DEF_MOD("vin6", 805, R8A77965_CLK_S0D2), DEF_MOD("vin5", 806, R8A77965_CLK_S0D2), -- cgit