cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

clock-sh7366.c (8729B)


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