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