1*09f455dcSMasahiro Yamada /* 2*09f455dcSMasahiro Yamada * (C) Copyright 2013 3*09f455dcSMasahiro Yamada * NVIDIA Corporation <www.nvidia.com> 4*09f455dcSMasahiro Yamada * 5*09f455dcSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 6*09f455dcSMasahiro Yamada */ 7*09f455dcSMasahiro Yamada 8*09f455dcSMasahiro Yamada #include <common.h> 9*09f455dcSMasahiro Yamada #include <asm/io.h> 10*09f455dcSMasahiro Yamada #include <asm/arch/ahb.h> 11*09f455dcSMasahiro Yamada #include <asm/arch/clock.h> 12*09f455dcSMasahiro Yamada #include <asm/arch/flow.h> 13*09f455dcSMasahiro Yamada #include <asm/arch/pinmux.h> 14*09f455dcSMasahiro Yamada #include <asm/arch/tegra.h> 15*09f455dcSMasahiro Yamada #include <asm/arch-tegra/clk_rst.h> 16*09f455dcSMasahiro Yamada #include <asm/arch-tegra/pmc.h> 17*09f455dcSMasahiro Yamada #include <asm/arch-tegra/ap.h> 18*09f455dcSMasahiro Yamada #include "../cpu.h" 19*09f455dcSMasahiro Yamada 20*09f455dcSMasahiro Yamada /* Tegra124-specific CPU init code */ 21*09f455dcSMasahiro Yamada 22*09f455dcSMasahiro Yamada static void enable_cpu_power_rail(void) 23*09f455dcSMasahiro Yamada { 24*09f455dcSMasahiro Yamada struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; 25*09f455dcSMasahiro Yamada 26*09f455dcSMasahiro Yamada debug("enable_cpu_power_rail entry\n"); 27*09f455dcSMasahiro Yamada 28*09f455dcSMasahiro Yamada /* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ 29*09f455dcSMasahiro Yamada pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6); 30*09f455dcSMasahiro Yamada pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SDA_PZ7); 31*09f455dcSMasahiro Yamada 32*09f455dcSMasahiro Yamada pmic_enable_cpu_vdd(); 33*09f455dcSMasahiro Yamada 34*09f455dcSMasahiro Yamada /* 35*09f455dcSMasahiro Yamada * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz), 36*09f455dcSMasahiro Yamada * set it for 5ms as per SysEng (102MHz*5ms = 510000 (7C830h). 37*09f455dcSMasahiro Yamada */ 38*09f455dcSMasahiro Yamada writel(0x7C830, &pmc->pmc_cpupwrgood_timer); 39*09f455dcSMasahiro Yamada 40*09f455dcSMasahiro Yamada /* Set polarity to 0 (normal) and enable CPUPWRREQ_OE */ 41*09f455dcSMasahiro Yamada clrbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_POL); 42*09f455dcSMasahiro Yamada setbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_OE); 43*09f455dcSMasahiro Yamada } 44*09f455dcSMasahiro Yamada 45*09f455dcSMasahiro Yamada static void enable_cpu_clocks(void) 46*09f455dcSMasahiro Yamada { 47*09f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 48*09f455dcSMasahiro Yamada u32 reg; 49*09f455dcSMasahiro Yamada 50*09f455dcSMasahiro Yamada debug("enable_cpu_clocks entry\n"); 51*09f455dcSMasahiro Yamada 52*09f455dcSMasahiro Yamada /* Wait for PLL-X to lock */ 53*09f455dcSMasahiro Yamada do { 54*09f455dcSMasahiro Yamada reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); 55*09f455dcSMasahiro Yamada debug("%s: PLLX base = 0x%08X\n", __func__, reg); 56*09f455dcSMasahiro Yamada } while ((reg & PLL_LOCK_MASK) == 0); 57*09f455dcSMasahiro Yamada 58*09f455dcSMasahiro Yamada debug("%s: PLLX locked, delay for stable clocks\n", __func__); 59*09f455dcSMasahiro Yamada /* Wait until all clocks are stable */ 60*09f455dcSMasahiro Yamada udelay(PLL_STABILIZATION_DELAY); 61*09f455dcSMasahiro Yamada 62*09f455dcSMasahiro Yamada debug("%s: Setting CCLK_BURST and DIVIDER\n", __func__); 63*09f455dcSMasahiro Yamada writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); 64*09f455dcSMasahiro Yamada writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); 65*09f455dcSMasahiro Yamada 66*09f455dcSMasahiro Yamada debug("%s: Enabling clock to all CPUs\n", __func__); 67*09f455dcSMasahiro Yamada /* Enable the clock to all CPUs */ 68*09f455dcSMasahiro Yamada reg = CLR_CPU3_CLK_STP | CLR_CPU2_CLK_STP | CLR_CPU1_CLK_STP | 69*09f455dcSMasahiro Yamada CLR_CPU0_CLK_STP; 70*09f455dcSMasahiro Yamada writel(reg, &clkrst->crc_clk_cpu_cmplx_clr); 71*09f455dcSMasahiro Yamada 72*09f455dcSMasahiro Yamada debug("%s: Enabling main CPU complex clocks\n", __func__); 73*09f455dcSMasahiro Yamada /* Always enable the main CPU complex clocks */ 74*09f455dcSMasahiro Yamada clock_enable(PERIPH_ID_CPU); 75*09f455dcSMasahiro Yamada clock_enable(PERIPH_ID_CPULP); 76*09f455dcSMasahiro Yamada clock_enable(PERIPH_ID_CPUG); 77*09f455dcSMasahiro Yamada 78*09f455dcSMasahiro Yamada debug("%s: Done\n", __func__); 79*09f455dcSMasahiro Yamada } 80*09f455dcSMasahiro Yamada 81*09f455dcSMasahiro Yamada static void remove_cpu_resets(void) 82*09f455dcSMasahiro Yamada { 83*09f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 84*09f455dcSMasahiro Yamada u32 reg; 85*09f455dcSMasahiro Yamada 86*09f455dcSMasahiro Yamada debug("remove_cpu_resets entry\n"); 87*09f455dcSMasahiro Yamada 88*09f455dcSMasahiro Yamada /* Take the slow and fast partitions out of reset */ 89*09f455dcSMasahiro Yamada reg = CLR_NONCPURESET; 90*09f455dcSMasahiro Yamada writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr); 91*09f455dcSMasahiro Yamada writel(reg, &clkrst->crc_rst_cpug_cmplx_clr); 92*09f455dcSMasahiro Yamada 93*09f455dcSMasahiro Yamada /* Clear the SW-controlled reset of the slow cluster */ 94*09f455dcSMasahiro Yamada reg = CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 | 95*09f455dcSMasahiro Yamada CLR_L2RESET | CLR_PRESETDBG; 96*09f455dcSMasahiro Yamada writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr); 97*09f455dcSMasahiro Yamada 98*09f455dcSMasahiro Yamada /* Clear the SW-controlled reset of the fast cluster */ 99*09f455dcSMasahiro Yamada reg = CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 | 100*09f455dcSMasahiro Yamada CLR_CPURESET1 | CLR_DBGRESET1 | CLR_CORERESET1 | CLR_CXRESET1 | 101*09f455dcSMasahiro Yamada CLR_CPURESET2 | CLR_DBGRESET2 | CLR_CORERESET2 | CLR_CXRESET2 | 102*09f455dcSMasahiro Yamada CLR_CPURESET3 | CLR_DBGRESET3 | CLR_CORERESET3 | CLR_CXRESET3 | 103*09f455dcSMasahiro Yamada CLR_L2RESET | CLR_PRESETDBG; 104*09f455dcSMasahiro Yamada writel(reg, &clkrst->crc_rst_cpug_cmplx_clr); 105*09f455dcSMasahiro Yamada } 106*09f455dcSMasahiro Yamada 107*09f455dcSMasahiro Yamada /** 108*09f455dcSMasahiro Yamada * The Tegra124 requires some special clock initialization, including setting up 109*09f455dcSMasahiro Yamada * the DVC I2C, turning on MSELECT and selecting the G CPU cluster 110*09f455dcSMasahiro Yamada */ 111*09f455dcSMasahiro Yamada void tegra124_init_clocks(void) 112*09f455dcSMasahiro Yamada { 113*09f455dcSMasahiro Yamada struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; 114*09f455dcSMasahiro Yamada struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; 115*09f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = 116*09f455dcSMasahiro Yamada (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 117*09f455dcSMasahiro Yamada u32 val; 118*09f455dcSMasahiro Yamada 119*09f455dcSMasahiro Yamada debug("tegra124_init_clocks entry\n"); 120*09f455dcSMasahiro Yamada 121*09f455dcSMasahiro Yamada /* Set active CPU cluster to G */ 122*09f455dcSMasahiro Yamada clrbits_le32(&flow->cluster_control, 1); 123*09f455dcSMasahiro Yamada 124*09f455dcSMasahiro Yamada /* Change the oscillator drive strength */ 125*09f455dcSMasahiro Yamada val = readl(&clkrst->crc_osc_ctrl); 126*09f455dcSMasahiro Yamada val &= ~OSC_XOFS_MASK; 127*09f455dcSMasahiro Yamada val |= (OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT); 128*09f455dcSMasahiro Yamada writel(val, &clkrst->crc_osc_ctrl); 129*09f455dcSMasahiro Yamada 130*09f455dcSMasahiro Yamada /* Update same value in PMC_OSC_EDPD_OVER XOFS field for warmboot */ 131*09f455dcSMasahiro Yamada val = readl(&pmc->pmc_osc_edpd_over); 132*09f455dcSMasahiro Yamada val &= ~PMC_XOFS_MASK; 133*09f455dcSMasahiro Yamada val |= (OSC_DRIVE_STRENGTH << PMC_XOFS_SHIFT); 134*09f455dcSMasahiro Yamada writel(val, &pmc->pmc_osc_edpd_over); 135*09f455dcSMasahiro Yamada 136*09f455dcSMasahiro Yamada /* Set HOLD_CKE_LOW_EN to 1 */ 137*09f455dcSMasahiro Yamada setbits_le32(&pmc->pmc_cntrl2, HOLD_CKE_LOW_EN); 138*09f455dcSMasahiro Yamada 139*09f455dcSMasahiro Yamada debug("Setting up PLLX\n"); 140*09f455dcSMasahiro Yamada init_pllx(); 141*09f455dcSMasahiro Yamada 142*09f455dcSMasahiro Yamada val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); 143*09f455dcSMasahiro Yamada writel(val, &clkrst->crc_clk_sys_rate); 144*09f455dcSMasahiro Yamada 145*09f455dcSMasahiro Yamada /* Enable clocks to required peripherals. TBD - minimize this list */ 146*09f455dcSMasahiro Yamada debug("Enabling clocks\n"); 147*09f455dcSMasahiro Yamada 148*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_CACHE2, 1); 149*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_GPIO, 1); 150*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_TMR, 1); 151*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_CPU, 1); 152*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_EMC, 1); 153*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_I2C5, 1); 154*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_APBDMA, 1); 155*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_MEM, 1); 156*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_CORESIGHT, 1); 157*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_MSELECT, 1); 158*09f455dcSMasahiro Yamada clock_set_enable(PERIPH_ID_DVFS, 1); 159*09f455dcSMasahiro Yamada 160*09f455dcSMasahiro Yamada /* 161*09f455dcSMasahiro Yamada * Set MSELECT clock source as PLLP (00), and ask for a clock 162*09f455dcSMasahiro Yamada * divider that would set the MSELECT clock at 102MHz for a 163*09f455dcSMasahiro Yamada * PLLP base of 408MHz. 164*09f455dcSMasahiro Yamada */ 165*09f455dcSMasahiro Yamada clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, 166*09f455dcSMasahiro Yamada CLK_DIVIDER(NVBL_PLLP_KHZ, 102000)); 167*09f455dcSMasahiro Yamada 168*09f455dcSMasahiro Yamada /* Give clock time to stabilize */ 169*09f455dcSMasahiro Yamada udelay(IO_STABILIZATION_DELAY); 170*09f455dcSMasahiro Yamada 171*09f455dcSMasahiro Yamada /* I2C5 (DVC) gets CLK_M and a divisor of 17 */ 172*09f455dcSMasahiro Yamada clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16); 173*09f455dcSMasahiro Yamada 174*09f455dcSMasahiro Yamada /* Give clock time to stabilize */ 175*09f455dcSMasahiro Yamada udelay(IO_STABILIZATION_DELAY); 176*09f455dcSMasahiro Yamada 177*09f455dcSMasahiro Yamada /* Take required peripherals out of reset */ 178*09f455dcSMasahiro Yamada debug("Taking periphs out of reset\n"); 179*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_CACHE2, 0); 180*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_GPIO, 0); 181*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_TMR, 0); 182*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_COP, 0); 183*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_EMC, 0); 184*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_I2C5, 0); 185*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_APBDMA, 0); 186*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_MEM, 0); 187*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_CORESIGHT, 0); 188*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_MSELECT, 0); 189*09f455dcSMasahiro Yamada reset_set_enable(PERIPH_ID_DVFS, 0); 190*09f455dcSMasahiro Yamada 191*09f455dcSMasahiro Yamada debug("tegra124_init_clocks exit\n"); 192*09f455dcSMasahiro Yamada } 193*09f455dcSMasahiro Yamada 194*09f455dcSMasahiro Yamada static bool is_partition_powered(u32 partid) 195*09f455dcSMasahiro Yamada { 196*09f455dcSMasahiro Yamada struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; 197*09f455dcSMasahiro Yamada u32 reg; 198*09f455dcSMasahiro Yamada 199*09f455dcSMasahiro Yamada /* Get power gate status */ 200*09f455dcSMasahiro Yamada reg = readl(&pmc->pmc_pwrgate_status); 201*09f455dcSMasahiro Yamada return !!(reg & (1 << partid)); 202*09f455dcSMasahiro Yamada } 203*09f455dcSMasahiro Yamada 204*09f455dcSMasahiro Yamada static void power_partition(u32 partid) 205*09f455dcSMasahiro Yamada { 206*09f455dcSMasahiro Yamada struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; 207*09f455dcSMasahiro Yamada 208*09f455dcSMasahiro Yamada debug("%s: part ID = %08X\n", __func__, partid); 209*09f455dcSMasahiro Yamada /* Is the partition already on? */ 210*09f455dcSMasahiro Yamada if (!is_partition_powered(partid)) { 211*09f455dcSMasahiro Yamada /* No, toggle the partition power state (OFF -> ON) */ 212*09f455dcSMasahiro Yamada debug("power_partition, toggling state\n"); 213*09f455dcSMasahiro Yamada writel(START_CP | partid, &pmc->pmc_pwrgate_toggle); 214*09f455dcSMasahiro Yamada 215*09f455dcSMasahiro Yamada /* Wait for the power to come up */ 216*09f455dcSMasahiro Yamada while (!is_partition_powered(partid)) 217*09f455dcSMasahiro Yamada ; 218*09f455dcSMasahiro Yamada 219*09f455dcSMasahiro Yamada /* Give I/O signals time to stabilize */ 220*09f455dcSMasahiro Yamada udelay(IO_STABILIZATION_DELAY); 221*09f455dcSMasahiro Yamada } 222*09f455dcSMasahiro Yamada } 223*09f455dcSMasahiro Yamada 224*09f455dcSMasahiro Yamada void powerup_cpus(void) 225*09f455dcSMasahiro Yamada { 226*09f455dcSMasahiro Yamada debug("powerup_cpus entry\n"); 227*09f455dcSMasahiro Yamada 228*09f455dcSMasahiro Yamada /* We boot to the fast cluster */ 229*09f455dcSMasahiro Yamada debug("powerup_cpus entry: G cluster\n"); 230*09f455dcSMasahiro Yamada 231*09f455dcSMasahiro Yamada /* Power up the fast cluster rail partition */ 232*09f455dcSMasahiro Yamada debug("powerup_cpus: CRAIL\n"); 233*09f455dcSMasahiro Yamada power_partition(CRAIL); 234*09f455dcSMasahiro Yamada 235*09f455dcSMasahiro Yamada /* Power up the fast cluster non-CPU partition */ 236*09f455dcSMasahiro Yamada debug("powerup_cpus: C0NC\n"); 237*09f455dcSMasahiro Yamada power_partition(C0NC); 238*09f455dcSMasahiro Yamada 239*09f455dcSMasahiro Yamada /* Power up the fast cluster CPU0 partition */ 240*09f455dcSMasahiro Yamada debug("powerup_cpus: CE0\n"); 241*09f455dcSMasahiro Yamada power_partition(CE0); 242*09f455dcSMasahiro Yamada 243*09f455dcSMasahiro Yamada debug("powerup_cpus: done\n"); 244*09f455dcSMasahiro Yamada } 245*09f455dcSMasahiro Yamada 246*09f455dcSMasahiro Yamada void start_cpu(u32 reset_vector) 247*09f455dcSMasahiro Yamada { 248*09f455dcSMasahiro Yamada struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; 249*09f455dcSMasahiro Yamada 250*09f455dcSMasahiro Yamada debug("start_cpu entry, reset_vector = %x\n", reset_vector); 251*09f455dcSMasahiro Yamada 252*09f455dcSMasahiro Yamada tegra124_init_clocks(); 253*09f455dcSMasahiro Yamada 254*09f455dcSMasahiro Yamada /* Set power-gating timer multiplier */ 255*09f455dcSMasahiro Yamada writel((MULT_8 << TIMER_MULT_SHIFT) | (MULT_8 << TIMER_MULT_CPU_SHIFT), 256*09f455dcSMasahiro Yamada &pmc->pmc_pwrgate_timer_mult); 257*09f455dcSMasahiro Yamada 258*09f455dcSMasahiro Yamada enable_cpu_power_rail(); 259*09f455dcSMasahiro Yamada enable_cpu_clocks(); 260*09f455dcSMasahiro Yamada clock_enable_coresight(1); 261*09f455dcSMasahiro Yamada remove_cpu_resets(); 262*09f455dcSMasahiro Yamada writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); 263*09f455dcSMasahiro Yamada powerup_cpus(); 264*09f455dcSMasahiro Yamada debug("start_cpu exit, should continue @ reset_vector\n"); 265*09f455dcSMasahiro Yamada } 266