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 1526ad30e9SSimon Glass enum { 1626ad30e9SSimon Glass ROCKCHIP_SYSCON_NOC, 1726ad30e9SSimon Glass ROCKCHIP_SYSCON_GRF, 1826ad30e9SSimon Glass ROCKCHIP_SYSCON_SGRF, 1926ad30e9SSimon Glass ROCKCHIP_SYSCON_PMU, 20c55e30ebSKever Yang ROCKCHIP_SYSCON_PMUGRF, 212adb9812SKever Yang ROCKCHIP_SYSCON_PMUSGRF, 222adb9812SKever Yang ROCKCHIP_SYSCON_CIC, 23168eef7aSKever Yang ROCKCHIP_SYSCON_MSCH, 24be82169bSWu Liang feng ROCKCHIP_SYSCON_USBGRF, 2526ad30e9SSimon Glass }; 2626ad30e9SSimon Glass 2726ad30e9SSimon Glass /* Standard Rockchip clock numbers */ 2826ad30e9SSimon Glass enum rk_clk_id { 2926ad30e9SSimon Glass CLK_OSC, 3026ad30e9SSimon Glass CLK_ARM, 3126ad30e9SSimon Glass CLK_DDR, 3226ad30e9SSimon Glass CLK_CODEC, 3326ad30e9SSimon Glass CLK_GENERAL, 3426ad30e9SSimon Glass CLK_NEW, 3526ad30e9SSimon Glass 3626ad30e9SSimon Glass CLK_COUNT, 3726ad30e9SSimon Glass }; 3826ad30e9SSimon Glass 392f0a72b1SElaine Zhang #define PLL(_type, _id, _con, _mode, _mshift, \ 402f0a72b1SElaine Zhang _lshift, _pflags, _rtable) \ 412f0a72b1SElaine Zhang { \ 422f0a72b1SElaine Zhang .id = _id, \ 432f0a72b1SElaine Zhang .type = _type, \ 442f0a72b1SElaine Zhang .con_offset = _con, \ 452f0a72b1SElaine Zhang .mode_offset = _mode, \ 462f0a72b1SElaine Zhang .mode_shift = _mshift, \ 472f0a72b1SElaine Zhang .lock_shift = _lshift, \ 482f0a72b1SElaine Zhang .pll_flags = _pflags, \ 492f0a72b1SElaine Zhang .rate_table = _rtable, \ 502f0a72b1SElaine Zhang } 512f0a72b1SElaine Zhang 522f0a72b1SElaine Zhang #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ 532f0a72b1SElaine Zhang _postdiv2, _dsmpd, _frac) \ 542f0a72b1SElaine Zhang { \ 552f0a72b1SElaine Zhang .rate = _rate##U, \ 562f0a72b1SElaine Zhang .fbdiv = _fbdiv, \ 572f0a72b1SElaine Zhang .postdiv1 = _postdiv1, \ 582f0a72b1SElaine Zhang .refdiv = _refdiv, \ 592f0a72b1SElaine Zhang .postdiv2 = _postdiv2, \ 602f0a72b1SElaine Zhang .dsmpd = _dsmpd, \ 612f0a72b1SElaine Zhang .frac = _frac, \ 622f0a72b1SElaine Zhang } 632f0a72b1SElaine Zhang 64*a962a5fdSElaine Zhang #define RK3588_PLL_RATE(_rate, _p, _m, _s, _k) \ 65*a962a5fdSElaine Zhang { \ 66*a962a5fdSElaine Zhang .rate = _rate##U, \ 67*a962a5fdSElaine Zhang .p = _p, \ 68*a962a5fdSElaine Zhang .m = _m, \ 69*a962a5fdSElaine Zhang .s = _s, \ 70*a962a5fdSElaine Zhang .k = _k, \ 71*a962a5fdSElaine Zhang } 72*a962a5fdSElaine Zhang 732f0a72b1SElaine Zhang struct rockchip_pll_rate_table { 742f0a72b1SElaine Zhang unsigned long rate; 752f0a72b1SElaine Zhang unsigned int nr; 762f0a72b1SElaine Zhang unsigned int nf; 772f0a72b1SElaine Zhang unsigned int no; 782f0a72b1SElaine Zhang unsigned int nb; 792f0a72b1SElaine Zhang /* for RK3036/RK3399 */ 802f0a72b1SElaine Zhang unsigned int fbdiv; 812f0a72b1SElaine Zhang unsigned int postdiv1; 822f0a72b1SElaine Zhang unsigned int refdiv; 832f0a72b1SElaine Zhang unsigned int postdiv2; 842f0a72b1SElaine Zhang unsigned int dsmpd; 852f0a72b1SElaine Zhang unsigned int frac; 86*a962a5fdSElaine Zhang /* for RK3588 */ 87*a962a5fdSElaine Zhang unsigned int m; 88*a962a5fdSElaine Zhang unsigned int p; 89*a962a5fdSElaine Zhang unsigned int s; 90*a962a5fdSElaine Zhang unsigned int k; 912f0a72b1SElaine Zhang }; 922f0a72b1SElaine Zhang 932f0a72b1SElaine Zhang enum rockchip_pll_type { 942f0a72b1SElaine Zhang pll_rk3036, 952f0a72b1SElaine Zhang pll_rk3066, 962f0a72b1SElaine Zhang pll_rk3328, 972f0a72b1SElaine Zhang pll_rk3366, 982f0a72b1SElaine Zhang pll_rk3399, 99*a962a5fdSElaine Zhang pll_rk3588, 1002f0a72b1SElaine Zhang }; 1012f0a72b1SElaine Zhang 1022f0a72b1SElaine Zhang struct rockchip_pll_clock { 1032f0a72b1SElaine Zhang unsigned int id; 1042f0a72b1SElaine Zhang unsigned int con_offset; 1052f0a72b1SElaine Zhang unsigned int mode_offset; 1062f0a72b1SElaine Zhang unsigned int mode_shift; 1072f0a72b1SElaine Zhang unsigned int lock_shift; 1082f0a72b1SElaine Zhang enum rockchip_pll_type type; 1092f0a72b1SElaine Zhang unsigned int pll_flags; 1102f0a72b1SElaine Zhang struct rockchip_pll_rate_table *rate_table; 1112f0a72b1SElaine Zhang unsigned int mode_mask; 1122f0a72b1SElaine Zhang }; 1132f0a72b1SElaine Zhang 1142f0a72b1SElaine Zhang struct rockchip_cpu_rate_table { 1152f0a72b1SElaine Zhang unsigned long rate; 1162f0a72b1SElaine Zhang unsigned int aclk_div; 1172f0a72b1SElaine Zhang unsigned int pclk_div; 1182f0a72b1SElaine Zhang }; 1192f0a72b1SElaine Zhang 1202f0a72b1SElaine Zhang int rockchip_pll_set_rate(struct rockchip_pll_clock *pll, 1212f0a72b1SElaine Zhang void __iomem *base, ulong clk_id, 1222f0a72b1SElaine Zhang ulong drate); 1232f0a72b1SElaine Zhang ulong rockchip_pll_get_rate(struct rockchip_pll_clock *pll, 1242f0a72b1SElaine Zhang void __iomem *base, ulong clk_id); 1252f0a72b1SElaine Zhang const struct rockchip_cpu_rate_table * 1262f0a72b1SElaine Zhang rockchip_get_cpu_settings(struct rockchip_cpu_rate_table *cpu_table, 1272f0a72b1SElaine Zhang ulong rate); 1282f0a72b1SElaine Zhang 12926ad30e9SSimon Glass static inline int rk_pll_id(enum rk_clk_id clk_id) 13026ad30e9SSimon Glass { 13126ad30e9SSimon Glass return clk_id - 1; 13226ad30e9SSimon Glass } 13326ad30e9SSimon Glass 134116397d6SKever Yang struct sysreset_reg { 135116397d6SKever Yang unsigned int glb_srst_fst_value; 136116397d6SKever Yang unsigned int glb_srst_snd_value; 137116397d6SKever Yang }; 138116397d6SKever Yang 1393d555d75SElaine Zhang struct softreset_reg { 1403d555d75SElaine Zhang void __iomem *base; 1413d555d75SElaine Zhang unsigned int sf_reset_offset; 1423d555d75SElaine Zhang unsigned int sf_reset_num; 1433d555d75SElaine Zhang }; 1443d555d75SElaine Zhang 14526ad30e9SSimon Glass /** 1461b2fd5bfSSimon Glass * clk_get_divisor() - Calculate the required clock divisior 1471b2fd5bfSSimon Glass * 1481b2fd5bfSSimon Glass * Given an input rate and a required output_rate, calculate the Rockchip 1491b2fd5bfSSimon Glass * divisor needed to achieve this. 1501b2fd5bfSSimon Glass * 1511b2fd5bfSSimon Glass * @input_rate: Input clock rate in Hz 1521b2fd5bfSSimon Glass * @output_rate: Output clock rate in Hz 1531b2fd5bfSSimon Glass * @return divisor register value to use 1541b2fd5bfSSimon Glass */ 1551b2fd5bfSSimon Glass static inline u32 clk_get_divisor(ulong input_rate, uint output_rate) 1561b2fd5bfSSimon Glass { 1571b2fd5bfSSimon Glass uint clk_div; 1581b2fd5bfSSimon Glass 1591b2fd5bfSSimon Glass clk_div = input_rate / output_rate; 1601b2fd5bfSSimon Glass clk_div = (clk_div + 1) & 0xfffe; 1611b2fd5bfSSimon Glass 1621b2fd5bfSSimon Glass return clk_div; 1631b2fd5bfSSimon Glass } 1641b2fd5bfSSimon Glass 1651b2fd5bfSSimon Glass /** 16626ad30e9SSimon Glass * rockchip_get_cru() - get a pointer to the clock/reset unit registers 16726ad30e9SSimon Glass * 16826ad30e9SSimon Glass * @return pointer to registers, or -ve error on error 16926ad30e9SSimon Glass */ 17026ad30e9SSimon Glass void *rockchip_get_cru(void); 17126ad30e9SSimon Glass 1725ae2fd97SKever Yang /** 1735ae2fd97SKever Yang * rockchip_get_pmucru() - get a pointer to the clock/reset unit registers 1745ae2fd97SKever Yang * 1755ae2fd97SKever Yang * @return pointer to registers, or -ve error on error 1765ae2fd97SKever Yang */ 1775ae2fd97SKever Yang void *rockchip_get_pmucru(void); 1785ae2fd97SKever Yang 179dae594f2SSimon Glass struct rk3288_cru; 180dae594f2SSimon Glass struct rk3288_grf; 181dae594f2SSimon Glass 182b339b5dbSHeiko Stübner void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf); 183dae594f2SSimon Glass 184a617c5d3SSimon Glass int rockchip_get_clk(struct udevice **devp); 185a617c5d3SSimon Glass 18660410d28SElaine Zhang int rockchip_get_scmi_clk(struct udevice **devp); 18760410d28SElaine Zhang 18826ad30e9SSimon Glass #endif 189