From 4ecfcfaa9ed1bb2ee73585752f9c36a12d1600c6 Mon Sep 17 00:00:00 2001 From: Aneesh V Date: Thu, 8 Sep 2011 11:05:56 -0400 Subject: [PATCH] omap4: IO settings Tuning some IO settings for better performance and power. And consolidate all such IO settings at one place. Signed-off-by: Aneesh V Signed-off-by: Sandeep Paulraj --- arch/arm/cpu/armv7/omap4/board.c | 62 +++++++++++++++++++++++++ arch/arm/cpu/armv7/omap4/emif.c | 25 ---------- arch/arm/include/asm/arch-omap4/emif.h | 18 ------- arch/arm/include/asm/arch-omap4/omap4.h | 45 +++++++++++++++++- 4 files changed, 105 insertions(+), 45 deletions(-) diff --git a/arch/arm/cpu/armv7/omap4/board.c b/arch/arm/cpu/armv7/omap4/board.c index 69a0ce5513..309b244ad2 100644 --- a/arch/arm/cpu/armv7/omap4/board.c +++ b/arch/arm/cpu/armv7/omap4/board.c @@ -70,6 +70,67 @@ u32 omap_boot_mode(void) { return omap4_boot_mode; } + +/* + * Some tuning of IOs for optimal power and performance + */ +static void do_io_settings(void) +{ + u32 lpddr2io; + struct control_lpddr2io_regs *lpddr2io_regs = + (struct control_lpddr2io_regs *)LPDDR2_IO_REGS_BASE; + struct omap4_sys_ctrl_regs *const ctrl = + (struct omap4_sys_ctrl_regs *)SYSCTRL_GENERAL_CORE_BASE; + + u32 omap4_rev = omap_revision(); + + if (omap4_rev == OMAP4430_ES1_0) + lpddr2io = CONTROL_LPDDR2IO_SLEW_125PS_DRV8_PULL_DOWN; + else if (omap4_rev == OMAP4430_ES2_0) + lpddr2io = CONTROL_LPDDR2IO_SLEW_325PS_DRV8_GATE_KEEPER; + else + lpddr2io = CONTROL_LPDDR2IO_SLEW_315PS_DRV12_PULL_DOWN; + + /* EMIF1 */ + writel(lpddr2io, &lpddr2io_regs->control_lpddr2io1_0); + writel(lpddr2io, &lpddr2io_regs->control_lpddr2io1_1); + /* No pull for GR10 as per hw team's recommendation */ + writel(lpddr2io & ~LPDDR2IO_GR10_WD_MASK, + &lpddr2io_regs->control_lpddr2io1_2); + writel(CONTROL_LPDDR2IO_3_VAL, &lpddr2io_regs->control_lpddr2io1_3); + + /* EMIF2 */ + writel(lpddr2io, &lpddr2io_regs->control_lpddr2io2_0); + writel(lpddr2io, &lpddr2io_regs->control_lpddr2io2_1); + /* No pull for GR10 as per hw team's recommendation */ + writel(lpddr2io & ~LPDDR2IO_GR10_WD_MASK, + &lpddr2io_regs->control_lpddr2io2_2); + writel(CONTROL_LPDDR2IO_3_VAL, &lpddr2io_regs->control_lpddr2io2_3); + + /* + * Some of these settings (TRIM values) come from eFuse and are + * in turn programmed in the eFuse at manufacturing time after + * calibration of the device. Do the software over-ride only if + * the device is not correctly trimmed + */ + if (!(readl(&ctrl->control_std_fuse_opp_bgap) & 0xFFFF)) { + + writel(LDOSRAM_VOLT_CTRL_OVERRIDE, + &ctrl->control_ldosram_iva_voltage_ctrl); + + writel(LDOSRAM_VOLT_CTRL_OVERRIDE, + &ctrl->control_ldosram_mpu_voltage_ctrl); + + writel(LDOSRAM_VOLT_CTRL_OVERRIDE, + &ctrl->control_ldosram_core_voltage_ctrl); + } + + if (!readl(&ctrl->control_efuse_1)) + writel(CONTROL_EFUSE_1_OVERRIDE, &ctrl->control_efuse_1); + + if (!readl(&ctrl->control_efuse_2)) + writel(CONTROL_EFUSE_2_OVERRIDE, &ctrl->control_efuse_2); +} #endif void do_set_mux(u32 base, struct pad_conf_entry const *array, int size) @@ -197,6 +258,7 @@ void s_init(void) set_mux_conf_regs(); #ifdef CONFIG_SPL_BUILD preloader_console_init(); + do_io_settings(); #endif prcm_init(); #ifdef CONFIG_SPL_BUILD diff --git a/arch/arm/cpu/armv7/omap4/emif.c b/arch/arm/cpu/armv7/omap4/emif.c index 8c46464988..988b2050fa 100644 --- a/arch/arm/cpu/armv7/omap4/emif.c +++ b/arch/arm/cpu/armv7/omap4/emif.c @@ -1063,30 +1063,6 @@ static void do_sdram_init(u32 base) debug("<control_lpddr2io1_0); - writel(lpddr2io, &lpddr2io_regs->control_lpddr2io1_1); - writel(lpddr2io, &lpddr2io_regs->control_lpddr2io1_2); - writel(lpddr2io, &lpddr2io_regs->control_lpddr2io2_0); - writel(lpddr2io, &lpddr2io_regs->control_lpddr2io2_1); - writel(lpddr2io, &lpddr2io_regs->control_lpddr2io2_2); - - writel(CONTROL_EFUSE_2_NMOS_PMOS_PTV_CODE_1, CONTROL_EFUSE_2); -} - static void emif_post_init_config(u32 base) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; @@ -1243,7 +1219,6 @@ void sdram_init(void) debug("in_sdram = %d\n", in_sdram); if (!in_sdram) { - sdram_init_pads(); bypass_dpll(&prcm->cm_clkmode_dpll_core); } diff --git a/arch/arm/include/asm/arch-omap4/emif.h b/arch/arm/include/asm/arch-omap4/emif.h index 6845c65b2d..3a549bad5e 100644 --- a/arch/arm/include/asm/arch-omap4/emif.h +++ b/arch/arm/include/asm/arch-omap4/emif.h @@ -593,17 +593,6 @@ struct dmm_lisa_map_regs { u32 dmm_lisa_map_3; }; -struct control_lpddr2io_regs { - u32 control_lpddr2io1_0; - u32 control_lpddr2io1_1; - u32 control_lpddr2io1_2; - u32 control_lpddr2io1_3; - u32 control_lpddr2io2_0; - u32 control_lpddr2io2_1; - u32 control_lpddr2io2_2; - u32 control_lpddr2io2_3; -}; - #define CS0 0 #define CS1 1 /* The maximum frequency at which the LPDDR2 interface can operate in Hz*/ @@ -823,13 +812,6 @@ struct control_lpddr2io_regs { /* MR16 value: refresh full array(no partial array self refresh) */ #define MR16_REF_FULL_ARRAY 0 -/* LPDDR2 IO regs */ -#define CONTROL_LPDDR2IO_SLEW_125PS_DRV8_PULL_DOWN 0x1C1C1C1C -#define CONTROL_LPDDR2IO_SLEW_325PS_DRV8_GATE_KEEPER 0x9E9E9E9E - -/* CONTROL_EFUSE_2 */ -#define CONTROL_EFUSE_2_NMOS_PMOS_PTV_CODE_1 0x00ffc000 - /* * Maximum number of entries we keep in our array of timing tables * We need not keep all the speed bins supported by the device diff --git a/arch/arm/include/asm/arch-omap4/omap4.h b/arch/arm/include/asm/arch-omap4/omap4.h index 7ff46d771c..a6e1e42e22 100644 --- a/arch/arm/include/asm/arch-omap4/omap4.h +++ b/arch/arm/include/asm/arch-omap4/omap4.h @@ -54,8 +54,6 @@ /* LPDDR2 IO regs */ #define LPDDR2_IO_REGS_BASE 0x4A100638 -#define CONTROL_EFUSE_2 0x4A100704 - /* CONTROL_ID_CODE */ #define CONTROL_ID_CODE 0x4A002204 @@ -84,6 +82,9 @@ /* GPMC */ #define OMAP44XX_GPMC_BASE 0x50000000 +/* SYSTEM CONTROL MODULE */ +#define SYSCTRL_GENERAL_CORE_BASE 0x4A002000 + /* * Hardware Register Details */ @@ -108,6 +109,22 @@ #define PRM_RSTCTRL PRM_DEVICE_BASE #define PRM_RSTCTRL_RESET 0x01 +/* Control Module */ +#define LDOSRAM_ACTMODE_VSET_IN_MASK (0x1F << 5) +#define LDOSRAM_VOLT_CTRL_OVERRIDE 0x0401040f +#define CONTROL_EFUSE_1_OVERRIDE 0x1C4D0110 +#define CONTROL_EFUSE_2_OVERRIDE 0x00084000 + +/* LPDDR2 IO regs */ +#define CONTROL_LPDDR2IO_SLEW_125PS_DRV8_PULL_DOWN 0x1C1C1C1C +#define CONTROL_LPDDR2IO_SLEW_325PS_DRV8_GATE_KEEPER 0x9E9E9E9E +#define CONTROL_LPDDR2IO_SLEW_315PS_DRV12_PULL_DOWN 0x7C7C7C7C +#define LPDDR2IO_GR10_WD_MASK (3 << 17) +#define CONTROL_LPDDR2IO_3_VAL 0xA0888C00 + +/* CONTROL_EFUSE_2 */ +#define CONTROL_EFUSE_2_NMOS_PMOS_PTV_CODE_1 0x00ffc000 + #ifndef __ASSEMBLY__ struct s32ktimer { @@ -115,6 +132,30 @@ struct s32ktimer { unsigned int s32k_cr; /* 0x10 */ }; +struct omap4_sys_ctrl_regs { + unsigned int pad1[129]; + unsigned int control_id_code; /* 0x4A002204 */ + unsigned int pad11[22]; + unsigned int control_std_fuse_opp_bgap; /* 0x4a002260 */ + unsigned int pad2[47]; + unsigned int control_ldosram_iva_voltage_ctrl; /* 0x4A002320 */ + unsigned int control_ldosram_mpu_voltage_ctrl; /* 0x4A002324 */ + unsigned int control_ldosram_core_voltage_ctrl; /* 0x4A002328 */ + unsigned int pad3[260341]; + unsigned int control_efuse_1; /* 0x4A100700 */ + unsigned int control_efuse_2; /* 0x4A100704 */ +}; + +struct control_lpddr2io_regs { + unsigned int control_lpddr2io1_0; + unsigned int control_lpddr2io1_1; + unsigned int control_lpddr2io1_2; + unsigned int control_lpddr2io1_3; + unsigned int control_lpddr2io2_0; + unsigned int control_lpddr2io2_1; + unsigned int control_lpddr2io2_2; + unsigned int control_lpddr2io2_3; +}; #endif /* __ASSEMBLY__ */ /*