root/arch/sh/kernel/cpu/sh4a/clock-sh7343.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dll_recalc
  2. pll_recalc
  3. arch_clk_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * arch/sh/kernel/cpu/sh4a/clock-sh7343.c
   4  *
   5  * SH7343 clock framework support
   6  *
   7  * Copyright (C) 2009 Magnus Damm
   8  */
   9 #include <linux/init.h>
  10 #include <linux/kernel.h>
  11 #include <linux/io.h>
  12 #include <linux/clkdev.h>
  13 #include <asm/clock.h>
  14 
  15 /* SH7343 registers */
  16 #define FRQCR           0xa4150000
  17 #define VCLKCR          0xa4150004
  18 #define SCLKACR         0xa4150008
  19 #define SCLKBCR         0xa415000c
  20 #define PLLCR           0xa4150024
  21 #define MSTPCR0         0xa4150030
  22 #define MSTPCR1         0xa4150034
  23 #define MSTPCR2         0xa4150038
  24 #define DLLFRQ          0xa4150050
  25 
  26 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
  27 static struct clk r_clk = {
  28         .rate           = 32768,
  29 };
  30 
  31 /*
  32  * Default rate for the root input clock, reset this with clk_set_rate()
  33  * from the platform code.
  34  */
  35 struct clk extal_clk = {
  36         .rate           = 33333333,
  37 };
  38 
  39 /* The dll block multiplies the 32khz r_clk, may be used instead of extal */
  40 static unsigned long dll_recalc(struct clk *clk)
  41 {
  42         unsigned long mult;
  43 
  44         if (__raw_readl(PLLCR) & 0x1000)
  45                 mult = __raw_readl(DLLFRQ);
  46         else
  47                 mult = 0;
  48 
  49         return clk->parent->rate * mult;
  50 }
  51 
  52 static struct sh_clk_ops dll_clk_ops = {
  53         .recalc         = dll_recalc,
  54 };
  55 
  56 static struct clk dll_clk = {
  57         .ops            = &dll_clk_ops,
  58         .parent         = &r_clk,
  59         .flags          = CLK_ENABLE_ON_INIT,
  60 };
  61 
  62 static unsigned long pll_recalc(struct clk *clk)
  63 {
  64         unsigned long mult = 1;
  65 
  66         if (__raw_readl(PLLCR) & 0x4000)
  67                 mult = (((__raw_readl(FRQCR) >> 24) & 0x1f) + 1);
  68 
  69         return clk->parent->rate * mult;
  70 }
  71 
  72 static struct sh_clk_ops pll_clk_ops = {
  73         .recalc         = pll_recalc,
  74 };
  75 
  76 static struct clk pll_clk = {
  77         .ops            = &pll_clk_ops,
  78         .flags          = CLK_ENABLE_ON_INIT,
  79 };
  80 
  81 struct clk *main_clks[] = {
  82         &r_clk,
  83         &extal_clk,
  84         &dll_clk,
  85         &pll_clk,
  86 };
  87 
  88 static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
  89 static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
  90 
  91 static struct clk_div_mult_table div4_div_mult_table = {
  92         .divisors = divisors,
  93         .nr_divisors = ARRAY_SIZE(divisors),
  94         .multipliers = multipliers,
  95         .nr_multipliers = ARRAY_SIZE(multipliers),
  96 };
  97 
  98 static struct clk_div4_table div4_table = {
  99         .div_mult_table = &div4_div_mult_table,
 100 };
 101 
 102 enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
 103        DIV4_SIUA, DIV4_SIUB, DIV4_NR };
 104 
 105 #define DIV4(_reg, _bit, _mask, _flags) \
 106   SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
 107 
 108 struct clk div4_clks[DIV4_NR] = {
 109         [DIV4_I] = DIV4(FRQCR, 20, 0x1fff, CLK_ENABLE_ON_INIT),
 110         [DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
 111         [DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
 112         [DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
 113         [DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
 114         [DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0),
 115         [DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0),
 116         [DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0),
 117 };
 118 
 119 enum { DIV6_V, DIV6_NR };
 120 
 121 struct clk div6_clks[DIV6_NR] = {
 122         [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
 123 };
 124 
 125 #define MSTP(_parent, _reg, _bit, _flags) \
 126   SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
 127 
 128 enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026,
 129        MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016,
 130        MSTP015, MSTP014, MSTP013, MSTP012, MSTP011, MSTP010,
 131        MSTP007, MSTP006, MSTP005, MSTP004, MSTP003, MSTP002, MSTP001,
 132        MSTP109, MSTP108, MSTP100,
 133        MSTP225, MSTP224, MSTP218, MSTP217, MSTP216,
 134        MSTP214, MSTP213, MSTP212, MSTP211, MSTP208,
 135        MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
 136        MSTP_NR };
 137 
 138 static struct clk mstp_clks[MSTP_NR] = {
 139         [MSTP031] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
 140         [MSTP030] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
 141         [MSTP029] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
 142         [MSTP028] = MSTP(&div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
 143         [MSTP026] = MSTP(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
 144         [MSTP023] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 23, 0),
 145         [MSTP022] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 22, 0),
 146         [MSTP021] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
 147         [MSTP020] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
 148         [MSTP019] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
 149         [MSTP017] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
 150         [MSTP015] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
 151         [MSTP014] = MSTP(&r_clk, MSTPCR0, 14, 0),
 152         [MSTP013] = MSTP(&r_clk, MSTPCR0, 13, 0),
 153         [MSTP011] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
 154         [MSTP010] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
 155         [MSTP007] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
 156         [MSTP006] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 6, 0),
 157         [MSTP005] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
 158         [MSTP004] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
 159         [MSTP003] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
 160         [MSTP002] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
 161         [MSTP001] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
 162 
 163         [MSTP109] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
 164         [MSTP108] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 8, 0),
 165 
 166         [MSTP225] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 25, 0),
 167         [MSTP224] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
 168         [MSTP218] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 18, 0),
 169         [MSTP217] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 17, 0),
 170         [MSTP216] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 16, 0),
 171         [MSTP214] = MSTP(&r_clk, MSTPCR2, 14, 0),
 172         [MSTP213] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 13, 0),
 173         [MSTP212] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 12, 0),
 174         [MSTP211] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 11, 0),
 175         [MSTP208] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 8, 0),
 176         [MSTP206] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT),
 177         [MSTP205] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
 178         [MSTP204] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
 179         [MSTP203] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
 180         [MSTP202] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
 181         [MSTP201] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
 182         [MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
 183 };
 184 
 185 static struct clk_lookup lookups[] = {
 186         /* main clocks */
 187         CLKDEV_CON_ID("rclk", &r_clk),
 188         CLKDEV_CON_ID("extal", &extal_clk),
 189         CLKDEV_CON_ID("dll_clk", &dll_clk),
 190         CLKDEV_CON_ID("pll_clk", &pll_clk),
 191 
 192         /* DIV4 clocks */
 193         CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
 194         CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
 195         CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
 196         CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
 197         CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
 198         CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
 199         CLKDEV_CON_ID("siua_clk", &div4_clks[DIV4_SIUA]),
 200         CLKDEV_CON_ID("siub_clk", &div4_clks[DIV4_SIUB]),
 201 
 202         /* DIV6 clocks */
 203         CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
 204 
 205         /* MSTP32 clocks */
 206         CLKDEV_CON_ID("tlb0", &mstp_clks[MSTP031]),
 207         CLKDEV_CON_ID("ic0", &mstp_clks[MSTP030]),
 208         CLKDEV_CON_ID("oc0", &mstp_clks[MSTP029]),
 209         CLKDEV_CON_ID("uram0", &mstp_clks[MSTP028]),
 210         CLKDEV_CON_ID("xymem0", &mstp_clks[MSTP026]),
 211         CLKDEV_CON_ID("intc3", &mstp_clks[MSTP023]),
 212         CLKDEV_CON_ID("intc0", &mstp_clks[MSTP022]),
 213         CLKDEV_CON_ID("dmac0", &mstp_clks[MSTP021]),
 214         CLKDEV_CON_ID("sh0", &mstp_clks[MSTP020]),
 215         CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
 216         CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
 217         CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
 218         CLKDEV_ICK_ID("fck", "sh-cmt-32.0", &mstp_clks[MSTP014]),
 219         CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
 220         CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
 221         CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
 222 
 223         CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP007]),
 224         CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP006]),
 225         CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP005]),
 226         CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP004]),
 227 
 228         CLKDEV_CON_ID("sio0", &mstp_clks[MSTP003]),
 229         CLKDEV_CON_ID("siof0", &mstp_clks[MSTP002]),
 230         CLKDEV_CON_ID("siof1", &mstp_clks[MSTP001]),
 231         CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP109]),
 232         CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP108]),
 233         CLKDEV_CON_ID("tpu0", &mstp_clks[MSTP225]),
 234         CLKDEV_CON_ID("irda0", &mstp_clks[MSTP224]),
 235         CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP218]),
 236         CLKDEV_CON_ID("mmcif0", &mstp_clks[MSTP217]),
 237         CLKDEV_CON_ID("sim0", &mstp_clks[MSTP216]),
 238         CLKDEV_CON_ID("keysc0", &mstp_clks[MSTP214]),
 239         CLKDEV_CON_ID("tsif0", &mstp_clks[MSTP213]),
 240         CLKDEV_CON_ID("s3d40", &mstp_clks[MSTP212]),
 241         CLKDEV_CON_ID("usbf0", &mstp_clks[MSTP211]),
 242         CLKDEV_CON_ID("siu0", &mstp_clks[MSTP208]),
 243         CLKDEV_CON_ID("jpu0", &mstp_clks[MSTP206]),
 244         CLKDEV_CON_ID("vou0", &mstp_clks[MSTP205]),
 245         CLKDEV_CON_ID("beu0", &mstp_clks[MSTP204]),
 246         CLKDEV_CON_ID("ceu0", &mstp_clks[MSTP203]),
 247         CLKDEV_CON_ID("veu0", &mstp_clks[MSTP202]),
 248         CLKDEV_CON_ID("vpu0", &mstp_clks[MSTP201]),
 249         CLKDEV_CON_ID("lcdc0", &mstp_clks[MSTP200]),
 250 };
 251 
 252 int __init arch_clk_init(void)
 253 {
 254         int k, ret = 0;
 255 
 256         /* autodetect extal or dll configuration */
 257         if (__raw_readl(PLLCR) & 0x1000)
 258                 pll_clk.parent = &dll_clk;
 259         else
 260                 pll_clk.parent = &extal_clk;
 261 
 262         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 263                 ret = clk_register(main_clks[k]);
 264 
 265         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 266 
 267         if (!ret)
 268                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 269 
 270         if (!ret)
 271                 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 272 
 273         if (!ret)
 274                 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
 275 
 276         return ret;
 277 }

/* [<][>][^][v][top][bottom][index][help] */