linux/drivers/clk/renesas/r8a779a0-cpg-mssr.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * r8a779a0 Clock Pulse Generator / Module Standby and Software Reset
   4 *
   5 * Copyright (C) 2020 Renesas Electronics Corp.
   6 *
   7 * Based on r8a7795-cpg-mssr.c
   8 *
   9 * Copyright (C) 2015 Glider bvba
  10 * Copyright (C) 2015 Renesas Electronics Corp.
  11 */
  12
  13#include <linux/bug.h>
  14#include <linux/bitfield.h>
  15#include <linux/clk.h>
  16#include <linux/clk-provider.h>
  17#include <linux/device.h>
  18#include <linux/err.h>
  19#include <linux/init.h>
  20#include <linux/io.h>
  21#include <linux/kernel.h>
  22#include <linux/pm.h>
  23#include <linux/slab.h>
  24#include <linux/soc/renesas/rcar-rst.h>
  25
  26#include <dt-bindings/clock/r8a779a0-cpg-mssr.h>
  27
  28#include "rcar-cpg-lib.h"
  29#include "renesas-cpg-mssr.h"
  30
  31enum rcar_r8a779a0_clk_types {
  32        CLK_TYPE_R8A779A0_MAIN = CLK_TYPE_CUSTOM,
  33        CLK_TYPE_R8A779A0_PLL1,
  34        CLK_TYPE_R8A779A0_PLL2X_3X,     /* PLL[23][01] */
  35        CLK_TYPE_R8A779A0_PLL5,
  36        CLK_TYPE_R8A779A0_SD,
  37        CLK_TYPE_R8A779A0_MDSEL,        /* Select parent/divider using mode pin */
  38        CLK_TYPE_R8A779A0_OSC,  /* OSC EXTAL predivider and fixed divider */
  39};
  40
  41struct rcar_r8a779a0_cpg_pll_config {
  42        u8 extal_div;
  43        u8 pll1_mult;
  44        u8 pll1_div;
  45        u8 pll5_mult;
  46        u8 pll5_div;
  47        u8 osc_prediv;
  48};
  49
  50enum clk_ids {
  51        /* Core Clock Outputs exported to DT */
  52        LAST_DT_CORE_CLK = R8A779A0_CLK_OSC,
  53
  54        /* External Input Clocks */
  55        CLK_EXTAL,
  56        CLK_EXTALR,
  57
  58        /* Internal Core Clocks */
  59        CLK_MAIN,
  60        CLK_PLL1,
  61        CLK_PLL20,
  62        CLK_PLL21,
  63        CLK_PLL30,
  64        CLK_PLL31,
  65        CLK_PLL5,
  66        CLK_PLL1_DIV2,
  67        CLK_PLL20_DIV2,
  68        CLK_PLL21_DIV2,
  69        CLK_PLL30_DIV2,
  70        CLK_PLL31_DIV2,
  71        CLK_PLL5_DIV2,
  72        CLK_PLL5_DIV4,
  73        CLK_S1,
  74        CLK_S3,
  75        CLK_SDSRC,
  76        CLK_RPCSRC,
  77        CLK_OCO,
  78
  79        /* Module Clocks */
  80        MOD_CLK_BASE
  81};
  82
  83#define DEF_PLL(_name, _id, _offset)    \
  84        DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_PLL2X_3X, CLK_MAIN, \
  85                 .offset = _offset)
  86
  87#define DEF_SD(_name, _id, _parent, _offset)   \
  88        DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_SD, _parent, .offset = _offset)
  89
  90#define DEF_MDSEL(_name, _id, _md, _parent0, _div0, _parent1, _div1) \
  91        DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_MDSEL,   \
  92                 (_parent0) << 16 | (_parent1),         \
  93                 .div = (_div0) << 16 | (_div1), .offset = _md)
  94
  95#define DEF_OSC(_name, _id, _parent, _div)              \
  96        DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_OSC, _parent, .div = _div)
  97
  98static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
  99        /* External Clock Inputs */
 100        DEF_INPUT("extal",  CLK_EXTAL),
 101        DEF_INPUT("extalr", CLK_EXTALR),
 102
 103        /* Internal Core Clocks */
 104        DEF_BASE(".main", CLK_MAIN,     CLK_TYPE_R8A779A0_MAIN, CLK_EXTAL),
 105        DEF_BASE(".pll1", CLK_PLL1,     CLK_TYPE_R8A779A0_PLL1, CLK_MAIN),
 106        DEF_BASE(".pll5", CLK_PLL5,     CLK_TYPE_R8A779A0_PLL5, CLK_MAIN),
 107        DEF_PLL(".pll20", CLK_PLL20,    0x0834),
 108        DEF_PLL(".pll21", CLK_PLL21,    0x0838),
 109        DEF_PLL(".pll30", CLK_PLL30,    0x083c),
 110        DEF_PLL(".pll31", CLK_PLL31,    0x0840),
 111
 112        DEF_FIXED(".pll1_div2",         CLK_PLL1_DIV2,  CLK_PLL1,       2, 1),
 113        DEF_FIXED(".pll20_div2",        CLK_PLL20_DIV2, CLK_PLL20,      2, 1),
 114        DEF_FIXED(".pll21_div2",        CLK_PLL21_DIV2, CLK_PLL21,      2, 1),
 115        DEF_FIXED(".pll30_div2",        CLK_PLL30_DIV2, CLK_PLL30,      2, 1),
 116        DEF_FIXED(".pll31_div2",        CLK_PLL31_DIV2, CLK_PLL31,      2, 1),
 117        DEF_FIXED(".pll5_div2",         CLK_PLL5_DIV2,  CLK_PLL5,       2, 1),
 118        DEF_FIXED(".pll5_div4",         CLK_PLL5_DIV4,  CLK_PLL5_DIV2,  2, 1),
 119        DEF_FIXED(".s1",                CLK_S1,         CLK_PLL1_DIV2,  2, 1),
 120        DEF_FIXED(".s3",                CLK_S3,         CLK_PLL1_DIV2,  4, 1),
 121        DEF_FIXED(".sdsrc",             CLK_SDSRC,      CLK_PLL5_DIV4,  1, 1),
 122        DEF_RATE(".oco",                CLK_OCO,        32768),
 123
 124        /* Core Clock Outputs */
 125        DEF_FIXED("zx",         R8A779A0_CLK_ZX,        CLK_PLL20_DIV2, 2, 1),
 126        DEF_FIXED("s1d1",       R8A779A0_CLK_S1D1,      CLK_S1,         1, 1),
 127        DEF_FIXED("s1d2",       R8A779A0_CLK_S1D2,      CLK_S1,         2, 1),
 128        DEF_FIXED("s1d4",       R8A779A0_CLK_S1D4,      CLK_S1,         4, 1),
 129        DEF_FIXED("s1d8",       R8A779A0_CLK_S1D8,      CLK_S1,         8, 1),
 130        DEF_FIXED("s1d12",      R8A779A0_CLK_S1D12,     CLK_S1,         12, 1),
 131        DEF_FIXED("s3d1",       R8A779A0_CLK_S3D1,      CLK_S3,         1, 1),
 132        DEF_FIXED("s3d2",       R8A779A0_CLK_S3D2,      CLK_S3,         2, 1),
 133        DEF_FIXED("s3d4",       R8A779A0_CLK_S3D4,      CLK_S3,         4, 1),
 134        DEF_FIXED("zs",         R8A779A0_CLK_ZS,        CLK_PLL1_DIV2,  4, 1),
 135        DEF_FIXED("zt",         R8A779A0_CLK_ZT,        CLK_PLL1_DIV2,  2, 1),
 136        DEF_FIXED("ztr",        R8A779A0_CLK_ZTR,       CLK_PLL1_DIV2,  2, 1),
 137        DEF_FIXED("zr",         R8A779A0_CLK_ZR,        CLK_PLL1_DIV2,  1, 1),
 138        DEF_FIXED("cnndsp",     R8A779A0_CLK_CNNDSP,    CLK_PLL5_DIV4,  1, 1),
 139        DEF_FIXED("vip",        R8A779A0_CLK_VIP,       CLK_PLL5,       5, 1),
 140        DEF_FIXED("adgh",       R8A779A0_CLK_ADGH,      CLK_PLL5_DIV4,  1, 1),
 141        DEF_FIXED("icu",        R8A779A0_CLK_ICU,       CLK_PLL5_DIV4,  2, 1),
 142        DEF_FIXED("icud2",      R8A779A0_CLK_ICUD2,     CLK_PLL5_DIV4,  4, 1),
 143        DEF_FIXED("vcbus",      R8A779A0_CLK_VCBUS,     CLK_PLL5_DIV4,  1, 1),
 144        DEF_FIXED("cbfusa",     R8A779A0_CLK_CBFUSA,    CLK_EXTAL,      2, 1),
 145        DEF_FIXED("cp",         R8A779A0_CLK_CP,        CLK_EXTAL,      2, 1),
 146        DEF_FIXED("cl16mck",    R8A779A0_CLK_CL16MCK,   CLK_PLL1_DIV2,  64, 1),
 147
 148        DEF_SD("sd0",           R8A779A0_CLK_SD0,       CLK_SDSRC,      0x870),
 149
 150        DEF_DIV6P1("mso",       R8A779A0_CLK_MSO,       CLK_PLL5_DIV4,  0x87c),
 151        DEF_DIV6P1("canfd",     R8A779A0_CLK_CANFD,     CLK_PLL5_DIV4,  0x878),
 152        DEF_DIV6P1("csi0",      R8A779A0_CLK_CSI0,      CLK_PLL5_DIV4,  0x880),
 153        DEF_DIV6P1("dsi",       R8A779A0_CLK_DSI,       CLK_PLL5_DIV4,  0x884),
 154
 155        DEF_OSC("osc",          R8A779A0_CLK_OSC,       CLK_EXTAL,      8),
 156        DEF_MDSEL("r",          R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
 157};
 158
 159static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
 160        DEF_MOD("avb0",         211,    R8A779A0_CLK_S3D2),
 161        DEF_MOD("avb1",         212,    R8A779A0_CLK_S3D2),
 162        DEF_MOD("avb2",         213,    R8A779A0_CLK_S3D2),
 163        DEF_MOD("avb3",         214,    R8A779A0_CLK_S3D2),
 164        DEF_MOD("avb4",         215,    R8A779A0_CLK_S3D2),
 165        DEF_MOD("avb5",         216,    R8A779A0_CLK_S3D2),
 166        DEF_MOD("csi40",        331,    R8A779A0_CLK_CSI0),
 167        DEF_MOD("csi41",        400,    R8A779A0_CLK_CSI0),
 168        DEF_MOD("csi42",        401,    R8A779A0_CLK_CSI0),
 169        DEF_MOD("csi43",        402,    R8A779A0_CLK_CSI0),
 170        DEF_MOD("du",           411,    R8A779A0_CLK_S3D1),
 171        DEF_MOD("dsi0",         415,    R8A779A0_CLK_DSI),
 172        DEF_MOD("dsi1",         416,    R8A779A0_CLK_DSI),
 173        DEF_MOD("fcpvd0",       508,    R8A779A0_CLK_S3D1),
 174        DEF_MOD("fcpvd1",       509,    R8A779A0_CLK_S3D1),
 175        DEF_MOD("hscif0",       514,    R8A779A0_CLK_S1D2),
 176        DEF_MOD("hscif1",       515,    R8A779A0_CLK_S1D2),
 177        DEF_MOD("hscif2",       516,    R8A779A0_CLK_S1D2),
 178        DEF_MOD("hscif3",       517,    R8A779A0_CLK_S1D2),
 179        DEF_MOD("i2c0",         518,    R8A779A0_CLK_S1D4),
 180        DEF_MOD("i2c1",         519,    R8A779A0_CLK_S1D4),
 181        DEF_MOD("i2c2",         520,    R8A779A0_CLK_S1D4),
 182        DEF_MOD("i2c3",         521,    R8A779A0_CLK_S1D4),
 183        DEF_MOD("i2c4",         522,    R8A779A0_CLK_S1D4),
 184        DEF_MOD("i2c5",         523,    R8A779A0_CLK_S1D4),
 185        DEF_MOD("i2c6",         524,    R8A779A0_CLK_S1D4),
 186        DEF_MOD("ispcs0",       612,    R8A779A0_CLK_S1D1),
 187        DEF_MOD("ispcs1",       613,    R8A779A0_CLK_S1D1),
 188        DEF_MOD("ispcs2",       614,    R8A779A0_CLK_S1D1),
 189        DEF_MOD("ispcs3",       615,    R8A779A0_CLK_S1D1),
 190        DEF_MOD("msi0",         618,    R8A779A0_CLK_MSO),
 191        DEF_MOD("msi1",         619,    R8A779A0_CLK_MSO),
 192        DEF_MOD("msi2",         620,    R8A779A0_CLK_MSO),
 193        DEF_MOD("msi3",         621,    R8A779A0_CLK_MSO),
 194        DEF_MOD("msi4",         622,    R8A779A0_CLK_MSO),
 195        DEF_MOD("msi5",         623,    R8A779A0_CLK_MSO),
 196        DEF_MOD("scif0",        702,    R8A779A0_CLK_S1D8),
 197        DEF_MOD("scif1",        703,    R8A779A0_CLK_S1D8),
 198        DEF_MOD("scif3",        704,    R8A779A0_CLK_S1D8),
 199        DEF_MOD("scif4",        705,    R8A779A0_CLK_S1D8),
 200        DEF_MOD("sdhi0",        706,    R8A779A0_CLK_SD0),
 201        DEF_MOD("sydm1",        709,    R8A779A0_CLK_S1D2),
 202        DEF_MOD("sydm2",        710,    R8A779A0_CLK_S1D2),
 203        DEF_MOD("tmu0",         713,    R8A779A0_CLK_CL16MCK),
 204        DEF_MOD("tmu1",         714,    R8A779A0_CLK_S1D4),
 205        DEF_MOD("tmu2",         715,    R8A779A0_CLK_S1D4),
 206        DEF_MOD("tmu3",         716,    R8A779A0_CLK_S1D4),
 207        DEF_MOD("tmu4",         717,    R8A779A0_CLK_S1D4),
 208        DEF_MOD("vin00",        730,    R8A779A0_CLK_S1D1),
 209        DEF_MOD("vin01",        731,    R8A779A0_CLK_S1D1),
 210        DEF_MOD("vin02",        800,    R8A779A0_CLK_S1D1),
 211        DEF_MOD("vin03",        801,    R8A779A0_CLK_S1D1),
 212        DEF_MOD("vin04",        802,    R8A779A0_CLK_S1D1),
 213        DEF_MOD("vin05",        803,    R8A779A0_CLK_S1D1),
 214        DEF_MOD("vin06",        804,    R8A779A0_CLK_S1D1),
 215        DEF_MOD("vin07",        805,    R8A779A0_CLK_S1D1),
 216        DEF_MOD("vin10",        806,    R8A779A0_CLK_S1D1),
 217        DEF_MOD("vin11",        807,    R8A779A0_CLK_S1D1),
 218        DEF_MOD("vin12",        808,    R8A779A0_CLK_S1D1),
 219        DEF_MOD("vin13",        809,    R8A779A0_CLK_S1D1),
 220        DEF_MOD("vin14",        810,    R8A779A0_CLK_S1D1),
 221        DEF_MOD("vin15",        811,    R8A779A0_CLK_S1D1),
 222        DEF_MOD("vin16",        812,    R8A779A0_CLK_S1D1),
 223        DEF_MOD("vin17",        813,    R8A779A0_CLK_S1D1),
 224        DEF_MOD("vin20",        814,    R8A779A0_CLK_S1D1),
 225        DEF_MOD("vin21",        815,    R8A779A0_CLK_S1D1),
 226        DEF_MOD("vin22",        816,    R8A779A0_CLK_S1D1),
 227        DEF_MOD("vin23",        817,    R8A779A0_CLK_S1D1),
 228        DEF_MOD("vin24",        818,    R8A779A0_CLK_S1D1),
 229        DEF_MOD("vin25",        819,    R8A779A0_CLK_S1D1),
 230        DEF_MOD("vin26",        820,    R8A779A0_CLK_S1D1),
 231        DEF_MOD("vin27",        821,    R8A779A0_CLK_S1D1),
 232        DEF_MOD("vin30",        822,    R8A779A0_CLK_S1D1),
 233        DEF_MOD("vin31",        823,    R8A779A0_CLK_S1D1),
 234        DEF_MOD("vin32",        824,    R8A779A0_CLK_S1D1),
 235        DEF_MOD("vin33",        825,    R8A779A0_CLK_S1D1),
 236        DEF_MOD("vin34",        826,    R8A779A0_CLK_S1D1),
 237        DEF_MOD("vin35",        827,    R8A779A0_CLK_S1D1),
 238        DEF_MOD("vin36",        828,    R8A779A0_CLK_S1D1),
 239        DEF_MOD("vin37",        829,    R8A779A0_CLK_S1D1),
 240        DEF_MOD("vspd0",        830,    R8A779A0_CLK_S3D1),
 241        DEF_MOD("vspd1",        831,    R8A779A0_CLK_S3D1),
 242        DEF_MOD("rwdt",         907,    R8A779A0_CLK_R),
 243        DEF_MOD("cmt0",         910,    R8A779A0_CLK_R),
 244        DEF_MOD("cmt1",         911,    R8A779A0_CLK_R),
 245        DEF_MOD("cmt2",         912,    R8A779A0_CLK_R),
 246        DEF_MOD("cmt3",         913,    R8A779A0_CLK_R),
 247        DEF_MOD("pfc0",         915,    R8A779A0_CLK_CP),
 248        DEF_MOD("pfc1",         916,    R8A779A0_CLK_CP),
 249        DEF_MOD("pfc2",         917,    R8A779A0_CLK_CP),
 250        DEF_MOD("pfc3",         918,    R8A779A0_CLK_CP),
 251        DEF_MOD("tsc",          919,    R8A779A0_CLK_CL16MCK),
 252        DEF_MOD("vspx0",        1028,   R8A779A0_CLK_S1D1),
 253        DEF_MOD("vspx1",        1029,   R8A779A0_CLK_S1D1),
 254        DEF_MOD("vspx2",        1030,   R8A779A0_CLK_S1D1),
 255        DEF_MOD("vspx3",        1031,   R8A779A0_CLK_S1D1),
 256};
 257
 258static const struct rcar_r8a779a0_cpg_pll_config *cpg_pll_config __initdata;
 259static unsigned int cpg_clk_extalr __initdata;
 260static u32 cpg_mode __initdata;
 261
 262static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
 263        const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
 264        struct clk **clks, void __iomem *base,
 265        struct raw_notifier_head *notifiers)
 266{
 267        const struct clk *parent;
 268        unsigned int mult = 1;
 269        unsigned int div = 1;
 270        u32 value;
 271
 272        parent = clks[core->parent & 0xffff];   /* some types use high bits */
 273        if (IS_ERR(parent))
 274                return ERR_CAST(parent);
 275
 276        switch (core->type) {
 277        case CLK_TYPE_R8A779A0_MAIN:
 278                div = cpg_pll_config->extal_div;
 279                break;
 280
 281        case CLK_TYPE_R8A779A0_PLL1:
 282                mult = cpg_pll_config->pll1_mult;
 283                div = cpg_pll_config->pll1_div;
 284                break;
 285
 286        case CLK_TYPE_R8A779A0_PLL2X_3X:
 287                value = readl(base + core->offset);
 288                mult = (((value >> 24) & 0x7f) + 1) * 2;
 289                break;
 290
 291        case CLK_TYPE_R8A779A0_PLL5:
 292                mult = cpg_pll_config->pll5_mult;
 293                div = cpg_pll_config->pll5_div;
 294                break;
 295
 296        case CLK_TYPE_R8A779A0_SD:
 297                return cpg_sd_clk_register(core->name, base, core->offset,
 298                                           __clk_get_name(parent), notifiers,
 299                                           false);
 300                break;
 301
 302        case CLK_TYPE_R8A779A0_MDSEL:
 303                /*
 304                 * Clock selectable between two parents and two fixed dividers
 305                 * using a mode pin
 306                 */
 307                if (cpg_mode & BIT(core->offset)) {
 308                        div = core->div & 0xffff;
 309                } else {
 310                        parent = clks[core->parent >> 16];
 311                        if (IS_ERR(parent))
 312                                return ERR_CAST(parent);
 313                        div = core->div >> 16;
 314                }
 315                mult = 1;
 316                break;
 317
 318        case CLK_TYPE_R8A779A0_OSC:
 319                /*
 320                 * Clock combining OSC EXTAL predivider and a fixed divider
 321                 */
 322                div = cpg_pll_config->osc_prediv * core->div;
 323                break;
 324
 325        default:
 326                return ERR_PTR(-EINVAL);
 327        }
 328
 329        return clk_register_fixed_factor(NULL, core->name,
 330                                         __clk_get_name(parent), 0, mult, div);
 331}
 332
 333static const unsigned int r8a779a0_crit_mod_clks[] __initconst = {
 334        MOD_CLK_ID(907),        /* RWDT */
 335};
 336
 337/*
 338 * CPG Clock Data
 339 */
 340/*
 341 *   MD  EXTAL          PLL1    PLL20   PLL30   PLL4    PLL5    OSC
 342 * 14 13 (MHz)                     21      31
 343 * --------------------------------------------------------
 344 * 0  0  16.66 x 1      x128    x216    x128    x144    x192    /16
 345 * 0  1  20    x 1      x106    x180    x106    x120    x160    /19
 346 * 1  0  Prohibited setting
 347 * 1  1  33.33 / 2      x128    x216    x128    x144    x192    /32
 348 */
 349#define CPG_PLL_CONFIG_INDEX(md)        ((((md) & BIT(14)) >> 13) | \
 350                                         (((md) & BIT(13)) >> 13))
 351
 352static const struct rcar_r8a779a0_cpg_pll_config cpg_pll_configs[4] = {
 353        /* EXTAL div    PLL1 mult/div   PLL5 mult/div   OSC prediv */
 354        { 1,            128,    1,      192,    1,      16,     },
 355        { 1,            106,    1,      160,    1,      19,     },
 356        { 0,            0,      0,      0,      0,      0,      },
 357        { 2,            128,    1,      192,    1,      32,     },
 358};
 359
 360static int __init r8a779a0_cpg_mssr_init(struct device *dev)
 361{
 362        int error;
 363
 364        error = rcar_rst_read_mode_pins(&cpg_mode);
 365        if (error)
 366                return error;
 367
 368        cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
 369        cpg_clk_extalr = CLK_EXTALR;
 370        spin_lock_init(&cpg_lock);
 371
 372        return 0;
 373}
 374
 375const struct cpg_mssr_info r8a779a0_cpg_mssr_info __initconst = {
 376        /* Core Clocks */
 377        .core_clks = r8a779a0_core_clks,
 378        .num_core_clks = ARRAY_SIZE(r8a779a0_core_clks),
 379        .last_dt_core_clk = LAST_DT_CORE_CLK,
 380        .num_total_core_clks = MOD_CLK_BASE,
 381
 382        /* Module Clocks */
 383        .mod_clks = r8a779a0_mod_clks,
 384        .num_mod_clks = ARRAY_SIZE(r8a779a0_mod_clks),
 385        .num_hw_mod_clks = 15 * 32,
 386
 387        /* Critical Module Clocks */
 388        .crit_mod_clks          = r8a779a0_crit_mod_clks,
 389        .num_crit_mod_clks      = ARRAY_SIZE(r8a779a0_crit_mod_clks),
 390
 391        /* Callbacks */
 392        .init = r8a779a0_cpg_mssr_init,
 393        .cpg_clk_register = rcar_r8a779a0_cpg_clk_register,
 394
 395        .reg_layout = CLK_REG_LAYOUT_RCAR_V3U,
 396};
 397