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