From patchwork Wed Oct 26 21:13:37 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Rini X-Patchwork-Id: 122009 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 D6B96B6F7B for ; Thu, 27 Oct 2011 08:14:23 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2FDE729786; Wed, 26 Oct 2011 23:14:22 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de 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 jvfem9l0nyNP; Wed, 26 Oct 2011 23:14:21 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 71E2A29790; Wed, 26 Oct 2011 23:14:19 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 64D7329769 for ; Wed, 26 Oct 2011 23:13:56 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de 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 yTkZIbWhMR7B for ; Wed, 26 Oct 2011 23:13:54 +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 devils.ext.ti.com (devils.ext.ti.com [198.47.26.153]) by theia.denx.de (Postfix) with ESMTPS id 5BFF529768 for ; Wed, 26 Oct 2011 23:13:52 +0200 (CEST) Received: from dbdp20.itg.ti.com ([172.24.170.38]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id p9QLDmjT002474 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 26 Oct 2011 16:13:50 -0500 Received: from dbde70.ent.ti.com (localhost [127.0.0.1]) by dbdp20.itg.ti.com (8.13.8/8.13.8) with ESMTP id p9QLDl8O010845 for ; Thu, 27 Oct 2011 02:43:47 +0530 (IST) Received: from dbdp31.itg.ti.com (172.24.170.98) by DBDE70.ent.ti.com (172.24.170.148) with Microsoft SMTP Server id 8.3.106.1; Thu, 27 Oct 2011 02:43:47 +0530 Received: from localhost.localdomain (dbdp20.itg.ti.com [172.24.170.38]) by dbdp31.itg.ti.com (8.13.8/8.13.8) with ESMTP id p9QLDgqY021072 for ; Thu, 27 Oct 2011 02:43:45 +0530 (IST) From: Tom Rini To: Date: Wed, 26 Oct 2011 14:13:37 -0700 Message-ID: <1319663618-10005-2-git-send-email-trini@ti.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1319663618-10005-1-git-send-email-trini@ti.com> References: <1319663618-10005-1-git-send-email-trini@ti.com> MIME-Version: 1.0 Subject: [U-Boot] [PATCH 1/2] OMAP3 SPL: Rework memory initalization and devkit 8000 support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This changes to making the board be responsible for providing the memory initialization timings in SPL and converts the devkit 8000 to this framework. As part of this suffix the Micron DDR settings with their speed and add a few more timing values that will be needed. We also make sure that in mem_ok() we clear the values off as we may be testing the same banks multiple times. Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap3/mem.c | 1 + arch/arm/cpu/armv7/omap3/sdrc.c | 132 +++++++++++++++------------ arch/arm/include/asm/arch-omap3/mem.h | 58 +++++------- arch/arm/include/asm/arch-omap3/sys_proto.h | 2 +- board/timll/devkit8000/devkit8000.c | 24 +++++ 5 files changed, 123 insertions(+), 94 deletions(-) diff --git a/arch/arm/cpu/armv7/omap3/mem.c b/arch/arm/cpu/armv7/omap3/mem.c index a01c303..cd5fe5c 100644 --- a/arch/arm/cpu/armv7/omap3/mem.c +++ b/arch/arm/cpu/armv7/omap3/mem.c @@ -86,6 +86,7 @@ u32 mem_ok(u32 cs) writel(0x0, addr + 4); /* remove pattern off the bus */ val1 = readl(addr + 0x400); /* get pos A value */ val2 = readl(addr); /* get val2 */ + writel(0x0, addr + 0x400); /* clear pos A */ if ((val1 != 0) || (val2 != pattern)) /* see if pos A val changed */ return 0; diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c index 0dd1955..4799787 100644 --- a/arch/arm/cpu/armv7/omap3/sdrc.c +++ b/arch/arm/cpu/armv7/omap3/sdrc.c @@ -109,15 +109,56 @@ u32 get_sdr_cs_offset(u32 cs) } /* + * write_sdrc_timings - + * - Takes CS and associated timings and initalize SDRAM + * - Test CS to make sure it's OK for use + */ +static void write_sdrc_timings(u32 cs, struct sdrc_actim *sdrc_actim_base, + u32 mcfg, u32 ctrla, u32 ctrlb, u32 rfr_ctrl, u32 mr) +{ + /* Setup timings we got from the board. */ + writel(mcfg, &sdrc_base->cs[cs].mcfg); + writel(ctrla, &sdrc_actim_base->ctrla); + writel(ctrlb, &sdrc_actim_base->ctrlb); + writel(rfr_ctrl, &sdrc_base->cs[cs].rfr_ctrl); + writel(CMD_NOP, &sdrc_base->cs[cs].manual); + writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); + writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); + writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); + writel(mr, &sdrc_base->cs[cs].mr); + + /* + * Test ram in this bank + * Disable if bad or not present + */ + if (!mem_ok(cs)) + writel(0, &sdrc_base->cs[cs].mcfg); +} + +/* * do_sdrc_init - - * - Initialize the SDRAM for use. - * - code called once in C-Stack only context for CS0 and a possible 2nd - * time depending on memory configuration from stack+global context + * - Code called once in C-Stack only context for CS0 and with early being + * true and a possible 2nd time depending on memory configuration from + * stack+global context. */ void do_sdrc_init(u32 cs, u32 early) { - struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1; + struct sdrc_actim *sdrc_actim_base0; + u32 mcfg, ctrla, ctrlb, rfr_ctrl, mr; +#ifdef CONFIG_SPL_BUILD + u32 cs_cfg; +#endif + /* + * When called in the early context this may be SPL and we will + * need to set all of the timings. This ends up being board + * specific so we call a helper function to take care of this + * for us. Otherwise, to be safe, we need to copy the settings + * from the first bank to the second. + */ +#ifdef CONFIG_SPL_BUILD + get_board_mem_timings(&cs_cfg, &mcfg, &ctrla, &ctrlb, &rfr_ctrl, &mr); +#endif if (early) { /* reset sdrc controller */ writel(SOFTRESET, &sdrc_base->sysconfig); @@ -128,73 +169,45 @@ void do_sdrc_init(u32 cs, u32 early) /* setup sdrc to ball mux */ writel(SDRC_SHARING, &sdrc_base->sharing); - /* Disable Power Down of CKE cuz of 1 CKE on combo part */ + /* Disable Power Down of CKE because of 1 CKE on combo part */ writel(WAKEUPPROC | SRFRONRESET | PAGEPOLICY_HIGH, &sdrc_base->power); writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl); sdelay(0x20000); - } - -/* As long as V_MCFG and V_RFR_CTRL is not defined for all OMAP3 boards we need - * to prevent this to be build in non-SPL build */ #ifdef CONFIG_SPL_BUILD - /* If we use a SPL there is no x-loader nor config header so we have - * to do the job ourselfs - */ - if (cs == CS0) { - sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; - - /* General SDRC config */ - writel(V_MCFG, &sdrc_base->cs[cs].mcfg); - writel(V_RFR_CTRL, &sdrc_base->cs[cs].rfr_ctrl); - - /* AC timings */ - writel(V_ACTIMA_165, &sdrc_actim_base0->ctrla); - writel(V_ACTIMB_165, &sdrc_actim_base0->ctrlb); - - /* Initialize */ - writel(CMD_NOP, &sdrc_base->cs[cs].manual); - writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); - writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); - writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); + /* We only set cs_cfg in this case */ + writel(cs_cfg, &sdrc_base->cs_cfg); + + /* We need to do both banks now, in many cases. */ + write_sdrc_timings(CS0, + (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE, + mcfg, ctrla, ctrlb, rfr_ctrl, mr); + write_sdrc_timings(CS1, + (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE, + mcfg, ctrla, ctrlb, rfr_ctrl, mr); +#endif - writel(V_MR, &sdrc_base->cs[cs].mr); } -#endif /* - * SDRC timings are set up by x-load or config header - * We don't need to redo them here. - * Older x-loads configure only CS0 - * configure CS1 to handle this ommission + * If we aren't using SPL we have been loaded by some + * other means which may not have correctly initialized + * both CS0 and CS1 (such as some older versions of x-loader) + * so we may be asked now to setup CS1. */ if (cs == CS1) { sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; - sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; - writel(readl(&sdrc_base->cs[CS0].mcfg), - &sdrc_base->cs[CS1].mcfg); - writel(readl(&sdrc_base->cs[CS0].rfr_ctrl), - &sdrc_base->cs[CS1].rfr_ctrl); - writel(readl(&sdrc_actim_base0->ctrla), - &sdrc_actim_base1->ctrla); - writel(readl(&sdrc_actim_base0->ctrlb), - &sdrc_actim_base1->ctrlb); - - writel(CMD_NOP, &sdrc_base->cs[cs].manual); - writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); - writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); - writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); - writel(readl(&sdrc_base->cs[CS0].mr), - &sdrc_base->cs[CS1].mr); - } + mcfg = readl(&sdrc_base->cs[CS0].mcfg), + rfr_ctrl = readl(&sdrc_base->cs[CS0].rfr_ctrl); + ctrla = readl(&sdrc_actim_base0->ctrla), + ctrlb = readl(&sdrc_actim_base0->ctrlb); + mr = readl(&sdrc_base->cs[CS0].mr); + write_sdrc_timings(cs, + (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE, + mcfg, ctrla, ctrlb, rfr_ctrl, mr); - /* - * Test ram in this bank - * Disable if bad or not present - */ - if (!mem_ok(cs)) - writel(0, &sdrc_base->cs[cs].mcfg); + } } /* @@ -208,8 +221,9 @@ int dram_init(void) size0 = get_sdr_cs_size(CS0); /* * If a second bank of DDR is attached to CS1 this is - * where it can be started. Early init code will init - * memory on CS0. + * where it can be found. If we have SPL that code will have + * initalized it already, otherwise early init code will init + * memory on CS0 only. */ if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) { do_sdrc_init(CS1, NOT_EARLY); diff --git a/arch/arm/include/asm/arch-omap3/mem.h b/arch/arm/include/asm/arch-omap3/mem.h index 8e28f77..af3504c 100644 --- a/arch/arm/include/asm/arch-omap3/mem.h +++ b/arch/arm/include/asm/arch-omap3/mem.h @@ -37,12 +37,28 @@ enum { }; #endif /* __ASSEMBLY__ */ +/* Memory that can be connected to GPMC */ +#define GPMC_NOR 0 +#define GPMC_NAND 1 +#define GPMC_MDOC 2 +#define GPMC_ONENAND 3 +#define MMC_NAND 4 +#define MMC_ONENAND 5 +#define GPMC_NONE 6 +#define GPMC_ONENAND_TRY 7 + #define EARLY_INIT 1 /* Slower full frequency range default timings for x32 operation*/ #define SDRC_SHARING 0x00000100 #define SDRC_MR_0_SDR 0x00000031 +/* optimized timings good for current shipping parts */ +#define SDP_3430_SDRC_RFR_CTRL_100MHz 0x0002da01 +#define SDP_3430_SDRC_RFR_CTRL_133MHz 0x0003de01 /* 7.8us/7.5ns - 50=0x3de */ +#define SDP_3430_SDRC_RFR_CTRL_165MHz 0x0004e201 /* 7.8us/6ns - 50=0x4e2 */ +#define SDP_3430_SDRC_RFR_CTRL_200MHz 0x0005e601 /* 7.8us/5ns - 50=0x5e6 */ + #define DLL_OFFSET 0 #define DLL_WRITEDDRCLKX2DIS 1 #define DLL_ENADLL 1 @@ -138,15 +154,15 @@ enum { #define MICRON_CASWIDTH 0x5 #define MICRON_RASWIDTH 0x2 #define MICRON_LOCKSTATUS 0x0 -#define MICRON_V_MCFG ((MICRON_LOCKSTATUS << 30) | (MICRON_RASWIDTH << 24) | \ - (MICRON_CASWIDTH << 20) | (MICRON_ADDRMUXLEGACY << 19) | \ - (MICRON_RAMSIZE << 8) | (MICRON_BANKALLOCATION << 6) | \ - (MICRON_B32NOT16 << 4) | (MICRON_DEEPPD << 3) | \ - (MICRON_DDRTYPE << 2) | (MICRON_RAMTYPE)) +#define MICRON_V_MCFG_165 ((MICRON_LOCKSTATUS << 30) | \ + (MICRON_RASWIDTH << 24) | (MICRON_CASWIDTH << 20) | \ + (MICRON_ADDRMUXLEGACY << 19) | (MICRON_RAMSIZE << 8) | \ + (MICRON_BANKALLOCATION << 6) | (MICRON_B32NOT16 << 4) | \ + (MICRON_DEEPPD << 3) | (MICRON_DDRTYPE << 2) | (MICRON_RAMTYPE)) -#define MICRON_ARCV 2030 -#define MICRON_ARE 0x1 -#define MICRON_V_RFR_CTRL ((MICRON_ARCV << 8) | (MICRON_ARE)) +#define MICRON_ARCV_165 0x4e2 +#define MICRON_ARE 0x1 +#define MICRON_V_RFR_CTRL_165 ((MICRON_ARCV_165 << 8) | (MICRON_ARE)) #define MICRON_BL 0x2 #define MICRON_SIL 0x0 @@ -194,32 +210,6 @@ enum { (NUMONYX_XSR_165 << 0) | (NUMONYX_TXP_165 << 8) | \ (NUMONYX_TWTR_165 << 16)) -#ifdef CONFIG_OMAP3_INFINEON_DDR -#define V_ACTIMA_165 INFINEON_V_ACTIMA_165 -#define V_ACTIMB_165 INFINEON_V_ACTIMB_165 -#endif - -#ifdef CONFIG_OMAP3_MICRON_DDR -#define V_ACTIMA_165 MICRON_V_ACTIMA_165 -#define V_ACTIMB_165 MICRON_V_ACTIMB_165 -#define V_MCFG MICRON_V_MCFG -#define V_RFR_CTRL MICRON_V_RFR_CTRL -#define V_MR MICRON_V_MR -#endif - -#ifdef CONFIG_OMAP3_NUMONYX_DDR -#define V_ACTIMA_165 NUMONYX_V_ACTIMA_165 -#define V_ACTIMB_165 NUMONYX_V_ACTIMB_165 -#endif - -#if !defined(V_ACTIMA_165) || !defined(V_ACTIMB_165) -#error "Please choose the right DDR type in config header" -#endif - -#if defined(CONFIG_SPL_BUILD) && (!defined(V_MCFG) || !defined(V_RFR_CTRL)) -#error "Please choose the right DDR type in config header" -#endif - /* * GPMC settings - * Definitions is as per the following format diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h index 7b60051..a2c317a 100644 --- a/arch/arm/include/asm/arch-omap3/sys_proto.h +++ b/arch/arm/include/asm/arch-omap3/sys_proto.h @@ -38,6 +38,7 @@ void per_clocks_enable(void); void memif_init(void); void sdrc_init(void); void do_sdrc_init(u32, u32); +void get_board_mem_timings(u32 *, u32 *, u32 *, u32 *, u32 *, u32 *); void emif4_init(void); void gpmc_init(void); void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base, @@ -49,7 +50,6 @@ void set_muxconf_regs(void); u32 get_cpu_family(void); u32 get_cpu_rev(void); u32 get_sku_id(void); -u32 get_mem_type(void); u32 get_sysboot_value(void); u32 is_gpmc_muxed(void); u32 get_gpmc0_type(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index f50d113..568f02e 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -138,3 +138,27 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +/* + * Routine: get_board_mem_timings + * Description: If we use SPL then there is no x-loader nor config header + * so we have to setup the DDR timings outself on the first bank. This + * provides the timing values back to the function that configures + * the memory. + */ +void get_board_mem_timings(u32 *cs_cfg, u32 *mcfg, u32 *ctrla, u32 *ctrlb, + u32 *rfr_ctrl, u32 *mr) +{ + /* 128MiB/bank */ + *cs_cfg = 0x1; + + /* General SDRC config */ + *mcfg = MICRON_V_MCFG_165; + *rfr_ctrl = MICRON_V_RFR_CTRL_165; + + /* AC timings */ + *ctrla = MICRON_V_ACTIMA_165; + *ctrlb = MICRON_V_ACTIMB_165; + + *mr = MICRON_V_MR; +}