diff options
author | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2015-08-18 10:51:00 +0200 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2015-08-18 10:51:00 +0200 |
commit | f7c3186985ebb244d075b04ed7c055f39f485670 (patch) | |
tree | 92f9b896ae3e5073e4cf9f47c82626e3d27f77b7 | |
parent | f9e7649338178f823e291386dde5086ad636b703 (diff) |
colibri_t20: implement early pmic rail configuration
Implement early TPS6586X PMIC rail configuration setting SM0 being
VDD_CORE_1.2V to 1.2 volts and SM1 being VDD_CPU_1.0V to 1.0 volts.
While those are PMIC power-up defaults the SoC might have been reset
separately with certain rails being left at lower DVFS states which
is e.g. the case upon watchdog reset while otherwise nearly idling.
-rw-r--r-- | arch/arm/mach-tegra/tegra20/cpu.c | 78 | ||||
-rw-r--r-- | include/configs/colibri_t20.h | 2 |
2 files changed, 79 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/tegra20/cpu.c b/arch/arm/mach-tegra/tegra20/cpu.c index 67f49d77561..1a74499946f 100644 --- a/arch/arm/mach-tegra/tegra20/cpu.c +++ b/arch/arm/mach-tegra/tegra20/cpu.c @@ -15,16 +15,66 @@ */ #include <common.h> -#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/pmu.h> #include <asm/arch/tegra.h> +#include <asm/arch-tegra/clk_rst.h> #include <asm/arch-tegra/pmc.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include <asm/io.h> #include "../cpu.h" +#define I2C_SEND_2_BYTES 0x0a02 +#define TPS6586X_I2C_ADDR (0x34<<1) +#define TPS6586X_VCC1_REG 0x20 +#define TPS6586X_SM1V1_REG 0x23 +#define TPS6586X_SM0V1_REG 0x26 + +/* Tegra20-specific DVC init code */ +void tegra_i2c_ll_init(void) +{ + struct dvc_ctlr *reg = (struct dvc_ctlr *)TEGRA_DVC_BASE; + + writel(DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK, ®->ctrl3); +} + +void tegra_i2c_ll_write(uint offset, uint8_t data) +{ + struct dvc_ctlr *reg = (struct dvc_ctlr *)TEGRA_DVC_BASE; + + writel(TPS6586X_I2C_ADDR, ®->cmd_addr0); + writel(2, ®->cnfg); + + writel((data << 8) | (offset & 0xff), ®->cmd_data1); + writel(I2C_SEND_2_BYTES, ®->cnfg); +} + static void enable_cpu_power_rail(void) { struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; u32 reg; + debug("enable_cpu_power_rail entry\n"); + +#ifdef CONFIG_TEGRA_EARLY_TPS6586X + tegra_i2c_ll_init(); + + /* Set SM0 being VDD_CORE_1.2V to 1.2 volts */ + tegra_i2c_ll_write(TPS6586X_SM0V1_REG, 0x13); + + udelay(1000); + + /* Set SM1 being VDD_CPU_1.0V to 1.0 volts */ + tegra_i2c_ll_write(TPS6586X_SM1V1_REG, 0x0b); + + udelay(1000); + + /* Make sure primary voltages are selected and ramped towards */ + tegra_i2c_ll_write(TPS6586X_VCC1_REG, 0x05); + + udelay(10 * 1000); +#endif + reg = readl(&pmc->pmc_cntrl); reg |= CPUPWRREQ_OE; writel(reg, &pmc->pmc_cntrl); @@ -38,8 +88,34 @@ static void enable_cpu_power_rail(void) udelay(3750); } +/* T20 requires some special clock initialization, incl. setting up DVC I2C */ +void t20_init_clocks(void) +{ + debug("t20_init_clocks entry\n"); + + /* Put i2c in reset and enable clocks */ + reset_set_enable(PERIPH_ID_DVC_I2C, 1); + clock_set_enable(PERIPH_ID_DVC_I2C, 1); + + /* + * Our high-level clock routines are not available prior to + * relocation. We use the low-level functions which require a + * hard-coded divisor. Use CLK_M with divide by (n + 1 = 16) + */ + clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 15); + + /* Give clocks time to stabilize, then take i2c out of reset */ + udelay(1000); + + reset_set_enable(PERIPH_ID_DVC_I2C, 0); +} + void start_cpu(u32 reset_vector) { + debug("%s entry, reset_vector = %x\n", __func__, reset_vector); + + t20_init_clocks(); + /* Enable VDD_CPU */ enable_cpu_power_rail(); diff --git a/include/configs/colibri_t20.h b/include/configs/colibri_t20.h index 0aa07959c83..63e832dd6c3 100644 --- a/include/configs/colibri_t20.h +++ b/include/configs/colibri_t20.h @@ -14,6 +14,8 @@ #undef CONFIG_SYS_DCACHE_OFF /* breaks L4T kernel boot */ #define CONFIG_ARCH_MISC_INIT +#define CONFIG_TEGRA_EARLY_TPS6586X + /* High-level configuration options */ #define V_PROMPT "Colibri T20 # " #define CONFIG_CUSTOM_BOARDINFO /* not from device-tree model node */ |