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-sh7264.c (4234B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * arch/sh/kernel/cpu/sh2a/clock-sh7264.c
      4 *
      5 * SH7264 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/* SH7264 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#define STBCR8		0xfffe041c
     23
     24static const unsigned int pll1rate[] = {8, 12};
     25
     26static unsigned int pll1_div;
     27
     28/* Fixed 32 KHz root clock for RTC */
     29static struct clk r_clk = {
     30	.rate           = 32768,
     31};
     32
     33/*
     34 * Default rate for the root input clock, reset this with clk_set_rate()
     35 * from the platform code.
     36 */
     37static struct clk extal_clk = {
     38	.rate		= 18000000,
     39};
     40
     41static unsigned long pll_recalc(struct clk *clk)
     42{
     43	unsigned long rate = clk->parent->rate / pll1_div;
     44	return rate * pll1rate[(__raw_readw(FRQCR) >> 8) & 1];
     45}
     46
     47static struct sh_clk_ops pll_clk_ops = {
     48	.recalc		= pll_recalc,
     49};
     50
     51static struct clk pll_clk = {
     52	.ops		= &pll_clk_ops,
     53	.parent		= &extal_clk,
     54	.flags		= CLK_ENABLE_ON_INIT,
     55};
     56
     57struct clk *main_clks[] = {
     58	&r_clk,
     59	&extal_clk,
     60	&pll_clk,
     61};
     62
     63static int div2[] = { 1, 2, 3, 4, 6, 8, 12 };
     64
     65static struct clk_div_mult_table div4_div_mult_table = {
     66	.divisors = div2,
     67	.nr_divisors = ARRAY_SIZE(div2),
     68};
     69
     70static struct clk_div4_table div4_table = {
     71	.div_mult_table = &div4_div_mult_table,
     72};
     73
     74enum { DIV4_I, DIV4_P,
     75       DIV4_NR };
     76
     77#define DIV4(_reg, _bit, _mask, _flags) \
     78  SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
     79
     80/* The mask field specifies the div2 entries that are valid */
     81struct clk div4_clks[DIV4_NR] = {
     82	[DIV4_I] = DIV4(FRQCR, 4, 0x7,  CLK_ENABLE_REG_16BIT
     83					| CLK_ENABLE_ON_INIT),
     84	[DIV4_P] = DIV4(FRQCR, 0, 0x78, CLK_ENABLE_REG_16BIT),
     85};
     86
     87enum {	MSTP77, MSTP74, MSTP72,
     88	MSTP60,
     89	MSTP35, MSTP34, MSTP33, MSTP32, MSTP30,
     90	MSTP_NR };
     91
     92static struct clk mstp_clks[MSTP_NR] = {
     93	[MSTP77] = SH_CLK_MSTP8(&div4_clks[DIV4_P], STBCR7, 7, 0), /* SCIF */
     94	[MSTP74] = SH_CLK_MSTP8(&div4_clks[DIV4_P], STBCR7, 4, 0), /* VDC */
     95	[MSTP72] = SH_CLK_MSTP8(&div4_clks[DIV4_P], STBCR7, 2, 0), /* CMT */
     96	[MSTP60] = SH_CLK_MSTP8(&div4_clks[DIV4_P], STBCR6, 0, 0), /* USB */
     97	[MSTP35] = SH_CLK_MSTP8(&div4_clks[DIV4_P], STBCR3, 6, 0), /* MTU2 */
     98	[MSTP34] = SH_CLK_MSTP8(&div4_clks[DIV4_P], STBCR3, 4, 0), /* SDHI0 */
     99	[MSTP33] = SH_CLK_MSTP8(&div4_clks[DIV4_P], STBCR3, 3, 0), /* SDHI1 */
    100	[MSTP32] = SH_CLK_MSTP8(&div4_clks[DIV4_P], STBCR3, 2, 0), /* ADC */
    101	[MSTP30] = SH_CLK_MSTP8(&r_clk, STBCR3, 0, 0),	/* RTC */
    102};
    103
    104static struct clk_lookup lookups[] = {
    105	/* main clocks */
    106	CLKDEV_CON_ID("rclk", &r_clk),
    107	CLKDEV_CON_ID("extal", &extal_clk),
    108	CLKDEV_CON_ID("pll_clk", &pll_clk),
    109
    110	/* DIV4 clocks */
    111	CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
    112	CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
    113
    114	/* MSTP clocks */
    115	CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP77]),
    116	CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP77]),
    117	CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP77]),
    118	CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP77]),
    119	CLKDEV_ICK_ID("fck", "sh-sci.4", &mstp_clks[MSTP77]),
    120	CLKDEV_ICK_ID("fck", "sh-sci.5", &mstp_clks[MSTP77]),
    121	CLKDEV_ICK_ID("fck", "sh-sci.6", &mstp_clks[MSTP77]),
    122	CLKDEV_ICK_ID("fck", "sh-sci.7", &mstp_clks[MSTP77]),
    123	CLKDEV_CON_ID("vdc3", &mstp_clks[MSTP74]),
    124	CLKDEV_ICK_ID("fck", "sh-cmt-16.0", &mstp_clks[MSTP72]),
    125	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP60]),
    126	CLKDEV_ICK_ID("fck", "sh-mtu2", &mstp_clks[MSTP35]),
    127	CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP34]),
    128	CLKDEV_CON_ID("sdhi1", &mstp_clks[MSTP33]),
    129	CLKDEV_CON_ID("adc0", &mstp_clks[MSTP32]),
    130	CLKDEV_CON_ID("rtc0", &mstp_clks[MSTP30]),
    131};
    132
    133int __init arch_clk_init(void)
    134{
    135	int k, ret = 0;
    136
    137	if (test_mode_pin(MODE_PIN0)) {
    138		if (test_mode_pin(MODE_PIN1))
    139			pll1_div = 3;
    140		else
    141			pll1_div = 4;
    142	} else
    143		pll1_div = 1;
    144
    145	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
    146		ret = clk_register(main_clks[k]);
    147
    148	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
    149
    150	if (!ret)
    151		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
    152
    153	if (!ret)
    154		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
    155
    156	return ret;
    157}