From 04737d5ffd16248cb80ab3dd4f3765057a803f18 Mon Sep 17 00:00:00 2001 From: Prodyut Hazarika Date: Wed, 27 Aug 2008 16:39:00 -0700 Subject: ppc4xx: Optimizations/Cleanups for IBM DDR2 Memory Controller Removed Magic numbers from Initialization preload registers Tested with Kilauea, Glacier, Canyonlands and Katmai boards About 5-7% improvement seen for LMBench memtests Signed-off-by: Prodyut Hazarika Signed-off-by: Stefan Roese --- cpu/ppc4xx/44x_spd_ddr2.c | 73 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 17 deletions(-) (limited to 'cpu') diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index 001f2c1..15250d4 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -118,6 +118,7 @@ static inline void ppc4xx_ibm_ddr2_register_dump(void); #define ODS_FULL 0x00000000 #define ODS_REDUCED 0x00000002 +#define OCD_CALIB_DEF 0x00000380 /* defines for ODT (On Die Termination) of the 440SP(e) DDR2 controller */ #define ODT_EB0R (0x80000000 >> 8) @@ -570,15 +571,24 @@ phys_size_t initdram(int board_type) mtsdram(SDRAM_MCOPT2, (val & ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_DCEN_MASK | SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_ISIE_MASK)) | - (SDRAM_MCOPT2_DCEN_ENABLE | SDRAM_MCOPT2_IPTR_EXECUTE)); + SDRAM_MCOPT2_IPTR_EXECUTE); /*------------------------------------------------------------------ - * Wait for SDRAM_CFG0_DC_EN to complete. + * Wait for IPTR_EXECUTE init sequence to complete. *-----------------------------------------------------------------*/ do { mfsdram(SDRAM_MCSTAT, val); } while ((val & SDRAM_MCSTAT_MIC_MASK) == SDRAM_MCSTAT_MIC_NOTCOMP); + /* enable the controller only after init sequence completes */ + mfsdram(SDRAM_MCOPT2, val); + mtsdram(SDRAM_MCOPT2, (val | SDRAM_MCOPT2_DCEN_ENABLE)); + + /* Make sure delay-line calibration is done before proceeding */ + do { + mfsdram(SDRAM_DLCR, val); + } while (!(val & SDRAM_DLCR_DLCS_COMPLETE)); + /* get installed memory size */ dram_size = sdram_memsize(); @@ -1343,22 +1353,50 @@ static void program_initplr(unsigned long *dimm_populated, emr = CMD_EMR | SELECT_EMR | odt | ods; emr2 = CMD_EMR | SELECT_EMR2; emr3 = CMD_EMR | SELECT_EMR3; - mtsdram(SDRAM_INITPLR0, 0xB5000000 | CMD_NOP); /* NOP */ + /* NOP - Wait 106 MemClk cycles */ + mtsdram(SDRAM_INITPLR0, SDRAM_INITPLR_ENABLE | CMD_NOP | + SDRAM_INITPLR_IMWT_ENCODE(106)); udelay(1000); - mtsdram(SDRAM_INITPLR1, 0x82000400 | CMD_PRECHARGE); /* precharge 8 DDR clock cycle */ - mtsdram(SDRAM_INITPLR2, 0x80800000 | emr2); /* EMR2 */ - mtsdram(SDRAM_INITPLR3, 0x80800000 | emr3); /* EMR3 */ - mtsdram(SDRAM_INITPLR4, 0x80800000 | emr); /* EMR DLL ENABLE */ - mtsdram(SDRAM_INITPLR5, 0x80800000 | mr | DLL_RESET); /* MR w/ DLL reset */ + /* precharge 4 MemClk cycles */ + mtsdram(SDRAM_INITPLR1, SDRAM_INITPLR_ENABLE | CMD_PRECHARGE | + SDRAM_INITPLR_IMWT_ENCODE(4)); + /* EMR2 - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR2, SDRAM_INITPLR_ENABLE | emr2 | + SDRAM_INITPLR_IMWT_ENCODE(2)); + /* EMR3 - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR3, SDRAM_INITPLR_ENABLE | emr3 | + SDRAM_INITPLR_IMWT_ENCODE(2)); + /* EMR DLL ENABLE - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR4, SDRAM_INITPLR_ENABLE | emr | + SDRAM_INITPLR_IMWT_ENCODE(2)); + /* MR w/ DLL reset - 200 cycle wait for DLL reset */ + mtsdram(SDRAM_INITPLR5, SDRAM_INITPLR_ENABLE | mr | DLL_RESET | + SDRAM_INITPLR_IMWT_ENCODE(200)); udelay(1000); - mtsdram(SDRAM_INITPLR6, 0x82000400 | CMD_PRECHARGE); /* precharge 8 DDR clock cycle */ - mtsdram(SDRAM_INITPLR7, 0x8a000000 | CMD_REFRESH); /* Refresh 50 DDR clock cycle */ - mtsdram(SDRAM_INITPLR8, 0x8a000000 | CMD_REFRESH); /* Refresh 50 DDR clock cycle */ - mtsdram(SDRAM_INITPLR9, 0x8a000000 | CMD_REFRESH); /* Refresh 50 DDR clock cycle */ - mtsdram(SDRAM_INITPLR10, 0x8a000000 | CMD_REFRESH); /* Refresh 50 DDR clock cycle */ - mtsdram(SDRAM_INITPLR11, 0x80000000 | mr); /* MR w/o DLL reset */ - mtsdram(SDRAM_INITPLR12, 0x80800380 | emr); /* EMR OCD Default */ - mtsdram(SDRAM_INITPLR13, 0x80800000 | emr); /* EMR OCD Exit */ + /* precharge 4 MemClk cycles */ + mtsdram(SDRAM_INITPLR6, SDRAM_INITPLR_ENABLE | CMD_PRECHARGE | + SDRAM_INITPLR_IMWT_ENCODE(4)); + /* Refresh 25 MemClk cycles */ + mtsdram(SDRAM_INITPLR7, SDRAM_INITPLR_ENABLE | CMD_REFRESH | + SDRAM_INITPLR_IMWT_ENCODE(25)); + /* Refresh 25 MemClk cycles */ + mtsdram(SDRAM_INITPLR8, SDRAM_INITPLR_ENABLE | CMD_REFRESH | + SDRAM_INITPLR_IMWT_ENCODE(25)); + /* Refresh 25 MemClk cycles */ + mtsdram(SDRAM_INITPLR9, SDRAM_INITPLR_ENABLE | CMD_REFRESH | + SDRAM_INITPLR_IMWT_ENCODE(25)); + /* Refresh 25 MemClk cycles */ + mtsdram(SDRAM_INITPLR10, SDRAM_INITPLR_ENABLE | CMD_REFRESH | + SDRAM_INITPLR_IMWT_ENCODE(25)); + /* MR w/o DLL reset - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR11, SDRAM_INITPLR_ENABLE | mr | + SDRAM_INITPLR_IMWT_ENCODE(2)); + /* EMR OCD Default - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR12, SDRAM_INITPLR_ENABLE | OCD_CALIB_DEF | + SDRAM_INITPLR_IMWT_ENCODE(2) | emr); + /* EMR OCD Exit */ + mtsdram(SDRAM_INITPLR13, SDRAM_INITPLR_ENABLE | emr | + SDRAM_INITPLR_IMWT_ENCODE(2)); } else { printf("ERROR: ucode error as unknown DDR type in program_initplr"); spd_ddr_init_hang (); @@ -2466,12 +2504,13 @@ static void program_DQS_calibration(unsigned long *dimm_populated, * Program RFDC register * Set Feedback Fractional Oversample * Auto-detect read sample cycle enable + * Set RFOS to 1/4 of memclk cycle (0x3f) *-----------------------------------------------------------------*/ mfsdram(SDRAM_RFDC, val); mtsdram(SDRAM_RFDC, (val & ~(SDRAM_RFDC_ARSE_MASK | SDRAM_RFDC_RFOS_MASK | SDRAM_RFDC_RFFD_MASK)) - | (SDRAM_RFDC_ARSE_ENABLE | SDRAM_RFDC_RFOS_ENCODE(0) | + | (SDRAM_RFDC_ARSE_ENABLE | SDRAM_RFDC_RFOS_ENCODE(0x3f) | SDRAM_RFDC_RFFD_ENCODE(0))); DQS_calibration_process(); -- cgit v1.1 From 5bc542a593abc9e974fbd34704af85c37c366c60 Mon Sep 17 00:00:00 2001 From: Victor Gallardo Date: Thu, 28 Aug 2008 16:03:28 -0700 Subject: ppc4xx: fix UIC external_interrupt hang on UIC0 This patch fixes a UIC external_interrupt hang if critical or non-critical interrupt is set at the same time as a normal interrupt is set on UIC0. Signed-off-by: Victor Gallardo Signed-off-by: Stefan Roese --- cpu/ppc4xx/uic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cpu') diff --git a/cpu/ppc4xx/uic.c b/cpu/ppc4xx/uic.c index 7944c6c..a95d1cb 100644 --- a/cpu/ppc4xx/uic.c +++ b/cpu/ppc4xx/uic.c @@ -129,11 +129,11 @@ void external_interrupt(struct pt_regs *regs) uic_interrupt(UIC3_DCR_BASE, 96); #endif + mtdcr(uic0sr, (uic_msr & UICB0_ALL)); + if (uic_msr & ~(UICB0_ALL)) uic_interrupt(UIC0_DCR_BASE, 0); - mtdcr(uic0sr, uic_msr); - return; } -- cgit v1.1 From 52aef8f9ba28b747973bf76741c23db658d5773c Mon Sep 17 00:00:00 2001 From: Wolfgang Ocker Date: Tue, 26 Aug 2008 19:55:23 +0200 Subject: ppc4xx: NAND configuration Made NAND bank configuration setting a config variable. Signed-off-by: Wolfgang Ocker Signed-off-by: Stefan Roese --- cpu/ppc4xx/ndfc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'cpu') diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c index 72acfd0..a8e8aba 100644 --- a/cpu/ppc4xx/ndfc.c +++ b/cpu/ppc4xx/ndfc.c @@ -149,6 +149,10 @@ static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len } #endif /* #ifndef CONFIG_NAND_SPL */ +#ifndef CFG_NAND_BCR +#define CFG_NAND_BCR 0x80002222 +#endif + void board_nand_select_device(struct nand_chip *nand, int chip) { /* @@ -161,7 +165,7 @@ void board_nand_select_device(struct nand_chip *nand, int chip) /* Set NandFlash Core Configuration Register */ /* 1 col x 2 rows */ out_be32((u32 *)(base + NDFC_CCR), 0x00000000 | (cs << 24)); - out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), 0x80002222); + out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), CFG_NAND_BCR); } int board_nand_init(struct nand_chip *nand) -- cgit v1.1 From c2b4b2e4814f4ace9015fdb64132894327400bf0 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 29 Aug 2008 11:56:49 +0200 Subject: ppc4xx/NAND: Add select_chip function to 4xx NDFC driver This function is needed for the new NAND infrastructure. We only need a dummy implementation though for the NDFC. Signed-off-by: Stefan Roese --- cpu/ppc4xx/ndfc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'cpu') diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c index a8e8aba..7d96e79 100644 --- a/cpu/ppc4xx/ndfc.c +++ b/cpu/ppc4xx/ndfc.c @@ -168,6 +168,13 @@ void board_nand_select_device(struct nand_chip *nand, int chip) out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), CFG_NAND_BCR); } +static void ndfc_select_chip(struct mtd_info *mtd, int chip) +{ + /* + * Nothing to do here! + */ +} + int board_nand_init(struct nand_chip *nand) { int cs = (ulong)nand->IO_ADDR_W & 0x00000003; @@ -196,6 +203,7 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.mode = NAND_ECC_HW; nand->ecc.size = 256; nand->ecc.bytes = 3; + nand->select_chip = ndfc_select_chip; #ifndef CONFIG_NAND_SPL nand->write_buf = ndfc_write_buf; -- cgit v1.1