uboot/arch/arm/mach-tegra/tegra30/cpu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2010-2014, NVIDIA CORPORATION.  All rights reserved.
   4 */
   5
   6#include <common.h>
   7#include <asm/io.h>
   8#include <asm/arch/clock.h>
   9#include <asm/arch/flow.h>
  10#include <asm/arch/tegra.h>
  11#include <asm/arch-tegra/clk_rst.h>
  12#include <asm/arch-tegra/pmc.h>
  13#include <asm/arch-tegra/tegra_i2c.h>
  14#include "../cpu.h"
  15
  16/* Tegra30-specific CPU init code */
  17void tegra_i2c_ll_write_addr(uint addr, uint config)
  18{
  19        struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
  20
  21        writel(addr, &reg->cmd_addr0);
  22        writel(config, &reg->cnfg);
  23}
  24
  25void tegra_i2c_ll_write_data(uint data, uint config)
  26{
  27        struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
  28
  29        writel(data, &reg->cmd_data1);
  30        writel(config, &reg->cnfg);
  31}
  32
  33#define TPS62366A_I2C_ADDR              0xC0
  34#define TPS62366A_SET1_REG              0x01
  35#define TPS62366A_SET1_DATA             (0x4600 | TPS62366A_SET1_REG)
  36
  37#define TPS62361B_I2C_ADDR              0xC0
  38#define TPS62361B_SET3_REG              0x03
  39#define TPS62361B_SET3_DATA             (0x4600 | TPS62361B_SET3_REG)
  40
  41#define TPS65911_I2C_ADDR               0x5A
  42#define TPS65911_VDDCTRL_OP_REG         0x28
  43#define TPS65911_VDDCTRL_SR_REG         0x27
  44#define TPS65911_VDDCTRL_OP_DATA        (0x2400 | TPS65911_VDDCTRL_OP_REG)
  45#define TPS65911_VDDCTRL_SR_DATA        (0x0100 | TPS65911_VDDCTRL_SR_REG)
  46#define I2C_SEND_2_BYTES                0x0A02
  47
  48static void enable_cpu_power_rail(void)
  49{
  50        struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
  51        u32 reg;
  52
  53        debug("enable_cpu_power_rail entry\n");
  54        reg = readl(&pmc->pmc_cntrl);
  55        reg |= CPUPWRREQ_OE;
  56        writel(reg, &pmc->pmc_cntrl);
  57
  58        /* Set VDD_CORE to 1.200V. */
  59#ifdef CONFIG_TEGRA_VDD_CORE_TPS62366A_SET1
  60        tegra_i2c_ll_write_addr(TPS62366A_I2C_ADDR, 2);
  61        tegra_i2c_ll_write_data(TPS62366A_SET1_DATA, I2C_SEND_2_BYTES);
  62#endif
  63#ifdef CONFIG_TEGRA_VDD_CORE_TPS62361B_SET3
  64        tegra_i2c_ll_write_addr(TPS62361B_I2C_ADDR, 2);
  65        tegra_i2c_ll_write_data(TPS62361B_SET3_DATA, I2C_SEND_2_BYTES);
  66#endif
  67        udelay(1000);
  68
  69        /*
  70         * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus.
  71         * First set VDD to 1.0125V, then enable the VDD regulator.
  72         */
  73        tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2);
  74        tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES);
  75        udelay(1000);
  76        tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES);
  77        udelay(10 * 1000);
  78}
  79
  80/**
  81 * The T30 requires some special clock initialization, including setting up
  82 * the dvc i2c, turning on mselect and selecting the G CPU cluster
  83 */
  84void t30_init_clocks(void)
  85{
  86        struct clk_rst_ctlr *clkrst =
  87                        (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
  88        struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
  89        u32 val;
  90
  91        debug("t30_init_clocks entry\n");
  92        /* Set active CPU cluster to G */
  93        clrbits_le32(flow->cluster_control, 1 << 0);
  94
  95        writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div);
  96
  97        val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) |
  98                (1 << CLK_SYS_RATE_AHB_RATE_SHIFT) |
  99                (0 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) |
 100                (0 << CLK_SYS_RATE_APB_RATE_SHIFT);
 101        writel(val, &clkrst->crc_clk_sys_rate);
 102
 103        /* Put i2c, mselect in reset and enable clocks */
 104        reset_set_enable(PERIPH_ID_DVC_I2C, 1);
 105        clock_set_enable(PERIPH_ID_DVC_I2C, 1);
 106        reset_set_enable(PERIPH_ID_MSELECT, 1);
 107        clock_set_enable(PERIPH_ID_MSELECT, 1);
 108
 109        /* Switch MSELECT clock to PLLP (00) and use a divisor of 2 */
 110        clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, 2);
 111
 112        /*
 113         * Our high-level clock routines are not available prior to
 114         * relocation. We use the low-level functions which require a
 115         * hard-coded divisor. Use CLK_M with divide by (n + 1 = 17)
 116         */
 117        clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 16);
 118
 119        /*
 120         * Give clocks time to stabilize, then take i2c and mselect out of
 121         * reset
 122         */
 123        udelay(1000);
 124        reset_set_enable(PERIPH_ID_DVC_I2C, 0);
 125        reset_set_enable(PERIPH_ID_MSELECT, 0);
 126}
 127
 128static void set_cpu_running(int run)
 129{
 130        struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
 131
 132        debug("set_cpu_running entry, run = %d\n", run);
 133        writel(run ? FLOW_MODE_NONE : FLOW_MODE_STOP, &flow->halt_cpu_events);
 134}
 135
 136void start_cpu(u32 reset_vector)
 137{
 138        debug("start_cpu entry, reset_vector = %x\n", reset_vector);
 139        t30_init_clocks();
 140
 141        /* Enable VDD_CPU */
 142        enable_cpu_power_rail();
 143
 144        set_cpu_running(0);
 145
 146        /* Hold the CPUs in reset */
 147        reset_A9_cpu(1);
 148
 149        /* Disable the CPU clock */
 150        enable_cpu_clock(0);
 151
 152        /* Enable CoreSight */
 153        clock_enable_coresight(1);
 154
 155        /*
 156         * Set the entry point for CPU execution from reset,
 157         *  if it's a non-zero value.
 158         */
 159        if (reset_vector)
 160                writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
 161
 162        /* Enable the CPU clock */
 163        enable_cpu_clock(1);
 164
 165        /* If the CPU doesn't already have power, power it up */
 166        powerup_cpu();
 167
 168        /* Take the CPU out of reset */
 169        reset_A9_cpu(0);
 170
 171        set_cpu_running(1);
 172}
 173