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-sh7269.c (4825B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * arch/sh/kernel/cpu/sh2a/clock-sh7269.c
      4 *
      5 * SH7269 clock framework support
      6 *
      7 * Copyright (C) 2012  Phil Edworthy
      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/* SH7269 registers */
     16#define FRQCR		0xfffe0010
     17#define STBCR3 		0xfffe0408
     18#define STBCR4 		0xfffe040c
     19#define STBCR5 		0xfffe0410
     20#define STBCR6 		0xfffe0414
     21#define STBCR7 		0xfffe0418
     22
     23#define PLL_RATE 20
     24
     25/* Fixed 32 KHz root clock for RTC */
     26static struct clk r_clk = {
     27	.rate           = 32768,
     28};
     29
     30/*
     31 * Default rate for the root input clock, reset this with clk_set_rate()
     32 * from the platform code.
     33 */
     34static struct clk extal_clk = {
     35	.rate		= 13340000,
     36};
     37
     38static unsigned long pll_recalc(struct clk *clk)
     39{
     40	return clk->parent->rate * PLL_RATE;
     41}
     42
     43static struct sh_clk_ops pll_clk_ops = {
     44	.recalc		= pll_recalc,
     45};
     46
     47static struct clk pll_clk = {
     48	.ops		= &pll_clk_ops,
     49	.parent		= &extal_clk,
     50	.flags		= CLK_ENABLE_ON_INIT,
     51};
     52
     53static unsigned long peripheral0_recalc(struct clk *clk)
     54{
     55	return clk->parent->rate / 8;
     56}
     57
     58static struct sh_clk_ops peripheral0_clk_ops = {
     59	.recalc		= peripheral0_recalc,
     60};
     61
     62static struct clk peripheral0_clk = {
     63	.ops		= &peripheral0_clk_ops,
     64	.parent		= &pll_clk,
     65	.flags		= CLK_ENABLE_ON_INIT,
     66};
     67
     68static unsigned long peripheral1_recalc(struct clk *clk)
     69{
     70	return clk->parent->rate / 4;
     71}
     72
     73static struct sh_clk_ops peripheral1_clk_ops = {
     74	.recalc		= peripheral1_recalc,
     75};
     76
     77static struct clk peripheral1_clk = {
     78	.ops		= &peripheral1_clk_ops,
     79	.parent		= &pll_clk,
     80	.flags		= CLK_ENABLE_ON_INIT,
     81};
     82
     83struct clk *main_clks[] = {
     84	&r_clk,
     85	&extal_clk,
     86	&pll_clk,
     87	&peripheral0_clk,
     88	&peripheral1_clk,
     89};
     90
     91static int div2[] = { 1, 2, 0, 4 };
     92
     93static struct clk_div_mult_table div4_div_mult_table = {
     94	.divisors = div2,
     95	.nr_divisors = ARRAY_SIZE(div2),
     96};
     97
     98static struct clk_div4_table div4_table = {
     99	.div_mult_table = &div4_div_mult_table,
    100};
    101
    102enum { DIV4_I, DIV4_B,
    103       DIV4_NR };
    104
    105#define DIV4(_reg, _bit, _mask, _flags) \
    106  SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
    107
    108/* The mask field specifies the div2 entries that are valid */
    109struct clk div4_clks[DIV4_NR] = {
    110	[DIV4_I]  = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT
    111					| CLK_ENABLE_ON_INIT),
    112	[DIV4_B]  = DIV4(FRQCR, 4, 0xA, CLK_ENABLE_REG_16BIT
    113					| CLK_ENABLE_ON_INIT),
    114};
    115
    116enum { MSTP72,
    117	MSTP60,
    118	MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40,
    119	MSTP35, MSTP32, MSTP30,
    120	MSTP_NR };
    121
    122static struct clk mstp_clks[MSTP_NR] = {
    123	[MSTP72] = SH_CLK_MSTP8(&peripheral0_clk, STBCR7, 2, 0), /* CMT */
    124	[MSTP60] = SH_CLK_MSTP8(&peripheral1_clk, STBCR6, 0, 0), /* USB */
    125	[MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */
    126	[MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */
    127	[MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */
    128	[MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */
    129	[MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */
    130	[MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */
    131	[MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */
    132	[MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */
    133	[MSTP35] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 5, 0), /* MTU2 */
    134	[MSTP32] = SH_CLK_MSTP8(&peripheral1_clk, STBCR3, 2, 0), /* ADC */
    135	[MSTP30] = SH_CLK_MSTP8(&r_clk, STBCR3, 0, 0), /* RTC */
    136};
    137
    138static struct clk_lookup lookups[] = {
    139	/* main clocks */
    140	CLKDEV_CON_ID("rclk", &r_clk),
    141	CLKDEV_CON_ID("extal", &extal_clk),
    142	CLKDEV_CON_ID("pll_clk", &pll_clk),
    143	CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk),
    144
    145	/* DIV4 clocks */
    146	CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
    147	CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
    148
    149	/* MSTP clocks */
    150	CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP47]),
    151	CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP46]),
    152	CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP45]),
    153	CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP44]),
    154	CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP43]),
    155	CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP42]),
    156	CLKDEV_ICK_ID("fck", "sh-sci.6", &mstp_clks[MSTP41]),
    157	CLKDEV_ICK_ID("fck", "sh-sci.7", &mstp_clks[MSTP40]),
    158	CLKDEV_ICK_ID("fck", "sh-cmt-16.0", &mstp_clks[MSTP72]),
    159	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
    160	CLKDEV_ICK_ID("fck", "sh-mtu2", &mstp_clks[MSTP35]),
    161	CLKDEV_CON_ID("adc0", &mstp_clks[MSTP32]),
    162	CLKDEV_CON_ID("rtc0", &mstp_clks[MSTP30]),
    163};
    164
    165int __init arch_clk_init(void)
    166{
    167	int k, ret = 0;
    168
    169	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
    170		ret = clk_register(main_clks[k]);
    171
    172	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
    173
    174	if (!ret)
    175		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
    176
    177	if (!ret)
    178		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
    179
    180	return ret;
    181}