xref: /rk3399_rockchip-uboot/arch/arm/include/asm/arch-rockchip/clock.h (revision 86b248b47bf24e82e4e2fa1b28c65a55cbe6cf7b)
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,
25e1cfe1c9SJoseph Chen 	ROCKCHIP_SYSCON_PCIE30_PHY_GRF,
26e1cfe1c9SJoseph Chen 	ROCKCHIP_SYSCON_PHP_GRF,
27e1cfe1c9SJoseph Chen 	ROCKCHIP_SYSCON_PIPE_PHY0_GRF,
28e1cfe1c9SJoseph Chen 	ROCKCHIP_SYSCON_PIPE_PHY1_GRF,
29e1cfe1c9SJoseph Chen 	ROCKCHIP_SYSCON_PIPE_PHY2_GRF,
30*86b248b4SDamon Ding 	ROCKCHIP_SYSCON_VOP_GRF,
31*86b248b4SDamon Ding 	ROCKCHIP_SYSCON_VO_GRF,
3226ad30e9SSimon Glass };
3326ad30e9SSimon Glass 
3426ad30e9SSimon Glass /* Standard Rockchip clock numbers */
3526ad30e9SSimon Glass enum rk_clk_id {
3626ad30e9SSimon Glass 	CLK_OSC,
3726ad30e9SSimon Glass 	CLK_ARM,
3826ad30e9SSimon Glass 	CLK_DDR,
3926ad30e9SSimon Glass 	CLK_CODEC,
4026ad30e9SSimon Glass 	CLK_GENERAL,
4126ad30e9SSimon Glass 	CLK_NEW,
4226ad30e9SSimon Glass 
4326ad30e9SSimon Glass 	CLK_COUNT,
4426ad30e9SSimon Glass };
4526ad30e9SSimon Glass 
462f0a72b1SElaine Zhang #define PLL(_type, _id, _con, _mode, _mshift,			\
472f0a72b1SElaine Zhang 		 _lshift, _pflags, _rtable)			\
482f0a72b1SElaine Zhang 	{							\
492f0a72b1SElaine Zhang 		.id		= _id,				\
502f0a72b1SElaine Zhang 		.type		= _type,			\
512f0a72b1SElaine Zhang 		.con_offset	= _con,				\
522f0a72b1SElaine Zhang 		.mode_offset	= _mode,			\
532f0a72b1SElaine Zhang 		.mode_shift	= _mshift,			\
542f0a72b1SElaine Zhang 		.lock_shift	= _lshift,			\
552f0a72b1SElaine Zhang 		.pll_flags	= _pflags,			\
562f0a72b1SElaine Zhang 		.rate_table	= _rtable,			\
572f0a72b1SElaine Zhang 	}
582f0a72b1SElaine Zhang 
592f0a72b1SElaine Zhang #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
602f0a72b1SElaine Zhang 			_postdiv2, _dsmpd, _frac)		\
612f0a72b1SElaine Zhang {								\
622f0a72b1SElaine Zhang 	.rate	= _rate##U,					\
632f0a72b1SElaine Zhang 	.fbdiv = _fbdiv,					\
642f0a72b1SElaine Zhang 	.postdiv1 = _postdiv1,					\
652f0a72b1SElaine Zhang 	.refdiv = _refdiv,					\
662f0a72b1SElaine Zhang 	.postdiv2 = _postdiv2,					\
672f0a72b1SElaine Zhang 	.dsmpd = _dsmpd,					\
682f0a72b1SElaine Zhang 	.frac = _frac,						\
692f0a72b1SElaine Zhang }
702f0a72b1SElaine Zhang 
71a962a5fdSElaine Zhang #define RK3588_PLL_RATE(_rate, _p, _m, _s, _k)			\
72a962a5fdSElaine Zhang {								\
73a962a5fdSElaine Zhang 	.rate	= _rate##U,					\
74a962a5fdSElaine Zhang 	.p = _p,						\
75a962a5fdSElaine Zhang 	.m = _m,						\
76a962a5fdSElaine Zhang 	.s = _s,						\
77a962a5fdSElaine Zhang 	.k = _k,						\
78a962a5fdSElaine Zhang }
79a962a5fdSElaine Zhang 
802f0a72b1SElaine Zhang struct rockchip_pll_rate_table {
812f0a72b1SElaine Zhang 	unsigned long rate;
822f0a72b1SElaine Zhang 	unsigned int nr;
832f0a72b1SElaine Zhang 	unsigned int nf;
842f0a72b1SElaine Zhang 	unsigned int no;
852f0a72b1SElaine Zhang 	unsigned int nb;
862f0a72b1SElaine Zhang 	/* for RK3036/RK3399 */
872f0a72b1SElaine Zhang 	unsigned int fbdiv;
882f0a72b1SElaine Zhang 	unsigned int postdiv1;
892f0a72b1SElaine Zhang 	unsigned int refdiv;
902f0a72b1SElaine Zhang 	unsigned int postdiv2;
912f0a72b1SElaine Zhang 	unsigned int dsmpd;
922f0a72b1SElaine Zhang 	unsigned int frac;
93a962a5fdSElaine Zhang 	/* for RK3588 */
94a962a5fdSElaine Zhang 	unsigned int m;
95a962a5fdSElaine Zhang 	unsigned int p;
96a962a5fdSElaine Zhang 	unsigned int s;
97a962a5fdSElaine Zhang 	unsigned int k;
982f0a72b1SElaine Zhang };
992f0a72b1SElaine Zhang 
1002f0a72b1SElaine Zhang enum rockchip_pll_type {
1012f0a72b1SElaine Zhang 	pll_rk3036,
1022f0a72b1SElaine Zhang 	pll_rk3066,
1032f0a72b1SElaine Zhang 	pll_rk3328,
1042f0a72b1SElaine Zhang 	pll_rk3366,
1052f0a72b1SElaine Zhang 	pll_rk3399,
106a962a5fdSElaine Zhang 	pll_rk3588,
1072f0a72b1SElaine Zhang };
1082f0a72b1SElaine Zhang 
1092f0a72b1SElaine Zhang struct rockchip_pll_clock {
1102f0a72b1SElaine Zhang 	unsigned int			id;
1112f0a72b1SElaine Zhang 	unsigned int			con_offset;
1122f0a72b1SElaine Zhang 	unsigned int			mode_offset;
1132f0a72b1SElaine Zhang 	unsigned int			mode_shift;
1142f0a72b1SElaine Zhang 	unsigned int			lock_shift;
1152f0a72b1SElaine Zhang 	enum rockchip_pll_type		type;
1162f0a72b1SElaine Zhang 	unsigned int			pll_flags;
1172f0a72b1SElaine Zhang 	struct rockchip_pll_rate_table *rate_table;
1182f0a72b1SElaine Zhang 	unsigned int			mode_mask;
1192f0a72b1SElaine Zhang };
1202f0a72b1SElaine Zhang 
1212f0a72b1SElaine Zhang struct rockchip_cpu_rate_table {
1222f0a72b1SElaine Zhang 	unsigned long rate;
1232f0a72b1SElaine Zhang 	unsigned int aclk_div;
1242f0a72b1SElaine Zhang 	unsigned int pclk_div;
1252f0a72b1SElaine Zhang };
1262f0a72b1SElaine Zhang 
1272f0a72b1SElaine Zhang int rockchip_pll_set_rate(struct rockchip_pll_clock *pll,
1282f0a72b1SElaine Zhang 			  void __iomem *base, ulong clk_id,
1292f0a72b1SElaine Zhang 			  ulong drate);
1302f0a72b1SElaine Zhang ulong rockchip_pll_get_rate(struct rockchip_pll_clock *pll,
1312f0a72b1SElaine Zhang 			    void __iomem *base, ulong clk_id);
1322f0a72b1SElaine Zhang const struct rockchip_cpu_rate_table *
1332f0a72b1SElaine Zhang rockchip_get_cpu_settings(struct rockchip_cpu_rate_table *cpu_table,
1342f0a72b1SElaine Zhang 			  ulong rate);
1352f0a72b1SElaine Zhang 
13626ad30e9SSimon Glass static inline int rk_pll_id(enum rk_clk_id clk_id)
13726ad30e9SSimon Glass {
13826ad30e9SSimon Glass 	return clk_id - 1;
13926ad30e9SSimon Glass }
14026ad30e9SSimon Glass 
141116397d6SKever Yang struct sysreset_reg {
142116397d6SKever Yang 	unsigned int glb_srst_fst_value;
143116397d6SKever Yang 	unsigned int glb_srst_snd_value;
144116397d6SKever Yang };
145116397d6SKever Yang 
1463d555d75SElaine Zhang struct softreset_reg {
1473d555d75SElaine Zhang 	void __iomem *base;
1483d555d75SElaine Zhang 	unsigned int sf_reset_offset;
1493d555d75SElaine Zhang 	unsigned int sf_reset_num;
1503d555d75SElaine Zhang };
1513d555d75SElaine Zhang 
15226ad30e9SSimon Glass /**
1531b2fd5bfSSimon Glass  * clk_get_divisor() - Calculate the required clock divisior
1541b2fd5bfSSimon Glass  *
1551b2fd5bfSSimon Glass  * Given an input rate and a required output_rate, calculate the Rockchip
1561b2fd5bfSSimon Glass  * divisor needed to achieve this.
1571b2fd5bfSSimon Glass  *
1581b2fd5bfSSimon Glass  * @input_rate:		Input clock rate in Hz
1591b2fd5bfSSimon Glass  * @output_rate:	Output clock rate in Hz
1601b2fd5bfSSimon Glass  * @return divisor register value to use
1611b2fd5bfSSimon Glass  */
1621b2fd5bfSSimon Glass static inline u32 clk_get_divisor(ulong input_rate, uint output_rate)
1631b2fd5bfSSimon Glass {
1641b2fd5bfSSimon Glass 	uint clk_div;
1651b2fd5bfSSimon Glass 
1661b2fd5bfSSimon Glass 	clk_div = input_rate / output_rate;
1671b2fd5bfSSimon Glass 	clk_div = (clk_div + 1) & 0xfffe;
1681b2fd5bfSSimon Glass 
1691b2fd5bfSSimon Glass 	return clk_div;
1701b2fd5bfSSimon Glass }
1711b2fd5bfSSimon Glass 
1721b2fd5bfSSimon Glass /**
17326ad30e9SSimon Glass  * rockchip_get_cru() - get a pointer to the clock/reset unit registers
17426ad30e9SSimon Glass  *
17526ad30e9SSimon Glass  * @return pointer to registers, or -ve error on error
17626ad30e9SSimon Glass  */
17726ad30e9SSimon Glass void *rockchip_get_cru(void);
17826ad30e9SSimon Glass 
1795ae2fd97SKever Yang /**
1805ae2fd97SKever Yang  * rockchip_get_pmucru() - get a pointer to the clock/reset unit registers
1815ae2fd97SKever Yang  *
1825ae2fd97SKever Yang  * @return pointer to registers, or -ve error on error
1835ae2fd97SKever Yang  */
1845ae2fd97SKever Yang void *rockchip_get_pmucru(void);
1855ae2fd97SKever Yang 
186dae594f2SSimon Glass struct rk3288_cru;
187dae594f2SSimon Glass struct rk3288_grf;
188dae594f2SSimon Glass 
189b339b5dbSHeiko Stübner void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf);
190dae594f2SSimon Glass 
191a617c5d3SSimon Glass int rockchip_get_clk(struct udevice **devp);
192a617c5d3SSimon Glass 
19360410d28SElaine Zhang int rockchip_get_scmi_clk(struct udevice **devp);
19460410d28SElaine Zhang 
19526ad30e9SSimon Glass #endif
196