Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * r8a779f0 Clock Pulse Generator / Module Standby and Software Reset
0004  *
0005  * Copyright (C) 2021 Renesas Electronics Corp.
0006  *
0007  * Based on r8a779a0-cpg-mssr.c
0008  */
0009 
0010 #include <linux/bitfield.h>
0011 #include <linux/clk.h>
0012 #include <linux/clk-provider.h>
0013 #include <linux/device.h>
0014 #include <linux/err.h>
0015 #include <linux/kernel.h>
0016 #include <linux/soc/renesas/rcar-rst.h>
0017 
0018 #include <dt-bindings/clock/r8a779f0-cpg-mssr.h>
0019 
0020 #include "renesas-cpg-mssr.h"
0021 #include "rcar-gen4-cpg.h"
0022 
0023 enum clk_ids {
0024     /* Core Clock Outputs exported to DT */
0025     LAST_DT_CORE_CLK = R8A779F0_CLK_R,
0026 
0027     /* External Input Clocks */
0028     CLK_EXTAL,
0029     CLK_EXTALR,
0030 
0031     /* Internal Core Clocks */
0032     CLK_MAIN,
0033     CLK_PLL1,
0034     CLK_PLL2,
0035     CLK_PLL3,
0036     CLK_PLL5,
0037     CLK_PLL6,
0038     CLK_PLL1_DIV2,
0039     CLK_PLL2_DIV2,
0040     CLK_PLL3_DIV2,
0041     CLK_PLL5_DIV2,
0042     CLK_PLL5_DIV4,
0043     CLK_PLL6_DIV2,
0044     CLK_S0,
0045     CLK_SDSRC,
0046     CLK_RPCSRC,
0047     CLK_OCO,
0048 
0049     /* Module Clocks */
0050     MOD_CLK_BASE
0051 };
0052 
0053 static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
0054     /* External Clock Inputs */
0055     DEF_INPUT("extal",  CLK_EXTAL),
0056     DEF_INPUT("extalr", CLK_EXTALR),
0057 
0058     /* Internal Core Clocks */
0059     DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN4_MAIN, CLK_EXTAL),
0060     DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN4_PLL1, CLK_MAIN),
0061     DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN4_PLL2, CLK_MAIN),
0062     DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN4_PLL3, CLK_MAIN),
0063     DEF_BASE(".pll5", CLK_PLL5, CLK_TYPE_GEN4_PLL5, CLK_MAIN),
0064     DEF_BASE(".pll6", CLK_PLL6, CLK_TYPE_GEN4_PLL6, CLK_MAIN),
0065 
0066     DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2,  CLK_PLL1,   2, 1),
0067     DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2,  CLK_PLL2,   2, 1),
0068     DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2,  CLK_PLL3,   2, 1),
0069     DEF_FIXED(".pll5_div2", CLK_PLL5_DIV2,  CLK_PLL5,   2, 1),
0070     DEF_FIXED(".pll5_div4", CLK_PLL5_DIV4,  CLK_PLL5_DIV2,  2, 1),
0071     DEF_FIXED(".pll6_div2", CLK_PLL6_DIV2,  CLK_PLL6,   2, 1),
0072     DEF_FIXED(".s0",    CLK_S0,     CLK_PLL1_DIV2,  2, 1),
0073 
0074     DEF_BASE(".sdsrc",  CLK_SDSRC,  CLK_TYPE_GEN4_SDSRC, CLK_PLL5),
0075     DEF_RATE(".oco",    CLK_OCO,    32768),
0076 
0077     DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN4_RPCSRC, CLK_PLL5),
0078 
0079     /* Core Clock Outputs */
0080     DEF_GEN4_Z("z0",    R8A779F0_CLK_Z0,    CLK_TYPE_GEN4_Z,    CLK_PLL2,   2, 0),
0081     DEF_GEN4_Z("z1",    R8A779F0_CLK_Z1,    CLK_TYPE_GEN4_Z,    CLK_PLL2,   2, 8),
0082     DEF_FIXED("s0d2",   R8A779F0_CLK_S0D2,  CLK_S0,     2, 1),
0083     DEF_FIXED("s0d3",   R8A779F0_CLK_S0D3,  CLK_S0,     3, 1),
0084     DEF_FIXED("s0d4",   R8A779F0_CLK_S0D4,  CLK_S0,     4, 1),
0085     DEF_FIXED("cl16m",  R8A779F0_CLK_CL16M, CLK_S0,     48, 1),
0086     DEF_FIXED("s0d2_mm",    R8A779F0_CLK_S0D2_MM,   CLK_S0,     2, 1),
0087     DEF_FIXED("s0d3_mm",    R8A779F0_CLK_S0D3_MM,   CLK_S0,     3, 1),
0088     DEF_FIXED("s0d4_mm",    R8A779F0_CLK_S0D4_MM,   CLK_S0,     4, 1),
0089     DEF_FIXED("cl16m_mm",   R8A779F0_CLK_CL16M_MM,  CLK_S0,     48, 1),
0090     DEF_FIXED("s0d2_rt",    R8A779F0_CLK_S0D2_RT,   CLK_S0,     2, 1),
0091     DEF_FIXED("s0d3_rt",    R8A779F0_CLK_S0D3_RT,   CLK_S0,     3, 1),
0092     DEF_FIXED("s0d4_rt",    R8A779F0_CLK_S0D4_RT,   CLK_S0,     4, 1),
0093     DEF_FIXED("s0d6_rt",    R8A779F0_CLK_S0D6_RT,   CLK_S0,     6, 1),
0094     DEF_FIXED("cl16m_rt",   R8A779F0_CLK_CL16M_RT,  CLK_S0,     48, 1),
0095     DEF_FIXED("s0d3_per",   R8A779F0_CLK_S0D3_PER,  CLK_S0,     3, 1),
0096     DEF_FIXED("s0d6_per",   R8A779F0_CLK_S0D6_PER,  CLK_S0,     6, 1),
0097     DEF_FIXED("s0d12_per",  R8A779F0_CLK_S0D12_PER, CLK_S0,     12, 1),
0098     DEF_FIXED("s0d24_per",  R8A779F0_CLK_S0D24_PER, CLK_S0,     24, 1),
0099     DEF_FIXED("cl16m_per",  R8A779F0_CLK_CL16M_PER, CLK_S0,     48, 1),
0100     DEF_FIXED("s0d2_hsc",   R8A779F0_CLK_S0D2_HSC,  CLK_S0,     2, 1),
0101     DEF_FIXED("s0d3_hsc",   R8A779F0_CLK_S0D3_HSC,  CLK_S0,     3, 1),
0102     DEF_FIXED("s0d4_hsc",   R8A779F0_CLK_S0D4_HSC,  CLK_S0,     4, 1),
0103     DEF_FIXED("s0d6_hsc",   R8A779F0_CLK_S0D6_HSC,  CLK_S0,     6, 1),
0104     DEF_FIXED("s0d12_hsc",  R8A779F0_CLK_S0D12_HSC, CLK_S0,     12, 1),
0105     DEF_FIXED("cl16m_hsc",  R8A779F0_CLK_CL16M_HSC, CLK_S0,     48, 1),
0106     DEF_FIXED("s0d2_cc",    R8A779F0_CLK_S0D2_CC,   CLK_S0,     2, 1),
0107     DEF_FIXED("rsw2",   R8A779F0_CLK_RSW2,  CLK_PLL5_DIV2,  5, 1),
0108     DEF_FIXED("cbfusa", R8A779F0_CLK_CBFUSA,    CLK_EXTAL,  2, 1),
0109     DEF_FIXED("cpex",   R8A779F0_CLK_CPEX,  CLK_EXTAL,  2, 1),
0110 
0111     DEF_GEN4_SD("sd0",  R8A779F0_CLK_SD0,   CLK_SDSRC,  0x870),
0112 
0113     DEF_BASE("rpc",     R8A779F0_CLK_RPC,   CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
0114     DEF_BASE("rpcd2",   R8A779F0_CLK_RPCD2, CLK_TYPE_GEN4_RPCD2, R8A779F0_CLK_RPC),
0115 
0116     DEF_DIV6P1("mso",   R8A779F0_CLK_MSO,   CLK_PLL5_DIV4,  0x87c),
0117 
0118     DEF_GEN4_OSC("osc", R8A779F0_CLK_OSC,   CLK_EXTAL,  8),
0119     DEF_GEN4_MDSEL("r", R8A779F0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
0120 };
0121 
0122 static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
0123     DEF_MOD("hscif0",   514,    R8A779F0_CLK_S0D3),
0124     DEF_MOD("hscif1",   515,    R8A779F0_CLK_S0D3),
0125     DEF_MOD("hscif2",   516,    R8A779F0_CLK_S0D3),
0126     DEF_MOD("hscif3",   517,    R8A779F0_CLK_S0D3),
0127     DEF_MOD("i2c0",     518,    R8A779F0_CLK_S0D6_PER),
0128     DEF_MOD("i2c1",     519,    R8A779F0_CLK_S0D6_PER),
0129     DEF_MOD("i2c2",     520,    R8A779F0_CLK_S0D6_PER),
0130     DEF_MOD("i2c3",     521,    R8A779F0_CLK_S0D6_PER),
0131     DEF_MOD("i2c4",     522,    R8A779F0_CLK_S0D6_PER),
0132     DEF_MOD("i2c5",     523,    R8A779F0_CLK_S0D6_PER),
0133     DEF_MOD("pcie0",    624,    R8A779F0_CLK_S0D2),
0134     DEF_MOD("pcie1",    625,    R8A779F0_CLK_S0D2),
0135     DEF_MOD("scif0",    702,    R8A779F0_CLK_S0D12_PER),
0136     DEF_MOD("scif1",    703,    R8A779F0_CLK_S0D12_PER),
0137     DEF_MOD("scif3",    704,    R8A779F0_CLK_S0D12_PER),
0138     DEF_MOD("scif4",    705,    R8A779F0_CLK_S0D12_PER),
0139     DEF_MOD("sdhi0",        706,    R8A779F0_CLK_SD0),
0140     DEF_MOD("sys-dmac0",    709,    R8A779F0_CLK_S0D3_PER),
0141     DEF_MOD("sys-dmac1",    710,    R8A779F0_CLK_S0D3_PER),
0142     DEF_MOD("wdt",      907,    R8A779F0_CLK_R),
0143     DEF_MOD("pfc0",     915,    R8A779F0_CLK_CL16M),
0144     DEF_MOD("tsc",      919,    R8A779F0_CLK_CL16M),
0145     DEF_MOD("ufs",      1514,   R8A779F0_CLK_S0D4_HSC),
0146 };
0147 
0148 static const unsigned int r8a779f0_crit_mod_clks[] __initconst = {
0149     MOD_CLK_ID(907),    /* WDT */
0150 };
0151 
0152 /*
0153  * CPG Clock Data
0154  */
0155 /*
0156  *   MD  EXTAL      PLL1    PLL2    PLL3    PLL4    PLL5    PLL6    OSC
0157  * 14 13 (MHz)
0158  * ------------------------------------------------------------------------
0159  * 0  0  16    / 1  x200    x150    x200    n/a x200    x134    /15
0160  * 0  1  20    / 1  x160    x120    x160    n/a x160    x106    /19
0161  * 1  0  Prohibited setting
0162  * 1  1  40    / 2  x160    x120    x160    n/a x160    x106    /38
0163  */
0164 #define CPG_PLL_CONFIG_INDEX(md)    ((((md) & BIT(14)) >> 13) | \
0165                      (((md) & BIT(13)) >> 13))
0166 
0167 static const struct rcar_gen4_cpg_pll_config cpg_pll_configs[4] = {
0168     /* EXTAL div    PLL1 mult/div   PLL2 mult/div   PLL3 mult/div   PLL4 mult/div   PLL5 mult/div   PLL6 mult/div   OSC prediv */
0169     { 1,        200,    1,  150,    1,  200,    1,  0,  0,  200,    1,  134,    1,  15, },
0170     { 1,        160,    1,  120,    1,  160,    1,  0,  0,  160,    1,  106,    1,  19, },
0171     { 0,        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  },
0172     { 2,        160,    1,  120,    1,  160,    1,  0,  0,  160,    1,  106,    1,  38, },
0173 };
0174 
0175 static int __init r8a779f0_cpg_mssr_init(struct device *dev)
0176 {
0177     const struct rcar_gen4_cpg_pll_config *cpg_pll_config;
0178     u32 cpg_mode;
0179     int error;
0180 
0181     error = rcar_rst_read_mode_pins(&cpg_mode);
0182     if (error)
0183         return error;
0184 
0185     cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
0186     if (!cpg_pll_config->extal_div) {
0187         dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode);
0188         return -EINVAL;
0189     }
0190 
0191     return rcar_gen4_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
0192 }
0193 
0194 const struct cpg_mssr_info r8a779f0_cpg_mssr_info __initconst = {
0195     /* Core Clocks */
0196     .core_clks = r8a779f0_core_clks,
0197     .num_core_clks = ARRAY_SIZE(r8a779f0_core_clks),
0198     .last_dt_core_clk = LAST_DT_CORE_CLK,
0199     .num_total_core_clks = MOD_CLK_BASE,
0200 
0201     /* Module Clocks */
0202     .mod_clks = r8a779f0_mod_clks,
0203     .num_mod_clks = ARRAY_SIZE(r8a779f0_mod_clks),
0204     .num_hw_mod_clks = 28 * 32,
0205 
0206     /* Critical Module Clocks */
0207     .crit_mod_clks = r8a779f0_crit_mod_clks,
0208     .num_crit_mod_clks = ARRAY_SIZE(r8a779f0_crit_mod_clks),
0209 
0210     /* Callbacks */
0211     .init = r8a779f0_cpg_mssr_init,
0212     .cpg_clk_register = rcar_gen4_cpg_clk_register,
0213 
0214     .reg_layout = CLK_REG_LAYOUT_RCAR_GEN4,
0215 };