From patchwork Thu Aug 20 07:52:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcel Ziswiler X-Patchwork-Id: 508933 X-Patchwork-Delegate: twarren@nvidia.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id E95DC140134 for ; Thu, 20 Aug 2015 17:58:53 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 30AFF4B62C; Thu, 20 Aug 2015 09:58:45 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0KrE83RpjejG; Thu, 20 Aug 2015 09:58:45 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 476264B695; Thu, 20 Aug 2015 09:58:41 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C133F4B663 for ; Thu, 20 Aug 2015 09:58:36 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VYAKsCebOYsd for ; Thu, 20 Aug 2015 09:58:36 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mout.perfora.net (mout.perfora.net [74.208.4.196]) by theia.denx.de (Postfix) with ESMTPS id 9483B4B67C for ; Thu, 20 Aug 2015 09:58:29 +0200 (CEST) Received: from localhost.localdomain ([46.140.72.82]) by mrelay.perfora.net (mreueus001) with ESMTPA (Nemesis) id 0MQPKk-1ZKjw60UjE-00TpAL; Thu, 20 Aug 2015 09:52:58 +0200 From: Marcel Ziswiler To: u-boot@lists.denx.de Date: Thu, 20 Aug 2015 09:52:41 +0200 Message-Id: <1440057163-20081-2-git-send-email-marcel.ziswiler@toradex.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1440057163-20081-1-git-send-email-marcel.ziswiler@toradex.com> References: <1440057163-20081-1-git-send-email-marcel.ziswiler@toradex.com> X-Provags-ID: V03:K0:qyWqU4E037m9IVi3LSs3LSaAhklPwJ/cw5bci3j40dZZKIlY0ud bt51Mp6yW6Y3wvAn8yMF1b53zffUHLpPaM0HNs/jsJJjNSAiTPUniQ1uoKbijCaMwrhWUgH YD+kn4AhOE8CoGxL7L+bVe7ok1J104+315B3ifUCx9gNCkjfL5ZuMVF7eM236OBPaXwgA46 qTUl+Vl78dIzcYQCP5NTQ== X-UI-Out-Filterresults: notjunk:1; V01:K0:l9E/y84nlGU=:FSbxBlh1NQcocIiZHkRypi pRSGrp30s63zopTs97+KZVWmesqsUqq7trBc/ebU+tAWXRNC1cav0ty08bBS64o3U8zjlGrrx cWVe/yIqOrisVMynoPneA3gKz+qQDF2/3dy7yyuodCuR/kFGCjpSk+W7+lyK4jLsPDWX5+xL2 OWJLuxnSkhDXHQxmem1zcFAyl1IQri7ZL5YFI6FK6YicglD2myuO705oaBeFH3NYPe0lFRjVS CMNs+uziHRnTJhgBU3JZ+qObRspG3HVBUYWe5LqKHF4n/iaxtYEGE6u9SKOCK6uZuRk4Tmcli 0SEiT9Eb7Wk7b1qim8S7lmhdRUOcKlRNGaWaFlrlJpnr3CTLLdYbXs2WitrtEdirYoFOueeea /zQ042PU8j//T1vsS9iO0+U76k+3n5njw38hd2zsZUlcNXSYWxA0XZBkTgaeGqXjmFhm7l6Hj wOs7ZOSaCcB5Cm6tI9WnWWAp3vDFHb2ILQ3uV6mqGUaWPWAPpt2NsGt/nhGlqEkr1DpMQabjq hWSq6k51ts6/gKskVbd9W5duyE2gtdWaZKlIu5V7Zg07Qky5WT5rdeN8qeJNlqQT25c1Vl24A 9kzu6/wT36IRbsbkmocs8ncuDTXNWSNEbcASZX14ct4VUAD7ODKBxFn2jjY7qSC0Yaj++OM3K OeEoQuYxv/qZOJ0xI27G3PzE60enBzUNGP7yQeeFB8G8NH3Y34ZHYDMXFVAoK2SPg6r4= Cc: Stephen Warren , Tom Rini , Marcel Ziswiler , Masahiro Yamada , Tom Warren Subject: [U-Boot] [PATCH 1/3] arm: tegra20: implement early pmic rail configuration X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" 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. Signed-off-by: Marcel Ziswiler --- arch/arm/mach-tegra/tegra20/cpu.c | 76 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/tegra20/cpu.c b/arch/arm/mach-tegra/tegra20/cpu.c index 67f49d7..aa05e1b 100644 --- a/arch/arm/mach-tegra/tegra20/cpu.c +++ b/arch/arm/mach-tegra/tegra20/cpu.c @@ -15,16 +15,64 @@ */ #include -#include +#include #include #include +#include +#include #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("%s entry\n", __func__); + +#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 +86,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("%s entry\n", __func__); + + /* 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();