xref: /arm-trusted-firmware/drivers/marvell/ap807_clocks_init.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (C) 2018 Marvell International Ltd.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier:     BSD-3-Clause
5*91f16700Schasinglulu  * https://spdx.org/licenses
6*91f16700Schasinglulu  */
7*91f16700Schasinglulu 
8*91f16700Schasinglulu #include <drivers/delay_timer.h>
9*91f16700Schasinglulu #include <drivers/marvell/aro.h>
10*91f16700Schasinglulu #include <lib/mmio.h>
11*91f16700Schasinglulu 
12*91f16700Schasinglulu #include <a8k_plat_def.h>
13*91f16700Schasinglulu 
14*91f16700Schasinglulu /* Notify bootloader on DRAM setup */
15*91f16700Schasinglulu #define AP807_CPU_ARO_CTRL(cluster)	\
16*91f16700Schasinglulu 			(MVEBU_RFU_BASE + 0x82A8 + (0xA58 * (cluster)))
17*91f16700Schasinglulu 
18*91f16700Schasinglulu /* 0 - ARO clock is enabled, 1 - ARO clock is disabled */
19*91f16700Schasinglulu #define AP807_CPU_ARO_CLK_EN_OFFSET	0
20*91f16700Schasinglulu #define AP807_CPU_ARO_CLK_EN_MASK	(0x1 << AP807_CPU_ARO_CLK_EN_OFFSET)
21*91f16700Schasinglulu 
22*91f16700Schasinglulu /* 0 - ARO is the clock source, 1 - PLL is the clock source */
23*91f16700Schasinglulu #define AP807_CPU_ARO_SEL_PLL_OFFSET	5
24*91f16700Schasinglulu #define AP807_CPU_ARO_SEL_PLL_MASK	(0x1 << AP807_CPU_ARO_SEL_PLL_OFFSET)
25*91f16700Schasinglulu 
26*91f16700Schasinglulu /* AP807 clusters count */
27*91f16700Schasinglulu #define AP807_CLUSTER_NUM		2
28*91f16700Schasinglulu 
29*91f16700Schasinglulu /* PLL frequency values */
30*91f16700Schasinglulu #define PLL_FREQ_1200			0x2AE5F002 /* 1200 */
31*91f16700Schasinglulu #define PLL_FREQ_2000			0x2FC9F002 /* 2000 */
32*91f16700Schasinglulu #define PLL_FREQ_2200			0x2AC57001 /* 2200 */
33*91f16700Schasinglulu #define PLL_FREQ_2400			0x2AE5F001 /* 2400 */
34*91f16700Schasinglulu 
35*91f16700Schasinglulu /* CPU PLL control registers */
36*91f16700Schasinglulu #define AP807_CPU_PLL_CTRL(cluster)	\
37*91f16700Schasinglulu 			(MVEBU_RFU_BASE + 0x82E0 + (0x8 * (cluster)))
38*91f16700Schasinglulu 
39*91f16700Schasinglulu #define AP807_CPU_PLL_PARAM(cluster)	AP807_CPU_PLL_CTRL(cluster)
40*91f16700Schasinglulu #define AP807_CPU_PLL_CFG(cluster)	(AP807_CPU_PLL_CTRL(cluster) + 0x4)
41*91f16700Schasinglulu #define AP807_CPU_PLL_CFG_BYPASS_MODE	(0x1)
42*91f16700Schasinglulu #define AP807_CPU_PLL_FRC_DSCHG		(0x2)
43*91f16700Schasinglulu #define AP807_CPU_PLL_CFG_USE_REG_FILE	(0x1 << 9)
44*91f16700Schasinglulu 
45*91f16700Schasinglulu static void pll_set_freq(unsigned int freq_val)
46*91f16700Schasinglulu {
47*91f16700Schasinglulu 	int i;
48*91f16700Schasinglulu 
49*91f16700Schasinglulu 	if (freq_val != PLL_FREQ_2200)
50*91f16700Schasinglulu 		return;
51*91f16700Schasinglulu 
52*91f16700Schasinglulu 	for (i = 0 ; i < AP807_CLUSTER_NUM ; i++) {
53*91f16700Schasinglulu 		/* Set parameter of cluster i PLL to 2.2GHz */
54*91f16700Schasinglulu 		mmio_write_32(AP807_CPU_PLL_PARAM(i), freq_val);
55*91f16700Schasinglulu 		/* Set apll_lpf_frc_dschg - Control
56*91f16700Schasinglulu 		 * voltage of internal VCO is discharged
57*91f16700Schasinglulu 		 */
58*91f16700Schasinglulu 		mmio_write_32(AP807_CPU_PLL_CFG(i),
59*91f16700Schasinglulu 				AP807_CPU_PLL_FRC_DSCHG);
60*91f16700Schasinglulu 		/* Set use_rf_conf  load PLL parameter from register */
61*91f16700Schasinglulu 		mmio_write_32(AP807_CPU_PLL_CFG(i),
62*91f16700Schasinglulu 				AP807_CPU_PLL_FRC_DSCHG |
63*91f16700Schasinglulu 				AP807_CPU_PLL_CFG_USE_REG_FILE);
64*91f16700Schasinglulu 		/* Un-set apll_lpf_frc_dschg */
65*91f16700Schasinglulu 		mmio_write_32(AP807_CPU_PLL_CFG(i),
66*91f16700Schasinglulu 			      AP807_CPU_PLL_CFG_USE_REG_FILE);
67*91f16700Schasinglulu 	}
68*91f16700Schasinglulu }
69*91f16700Schasinglulu 
70*91f16700Schasinglulu /* Switch to ARO from PLL in ap807 */
71*91f16700Schasinglulu static void aro_to_pll(void)
72*91f16700Schasinglulu {
73*91f16700Schasinglulu 	unsigned int reg;
74*91f16700Schasinglulu 	int i;
75*91f16700Schasinglulu 
76*91f16700Schasinglulu 	for (i = 0 ; i < AP807_CLUSTER_NUM ; i++) {
77*91f16700Schasinglulu 		/* switch from ARO to PLL */
78*91f16700Schasinglulu 		reg = mmio_read_32(AP807_CPU_ARO_CTRL(i));
79*91f16700Schasinglulu 		reg |= AP807_CPU_ARO_SEL_PLL_MASK;
80*91f16700Schasinglulu 		mmio_write_32(AP807_CPU_ARO_CTRL(i), reg);
81*91f16700Schasinglulu 
82*91f16700Schasinglulu 		mdelay(100);
83*91f16700Schasinglulu 
84*91f16700Schasinglulu 		/* disable ARO clk driver */
85*91f16700Schasinglulu 		reg = mmio_read_32(AP807_CPU_ARO_CTRL(i));
86*91f16700Schasinglulu 		reg |= (AP807_CPU_ARO_CLK_EN_MASK);
87*91f16700Schasinglulu 		mmio_write_32(AP807_CPU_ARO_CTRL(i), reg);
88*91f16700Schasinglulu 	}
89*91f16700Schasinglulu }
90*91f16700Schasinglulu 
91*91f16700Schasinglulu /* switch from ARO to PLL
92*91f16700Schasinglulu  * in case of default frequency option, configure PLL registers
93*91f16700Schasinglulu  * to be aligned with new default frequency.
94*91f16700Schasinglulu  */
95*91f16700Schasinglulu void ap807_clocks_init(unsigned int freq_option)
96*91f16700Schasinglulu {
97*91f16700Schasinglulu 	/* Modifications in frequency table:
98*91f16700Schasinglulu 	 * 0x0: 764x: change to 2000 MHz.
99*91f16700Schasinglulu 	 * 0x2: 744x change to 1800 MHz, 764x change to 2200/2400.
100*91f16700Schasinglulu 	 * 0x3: 3900/744x/764x change to 1200 MHz.
101*91f16700Schasinglulu 	 */
102*91f16700Schasinglulu 
103*91f16700Schasinglulu 	if (freq_option == CPU_2200_DDR_1200_RCLK_1200)
104*91f16700Schasinglulu 		pll_set_freq(PLL_FREQ_2200);
105*91f16700Schasinglulu 
106*91f16700Schasinglulu 	/* Switch from ARO to PLL */
107*91f16700Schasinglulu 	aro_to_pll();
108*91f16700Schasinglulu 
109*91f16700Schasinglulu }
110