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