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

jz4725b-cgu.c (6262B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Ingenic JZ4725B SoC CGU driver
      4 *
      5 * Copyright (C) 2018 Paul Cercueil
      6 * Author: Paul Cercueil <paul@crapouillou.net>
      7 */
      8
      9#include <linux/clk-provider.h>
     10#include <linux/delay.h>
     11#include <linux/of.h>
     12
     13#include <dt-bindings/clock/ingenic,jz4725b-cgu.h>
     14
     15#include "cgu.h"
     16#include "pm.h"
     17
     18/* CGU register offsets */
     19#define CGU_REG_CPCCR		0x00
     20#define CGU_REG_LCR		0x04
     21#define CGU_REG_CPPCR		0x10
     22#define CGU_REG_CLKGR		0x20
     23#define CGU_REG_OPCR		0x24
     24#define CGU_REG_I2SCDR		0x60
     25#define CGU_REG_LPCDR		0x64
     26#define CGU_REG_MSCCDR		0x68
     27#define CGU_REG_SSICDR		0x74
     28#define CGU_REG_CIMCDR		0x78
     29
     30/* bits within the LCR register */
     31#define LCR_SLEEP		BIT(0)
     32
     33static struct ingenic_cgu *cgu;
     34
     35static const s8 pll_od_encoding[4] = {
     36	0x0, 0x1, -1, 0x3,
     37};
     38
     39static const u8 jz4725b_cgu_cpccr_div_table[] = {
     40	1, 2, 3, 4, 6, 8,
     41};
     42
     43static const u8 jz4725b_cgu_pll_half_div_table[] = {
     44	2, 1,
     45};
     46
     47static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
     48
     49	/* External clocks */
     50
     51	[JZ4725B_CLK_EXT] = { "ext", CGU_CLK_EXT },
     52	[JZ4725B_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT },
     53
     54	[JZ4725B_CLK_PLL] = {
     55		"pll", CGU_CLK_PLL,
     56		.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
     57		.pll = {
     58			.reg = CGU_REG_CPPCR,
     59			.rate_multiplier = 1,
     60			.m_shift = 23,
     61			.m_bits = 9,
     62			.m_offset = 2,
     63			.n_shift = 18,
     64			.n_bits = 5,
     65			.n_offset = 2,
     66			.od_shift = 16,
     67			.od_bits = 2,
     68			.od_max = 4,
     69			.od_encoding = pll_od_encoding,
     70			.stable_bit = 10,
     71			.bypass_reg = CGU_REG_CPPCR,
     72			.bypass_bit = 9,
     73			.enable_bit = 8,
     74		},
     75	},
     76
     77	/* Muxes & dividers */
     78
     79	[JZ4725B_CLK_PLL_HALF] = {
     80		"pll half", CGU_CLK_DIV,
     81		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
     82		.div = {
     83			CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0,
     84			jz4725b_cgu_pll_half_div_table,
     85		},
     86	},
     87
     88	[JZ4725B_CLK_CCLK] = {
     89		"cclk", CGU_CLK_DIV,
     90		/*
     91		 * Disabling the CPU clock or any parent clocks will hang the
     92		 * system; mark it critical.
     93		 */
     94		.flags = CLK_IS_CRITICAL,
     95		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
     96		.div = {
     97			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
     98			jz4725b_cgu_cpccr_div_table,
     99		},
    100	},
    101
    102	[JZ4725B_CLK_HCLK] = {
    103		"hclk", CGU_CLK_DIV,
    104		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
    105		.div = {
    106			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
    107			jz4725b_cgu_cpccr_div_table,
    108		},
    109	},
    110
    111	[JZ4725B_CLK_PCLK] = {
    112		"pclk", CGU_CLK_DIV,
    113		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
    114		.div = {
    115			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
    116			jz4725b_cgu_cpccr_div_table,
    117		},
    118	},
    119
    120	[JZ4725B_CLK_MCLK] = {
    121		"mclk", CGU_CLK_DIV,
    122		/*
    123		 * Disabling MCLK or its parents will render DRAM
    124		 * inaccessible; mark it critical.
    125		 */
    126		.flags = CLK_IS_CRITICAL,
    127		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
    128		.div = {
    129			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
    130			jz4725b_cgu_cpccr_div_table,
    131		},
    132	},
    133
    134	[JZ4725B_CLK_IPU] = {
    135		"ipu", CGU_CLK_DIV | CGU_CLK_GATE,
    136		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
    137		.div = {
    138			CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
    139			jz4725b_cgu_cpccr_div_table,
    140		},
    141		.gate = { CGU_REG_CLKGR, 13 },
    142	},
    143
    144	[JZ4725B_CLK_LCD] = {
    145		"lcd", CGU_CLK_DIV | CGU_CLK_GATE,
    146		.parents = { JZ4725B_CLK_PLL_HALF, -1, -1, -1 },
    147		.div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
    148		.gate = { CGU_REG_CLKGR, 9 },
    149	},
    150
    151	[JZ4725B_CLK_I2S] = {
    152		"i2s", CGU_CLK_MUX | CGU_CLK_DIV,
    153		.parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL_HALF, -1, -1 },
    154		.mux = { CGU_REG_CPCCR, 31, 1 },
    155		.div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 },
    156	},
    157
    158	[JZ4725B_CLK_SPI] = {
    159		"spi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
    160		.parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL, -1, -1 },
    161		.mux = { CGU_REG_SSICDR, 31, 1 },
    162		.div = { CGU_REG_SSICDR, 0, 1, 4, -1, -1, -1 },
    163		.gate = { CGU_REG_CLKGR, 4 },
    164	},
    165
    166	[JZ4725B_CLK_MMC_MUX] = {
    167		"mmc_mux", CGU_CLK_DIV,
    168		.parents = { JZ4725B_CLK_PLL_HALF, -1, -1, -1 },
    169		.div = { CGU_REG_MSCCDR, 0, 1, 5, -1, -1, -1 },
    170	},
    171
    172	[JZ4725B_CLK_UDC] = {
    173		"udc", CGU_CLK_MUX | CGU_CLK_DIV,
    174		.parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL_HALF, -1, -1 },
    175		.mux = { CGU_REG_CPCCR, 29, 1 },
    176		.div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 },
    177	},
    178
    179	/* Gate-only clocks */
    180
    181	[JZ4725B_CLK_UART] = {
    182		"uart", CGU_CLK_GATE,
    183		.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
    184		.gate = { CGU_REG_CLKGR, 0 },
    185	},
    186
    187	[JZ4725B_CLK_DMA] = {
    188		"dma", CGU_CLK_GATE,
    189		.parents = { JZ4725B_CLK_PCLK, -1, -1, -1 },
    190		.gate = { CGU_REG_CLKGR, 12 },
    191	},
    192
    193	[JZ4725B_CLK_ADC] = {
    194		"adc", CGU_CLK_GATE,
    195		.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
    196		.gate = { CGU_REG_CLKGR, 7 },
    197	},
    198
    199	[JZ4725B_CLK_I2C] = {
    200		"i2c", CGU_CLK_GATE,
    201		.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
    202		.gate = { CGU_REG_CLKGR, 3 },
    203	},
    204
    205	[JZ4725B_CLK_AIC] = {
    206		"aic", CGU_CLK_GATE,
    207		.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
    208		.gate = { CGU_REG_CLKGR, 5 },
    209	},
    210
    211	[JZ4725B_CLK_MMC0] = {
    212		"mmc0", CGU_CLK_GATE,
    213		.parents = { JZ4725B_CLK_MMC_MUX, -1, -1, -1 },
    214		.gate = { CGU_REG_CLKGR, 6 },
    215	},
    216
    217	[JZ4725B_CLK_MMC1] = {
    218		"mmc1", CGU_CLK_GATE,
    219		.parents = { JZ4725B_CLK_MMC_MUX, -1, -1, -1 },
    220		.gate = { CGU_REG_CLKGR, 16 },
    221	},
    222
    223	[JZ4725B_CLK_BCH] = {
    224		"bch", CGU_CLK_GATE,
    225		.parents = { JZ4725B_CLK_MCLK/* not sure */, -1, -1, -1 },
    226		.gate = { CGU_REG_CLKGR, 11 },
    227	},
    228
    229	[JZ4725B_CLK_TCU] = {
    230		"tcu", CGU_CLK_GATE,
    231		.parents = { JZ4725B_CLK_EXT/* not sure */, -1, -1, -1 },
    232		.gate = { CGU_REG_CLKGR, 1 },
    233	},
    234
    235	[JZ4725B_CLK_EXT512] = {
    236		"ext/512", CGU_CLK_FIXDIV,
    237		.parents = { JZ4725B_CLK_EXT },
    238
    239		/* Doc calls it EXT512, but it seems to be /256... */
    240		.fixdiv = { 256 },
    241	},
    242
    243	[JZ4725B_CLK_RTC] = {
    244		"rtc", CGU_CLK_MUX,
    245		.parents = { JZ4725B_CLK_EXT512, JZ4725B_CLK_OSC32K, -1, -1 },
    246		.mux = { CGU_REG_OPCR, 2, 1},
    247	},
    248
    249	[JZ4725B_CLK_UDC_PHY] = {
    250		"udc_phy", CGU_CLK_GATE,
    251		.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
    252		.gate = { CGU_REG_OPCR, 6, true },
    253	},
    254};
    255
    256static void __init jz4725b_cgu_init(struct device_node *np)
    257{
    258	int retval;
    259
    260	cgu = ingenic_cgu_new(jz4725b_cgu_clocks,
    261			      ARRAY_SIZE(jz4725b_cgu_clocks), np);
    262	if (!cgu) {
    263		pr_err("%s: failed to initialise CGU\n", __func__);
    264		return;
    265	}
    266
    267	retval = ingenic_cgu_register_clocks(cgu);
    268	if (retval)
    269		pr_err("%s: failed to register CGU Clocks\n", __func__);
    270
    271	ingenic_cgu_register_syscore_ops(cgu);
    272}
    273CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init);