126ad30e9SSimon Glass /* 226ad30e9SSimon Glass * (C) Copyright 2015 Google, Inc 326ad30e9SSimon Glass * 426ad30e9SSimon Glass * SPDX-License-Identifier: GPL-2.0 526ad30e9SSimon Glass */ 626ad30e9SSimon Glass 726ad30e9SSimon Glass #ifndef _ASM_ARCH_CLOCK_H 826ad30e9SSimon Glass #define _ASM_ARCH_CLOCK_H 926ad30e9SSimon Glass 1026ad30e9SSimon Glass /* define pll mode */ 1126ad30e9SSimon Glass #define RKCLK_PLL_MODE_SLOW 0 1226ad30e9SSimon Glass #define RKCLK_PLL_MODE_NORMAL 1 132f0a72b1SElaine Zhang #define RKCLK_PLL_MODE_DEEP 2 1426ad30e9SSimon Glass 15*c6f7c1a3SJoseph Chen /* 16*c6f7c1a3SJoseph Chen * PLL flags 17*c6f7c1a3SJoseph Chen */ 18*c6f7c1a3SJoseph Chen #define ROCKCHIP_PLL_SYNC_RATE BIT(0) 19*c6f7c1a3SJoseph Chen /* normal mode only. now only for pll_rk3036, pll_rk3328 type */ 20*c6f7c1a3SJoseph Chen #define ROCKCHIP_PLL_FIXED_MODE BIT(1) 21*c6f7c1a3SJoseph Chen 2226ad30e9SSimon Glass enum { 2326ad30e9SSimon Glass ROCKCHIP_SYSCON_NOC, 2426ad30e9SSimon Glass ROCKCHIP_SYSCON_GRF, 2526ad30e9SSimon Glass ROCKCHIP_SYSCON_SGRF, 2626ad30e9SSimon Glass ROCKCHIP_SYSCON_PMU, 27c55e30ebSKever Yang ROCKCHIP_SYSCON_PMUGRF, 282adb9812SKever Yang ROCKCHIP_SYSCON_PMUSGRF, 292adb9812SKever Yang ROCKCHIP_SYSCON_CIC, 30168eef7aSKever Yang ROCKCHIP_SYSCON_MSCH, 31be82169bSWu Liang feng ROCKCHIP_SYSCON_USBGRF, 32e1cfe1c9SJoseph Chen ROCKCHIP_SYSCON_PCIE30_PHY_GRF, 33e1cfe1c9SJoseph Chen ROCKCHIP_SYSCON_PHP_GRF, 34e1cfe1c9SJoseph Chen ROCKCHIP_SYSCON_PIPE_PHY0_GRF, 35e1cfe1c9SJoseph Chen ROCKCHIP_SYSCON_PIPE_PHY1_GRF, 36e1cfe1c9SJoseph Chen ROCKCHIP_SYSCON_PIPE_PHY2_GRF, 3786b248b4SDamon Ding ROCKCHIP_SYSCON_VOP_GRF, 3886b248b4SDamon Ding ROCKCHIP_SYSCON_VO_GRF, 3926ad30e9SSimon Glass }; 4026ad30e9SSimon Glass 4126ad30e9SSimon Glass /* Standard Rockchip clock numbers */ 4226ad30e9SSimon Glass enum rk_clk_id { 4326ad30e9SSimon Glass CLK_OSC, 4426ad30e9SSimon Glass CLK_ARM, 4526ad30e9SSimon Glass CLK_DDR, 4626ad30e9SSimon Glass CLK_CODEC, 4726ad30e9SSimon Glass CLK_GENERAL, 4826ad30e9SSimon Glass CLK_NEW, 4926ad30e9SSimon Glass 5026ad30e9SSimon Glass CLK_COUNT, 5126ad30e9SSimon Glass }; 5226ad30e9SSimon Glass 532f0a72b1SElaine Zhang #define PLL(_type, _id, _con, _mode, _mshift, \ 542f0a72b1SElaine Zhang _lshift, _pflags, _rtable) \ 552f0a72b1SElaine Zhang { \ 562f0a72b1SElaine Zhang .id = _id, \ 572f0a72b1SElaine Zhang .type = _type, \ 582f0a72b1SElaine Zhang .con_offset = _con, \ 592f0a72b1SElaine Zhang .mode_offset = _mode, \ 602f0a72b1SElaine Zhang .mode_shift = _mshift, \ 612f0a72b1SElaine Zhang .lock_shift = _lshift, \ 622f0a72b1SElaine Zhang .pll_flags = _pflags, \ 632f0a72b1SElaine Zhang .rate_table = _rtable, \ 642f0a72b1SElaine Zhang } 652f0a72b1SElaine Zhang 662f0a72b1SElaine Zhang #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ 672f0a72b1SElaine Zhang _postdiv2, _dsmpd, _frac) \ 682f0a72b1SElaine Zhang { \ 692f0a72b1SElaine Zhang .rate = _rate##U, \ 702f0a72b1SElaine Zhang .fbdiv = _fbdiv, \ 712f0a72b1SElaine Zhang .postdiv1 = _postdiv1, \ 722f0a72b1SElaine Zhang .refdiv = _refdiv, \ 732f0a72b1SElaine Zhang .postdiv2 = _postdiv2, \ 742f0a72b1SElaine Zhang .dsmpd = _dsmpd, \ 752f0a72b1SElaine Zhang .frac = _frac, \ 762f0a72b1SElaine Zhang } 772f0a72b1SElaine Zhang 78a962a5fdSElaine Zhang #define RK3588_PLL_RATE(_rate, _p, _m, _s, _k) \ 79a962a5fdSElaine Zhang { \ 80a962a5fdSElaine Zhang .rate = _rate##U, \ 81a962a5fdSElaine Zhang .p = _p, \ 82a962a5fdSElaine Zhang .m = _m, \ 83a962a5fdSElaine Zhang .s = _s, \ 84a962a5fdSElaine Zhang .k = _k, \ 85a962a5fdSElaine Zhang } 86a962a5fdSElaine Zhang 872f0a72b1SElaine Zhang struct rockchip_pll_rate_table { 882f0a72b1SElaine Zhang unsigned long rate; 892f0a72b1SElaine Zhang unsigned int nr; 902f0a72b1SElaine Zhang unsigned int nf; 912f0a72b1SElaine Zhang unsigned int no; 922f0a72b1SElaine Zhang unsigned int nb; 932f0a72b1SElaine Zhang /* for RK3036/RK3399 */ 942f0a72b1SElaine Zhang unsigned int fbdiv; 952f0a72b1SElaine Zhang unsigned int postdiv1; 962f0a72b1SElaine Zhang unsigned int refdiv; 972f0a72b1SElaine Zhang unsigned int postdiv2; 982f0a72b1SElaine Zhang unsigned int dsmpd; 992f0a72b1SElaine Zhang unsigned int frac; 100a962a5fdSElaine Zhang /* for RK3588 */ 101a962a5fdSElaine Zhang unsigned int m; 102a962a5fdSElaine Zhang unsigned int p; 103a962a5fdSElaine Zhang unsigned int s; 104a962a5fdSElaine Zhang unsigned int k; 1052f0a72b1SElaine Zhang }; 1062f0a72b1SElaine Zhang 1072f0a72b1SElaine Zhang enum rockchip_pll_type { 1082f0a72b1SElaine Zhang pll_rk3036, 1092f0a72b1SElaine Zhang pll_rk3066, 1102f0a72b1SElaine Zhang pll_rk3328, 1112f0a72b1SElaine Zhang pll_rk3366, 1122f0a72b1SElaine Zhang pll_rk3399, 113a962a5fdSElaine Zhang pll_rk3588, 1142f0a72b1SElaine Zhang }; 1152f0a72b1SElaine Zhang 1162f0a72b1SElaine Zhang struct rockchip_pll_clock { 1172f0a72b1SElaine Zhang unsigned int id; 1182f0a72b1SElaine Zhang unsigned int con_offset; 1192f0a72b1SElaine Zhang unsigned int mode_offset; 1202f0a72b1SElaine Zhang unsigned int mode_shift; 1212f0a72b1SElaine Zhang unsigned int lock_shift; 1222f0a72b1SElaine Zhang enum rockchip_pll_type type; 1232f0a72b1SElaine Zhang unsigned int pll_flags; 1242f0a72b1SElaine Zhang struct rockchip_pll_rate_table *rate_table; 1252f0a72b1SElaine Zhang unsigned int mode_mask; 1262f0a72b1SElaine Zhang }; 1272f0a72b1SElaine Zhang 1282f0a72b1SElaine Zhang struct rockchip_cpu_rate_table { 1292f0a72b1SElaine Zhang unsigned long rate; 1302f0a72b1SElaine Zhang unsigned int aclk_div; 1312f0a72b1SElaine Zhang unsigned int pclk_div; 1322f0a72b1SElaine Zhang }; 1332f0a72b1SElaine Zhang 1347d793375SElaine Zhang #ifdef CONFIG_ROCKCHIP_IMAGE_TINY 1357d793375SElaine Zhang static inline ulong rockchip_pll_get_rate(struct rockchip_pll_clock *pll, 1367d793375SElaine Zhang void __iomem *base, 1377d793375SElaine Zhang ulong pll_id) 1387d793375SElaine Zhang { 1397d793375SElaine Zhang return 0; 1407d793375SElaine Zhang } 1417d793375SElaine Zhang 1427d793375SElaine Zhang static inline int rockchip_pll_set_rate(struct rockchip_pll_clock *pll, 1437d793375SElaine Zhang void __iomem *base, ulong pll_id, 1447d793375SElaine Zhang ulong drate) 1457d793375SElaine Zhang { 1467d793375SElaine Zhang return 0; 1477d793375SElaine Zhang } 1487d793375SElaine Zhang 1497d793375SElaine Zhang static inline const struct rockchip_cpu_rate_table * 1507d793375SElaine Zhang rockchip_get_cpu_settings(struct rockchip_cpu_rate_table *cpu_table, 1517d793375SElaine Zhang ulong rate) 1527d793375SElaine Zhang { 1537d793375SElaine Zhang return NULL; 1547d793375SElaine Zhang } 1557d793375SElaine Zhang #else 1562f0a72b1SElaine Zhang int rockchip_pll_set_rate(struct rockchip_pll_clock *pll, 1572f0a72b1SElaine Zhang void __iomem *base, ulong clk_id, 1582f0a72b1SElaine Zhang ulong drate); 1592f0a72b1SElaine Zhang ulong rockchip_pll_get_rate(struct rockchip_pll_clock *pll, 1602f0a72b1SElaine Zhang void __iomem *base, ulong clk_id); 1612f0a72b1SElaine Zhang const struct rockchip_cpu_rate_table * 1622f0a72b1SElaine Zhang rockchip_get_cpu_settings(struct rockchip_cpu_rate_table *cpu_table, 1632f0a72b1SElaine Zhang ulong rate); 1647d793375SElaine Zhang #endif 1652f0a72b1SElaine Zhang 16626ad30e9SSimon Glass static inline int rk_pll_id(enum rk_clk_id clk_id) 16726ad30e9SSimon Glass { 16826ad30e9SSimon Glass return clk_id - 1; 16926ad30e9SSimon Glass } 17026ad30e9SSimon Glass 171116397d6SKever Yang struct sysreset_reg { 172116397d6SKever Yang unsigned int glb_srst_fst_value; 173116397d6SKever Yang unsigned int glb_srst_snd_value; 174116397d6SKever Yang }; 175116397d6SKever Yang 1763d555d75SElaine Zhang struct softreset_reg { 1773d555d75SElaine Zhang void __iomem *base; 1783d555d75SElaine Zhang unsigned int sf_reset_offset; 1793d555d75SElaine Zhang unsigned int sf_reset_num; 1803d555d75SElaine Zhang }; 1813d555d75SElaine Zhang 18226ad30e9SSimon Glass /** 1831b2fd5bfSSimon Glass * clk_get_divisor() - Calculate the required clock divisior 1841b2fd5bfSSimon Glass * 1851b2fd5bfSSimon Glass * Given an input rate and a required output_rate, calculate the Rockchip 1861b2fd5bfSSimon Glass * divisor needed to achieve this. 1871b2fd5bfSSimon Glass * 1881b2fd5bfSSimon Glass * @input_rate: Input clock rate in Hz 1891b2fd5bfSSimon Glass * @output_rate: Output clock rate in Hz 1901b2fd5bfSSimon Glass * @return divisor register value to use 1911b2fd5bfSSimon Glass */ 1921b2fd5bfSSimon Glass static inline u32 clk_get_divisor(ulong input_rate, uint output_rate) 1931b2fd5bfSSimon Glass { 1941b2fd5bfSSimon Glass uint clk_div; 1951b2fd5bfSSimon Glass 1961b2fd5bfSSimon Glass clk_div = input_rate / output_rate; 1971b2fd5bfSSimon Glass clk_div = (clk_div + 1) & 0xfffe; 1981b2fd5bfSSimon Glass 1991b2fd5bfSSimon Glass return clk_div; 2001b2fd5bfSSimon Glass } 2011b2fd5bfSSimon Glass 2021b2fd5bfSSimon Glass /** 20326ad30e9SSimon Glass * rockchip_get_cru() - get a pointer to the clock/reset unit registers 20426ad30e9SSimon Glass * 20526ad30e9SSimon Glass * @return pointer to registers, or -ve error on error 20626ad30e9SSimon Glass */ 20726ad30e9SSimon Glass void *rockchip_get_cru(void); 20826ad30e9SSimon Glass 2095ae2fd97SKever Yang /** 2105ae2fd97SKever Yang * rockchip_get_pmucru() - get a pointer to the clock/reset unit registers 2115ae2fd97SKever Yang * 2125ae2fd97SKever Yang * @return pointer to registers, or -ve error on error 2135ae2fd97SKever Yang */ 2145ae2fd97SKever Yang void *rockchip_get_pmucru(void); 2155ae2fd97SKever Yang 216dae594f2SSimon Glass struct rk3288_cru; 217dae594f2SSimon Glass struct rk3288_grf; 218dae594f2SSimon Glass 219b339b5dbSHeiko Stübner void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf); 220dae594f2SSimon Glass 221a617c5d3SSimon Glass int rockchip_get_clk(struct udevice **devp); 222a617c5d3SSimon Glass 22360410d28SElaine Zhang int rockchip_get_scmi_clk(struct udevice **devp); 22460410d28SElaine Zhang 22526ad30e9SSimon Glass #endif 226