1 /* 2 * Copyright (c) 2019, Intel Corporation. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch.h> 8 #include <arch_helpers.h> 9 #include <assert.h> 10 #include <drivers/delay_timer.h> 11 #include <lib/mmio.h> 12 #include <platform_def.h> 13 14 #include "s10_clock_manager.h" 15 #include "s10_handoff.h" 16 17 static const CLOCK_SOURCE_CONFIG clk_source = { 18 /* clk_freq_of_eosc1 */ 19 (uint32_t) 25000000, 20 /* clk_freq_of_f2h_free */ 21 (uint32_t) 460000000, 22 /* clk_freq_of_cb_intosc_ls */ 23 (uint32_t) 50000000, 24 }; 25 26 void wait_pll_lock(void) 27 { 28 uint32_t data; 29 30 do { 31 data = mmio_read_32(ALT_CLKMGR + ALT_CLKMGR_STAT); 32 } while ((ALT_CLKMGR_STAT_MAINPLLLOCKED(data) == 0) || 33 (ALT_CLKMGR_STAT_PERPLLLOCKED(data) == 0)); 34 } 35 36 void wait_fsm(void) 37 { 38 uint32_t data; 39 40 do { 41 data = mmio_read_32(ALT_CLKMGR + ALT_CLKMGR_STAT); 42 } while (ALT_CLKMGR_STAT_BUSY(data) == ALT_CLKMGR_STAT_BUSY_E_BUSY); 43 } 44 45 void config_clkmgr_handoff(handoff *hoff_ptr) 46 { 47 uint32_t m_div, refclk_div, mscnt, hscnt; 48 49 /* Bypass all mainpllgrp's clocks */ 50 mmio_write_32(ALT_CLKMGR_MAINPLL + 51 ALT_CLKMGR_MAINPLL_BYPASS, 52 0x7); 53 wait_fsm(); 54 /* Bypass all perpllgrp's clocks */ 55 mmio_write_32(ALT_CLKMGR_PERPLL + 56 ALT_CLKMGR_PERPLL_BYPASS, 57 0x7f); 58 wait_fsm(); 59 60 /* Setup main PLL dividers */ 61 m_div = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(hoff_ptr->main_pll_fdbck); 62 refclk_div = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV( 63 hoff_ptr->main_pll_pllglob); 64 mscnt = 200 / ((6 + m_div) / refclk_div); 65 hscnt = (m_div + 6) * mscnt / refclk_div - 9; 66 67 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB, 68 hoff_ptr->main_pll_pllglob); 69 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK, 70 hoff_ptr->main_pll_fdbck); 71 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_VCOCALIB, 72 ALT_CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(hscnt) | 73 ALT_CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(mscnt)); 74 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC0, 75 hoff_ptr->main_pll_pllc0); 76 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC1, 77 hoff_ptr->main_pll_pllc1); 78 79 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCDIV, 80 hoff_ptr->main_pll_nocdiv); 81 82 /* Setup peripheral PLL dividers */ 83 m_div = ALT_CLKMGR_PERPLL_FDBCK_MDIV(hoff_ptr->per_pll_fdbck); 84 refclk_div = ALT_CLKMGR_PERPLL_PLLGLOB_REFCLKDIV( 85 hoff_ptr->per_pll_pllglob); 86 mscnt = 200 / ((6 + m_div) / refclk_div); 87 hscnt = (m_div + 6) * mscnt / refclk_div - 9; 88 89 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB, 90 hoff_ptr->per_pll_pllglob); 91 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_FDBCK, 92 hoff_ptr->per_pll_fdbck); 93 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_VCOCALIB, 94 ALT_CLKMGR_PERPLL_VCOCALIB_HSCNT_SET(hscnt) | 95 ALT_CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(mscnt)); 96 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC0, 97 hoff_ptr->per_pll_pllc0); 98 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC1, 99 hoff_ptr->per_pll_pllc1); 100 101 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_GPIODIV, 102 ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET( 103 hoff_ptr->per_pll_gpiodiv)); 104 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EMACCTL, 105 hoff_ptr->per_pll_emacctl); 106 107 108 /* Take both PLL out of reset and power up */ 109 mmio_setbits_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB, 110 ALT_CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK | 111 ALT_CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK); 112 mmio_setbits_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB, 113 ALT_CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK | 114 ALT_CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK); 115 116 wait_pll_lock(); 117 118 /* Dividers for C2 to C9 only init after PLLs are lock. */ 119 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_MPUCLK, 0xff); 120 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK, 0xff); 121 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR2CLK, 0xff); 122 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR3CLK, 0xff); 123 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR4CLK, 0xff); 124 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR5CLK, 0xff); 125 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK, 0xff); 126 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR7CLK, 0xff); 127 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR8CLK, 0xff); 128 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR9CLK, 0xff); 129 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR2CLK, 0xff); 130 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR3CLK, 0xff); 131 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR4CLK, 0xff); 132 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR5CLK, 0xff); 133 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR6CLK, 0xff); 134 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR7CLK, 0xff); 135 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR8CLK, 0xff); 136 137 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_MPUCLK, 138 hoff_ptr->main_pll_mpuclk); 139 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK, 140 hoff_ptr->main_pll_nocclk); 141 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR2CLK, 142 hoff_ptr->main_pll_cntr2clk); 143 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR3CLK, 144 hoff_ptr->main_pll_cntr3clk); 145 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR4CLK, 146 hoff_ptr->main_pll_cntr4clk); 147 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR5CLK, 148 hoff_ptr->main_pll_cntr5clk); 149 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK, 150 hoff_ptr->main_pll_cntr6clk); 151 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR7CLK, 152 hoff_ptr->main_pll_cntr7clk); 153 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR8CLK, 154 hoff_ptr->main_pll_cntr8clk); 155 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR9CLK, 156 hoff_ptr->main_pll_cntr9clk); 157 158 /* Peripheral PLL Clock Source and Counters/Divider */ 159 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR2CLK, 160 hoff_ptr->per_pll_cntr2clk); 161 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR3CLK, 162 hoff_ptr->per_pll_cntr3clk); 163 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR4CLK, 164 hoff_ptr->per_pll_cntr4clk); 165 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR5CLK, 166 hoff_ptr->per_pll_cntr5clk); 167 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR6CLK, 168 hoff_ptr->per_pll_cntr6clk); 169 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR7CLK, 170 hoff_ptr->per_pll_cntr7clk); 171 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR8CLK, 172 hoff_ptr->per_pll_cntr8clk); 173 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR9CLK, 174 hoff_ptr->per_pll_cntr9clk); 175 176 /* Take all PLLs out of bypass */ 177 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_BYPASS, 0); 178 wait_fsm(); 179 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_BYPASS, 0); 180 wait_fsm(); 181 182 /* Set safe mode/ out of boot mode */ 183 mmio_clrbits_32(ALT_CLKMGR + ALT_CLKMGR_CTRL, 184 ALT_CLKMGR_CTRL_BOOTMODE_SET_MSK); 185 wait_fsm(); 186 187 /* 10 Enable mainpllgrp's software-managed clock */ 188 mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_EN, 189 ALT_CLKMGR_MAINPLL_EN_RESET); 190 mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EN, 191 ALT_CLKMGR_PERPLL_EN_RESET); 192 193 /* Clear loss lock interrupt status register that */ 194 /* might be set during configuration */ 195 mmio_write_32(ALT_CLKMGR + ALT_CLKMGR_INTRCLR, 196 ALT_CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK | 197 ALT_CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK); 198 } 199 200 int get_wdt_clk(handoff *hoff_ptr) 201 { 202 int main_noc_base_clk, l3_main_free_clk, l4_sys_free_clk; 203 int data32, mdiv, refclkdiv, ref_clk; 204 205 data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB); 206 207 switch (ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(data32)) { 208 case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1: 209 ref_clk = clk_source.clk_freq_of_eosc1; 210 break; 211 case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC: 212 ref_clk = clk_source.clk_freq_of_cb_intosc_ls; 213 break; 214 case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S: 215 ref_clk = clk_source.clk_freq_of_f2h_free; 216 break; 217 default: 218 ref_clk = 0; 219 assert(0); 220 break; 221 } 222 223 refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(data32); 224 data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK); 225 mdiv = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(data32); 226 ref_clk = (ref_clk / refclkdiv) * (6 + mdiv); 227 228 main_noc_base_clk = ref_clk / (hoff_ptr->main_pll_pllc1 & 0xff); 229 l3_main_free_clk = main_noc_base_clk / (hoff_ptr->main_pll_nocclk + 1); 230 l4_sys_free_clk = l3_main_free_clk / 4; 231 232 return l4_sys_free_clk; 233 } 234