1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * (C) Copyright 2015 Google, Inc 4 */ 5 6#ifndef _ASM_ARCH_CLOCK_H 7#define _ASM_ARCH_CLOCK_H 8 9struct udevice; 10 11/* define pll mode */ 12#define RKCLK_PLL_MODE_SLOW 0 13#define RKCLK_PLL_MODE_NORMAL 1 14#define RKCLK_PLL_MODE_DEEP 2 15 16enum { 17 ROCKCHIP_SYSCON_NOC, 18 ROCKCHIP_SYSCON_GRF, 19 ROCKCHIP_SYSCON_SGRF, 20 ROCKCHIP_SYSCON_PMU, 21 ROCKCHIP_SYSCON_PMUGRF, 22 ROCKCHIP_SYSCON_PMUSGRF, 23 ROCKCHIP_SYSCON_CIC, 24 ROCKCHIP_SYSCON_MSCH, 25 ROCKCHIP_SYSCON_USBGRF, 26 ROCKCHIP_SYSCON_PCIE30_PHY_GRF, 27 ROCKCHIP_SYSCON_PHP_GRF, 28 ROCKCHIP_SYSCON_PIPE_PHY0_GRF, 29 ROCKCHIP_SYSCON_PIPE_PHY1_GRF, 30 ROCKCHIP_SYSCON_PIPE_PHY2_GRF, 31 ROCKCHIP_SYSCON_VOP_GRF, 32 ROCKCHIP_SYSCON_VO_GRF, 33}; 34 35/* Standard Rockchip clock numbers */ 36enum rk_clk_id { 37 CLK_OSC, 38 CLK_ARM, 39 CLK_DDR, 40 CLK_CODEC, 41 CLK_GENERAL, 42 CLK_NEW, 43 44 CLK_COUNT, 45}; 46 47#define PLL(_type, _id, _con, _mode, _mshift, \ 48 _lshift, _pflags, _rtable) \ 49 { \ 50 .id = _id, \ 51 .type = _type, \ 52 .con_offset = _con, \ 53 .mode_offset = _mode, \ 54 .mode_shift = _mshift, \ 55 .lock_shift = _lshift, \ 56 .pll_flags = _pflags, \ 57 .rate_table = _rtable, \ 58 } 59 60#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ 61 _postdiv2, _dsmpd, _frac) \ 62{ \ 63 .rate = _rate##U, \ 64 .fbdiv = _fbdiv, \ 65 .postdiv1 = _postdiv1, \ 66 .refdiv = _refdiv, \ 67 .postdiv2 = _postdiv2, \ 68 .dsmpd = _dsmpd, \ 69 .frac = _frac, \ 70} 71 72#define RK3588_PLL_RATE(_rate, _p, _m, _s, _k) \ 73{ \ 74 .rate = _rate##U, \ 75 .p = _p, \ 76 .m = _m, \ 77 .s = _s, \ 78 .k = _k, \ 79} 80 81struct rockchip_pll_rate_table { 82 unsigned long rate; 83 unsigned int nr; 84 unsigned int nf; 85 unsigned int no; 86 unsigned int nb; 87 /* for RK3036/RK3399 */ 88 unsigned int fbdiv; 89 unsigned int postdiv1; 90 unsigned int refdiv; 91 unsigned int postdiv2; 92 unsigned int dsmpd; 93 unsigned int frac; 94 /* for RK3588 */ 95 unsigned int m; 96 unsigned int p; 97 unsigned int s; 98 unsigned int k; 99}; 100 101enum rockchip_pll_type { 102 pll_rk3036, 103 pll_rk3066, 104 pll_rk3328, 105 pll_rk3366, 106 pll_rk3399, 107 pll_rk3588, 108}; 109 110struct rockchip_pll_clock { 111 unsigned int id; 112 unsigned int con_offset; 113 unsigned int mode_offset; 114 unsigned int mode_shift; 115 unsigned int lock_shift; 116 enum rockchip_pll_type type; 117 unsigned int pll_flags; 118 struct rockchip_pll_rate_table *rate_table; 119 unsigned int mode_mask; 120}; 121 122struct rockchip_cpu_rate_table { 123 unsigned long rate; 124 unsigned int aclk_div; 125 unsigned int pclk_div; 126}; 127 128int rockchip_pll_set_rate(struct rockchip_pll_clock *pll, 129 void __iomem *base, ulong clk_id, 130 ulong drate); 131ulong rockchip_pll_get_rate(struct rockchip_pll_clock *pll, 132 void __iomem *base, ulong clk_id); 133const struct rockchip_cpu_rate_table * 134rockchip_get_cpu_settings(struct rockchip_cpu_rate_table *cpu_table, 135 ulong rate); 136 137static inline int rk_pll_id(enum rk_clk_id clk_id) 138{ 139 return clk_id - 1; 140} 141 142struct sysreset_reg { 143 unsigned int glb_srst_fst_value; 144 unsigned int glb_srst_snd_value; 145}; 146 147/** 148 * clk_get_divisor() - Calculate the required clock divisior 149 * 150 * Given an input rate and a required output_rate, calculate the Rockchip 151 * divisor needed to achieve this. 152 * 153 * @input_rate: Input clock rate in Hz 154 * @output_rate: Output clock rate in Hz 155 * Return: divisor register value to use 156 */ 157static inline u32 clk_get_divisor(ulong input_rate, uint output_rate) 158{ 159 uint clk_div; 160 161 clk_div = input_rate / output_rate; 162 clk_div = (clk_div + 1) & 0xfffe; 163 164 return clk_div; 165} 166 167/** 168 * rockchip_get_cru() - get a pointer to the clock/reset unit registers 169 * 170 * Return: pointer to registers, or -ve error on error 171 */ 172void *rockchip_get_cru(void); 173 174/** 175 * rockchip_get_pmucru() - get a pointer to the clock/reset unit registers 176 * 177 * Return: pointer to registers, or -ve error on error 178 */ 179void *rockchip_get_pmucru(void); 180 181struct rockchip_cru; 182struct rk3288_grf; 183 184void rk3288_clk_configure_cpu(struct rockchip_cru *cru, struct rk3288_grf *grf); 185 186int rockchip_get_clk(struct udevice **devp); 187 188/* 189 * rockchip_reset_bind() - Bind soft reset device as child of clock device 190 * 191 * @pdev: clock udevice 192 * @reg_offset: the first offset in cru for softreset registers 193 * @reg_number: the reg numbers of softreset registers 194 * Return: 0 success, or error value 195 */ 196int rockchip_reset_bind(struct udevice *pdev, u32 reg_offset, u32 reg_number); 197/* 198 * rockchip_reset_bind_lut() - Bind soft reset device as child of clock device 199 * using a dedicated SoC lookup table 200 * @pdev: clock udevice 201 * @lookup_table: register lookup_table dedicated to SoC 202 * @reg_offset: the first offset in cru for softreset registers 203 * @reg_number: the reg numbers of softreset registers 204 * Return: 0 success, or error value 205 */ 206int rockchip_reset_bind_lut(struct udevice *pdev, const int *lookup_table, 207 u32 reg_offset, u32 reg_number); 208/* 209 * rk3588_reset_bind_lut() - Bind soft reset device as child of clock device 210 * using dedicated RK3588 lookup table 211 * 212 * @pdev: clock udevice 213 * @reg_offset: the first offset in cru for softreset registers 214 * @reg_number: the reg numbers of softreset registers 215 * Return: 0 success, or error value 216 */ 217int rk3588_reset_bind_lut(struct udevice *pdev, u32 reg_offset, u32 reg_number); 218 219#endif 220