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