[coreboot-gerrit] New patch to review for coreboot: t210: lp0_resume: Configure unused SDMMC1/3 pads for low power leakage

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Tue Sep 15 19:40:00 CET 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11656

-gerrit

commit c4984569f6a3561558929f433c89905bc84ccb00
Author: Yen Lin <yelin at nvidia.com>
Date:   Tue Sep 8 15:13:13 2015 -0700

    t210: lp0_resume: Configure unused SDMMC1/3 pads for low power leakage
    
    In LP0 resume, a couple of SDMMCx pad settings need to be set to 0 to
    reduce power leakage.
    
    BUG=None
    BRANCH=None
    TEST=Tested on Smaug; able to suspend/resume >100 times
    
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 9f35a90a8af2180443db2c4be75d4566d0990de5
    Original-Change-Id: Ifc946b0cea437ef0807cea0c11609d8e09387e8e
    Original-Signed-off-by: Yen Lin <yelin at nvidia.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/298195
    Original-Reviewed-by: Andrew Bresticker <abrestic at chromium.org>
    Original-Reviewed-by: Tom Warren <twarren at nvidia.com>
    Original-Tested-by: Joseph Lo <josephl at nvidia.com>
    Original-(cherry picked from commit be3ac49a6bc4c9088d3799555d69c87c8ce1693c)
    Original-Reviewed-on: https://chromium-review.googlesource.com/298154
    Original-Commit-Ready: Furquan Shaikh <furquan at chromium.org>
    Original-Tested-by: Furquan Shaikh <furquan at chromium.org>
    Original-Reviewed-by: Furquan Shaikh <furquan at chromium.org>
    
    Change-Id: If5d5cebc89b8220480b3c72293a410e782eb437e
---
 src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c | 50 ++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c b/src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c
index 956e8c5..87e42e3 100644
--- a/src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c
+++ b/src/soc/nvidia/tegra210/lp0/tegra_lp0_resume.c
@@ -30,6 +30,8 @@ enum {
 	PMC_CTLR_BASE = 0x7000e400,
 	MC_CTLR_BASE = 0x70019000,
 	FUSE_BASE = 0x7000F800,
+	TEGRA_SDMMC1_BASE = 0x700b0000,
+	TEGRA_SDMMC3_BASE = 0x700b0400,
 	EMC_BASE = 0x7001B000,
 	I2C5_BASE = 0x7000D000,
 	I2S_BASE = 0x702d1000
@@ -79,6 +81,8 @@ enum {
 	SWR_TRIG_SYS_RST = 0x1 << 2
 };
 
+static uint32_t *clk_rst_rst_devices_u_ptr = (void *)(CLK_RST_BASE + 0xc);
+
 static uint32_t *clk_rst_cclkg_burst_policy_ptr = (void *)(CLK_RST_BASE + 0x368);
 enum {
 	CCLKG_PLLP_BURST_POLICY = 0x20004444
@@ -810,6 +814,49 @@ static void mbist_workaround(void)
 		write32(clk_rst_clk_enb_w_set_ptr, CLK_ENB_MC1);
 }
 
+static uint32_t *sdmmc1_vendor_io_trim = (void *)(TEGRA_SDMMC1_BASE + 0x1ac);
+static uint32_t *sdmmc3_vendor_io_trim = (void *)(TEGRA_SDMMC3_BASE + 0x1ac);
+static uint32_t *sdmmc1_comppadctrl = (void *)(TEGRA_SDMMC1_BASE + 0x1e0);
+static uint32_t *sdmmc3_comppadctrl = (void *)(TEGRA_SDMMC3_BASE + 0x1e0);
+
+enum {
+	SDMMC1_DEV_L = 0x1 << 14,
+	SDMMC3_DEV_U = 0x1 << 5,
+	PAD_E_INPUT_COMPPADCTRL = 0x1 << 31,
+	SEL_VREG_VENDOR_IO_TRIM = 0x1 << 2
+};
+
+static void low_power_sdmmc_pads(void)
+{
+	/* Enable SDMMC1 clock */
+	setbits32(SDMMC1_DEV_L, clk_rst_clk_out_enb_l_ptr);
+	udelay(2);
+	/* Unreset SDMMC1 */
+	clrbits32(SDMMC1_DEV_L, clk_rst_rst_devices_l_ptr);
+
+	/* Clear SEL_VREG bit and PAD_E_INPUT bit of SDMMC1 */
+	clrbits32(SEL_VREG_VENDOR_IO_TRIM, sdmmc1_vendor_io_trim);
+	clrbits32(PAD_E_INPUT_COMPPADCTRL, sdmmc1_comppadctrl);
+	/* Read the last accessed SDMMC1 register then disable SDMMC1 clock */
+	read32(sdmmc1_comppadctrl);
+	/* Disable SDMMC1 clock, but keep SDMMC1 un-reset */
+	clrbits32(SDMMC1_DEV_L, clk_rst_clk_out_enb_l_ptr);
+
+	/* Enable SDMMC3 clock */
+	setbits32(SDMMC3_DEV_U, clk_rst_clk_out_enb_u_ptr);
+	udelay(2);
+	/* Unreset SDMMC3 */
+	clrbits32(SDMMC3_DEV_U, clk_rst_rst_devices_u_ptr);
+
+	/* Clear SEL_VREG bit and PAD_E_INPUT bit of SDMMC3 */
+	clrbits32(SEL_VREG_VENDOR_IO_TRIM, sdmmc3_vendor_io_trim);
+	clrbits32(PAD_E_INPUT_COMPPADCTRL, sdmmc3_comppadctrl);
+	/* Read the last accessed SDMMC3 register then disable SDMMC3 clock */
+	read32(sdmmc3_comppadctrl);
+	/* Disable SDMMC3 clock, but keep SDMMC3 un-reset */
+	clrbits32(SDMMC3_DEV_U, clk_rst_clk_out_enb_u_ptr);
+}
+
 static void config_mselect(void)
 {
 	/* Set MSELECT clock source to PLL_P with 1:4 divider */
@@ -895,6 +942,9 @@ void lp0_resume(void)
 	/* Restore CAR CE's, SLCG overrides */
 	mbist_workaround();
 
+	/* Configure unused SDMMC1/3 pads for low power leakage */
+	low_power_sdmmc_pads();
+
 	/*
 	 * Find out which CPU (slow or fast) to wake up. The default setting
 	 * in flow controller is to wake up GCPU



More information about the coreboot-gerrit mailing list