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

clk-cygnus.c (10117B)


      1/*
      2 * Copyright (C) 2014 Broadcom Corporation
      3 *
      4 * This program is free software; you can redistribute it and/or
      5 * modify it under the terms of the GNU General Public License as
      6 * published by the Free Software Foundation version 2.
      7 *
      8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
      9 * kind, whether express or implied; without even the implied warranty
     10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11 * GNU General Public License for more details.
     12 */
     13
     14#include <linux/kernel.h>
     15#include <linux/err.h>
     16#include <linux/clk-provider.h>
     17#include <linux/io.h>
     18#include <linux/of.h>
     19#include <linux/clkdev.h>
     20#include <linux/of_address.h>
     21#include <linux/delay.h>
     22
     23#include <dt-bindings/clock/bcm-cygnus.h>
     24#include "clk-iproc.h"
     25
     26#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
     27
     28#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
     29	.pwr_shift = ps, .iso_shift = is }
     30
     31#define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, }
     32
     33#define ASIU_DIV_VAL(o, es, hs, hw, ls, lw) \
     34		{ .offset = o, .en_shift = es, .high_shift = hs, \
     35		.high_width = hw, .low_shift = ls, .low_width = lw }
     36
     37#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
     38	.p_reset_shift = prs }
     39
     40#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\
     41	.ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas,    \
     42	.ka_width = kaw }
     43
     44#define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
     45
     46#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
     47	.hold_shift = hs, .bypass_shift = bs }
     48
     49#define ASIU_GATE_VAL(o, es) { .offset = o, .en_shift = es }
     50
     51static void __init cygnus_armpll_init(struct device_node *node)
     52{
     53	iproc_armpll_setup(node);
     54}
     55CLK_OF_DECLARE(cygnus_armpll, "brcm,cygnus-armpll", cygnus_armpll_init);
     56
     57static const struct iproc_pll_ctrl genpll = {
     58	.flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
     59		IPROC_CLK_PLL_NEEDS_SW_CFG,
     60	.aon = AON_VAL(0x0, 2, 1, 0),
     61	.reset = RESET_VAL(0x0, 11, 10),
     62	.dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
     63	.sw_ctrl = SW_CTRL_VAL(0x10, 31),
     64	.ndiv_int = REG_VAL(0x10, 20, 10),
     65	.ndiv_frac = REG_VAL(0x10, 0, 20),
     66	.pdiv = REG_VAL(0x14, 0, 4),
     67	.vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c),
     68	.status = REG_VAL(0x28, 12, 1),
     69};
     70
     71static const struct iproc_clk_ctrl genpll_clk[] = {
     72	[BCM_CYGNUS_GENPLL_AXI21_CLK] = {
     73		.channel = BCM_CYGNUS_GENPLL_AXI21_CLK,
     74		.flags = IPROC_CLK_AON,
     75		.enable = ENABLE_VAL(0x4, 6, 0, 12),
     76		.mdiv = REG_VAL(0x20, 0, 8),
     77	},
     78	[BCM_CYGNUS_GENPLL_250MHZ_CLK] = {
     79		.channel = BCM_CYGNUS_GENPLL_250MHZ_CLK,
     80		.flags = IPROC_CLK_AON,
     81		.enable = ENABLE_VAL(0x4, 7, 1, 13),
     82		.mdiv = REG_VAL(0x20, 10, 8),
     83	},
     84	[BCM_CYGNUS_GENPLL_IHOST_SYS_CLK] = {
     85		.channel = BCM_CYGNUS_GENPLL_IHOST_SYS_CLK,
     86		.flags = IPROC_CLK_AON,
     87		.enable = ENABLE_VAL(0x4, 8, 2, 14),
     88		.mdiv = REG_VAL(0x20, 20, 8),
     89	},
     90	[BCM_CYGNUS_GENPLL_ENET_SW_CLK] = {
     91		.channel = BCM_CYGNUS_GENPLL_ENET_SW_CLK,
     92		.flags = IPROC_CLK_AON,
     93		.enable = ENABLE_VAL(0x4, 9, 3, 15),
     94		.mdiv = REG_VAL(0x24, 0, 8),
     95	},
     96	[BCM_CYGNUS_GENPLL_AUDIO_125_CLK] = {
     97		.channel = BCM_CYGNUS_GENPLL_AUDIO_125_CLK,
     98		.flags = IPROC_CLK_AON,
     99		.enable = ENABLE_VAL(0x4, 10, 4, 16),
    100		.mdiv = REG_VAL(0x24, 10, 8),
    101	},
    102	[BCM_CYGNUS_GENPLL_CAN_CLK] = {
    103		.channel = BCM_CYGNUS_GENPLL_CAN_CLK,
    104		.flags = IPROC_CLK_AON,
    105		.enable = ENABLE_VAL(0x4, 11, 5, 17),
    106		.mdiv = REG_VAL(0x24, 20, 8),
    107	},
    108};
    109
    110static void __init cygnus_genpll_clk_init(struct device_node *node)
    111{
    112	iproc_pll_clk_setup(node, &genpll, NULL, 0, genpll_clk,
    113			    ARRAY_SIZE(genpll_clk));
    114}
    115CLK_OF_DECLARE(cygnus_genpll, "brcm,cygnus-genpll", cygnus_genpll_clk_init);
    116
    117static const struct iproc_pll_ctrl lcpll0 = {
    118	.flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
    119	.aon = AON_VAL(0x0, 2, 5, 4),
    120	.reset = RESET_VAL(0x0, 31, 30),
    121	.dig_filter = DF_VAL(0x0, 27, 3, 23, 4, 19, 4),
    122	.sw_ctrl = SW_CTRL_VAL(0x4, 31),
    123	.ndiv_int = REG_VAL(0x4, 16, 10),
    124	.pdiv = REG_VAL(0x4, 26, 4),
    125	.vco_ctrl = VCO_CTRL_VAL(0x10, 0x14),
    126	.status = REG_VAL(0x18, 12, 1),
    127};
    128
    129static const struct iproc_clk_ctrl lcpll0_clk[] = {
    130	[BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK] = {
    131		.channel = BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK,
    132		.flags = IPROC_CLK_AON,
    133		.enable = ENABLE_VAL(0x0, 7, 1, 13),
    134		.mdiv = REG_VAL(0x8, 0, 8),
    135	},
    136	[BCM_CYGNUS_LCPLL0_DDR_PHY_CLK] = {
    137		.channel = BCM_CYGNUS_LCPLL0_DDR_PHY_CLK,
    138		.flags = IPROC_CLK_AON,
    139		.enable = ENABLE_VAL(0x0, 8, 2, 14),
    140		.mdiv = REG_VAL(0x8, 10, 8),
    141	},
    142	[BCM_CYGNUS_LCPLL0_SDIO_CLK] = {
    143		.channel = BCM_CYGNUS_LCPLL0_SDIO_CLK,
    144		.flags = IPROC_CLK_AON,
    145		.enable = ENABLE_VAL(0x0, 9, 3, 15),
    146		.mdiv = REG_VAL(0x8, 20, 8),
    147	},
    148	[BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK] = {
    149		.channel = BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK,
    150		.flags = IPROC_CLK_AON,
    151		.enable = ENABLE_VAL(0x0, 10, 4, 16),
    152		.mdiv = REG_VAL(0xc, 0, 8),
    153	},
    154	[BCM_CYGNUS_LCPLL0_SMART_CARD_CLK] = {
    155		.channel = BCM_CYGNUS_LCPLL0_SMART_CARD_CLK,
    156		.flags = IPROC_CLK_AON,
    157		.enable = ENABLE_VAL(0x0, 11, 5, 17),
    158		.mdiv = REG_VAL(0xc, 10, 8),
    159	},
    160	[BCM_CYGNUS_LCPLL0_CH5_UNUSED] = {
    161		.channel = BCM_CYGNUS_LCPLL0_CH5_UNUSED,
    162		.flags = IPROC_CLK_AON,
    163		.enable = ENABLE_VAL(0x0, 12, 6, 18),
    164		.mdiv = REG_VAL(0xc, 20, 8),
    165	},
    166};
    167
    168static void __init cygnus_lcpll0_clk_init(struct device_node *node)
    169{
    170	iproc_pll_clk_setup(node, &lcpll0, NULL, 0, lcpll0_clk,
    171			    ARRAY_SIZE(lcpll0_clk));
    172}
    173CLK_OF_DECLARE(cygnus_lcpll0, "brcm,cygnus-lcpll0", cygnus_lcpll0_clk_init);
    174
    175/*
    176 * MIPI PLL VCO frequency parameter table
    177 */
    178static const struct iproc_pll_vco_param mipipll_vco_params[] = {
    179	/* rate (Hz) ndiv_int ndiv_frac pdiv */
    180	{ 750000000UL,   30,     0,        1 },
    181	{ 1000000000UL,  40,     0,        1 },
    182	{ 1350000000ul,  54,     0,        1 },
    183	{ 2000000000UL,  80,     0,        1 },
    184	{ 2100000000UL,  84,     0,        1 },
    185	{ 2250000000UL,  90,     0,        1 },
    186	{ 2500000000UL,  100,    0,        1 },
    187	{ 2700000000UL,  54,     0,        0 },
    188	{ 2975000000UL,  119,    0,        1 },
    189	{ 3100000000UL,  124,    0,        1 },
    190	{ 3150000000UL,  126,    0,        1 },
    191};
    192
    193static const struct iproc_pll_ctrl mipipll = {
    194	.flags = IPROC_CLK_PLL_ASIU | IPROC_CLK_PLL_HAS_NDIV_FRAC |
    195		 IPROC_CLK_NEEDS_READ_BACK,
    196	.aon = AON_VAL(0x0, 4, 17, 16),
    197	.asiu = ASIU_GATE_VAL(0x0, 3),
    198	.reset = RESET_VAL(0x0, 11, 10),
    199	.dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 4),
    200	.ndiv_int = REG_VAL(0x10, 20, 10),
    201	.ndiv_frac = REG_VAL(0x10, 0, 20),
    202	.pdiv = REG_VAL(0x14, 0, 4),
    203	.vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c),
    204	.status = REG_VAL(0x28, 12, 1),
    205};
    206
    207static const struct iproc_clk_ctrl mipipll_clk[] = {
    208	[BCM_CYGNUS_MIPIPLL_CH0_UNUSED] = {
    209		.channel = BCM_CYGNUS_MIPIPLL_CH0_UNUSED,
    210		.flags = IPROC_CLK_NEEDS_READ_BACK,
    211		.enable = ENABLE_VAL(0x4, 12, 6, 18),
    212		.mdiv = REG_VAL(0x20, 0, 8),
    213	},
    214	[BCM_CYGNUS_MIPIPLL_CH1_LCD] = {
    215		.channel = BCM_CYGNUS_MIPIPLL_CH1_LCD,
    216		.flags = IPROC_CLK_NEEDS_READ_BACK,
    217		.enable = ENABLE_VAL(0x4, 13, 7, 19),
    218		.mdiv = REG_VAL(0x20, 10, 8),
    219	},
    220	[BCM_CYGNUS_MIPIPLL_CH2_V3D] = {
    221		.channel = BCM_CYGNUS_MIPIPLL_CH2_V3D,
    222		.flags = IPROC_CLK_NEEDS_READ_BACK,
    223		.enable = ENABLE_VAL(0x4, 14, 8, 20),
    224		.mdiv = REG_VAL(0x20, 20, 8),
    225	},
    226	[BCM_CYGNUS_MIPIPLL_CH3_UNUSED] = {
    227		.channel = BCM_CYGNUS_MIPIPLL_CH3_UNUSED,
    228		.flags = IPROC_CLK_NEEDS_READ_BACK,
    229		.enable = ENABLE_VAL(0x4, 15, 9, 21),
    230		.mdiv = REG_VAL(0x24, 0, 8),
    231	},
    232	[BCM_CYGNUS_MIPIPLL_CH4_UNUSED] = {
    233		.channel = BCM_CYGNUS_MIPIPLL_CH4_UNUSED,
    234		.flags = IPROC_CLK_NEEDS_READ_BACK,
    235		.enable = ENABLE_VAL(0x4, 16, 10, 22),
    236		.mdiv = REG_VAL(0x24, 10, 8),
    237	},
    238	[BCM_CYGNUS_MIPIPLL_CH5_UNUSED] = {
    239		.channel = BCM_CYGNUS_MIPIPLL_CH5_UNUSED,
    240		.flags = IPROC_CLK_NEEDS_READ_BACK,
    241		.enable = ENABLE_VAL(0x4, 17, 11, 23),
    242		.mdiv = REG_VAL(0x24, 20, 8),
    243	},
    244};
    245
    246static void __init cygnus_mipipll_clk_init(struct device_node *node)
    247{
    248	iproc_pll_clk_setup(node, &mipipll, mipipll_vco_params,
    249			    ARRAY_SIZE(mipipll_vco_params), mipipll_clk,
    250			    ARRAY_SIZE(mipipll_clk));
    251}
    252CLK_OF_DECLARE(cygnus_mipipll, "brcm,cygnus-mipipll", cygnus_mipipll_clk_init);
    253
    254static const struct iproc_asiu_div asiu_div[] = {
    255	[BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_DIV_VAL(0x0, 31, 16, 10, 0, 10),
    256	[BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_DIV_VAL(0x4, 31, 16, 10, 0, 10),
    257	[BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_DIV_VAL(0x8, 31, 16, 10, 0, 10),
    258};
    259
    260static const struct iproc_asiu_gate asiu_gate[] = {
    261	[BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_GATE_VAL(0x0, 7),
    262	[BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_GATE_VAL(0x0, 9),
    263	[BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_GATE_VAL(IPROC_CLK_INVALID_OFFSET, 0),
    264};
    265
    266static void __init cygnus_asiu_init(struct device_node *node)
    267{
    268	iproc_asiu_setup(node, asiu_div, asiu_gate, ARRAY_SIZE(asiu_div));
    269}
    270CLK_OF_DECLARE(cygnus_asiu_clk, "brcm,cygnus-asiu-clk", cygnus_asiu_init);
    271
    272static const struct iproc_pll_ctrl audiopll = {
    273	.flags = IPROC_CLK_PLL_NEEDS_SW_CFG | IPROC_CLK_PLL_HAS_NDIV_FRAC |
    274		IPROC_CLK_PLL_USER_MODE_ON | IPROC_CLK_PLL_RESET_ACTIVE_LOW |
    275		IPROC_CLK_PLL_CALC_PARAM,
    276	.reset = RESET_VAL(0x5c, 0, 1),
    277	.dig_filter = DF_VAL(0x48, 0, 3, 6, 4, 3, 3),
    278	.sw_ctrl = SW_CTRL_VAL(0x4, 0),
    279	.ndiv_int = REG_VAL(0x8, 0, 10),
    280	.ndiv_frac = REG_VAL(0x8, 10, 20),
    281	.pdiv = REG_VAL(0x44, 0, 4),
    282	.vco_ctrl = VCO_CTRL_VAL(0x0c, 0x10),
    283	.status = REG_VAL(0x54, 0, 1),
    284	.macro_mode = REG_VAL(0x0, 0, 3),
    285};
    286
    287static const struct iproc_clk_ctrl audiopll_clk[] = {
    288	[BCM_CYGNUS_AUDIOPLL_CH0] = {
    289		.channel = BCM_CYGNUS_AUDIOPLL_CH0,
    290		.flags = IPROC_CLK_AON | IPROC_CLK_MCLK_DIV_BY_2,
    291		.enable = ENABLE_VAL(0x14, 8, 10, 9),
    292		.mdiv = REG_VAL(0x14, 0, 8),
    293	},
    294	[BCM_CYGNUS_AUDIOPLL_CH1] = {
    295		.channel = BCM_CYGNUS_AUDIOPLL_CH1,
    296		.flags = IPROC_CLK_AON,
    297		.enable = ENABLE_VAL(0x18, 8, 10, 9),
    298		.mdiv = REG_VAL(0x18, 0, 8),
    299	},
    300	[BCM_CYGNUS_AUDIOPLL_CH2] = {
    301		.channel = BCM_CYGNUS_AUDIOPLL_CH2,
    302		.flags = IPROC_CLK_AON,
    303		.enable = ENABLE_VAL(0x1c, 8, 10, 9),
    304		.mdiv = REG_VAL(0x1c, 0, 8),
    305	},
    306};
    307
    308static void __init cygnus_audiopll_clk_init(struct device_node *node)
    309{
    310	iproc_pll_clk_setup(node, &audiopll, NULL, 0,
    311			    audiopll_clk,  ARRAY_SIZE(audiopll_clk));
    312}
    313CLK_OF_DECLARE(cygnus_audiopll, "brcm,cygnus-audiopll",
    314			cygnus_audiopll_clk_init);