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

jz4740-cgu.c (6363B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Ingenic JZ4740 SoC CGU driver
      4 *
      5 * Copyright (c) 2015 Imagination Technologies
      6 * Author: Paul Burton <paul.burton@mips.com>
      7 */
      8
      9#include <linux/clk-provider.h>
     10#include <linux/delay.h>
     11#include <linux/io.h>
     12#include <linux/of.h>
     13
     14#include <dt-bindings/clock/ingenic,jz4740-cgu.h>
     15
     16#include "cgu.h"
     17#include "pm.h"
     18
     19/* CGU register offsets */
     20#define CGU_REG_CPCCR		0x00
     21#define CGU_REG_LCR		0x04
     22#define CGU_REG_CPPCR		0x10
     23#define CGU_REG_CLKGR		0x20
     24#define CGU_REG_SCR		0x24
     25#define CGU_REG_I2SCDR		0x60
     26#define CGU_REG_LPCDR		0x64
     27#define CGU_REG_MSCCDR		0x68
     28#define CGU_REG_UHCCDR		0x6c
     29#define CGU_REG_SSICDR		0x74
     30
     31/* bits within a PLL control register */
     32#define PLLCTL_M_SHIFT		23
     33#define PLLCTL_M_MASK		(0x1ff << PLLCTL_M_SHIFT)
     34#define PLLCTL_N_SHIFT		18
     35#define PLLCTL_N_MASK		(0x1f << PLLCTL_N_SHIFT)
     36#define PLLCTL_OD_SHIFT		16
     37#define PLLCTL_OD_MASK		(0x3 << PLLCTL_OD_SHIFT)
     38#define PLLCTL_STABLE		(1 << 10)
     39#define PLLCTL_BYPASS		(1 << 9)
     40#define PLLCTL_ENABLE		(1 << 8)
     41
     42/* bits within the LCR register */
     43#define LCR_SLEEP		(1 << 0)
     44
     45/* bits within the CLKGR register */
     46#define CLKGR_UDC		(1 << 11)
     47
     48static struct ingenic_cgu *cgu;
     49
     50static const s8 pll_od_encoding[4] = {
     51	0x0, 0x1, -1, 0x3,
     52};
     53
     54static const u8 jz4740_cgu_cpccr_div_table[] = {
     55	1, 2, 3, 4, 6, 8, 12, 16, 24, 32,
     56};
     57
     58static const u8 jz4740_cgu_pll_half_div_table[] = {
     59	2, 1,
     60};
     61
     62static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
     63
     64	/* External clocks */
     65
     66	[JZ4740_CLK_EXT] = { "ext", CGU_CLK_EXT },
     67	[JZ4740_CLK_RTC] = { "rtc", CGU_CLK_EXT },
     68
     69	[JZ4740_CLK_PLL] = {
     70		"pll", CGU_CLK_PLL,
     71		.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
     72		.pll = {
     73			.reg = CGU_REG_CPPCR,
     74			.rate_multiplier = 1,
     75			.m_shift = 23,
     76			.m_bits = 9,
     77			.m_offset = 2,
     78			.n_shift = 18,
     79			.n_bits = 5,
     80			.n_offset = 2,
     81			.od_shift = 16,
     82			.od_bits = 2,
     83			.od_max = 4,
     84			.od_encoding = pll_od_encoding,
     85			.stable_bit = 10,
     86			.bypass_reg = CGU_REG_CPPCR,
     87			.bypass_bit = 9,
     88			.enable_bit = 8,
     89		},
     90	},
     91
     92	/* Muxes & dividers */
     93
     94	[JZ4740_CLK_PLL_HALF] = {
     95		"pll half", CGU_CLK_DIV,
     96		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
     97		.div = {
     98			CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0,
     99			jz4740_cgu_pll_half_div_table,
    100		},
    101	},
    102
    103	[JZ4740_CLK_CCLK] = {
    104		"cclk", CGU_CLK_DIV,
    105		/*
    106		 * Disabling the CPU clock or any parent clocks will hang the
    107		 * system; mark it critical.
    108		 */
    109		.flags = CLK_IS_CRITICAL,
    110		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
    111		.div = {
    112			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
    113			jz4740_cgu_cpccr_div_table,
    114		},
    115	},
    116
    117	[JZ4740_CLK_HCLK] = {
    118		"hclk", CGU_CLK_DIV,
    119		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
    120		.div = {
    121			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
    122			jz4740_cgu_cpccr_div_table,
    123		},
    124	},
    125
    126	[JZ4740_CLK_PCLK] = {
    127		"pclk", CGU_CLK_DIV,
    128		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
    129		.div = {
    130			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
    131			jz4740_cgu_cpccr_div_table,
    132		},
    133	},
    134
    135	[JZ4740_CLK_MCLK] = {
    136		"mclk", CGU_CLK_DIV,
    137		/*
    138		 * Disabling MCLK or its parents will render DRAM
    139		 * inaccessible; mark it critical.
    140		 */
    141		.flags = CLK_IS_CRITICAL,
    142		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
    143		.div = {
    144			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
    145			jz4740_cgu_cpccr_div_table,
    146		},
    147	},
    148
    149	[JZ4740_CLK_LCD] = {
    150		"lcd", CGU_CLK_DIV | CGU_CLK_GATE,
    151		.parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
    152		.div = {
    153			CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1, 0,
    154			jz4740_cgu_cpccr_div_table,
    155		},
    156		.gate = { CGU_REG_CLKGR, 10 },
    157	},
    158
    159	[JZ4740_CLK_LCD_PCLK] = {
    160		"lcd_pclk", CGU_CLK_DIV,
    161		.parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
    162		.div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
    163	},
    164
    165	[JZ4740_CLK_I2S] = {
    166		"i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
    167		.parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 },
    168		.mux = { CGU_REG_CPCCR, 31, 1 },
    169		.div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 },
    170		.gate = { CGU_REG_CLKGR, 6 },
    171	},
    172
    173	[JZ4740_CLK_SPI] = {
    174		"spi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
    175		.parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL, -1, -1 },
    176		.mux = { CGU_REG_SSICDR, 31, 1 },
    177		.div = { CGU_REG_SSICDR, 0, 1, 4, -1, -1, -1 },
    178		.gate = { CGU_REG_CLKGR, 4 },
    179	},
    180
    181	[JZ4740_CLK_MMC] = {
    182		"mmc", CGU_CLK_DIV | CGU_CLK_GATE,
    183		.parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
    184		.div = { CGU_REG_MSCCDR, 0, 1, 5, -1, -1, -1 },
    185		.gate = { CGU_REG_CLKGR, 7 },
    186	},
    187
    188	[JZ4740_CLK_UHC] = {
    189		"uhc", CGU_CLK_DIV | CGU_CLK_GATE,
    190		.parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
    191		.div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 },
    192		.gate = { CGU_REG_CLKGR, 14 },
    193	},
    194
    195	[JZ4740_CLK_UDC] = {
    196		"udc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
    197		.parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 },
    198		.mux = { CGU_REG_CPCCR, 29, 1 },
    199		.div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 },
    200		.gate = { CGU_REG_SCR, 6, true },
    201	},
    202
    203	/* Gate-only clocks */
    204
    205	[JZ4740_CLK_UART0] = {
    206		"uart0", CGU_CLK_GATE,
    207		.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
    208		.gate = { CGU_REG_CLKGR, 0 },
    209	},
    210
    211	[JZ4740_CLK_UART1] = {
    212		"uart1", CGU_CLK_GATE,
    213		.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
    214		.gate = { CGU_REG_CLKGR, 15 },
    215	},
    216
    217	[JZ4740_CLK_DMA] = {
    218		"dma", CGU_CLK_GATE,
    219		.parents = { JZ4740_CLK_PCLK, -1, -1, -1 },
    220		.gate = { CGU_REG_CLKGR, 12 },
    221	},
    222
    223	[JZ4740_CLK_IPU] = {
    224		"ipu", CGU_CLK_GATE,
    225		.parents = { JZ4740_CLK_PCLK, -1, -1, -1 },
    226		.gate = { CGU_REG_CLKGR, 13 },
    227	},
    228
    229	[JZ4740_CLK_ADC] = {
    230		"adc", CGU_CLK_GATE,
    231		.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
    232		.gate = { CGU_REG_CLKGR, 8 },
    233	},
    234
    235	[JZ4740_CLK_I2C] = {
    236		"i2c", CGU_CLK_GATE,
    237		.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
    238		.gate = { CGU_REG_CLKGR, 3 },
    239	},
    240
    241	[JZ4740_CLK_AIC] = {
    242		"aic", CGU_CLK_GATE,
    243		.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
    244		.gate = { CGU_REG_CLKGR, 5 },
    245	},
    246
    247	[JZ4740_CLK_TCU] = {
    248		"tcu", CGU_CLK_GATE,
    249		.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
    250		.gate = { CGU_REG_CLKGR, 1 },
    251	},
    252};
    253
    254static void __init jz4740_cgu_init(struct device_node *np)
    255{
    256	int retval;
    257
    258	cgu = ingenic_cgu_new(jz4740_cgu_clocks,
    259			      ARRAY_SIZE(jz4740_cgu_clocks), np);
    260	if (!cgu) {
    261		pr_err("%s: failed to initialise CGU\n", __func__);
    262		return;
    263	}
    264
    265	retval = ingenic_cgu_register_clocks(cgu);
    266	if (retval)
    267		pr_err("%s: failed to register CGU Clocks\n", __func__);
    268
    269	ingenic_cgu_register_syscore_ops(cgu);
    270}
    271CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init);