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