Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * r8a77970 Clock Pulse Generator / Module Standby and Software Reset
0004  *
0005  * Copyright (C) 2017-2018 Cogent Embedded Inc.
0006  *
0007  * Based on r8a7795-cpg-mssr.c
0008  *
0009  * Copyright (C) 2015 Glider bvba
0010  */
0011 
0012 #include <linux/clk-provider.h>
0013 #include <linux/device.h>
0014 #include <linux/init.h>
0015 #include <linux/kernel.h>
0016 #include <linux/soc/renesas/rcar-rst.h>
0017 
0018 #include <dt-bindings/clock/r8a77970-cpg-mssr.h>
0019 
0020 #include "renesas-cpg-mssr.h"
0021 #include "rcar-gen3-cpg.h"
0022 
0023 #define CPG_SD0CKCR     0x0074
0024 
0025 enum r8a77970_clk_types {
0026     CLK_TYPE_R8A77970_SD0H = CLK_TYPE_GEN3_SOC_BASE,
0027     CLK_TYPE_R8A77970_SD0,
0028 };
0029 
0030 enum clk_ids {
0031     /* Core Clock Outputs exported to DT */
0032     LAST_DT_CORE_CLK = R8A77970_CLK_OSC,
0033 
0034     /* External Input Clocks */
0035     CLK_EXTAL,
0036     CLK_EXTALR,
0037 
0038     /* Internal Core Clocks */
0039     CLK_MAIN,
0040     CLK_PLL0,
0041     CLK_PLL1,
0042     CLK_PLL3,
0043     CLK_PLL1_DIV2,
0044     CLK_PLL1_DIV4,
0045 
0046     /* Module Clocks */
0047     MOD_CLK_BASE
0048 };
0049 
0050 static spinlock_t cpg_lock;
0051 
0052 static const struct clk_div_table cpg_sd0h_div_table[] = {
0053     {  0,  2 }, {  1,  3 }, {  2,  4 }, {  3,  6 },
0054     {  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
0055     {  8, 24 }, { 10, 36 }, { 11, 48 }, {  0,  0 },
0056 };
0057 
0058 static const struct clk_div_table cpg_sd0_div_table[] = {
0059     {  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
0060     {  8, 24 }, { 10, 36 }, { 11, 48 }, { 12, 10 },
0061     {  0,  0 },
0062 };
0063 
0064 static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
0065     /* External Clock Inputs */
0066     DEF_INPUT("extal",  CLK_EXTAL),
0067     DEF_INPUT("extalr", CLK_EXTALR),
0068 
0069     /* Internal Core Clocks */
0070     DEF_BASE(".main",   CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
0071     DEF_BASE(".pll0",   CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
0072     DEF_BASE(".pll1",   CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
0073     DEF_BASE(".pll3",   CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
0074 
0075     DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2,  CLK_PLL1,   2, 1),
0076     DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4,  CLK_PLL1_DIV2,  2, 1),
0077 
0078     /* Core Clock Outputs */
0079     DEF_FIXED("ztr",    R8A77970_CLK_ZTR,   CLK_PLL1_DIV2,  6, 1),
0080     DEF_FIXED("ztrd2",  R8A77970_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
0081     DEF_FIXED("zt",     R8A77970_CLK_ZT,    CLK_PLL1_DIV2,  4, 1),
0082     DEF_FIXED("zx",     R8A77970_CLK_ZX,    CLK_PLL1_DIV2,  3, 1),
0083     DEF_FIXED("s1d1",   R8A77970_CLK_S1D1,  CLK_PLL1_DIV2,  4, 1),
0084     DEF_FIXED("s1d2",   R8A77970_CLK_S1D2,  CLK_PLL1_DIV2,  8, 1),
0085     DEF_FIXED("s1d4",   R8A77970_CLK_S1D4,  CLK_PLL1_DIV2, 16, 1),
0086     DEF_FIXED("s2d1",   R8A77970_CLK_S2D1,  CLK_PLL1_DIV2,  6, 1),
0087     DEF_FIXED("s2d2",   R8A77970_CLK_S2D2,  CLK_PLL1_DIV2, 12, 1),
0088     DEF_FIXED("s2d4",   R8A77970_CLK_S2D4,  CLK_PLL1_DIV2, 24, 1),
0089 
0090     DEF_BASE("sd0h", R8A77970_CLK_SD0H, CLK_TYPE_R8A77970_SD0H,
0091          CLK_PLL1_DIV2),
0092     DEF_BASE("sd0", R8A77970_CLK_SD0, CLK_TYPE_R8A77970_SD0, CLK_PLL1_DIV2),
0093 
0094     DEF_FIXED("rpc",    R8A77970_CLK_RPC,   CLK_PLL1_DIV2,  5, 1),
0095     DEF_FIXED("rpcd2",  R8A77970_CLK_RPCD2, CLK_PLL1_DIV2, 10, 1),
0096 
0097     DEF_FIXED("cl",     R8A77970_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
0098     DEF_FIXED("cp",     R8A77970_CLK_CP,    CLK_EXTAL,      2, 1),
0099     DEF_FIXED("cpex",   R8A77970_CLK_CPEX,  CLK_EXTAL,      2, 1),
0100 
0101     DEF_DIV6P1("canfd", R8A77970_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
0102     DEF_DIV6P1("mso",   R8A77970_CLK_MSO,   CLK_PLL1_DIV4, 0x014),
0103     DEF_DIV6P1("csi0",  R8A77970_CLK_CSI0,  CLK_PLL1_DIV4, 0x00c),
0104 
0105     DEF_FIXED("osc",    R8A77970_CLK_OSC,   CLK_PLL1_DIV2, 12*1024, 1),
0106     DEF_FIXED("r",      R8A77970_CLK_R,     CLK_EXTALR,    1, 1),
0107 };
0108 
0109 static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
0110     DEF_MOD("tmu4",          121,   R8A77970_CLK_S2D2),
0111     DEF_MOD("tmu3",          122,   R8A77970_CLK_S2D2),
0112     DEF_MOD("tmu2",          123,   R8A77970_CLK_S2D2),
0113     DEF_MOD("tmu1",          124,   R8A77970_CLK_S2D2),
0114     DEF_MOD("tmu0",          125,   R8A77970_CLK_CP),
0115     DEF_MOD("ivcp1e",        127,   R8A77970_CLK_S2D1),
0116     DEF_MOD("scif4",         203,   R8A77970_CLK_S2D4),
0117     DEF_MOD("scif3",         204,   R8A77970_CLK_S2D4),
0118     DEF_MOD("scif1",         206,   R8A77970_CLK_S2D4),
0119     DEF_MOD("scif0",         207,   R8A77970_CLK_S2D4),
0120     DEF_MOD("msiof3",        208,   R8A77970_CLK_MSO),
0121     DEF_MOD("msiof2",        209,   R8A77970_CLK_MSO),
0122     DEF_MOD("msiof1",        210,   R8A77970_CLK_MSO),
0123     DEF_MOD("msiof0",        211,   R8A77970_CLK_MSO),
0124     DEF_MOD("mfis",          213,   R8A77970_CLK_S2D2),
0125     DEF_MOD("sys-dmac2",         217,   R8A77970_CLK_S2D1),
0126     DEF_MOD("sys-dmac1",         218,   R8A77970_CLK_S2D1),
0127     DEF_MOD("cmt3",          300,   R8A77970_CLK_R),
0128     DEF_MOD("cmt2",          301,   R8A77970_CLK_R),
0129     DEF_MOD("cmt1",          302,   R8A77970_CLK_R),
0130     DEF_MOD("cmt0",          303,   R8A77970_CLK_R),
0131     DEF_MOD("tpu0",          304,   R8A77970_CLK_S2D4),
0132     DEF_MOD("sd-if",         314,   R8A77970_CLK_SD0),
0133     DEF_MOD("rwdt",          402,   R8A77970_CLK_R),
0134     DEF_MOD("intc-ex",       407,   R8A77970_CLK_CP),
0135     DEF_MOD("intc-ap",       408,   R8A77970_CLK_S2D1),
0136     DEF_MOD("hscif3",        517,   R8A77970_CLK_S2D1),
0137     DEF_MOD("hscif2",        518,   R8A77970_CLK_S2D1),
0138     DEF_MOD("hscif1",        519,   R8A77970_CLK_S2D1),
0139     DEF_MOD("hscif0",        520,   R8A77970_CLK_S2D1),
0140     DEF_MOD("thermal",       522,   R8A77970_CLK_CP),
0141     DEF_MOD("pwm",           523,   R8A77970_CLK_S2D4),
0142     DEF_MOD("fcpvd0",        603,   R8A77970_CLK_S2D1),
0143     DEF_MOD("vspd0",         623,   R8A77970_CLK_S2D1),
0144     DEF_MOD("csi40",         716,   R8A77970_CLK_CSI0),
0145     DEF_MOD("du0",           724,   R8A77970_CLK_S2D1),
0146     DEF_MOD("lvds",          727,   R8A77970_CLK_S2D1),
0147     DEF_MOD("vin3",          808,   R8A77970_CLK_S2D1),
0148     DEF_MOD("vin2",          809,   R8A77970_CLK_S2D1),
0149     DEF_MOD("vin1",          810,   R8A77970_CLK_S2D1),
0150     DEF_MOD("vin0",          811,   R8A77970_CLK_S2D1),
0151     DEF_MOD("etheravb",      812,   R8A77970_CLK_S2D2),
0152     DEF_MOD("gpio5",         907,   R8A77970_CLK_CP),
0153     DEF_MOD("gpio4",         908,   R8A77970_CLK_CP),
0154     DEF_MOD("gpio3",         909,   R8A77970_CLK_CP),
0155     DEF_MOD("gpio2",         910,   R8A77970_CLK_CP),
0156     DEF_MOD("gpio1",         911,   R8A77970_CLK_CP),
0157     DEF_MOD("gpio0",         912,   R8A77970_CLK_CP),
0158     DEF_MOD("can-fd",        914,   R8A77970_CLK_S2D2),
0159     DEF_MOD("rpc-if",        917,   R8A77970_CLK_RPC),
0160     DEF_MOD("i2c4",          927,   R8A77970_CLK_S2D2),
0161     DEF_MOD("i2c3",          928,   R8A77970_CLK_S2D2),
0162     DEF_MOD("i2c2",          929,   R8A77970_CLK_S2D2),
0163     DEF_MOD("i2c1",          930,   R8A77970_CLK_S2D2),
0164     DEF_MOD("i2c0",          931,   R8A77970_CLK_S2D2),
0165 };
0166 
0167 static const unsigned int r8a77970_crit_mod_clks[] __initconst = {
0168     MOD_CLK_ID(402),    /* RWDT */
0169     MOD_CLK_ID(408),    /* INTC-AP (GIC) */
0170 };
0171 
0172 /*
0173  * CPG Clock Data
0174  */
0175 
0176 /*
0177  *   MD     EXTAL       PLL0    PLL1    PLL3
0178  * 14 13 19 (MHz)
0179  *-------------------------------------------------
0180  * 0  0  0  16.66 x 1   x192    x192    x96
0181  * 0  0  1  16.66 x 1   x192    x192    x80
0182  * 0  1  0  20    x 1   x160    x160    x80
0183  * 0  1  1  20    x 1   x160    x160    x66
0184  * 1  0  0  27    / 2   x236    x236    x118
0185  * 1  0  1  27    / 2   x236    x236    x98
0186  * 1  1  0  33.33 / 2   x192    x192    x96
0187  * 1  1  1  33.33 / 2   x192    x192    x80
0188  */
0189 #define CPG_PLL_CONFIG_INDEX(md)    ((((md) & BIT(14)) >> 12) | \
0190                      (((md) & BIT(13)) >> 12) | \
0191                      (((md) & BIT(19)) >> 19))
0192 
0193 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[8] __initconst = {
0194     /* EXTAL div    PLL1 mult/div   PLL3 mult/div */
0195     { 1,        192,    1,  96, 1,  },
0196     { 1,        192,    1,  80, 1,  },
0197     { 1,        160,    1,  80, 1,  },
0198     { 1,        160,    1,  66, 1,  },
0199     { 2,        236,    1,  118,    1,  },
0200     { 2,        236,    1,  98, 1,  },
0201     { 2,        192,    1,  96, 1,  },
0202     { 2,        192,    1,  80, 1,  },
0203 };
0204 
0205 static int __init r8a77970_cpg_mssr_init(struct device *dev)
0206 {
0207     const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
0208     u32 cpg_mode;
0209     int error;
0210 
0211     error = rcar_rst_read_mode_pins(&cpg_mode);
0212     if (error)
0213         return error;
0214 
0215     spin_lock_init(&cpg_lock);
0216 
0217     cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
0218 
0219     return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
0220 }
0221 
0222 static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
0223     const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
0224     struct clk **clks, void __iomem *base,
0225     struct raw_notifier_head *notifiers)
0226 {
0227     const struct clk_div_table *table;
0228     const struct clk *parent;
0229     unsigned int shift;
0230 
0231     switch (core->type) {
0232     case CLK_TYPE_R8A77970_SD0H:
0233         table = cpg_sd0h_div_table;
0234         shift = 8;
0235         break;
0236     case CLK_TYPE_R8A77970_SD0:
0237         table = cpg_sd0_div_table;
0238         shift = 4;
0239         break;
0240     default:
0241         return rcar_gen3_cpg_clk_register(dev, core, info, clks, base,
0242                           notifiers);
0243     }
0244 
0245     parent = clks[core->parent];
0246     if (IS_ERR(parent))
0247         return ERR_CAST(parent);
0248 
0249     return clk_register_divider_table(NULL, core->name,
0250                       __clk_get_name(parent), 0,
0251                       base + CPG_SD0CKCR,
0252                       shift, 4, 0, table, &cpg_lock);
0253 }
0254 
0255 const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = {
0256     /* Core Clocks */
0257     .core_clks = r8a77970_core_clks,
0258     .num_core_clks = ARRAY_SIZE(r8a77970_core_clks),
0259     .last_dt_core_clk = LAST_DT_CORE_CLK,
0260     .num_total_core_clks = MOD_CLK_BASE,
0261 
0262     /* Module Clocks */
0263     .mod_clks = r8a77970_mod_clks,
0264     .num_mod_clks = ARRAY_SIZE(r8a77970_mod_clks),
0265     .num_hw_mod_clks = 12 * 32,
0266 
0267     /* Critical Module Clocks */
0268     .crit_mod_clks = r8a77970_crit_mod_clks,
0269     .num_crit_mod_clks = ARRAY_SIZE(r8a77970_crit_mod_clks),
0270 
0271     /* Callbacks */
0272     .init = r8a77970_cpg_mssr_init,
0273     .cpg_clk_register = r8a77970_cpg_clk_register,
0274 };