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 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 */ 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 */ 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