[U-Boot] [PATCH 0/7][v2] powerpc/85xx: P1010RDB

Patch series adds support for P1010RDB, NAND support (for IFC on P1010) and various errata fixes for P1010.
V2 changes: * re-work based on CCSRBAR cleanup patches * white space fixes * checkpatch cleanup fixes * rework 'dummy' udelay in nand spl code
- k

From: Poonam Aggrwal poonam.aggrwal@freescale.com
Boot methods supported: NOR Flash, SPI Flash and SDCARD This patch adds the following basic interfaces: DDR3, eTSEC, DUART, I2C, SD/MMC, USB, SATA, PCIe, NOR Flash, SPI Flash.
P1010RDB Overview ----------------- 1Gbyte DDR3 (on board DDR) Local Bus (IFC): 32Mbyte 16bit NOR flash 32Mbyte SLC NAND Flash 64KB CPLD device(GPCM interface) SPI Flash: 128 Mbit SPI Flash memory SD/MMC: connector to interface with the SD memory card SATA: 1 internal SATA connect to 2.5. 160G SATA2 HDD 1 eSATA connector to rear panel USB 2.0: x1 USB 2.0 port: connected via a UTMI PHY to Mini-AB interface. x1 USB 2.0 port: directly connected to Mini-AB interface Ethernet eTSEC: eTSEC1: Connected to RGMII PHY VSC8641XKO eTSEC2: Connected to SGMII PHY VSC8221 eTSEC3: Connected to SGMII PHY VSC8221 eCAN: Two DB-9 female connectors for Field bus interface UART: supports two UARTs up to 115200 bps for console TDM: 2 FXS ports connected via an external SLIC to the TDM interface. SLIC: SPI SLIC I2C: Serial EEprom Real time clock 256 Kbit M24256 I2C EEPROM PCIe: PCIe and mPCIe connectors.
Signed-off-by: Poonam Aggrwal poonam.aggrwal@freescale.com Signed-off-by: Dipen Dudhat dipen.dudhat@freescale.com Signed-off-by: Prabhakar Kushwaha prabhakar@freescale.com Signed-off-by: Ramneek Mehresh ramneek.mehresh@freescale.com Signed-off-by: Bhaskar Upadhaya Bhaskar.Upadhaya@freescale.com Signed-off-by: York Sun yorksun@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org --- board/freescale/p1010rdb/Makefile | 52 +++ board/freescale/p1010rdb/ddr.c | 250 +++++++++++++ board/freescale/p1010rdb/law.c | 35 ++ board/freescale/p1010rdb/p1010rdb.c | 330 ++++++++++++++++ board/freescale/p1010rdb/tlb.c | 98 +++++ boards.cfg | 6 + include/configs/P1010RDB.h | 703 +++++++++++++++++++++++++++++++++++ 7 files changed, 1474 insertions(+), 0 deletions(-) create mode 100644 board/freescale/p1010rdb/Makefile create mode 100644 board/freescale/p1010rdb/ddr.c create mode 100644 board/freescale/p1010rdb/law.c create mode 100644 board/freescale/p1010rdb/p1010rdb.c create mode 100644 board/freescale/p1010rdb/tlb.c create mode 100644 include/configs/P1010RDB.h
diff --git a/board/freescale/p1010rdb/Makefile b/board/freescale/p1010rdb/Makefile new file mode 100644 index 0000000..1dcd490 --- /dev/null +++ b/board/freescale/p1010rdb/Makefile @@ -0,0 +1,52 @@ +# +# Copyright 2010-2011 Freescale Semiconductor, Inc. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +COBJS-y += $(BOARD).o +COBJS-y += ddr.o +COBJS-y += law.o +COBJS-y += tlb.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(call cmd_link_o_target, $(OBJS)) + +clean: + rm -f $(OBJS) $(SOBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/freescale/p1010rdb/ddr.c b/board/freescale/p1010rdb/ddr.c new file mode 100644 index 0000000..e5d8423 --- /dev/null +++ b/board/freescale/p1010rdb/ddr.c @@ -0,0 +1,250 @@ +/* + * Copyright 2010-2011 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/mmu.h> +#include <asm/immap_85xx.h> +#include <asm/processor.h> +#include <asm/fsl_ddr_sdram.h> +#include <asm/fsl_ddr_dimm_params.h> +#include <asm/io.h> +#include <asm/fsl_law.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_DDR_RAW_TIMING +#define CONFIG_SYS_DRAM_SIZE 1024 + +fsl_ddr_cfg_regs_t ddr_cfg_regs_800 = { + .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, + .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, + .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, + .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_800, + .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_800, + .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_800, + .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_800, + .ddr_sdram_cfg = CONFIG_SYS_DDR_CONTROL, + .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL_2, + .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_800, + .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_800, + .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, + .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_800, + .ddr_data_init = CONFIG_MEM_INIT_VALUE, + .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_800, + .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, + .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, + .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, + .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, + .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CONTROL, + .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CONTROL_800, + .ddr_sr_cntr = CONFIG_SYS_DDR_SR_CNTR, + .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, + .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 +}; + +fsl_ddr_cfg_regs_t ddr_cfg_regs_667 = { + .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, + .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, + .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, + .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_667, + .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_667, + .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_667, + .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_667, + .ddr_sdram_cfg = CONFIG_SYS_DDR_CONTROL, + .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL_2, + .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_667, + .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_667, + .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, + .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_667, + .ddr_data_init = CONFIG_MEM_INIT_VALUE, + .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_667, + .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, + .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, + .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, + .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, + .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CONTROL, + .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CONTROL_667, + .ddr_sr_cntr = CONFIG_SYS_DDR_SR_CNTR, + .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, + .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 +}; + +fixed_ddr_parm_t fixed_ddr_parm_0[] = { + {750, 850, &ddr_cfg_regs_800}, + {607, 749, &ddr_cfg_regs_667}, + {0, 0, NULL} +}; + +unsigned long get_sdram_size(void) +{ + struct cpu_type *cpu; + phys_size_t ddr_size; + + cpu = gd->cpu; + /* P1014 and it's derivatives support max 16it DDR width */ + if (cpu->soc_ver == SVR_P1014 || cpu->soc_ver == SVR_P1014_E) + ddr_size = (CONFIG_SYS_DRAM_SIZE / 2); + else + ddr_size = CONFIG_SYS_DRAM_SIZE; + + return ddr_size; +} + +/* + * Fixed sdram init -- doesn't use serial presence detect. + */ +phys_size_t fixed_sdram(void) +{ + int i; + char buf[32]; + fsl_ddr_cfg_regs_t ddr_cfg_regs; + phys_size_t ddr_size; + ulong ddr_freq, ddr_freq_mhz; + struct cpu_type *cpu; + +#if defined(CONFIG_SYS_RAMBOOT) + return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; +#endif + + ddr_freq = get_ddr_freq(0); + ddr_freq_mhz = ddr_freq / 1000000; + + printf("Configuring DDR for %s MT/s data rate\n", + strmhz(buf, ddr_freq)); + + for (i = 0; fixed_ddr_parm_0[i].max_freq > 0; i++) { + if ((ddr_freq_mhz > fixed_ddr_parm_0[i].min_freq) && + (ddr_freq_mhz <= fixed_ddr_parm_0[i].max_freq)) { + memcpy(&ddr_cfg_regs, fixed_ddr_parm_0[i].ddr_settings, + sizeof(ddr_cfg_regs)); + break; + } + } + + if (fixed_ddr_parm_0[i].max_freq == 0) + panic("Unsupported DDR data rate %s MT/s data rate\n", + strmhz(buf, ddr_freq)); + + cpu = gd->cpu; + /* P1014 and it's derivatives support max 16bit DDR width */ + if (cpu->soc_ver == SVR_P1014 || cpu->soc_ver == SVR_P1014_E) { + ddr_cfg_regs.ddr_sdram_cfg |= SDRAM_CFG_16_BE; + ddr_cfg_regs.cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS >> 1; + ddr_cfg_regs.ddr_sdram_cfg &= ~0x00180000; + ddr_cfg_regs.ddr_sdram_cfg |= 0x001080000; + } + + ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; + fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0); + + if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, ddr_size, + LAW_TRGT_IF_DDR_1) < 0) { + printf("ERROR setting Local Access Windows for DDR\n"); + return 0; + } + + return ddr_size; +} + +#else /* CONFIG_DDR_RAW_TIMING */ +/* + * Samsung K4B2G0846C-HCF8 + * The following timing are for "downshift" + * i.e. to use CL9 part as CL7 + * otherwise, tAA, tRCD, tRP will be 13500ps + * and tRC will be 49500ps + */ +dimm_params_t ddr_raw_timing = { + .n_ranks = 1, + .rank_density = 1073741824u, + .capacity = 1073741824u, + .primary_sdram_width = 32, + .ec_sdram_width = 0, + .registered_dimm = 0, + .mirrored_dimm = 0, + .n_row_addr = 15, + .n_col_addr = 10, + .n_banks_per_sdram_device = 8, + .edc_config = 0, + .burst_lengths_bitmask = 0x0c, + + .tCKmin_X_ps = 1875, + .caslat_X = 0x1e << 4, /* 5,6,7,8 */ + .tAA_ps = 13125, + .tWR_ps = 15000, + .tRCD_ps = 13125, + .tRRD_ps = 7500, + .tRP_ps = 13125, + .tRAS_ps = 37500, + .tRC_ps = 50625, + .tRFC_ps = 160000, + .tWTR_ps = 7500, + .tRTP_ps = 7500, + .refresh_rate_ps = 7800000, + .tFAW_ps = 37500, +}; + +int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, + unsigned int controller_number, + unsigned int dimm_number) +{ + const char dimm_model[] = "Fixed DDR on board"; + + if ((controller_number == 0) && (dimm_number == 0)) { + memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t)); + memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); + memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1); + } + + return 0; +} + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + struct cpu_type *cpu; + int i; + popts->clk_adjust = 6; + popts->cpo_override = 0x1f; + popts->write_data_delay = 2; + popts->half_strength_driver_enable = 1; + /* Write leveling override */ + popts->wrlvl_en = 1; + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0xf; + popts->wrlvl_start = 0x8; + popts->trwt_override = 1; + popts->trwt = 0; + + cpu = gd->cpu; + /* P1014 and it's derivatives support max 16it DDR width */ + if (cpu->soc_ver == SVR_P1014 || cpu->soc_ver == SVR_P1014_E) + popts->data_bus_width = DDR_DATA_BUS_WIDTH_16; + + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { + popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER; + popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS; + } +} + +#endif /* CONFIG_DDR_RAW_TIMING */ diff --git a/board/freescale/p1010rdb/law.c b/board/freescale/p1010rdb/law.c new file mode 100644 index 0000000..3ed77fc --- /dev/null +++ b/board/freescale/p1010rdb/law.c @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2011 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fsl_law.h> +#include <asm/mmu.h> + +struct law_entry law_table[] = { +#ifndef CONFIG_SDCARD + SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_IFC), + SET_LAW(CONFIG_SYS_CPLD_BASE_PHYS, LAW_SIZE_128K, LAW_TRGT_IF_IFC), + SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_IFC), +#endif +}; + +int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c new file mode 100644 index 0000000..03e9da1 --- /dev/null +++ b/board/freescale/p1010rdb/p1010rdb.c @@ -0,0 +1,330 @@ +/* + * Copyright 2010-2011 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> +#include <asm/mmu.h> +#include <asm/cache.h> +#include <asm/immap_85xx.h> +#include <asm/io.h> +#include <miiphy.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <fsl_mdio.h> +#include <tsec.h> +#include <mmc.h> +#include <netdev.h> +#include <pci.h> +#include <asm/fsl_serdes.h> +#include <asm/fsl_ifc.h> +#include <asm/fsl_pci.h> + +#ifndef CONFIG_SDCARD +#include <hwconfig.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#define GPIO4_PCIE_RESET_SET 0x08000000 +#define MUX_CPLD_CAN_UART 0x00 +#define MUX_CPLD_TDM 0x01 +#define MUX_CPLD_SPICS0_FLASH 0x00 +#define MUX_CPLD_SPICS0_SLIC 0x02 + +#ifndef CONFIG_SDCARD +struct cpld_data { + u8 cpld_ver; /* cpld revision */ + u8 pcba_ver; /* pcb revision number */ + u8 twindie_ddr3; + u8 res1[6]; + u8 bank_sel; /* NOR Flash bank */ + u8 res2[5]; + u8 usb2_sel; + u8 res3[1]; + u8 porsw_sel; + u8 tdm_can_sel; + u8 spi_cs0_sel; /* SPI CS0 SLIC/SPI Flash */ + u8 por0; /* POR Options */ + u8 por1; /* POR Options */ + u8 por2; /* POR Options */ + u8 por3; /* POR Options */ +}; + +void cpld_show(void) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + + printf("CPLD: V%x.%x PCBA: V%x.0\n", + in_8(&cpld_data->cpld_ver) & 0xF0, + in_8(&cpld_data->cpld_ver) & 0x0F, + in_8(&cpld_data->pcba_ver) & 0x0F); + +#ifdef CONFIG_DEBUG + printf("twindie_ddr =%x\n", + in_8(&cpld_data->twindie_ddr3)); + printf("bank_sel =%x\n", + in_8(&cpld_data->bank_sel)); + printf("usb2_sel =%x\n", + in_8(&cpld_data->usb2_sel)); + printf("porsw_sel =%x\n", + in_8(&cpld_data->porsw_sel)); + printf("tdm_can_sel =%x\n", + in_8(&cpld_data->tdm_can_sel)); + printf("tdm_can_sel =%x\n", + in_8(&cpld_data->tdm_can_sel)); + printf("spi_cs0_sel =%x\n", + in_8(&cpld_data->spi_cs0_sel)); + printf("bcsr0 =%x\n", + in_8(&cpld_data->bcsr0)); + printf("bcsr1 =%x\n", + in_8(&cpld_data->bcsr1)); + printf("bcsr2 =%x\n", + in_8(&cpld_data->bcsr2)); + printf("bcsr3 =%x\n", + in_8(&cpld_data->bcsr3)); +#endif +} +#endif + +int board_early_init_f(void) +{ + ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); +#ifndef CONFIG_SDCARD + struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR; + + /* Clock configuration to access CPLD using IFC(GPCM) */ + setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); +#endif + /* + * Reset PCIe slots via GPIO4 + */ + setbits_be32(&pgpio->gpdir, GPIO4_PCIE_RESET_SET); + setbits_be32(&pgpio->gpdat, GPIO4_PCIE_RESET_SET); + + return 0; +} + +int board_early_init_r(void) +{ +#ifndef CONFIG_SDCARD + const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; + const u8 flash_esel = find_tlb_idx((void *)flashbase, 1); + + /* + * Remap Boot flash region to caching-inhibited + * so that flash can be erased properly. + */ + + /* Flush d-cache and invalidate i-cache of any FLASH data */ + flush_dcache(); + invalidate_icache(); + + /* invalidate existing TLB entry for flash */ + disable_tlb(flash_esel); + + set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, flash_esel, BOOKE_PAGESZ_16M, 1); + + set_tlb(1, flashbase + 0x1000000, + CONFIG_SYS_FLASH_BASE_PHYS + 0x1000000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, flash_esel+1, BOOKE_PAGESZ_16M, 1); +#endif + return 0; +} + +#ifdef CONFIG_PCI +void pci_init_board(void) +{ + fsl_pcie_init_board(0); +} +#endif /* ifdef CONFIG_PCI */ + +int checkboard(void) +{ + struct cpu_type *cpu; + + cpu = gd->cpu; + printf("Board: %sRDB ", cpu->name); +#ifdef CONFIG_PHYS_64BIT + puts("(36-bit addrmap)"); +#endif + puts("\n"); + + return 0; +} + +#ifdef CONFIG_TSEC_ENET +int board_eth_init(bd_t *bis) +{ + struct fsl_pq_mdio_info mdio_info; + struct tsec_info_struct tsec_info[4]; + struct cpu_type *cpu; + int num = 0; + + cpu = gd->cpu; + +#ifdef CONFIG_TSEC1 + SET_STD_TSEC_INFO(tsec_info[num], 1); + num++; +#endif +#ifdef CONFIG_TSEC2 + SET_STD_TSEC_INFO(tsec_info[num], 2); + num++; +#endif +#ifdef CONFIG_TSEC3 + /* P1014 and it's derivatives do not support eTSEC3 */ + if (cpu->soc_ver != SVR_P1014 && cpu->soc_ver != SVR_P1014_E) { + SET_STD_TSEC_INFO(tsec_info[num], 3); + num++; + } +#endif + if (!num) { + printf("No TSECs initialized\n"); + return 0; + } + + mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; + mdio_info.name = DEFAULT_MII_NAME; + + fsl_pq_mdio_init(bis, &mdio_info); + + tsec_eth_init(bis, tsec_info, num); + + return pci_eth_init(bis); +} +#endif + +#if defined(CONFIG_OF_BOARD_SETUP) +void fdt_del_flexcan(void *blob) +{ + int nodeoff = 0; + + while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, + "fsl,flexcan-v1.0")) >= 0) { + fdt_del_node(blob, nodeoff); + } +} + +void fdt_del_spi_flash(void *blob) +{ + int nodeoff = 0; + + while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, + "spansion,s25sl12801")) >= 0) { + fdt_del_node(blob, nodeoff); + } +} + +void fdt_del_spi_slic(void *blob) +{ + int nodeoff = 0; + + while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, + "zarlink,le88266")) >= 0) { + fdt_del_node(blob, nodeoff); + } +} + +void fdt_del_tdm(void *blob) +{ + int nodeoff = 0; + + while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, + "fsl,starlite-tdm")) >= 0) { + fdt_del_node(blob, nodeoff); + } +} + +void ft_board_setup(void *blob, bd_t *bd) +{ + phys_addr_t base; + phys_size_t size; + struct cpu_type *cpu; + + cpu = gd->cpu; + + ft_cpu_setup(blob, bd); + + base = getenv_bootm_low(); + size = getenv_bootm_size(); + +#if defined(CONFIG_PCI) + FT_FSL_PCI_SETUP; +#endif + + fdt_fixup_memory(blob, (u64)base, (u64)size); + + fdt_fixup_dr_usb(blob, bd); + + /* P1014 and it's derivatives don't support CAN and eTSEC3 */ + if (cpu->soc_ver == SVR_P1014 || cpu->soc_ver == SVR_P1014_E) { + fdt_del_flexcan(blob); + fdt_del_node_and_alias(blob, "ethernet2"); + } +#ifndef CONFIG_SDCARD + if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "can")) { + printf("fdt CAN"); + fdt_del_tdm(blob); + fdt_del_spi_slic(blob); + } +#ifndef CONFIG_SPIFLASH + else if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "tdm")) { + printf("fdt TDM"); + fdt_del_flexcan(blob); + fdt_del_spi_flash(blob); + } +#endif +#endif +} +#endif + +#ifndef CONFIG_SDCARD +int misc_init_r(void) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + + if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "can")) { + clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN1_TDM | + MPC85xx_PMUXCR_CAN1_UART | + MPC85xx_PMUXCR_CAN2_TDM | + MPC85xx_PMUXCR_CAN2_UART); + out_8(&cpld_data->tdm_can_sel, MUX_CPLD_CAN_UART); + } +#ifndef CONFIG_SPIFLASH + if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "tdm")) { + printf("TDM"); + clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN2_UART | + MPC85xx_PMUXCR_CAN1_UART); + setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN2_TDM | + MPC85xx_PMUXCR_CAN1_TDM); + clrbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_GPIO); + setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_TDM); + out_8(&cpld_data->tdm_can_sel, MUX_CPLD_TDM); + out_8(&cpld_data->spi_cs0_sel, MUX_CPLD_SPICS0_SLIC); + } +#endif + return 0; +} +#endif diff --git a/board/freescale/p1010rdb/tlb.c b/board/freescale/p1010rdb/tlb.c new file mode 100644 index 0000000..4256bf4 --- /dev/null +++ b/board/freescale/p1010rdb/tlb.c @@ -0,0 +1,98 @@ +/* + * Copyright 2010-2011 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/mmu.h> + +struct fsl_e_tlb_entry tlb_table[] = { + /* TLB 0 - for temp stack in cache */ + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, CONFIG_SYS_INIT_RAM_ADDR, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024 , + CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024 , + CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024 , + CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + + /* TLB 1 */ + /* *I*** - Covers boot page */ + SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 0, BOOKE_PAGESZ_4K, 1), + + /* *I*G* - CCSRBAR */ + SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 1, BOOKE_PAGESZ_1M, 1), + +#ifndef CONFIG_NAND_SPL +#ifndef CONFIG_SDCARD + SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS, + MAS3_SX|MAS3_SR, MAS2_W|MAS2_G, + 0, 2, BOOKE_PAGESZ_16M, 1), + + SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE + 0x1000000, + CONFIG_SYS_FLASH_BASE_PHYS + 0x1000000, + MAS3_SX|MAS3_SR, MAS2_W|MAS2_G, + 0, 3, BOOKE_PAGESZ_16M, 1), +#endif + +#ifdef CONFIG_PCI + /* *I*G* - PCI */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 4, BOOKE_PAGESZ_1G, 1), + + /* *I*G* - PCI I/O */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_VIRT, CONFIG_SYS_PCIE1_IO_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 5, BOOKE_PAGESZ_256K, 1), +#endif +#endif + +#ifndef CONFIG_SDCARD + /* *I*G - Board CPLD */ + SET_TLB_ENTRY(1, CONFIG_SYS_CPLD_BASE, CONFIG_SYS_CPLD_BASE_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 6, BOOKE_PAGESZ_256K, 1), + + SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 7, BOOKE_PAGESZ_1M, 1), +#endif + +#if defined(CONFIG_SYS_RAMBOOT) + SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 8, BOOKE_PAGESZ_1G, 1) +#endif +}; + +int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/boards.cfg b/boards.cfg index 9a4dff7..1dead8e 100644 --- a/boards.cfg +++ b/boards.cfg @@ -579,6 +579,12 @@ MPC8569MDS_NAND powerpc mpc85xx mpc8569mds freesca MPC8572DS powerpc mpc85xx mpc8572ds freescale - MPC8572DS MPC8572DS_36BIT powerpc mpc85xx mpc8572ds freescale - MPC8572DS:36BIT MPC8572DS_NAND powerpc mpc85xx mpc8572ds freescale - MPC8572DS:NAND +P1010RDB_NOR powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB +P1010RDB_36BIT_NOR powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,36BIT +P1010RDB_SDCARD powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,SDCARD +P1010RDB_SPIFLASH powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,SPIFLASH +P1010RDB_36BIT_SDCARD powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,36BIT,SDCARD +P1010RDB_36BIT_SPIFLASH powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,36BIT,SPIFLASH P1011RDB powerpc mpc85xx p1_p2_rdb freescale - P1_P2_RDB:P1011RDB P1011RDB_36BIT powerpc mpc85xx p1_p2_rdb freescale - P1_P2_RDB:P1011RDB,36BIT P1011RDB_36BIT_SDCARD powerpc mpc85xx p1_p2_rdb freescale - P1_P2_RDB:P1011RDB,36BIT,SDCARD diff --git a/include/configs/P1010RDB.h b/include/configs/P1010RDB.h new file mode 100644 index 0000000..4171805 --- /dev/null +++ b/include/configs/P1010RDB.h @@ -0,0 +1,703 @@ +/* + * Copyright 2010-2011 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * P010 RDB board configuration file + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#ifdef CONFIG_36BIT +#define CONFIG_PHYS_64BIT +#endif + +#ifdef CONFIG_P1010RDB +#define CONFIG_P1010 +#endif + +#ifdef CONFIG_SDCARD +#define CONFIG_RAMBOOT_SDCARD +#define CONFIG_SYS_TEXT_BASE 0x11000000 +#define CONFIG_RESET_VECTOR_ADDRESS 0x1107fffc +#endif + +#ifdef CONFIG_SPIFLASH +#define CONFIG_RAMBOOT_SPIFLASH +#define CONFIG_SYS_TEXT_BASE 0x11000000 +#define CONFIG_RESET_VECTOR_ADDRESS 0x1107fffc +#endif + +#ifndef CONFIG_SYS_TEXT_BASE +#define CONFIG_SYS_TEXT_BASE 0xeff80000 +#endif + +#ifndef CONFIG_RESET_VECTOR_ADDRESS +#define CONFIG_RESET_VECTOR_ADDRESS 0xeffffffc +#endif + +#ifndef CONFIG_SYS_MONITOR_BASE +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* start of monitor */ +#endif + +/* High Level Configuration Options */ +#define CONFIG_BOOKE /* BOOKE */ +#define CONFIG_E500 /* BOOKE e500 family */ +#define CONFIG_MPC85xx +#define CONFIG_FSL_IFC /* Enable IFC Support */ +#define CONFIG_SYS_HAS_SERDES /* common SERDES init code */ + +#define CONFIG_PCI /* Enable PCI/PCIE */ +#if defined(CONFIG_PCI) +#define CONFIG_PCIE1 /* PCIE controler 1 (slot 1) */ +#define CONFIG_PCIE2 /* PCIE controler 2 (slot 2) */ +#define CONFIG_FSL_PCI_INIT /* Use common FSL init code */ +#define CONFIG_FSL_PCIE_RESET /* need PCIe reset errata */ +#define CONFIG_SYS_PCI_64BIT /* enable 64-bit PCI resources */ + +#define CONFIG_CMD_NET +#define CONFIG_CMD_PCI + +#define CONFIG_E1000 /* E1000 pci Ethernet card*/ + +/* + * PCI Windows + * Memory space is mapped 1-1, but I/O space must start from 0. + */ +/* controller 1, Slot 1, tgtid 1, Base address a000 */ +#define CONFIG_SYS_PCIE1_NAME "mini PCIe Slot" +#define CONFIG_SYS_PCIE1_MEM_VIRT 0x80000000 +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_PCIE1_MEM_BUS 0x80000000 +#define CONFIG_SYS_PCIE1_MEM_PHYS 0xc00000000ull +#else +#define CONFIG_SYS_PCIE1_MEM_BUS 0x80000000 +#define CONFIG_SYS_PCIE1_MEM_PHYS 0x80000000 +#endif +#define CONFIG_SYS_PCIE1_MEM_SIZE 0x20000000 /* 512M */ +#define CONFIG_SYS_PCIE1_IO_VIRT 0xffc00000 +#define CONFIG_SYS_PCIE1_IO_BUS 0x00000000 +#define CONFIG_SYS_PCIE1_IO_SIZE 0x00010000 /* 64k */ +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_PCIE1_IO_PHYS 0xfffc00000ull +#else +#define CONFIG_SYS_PCIE1_IO_PHYS 0xffc00000 +#endif + +/* controller 2, Slot 2, tgtid 2, Base address 9000 */ +#define CONFIG_SYS_PCIE2_NAME "PCIe Slot" +#define CONFIG_SYS_PCIE2_MEM_VIRT 0xa0000000 +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_PCIE2_MEM_BUS 0xc0000000 +#define CONFIG_SYS_PCIE2_MEM_PHYS 0xc20000000ull +#else +#define CONFIG_SYS_PCIE2_MEM_BUS 0xa0000000 +#define CONFIG_SYS_PCIE2_MEM_PHYS 0xa0000000 +#endif +#define CONFIG_SYS_PCIE2_MEM_SIZE 0x20000000 /* 512M */ +#define CONFIG_SYS_PCIE2_IO_VIRT 0xffc10000 +#define CONFIG_SYS_PCIE2_IO_BUS 0x00000000 +#define CONFIG_SYS_PCIE2_IO_SIZE 0x00010000 /* 64k */ +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_PCIE2_IO_PHYS 0xfffc10000ull +#else +#define CONFIG_SYS_PCIE2_IO_PHYS 0xffc10000 +#endif + +#define CONFIG_PCI_PNP /* do pci plug-and-play */ + +#define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ +#define CONFIG_DOS_PARTITION +#endif + +#define CONFIG_FSL_LAW /* Use common FSL init code */ +#define CONFIG_TSEC_ENET +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_DDR_CLK_FREQ 66666666 /* DDRCLK on P1010 RDB */ +#define CONFIG_SYS_CLK_FREQ 66666666 /* SYSCLK for P1010 RDB */ + +#ifndef CONFIG_SDCARD +#define CONFIG_MISC_INIT_R +#endif + +#define CONFIG_HWCONFIG +/* + * These can be toggled for performance analysis, otherwise use default. + */ +#define CONFIG_L2_CACHE /* toggle L2 cache */ +#define CONFIG_BTB /* toggle branch predition */ + +#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ + +#define CONFIG_ENABLE_36BIT_PHYS + +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_ADDR_MAP 1 +#define CONFIG_SYS_NUM_ADDR_MAP 16 /* number of TLB1 entries */ +#endif + +#define CONFIG_SYS_MEMTEST_START 0x00000000 /* memtest works on */ +#define CONFIG_SYS_MEMTEST_END 0x1fffffff +#define CONFIG_PANIC_HANG /* do not reset board on panic */ + +/* DDR Setup */ +#define CONFIG_FSL_DDR3 +#define CONFIG_DDR_RAW_TIMING +#define CONFIG_DDR_SPD +#define CONFIG_SYS_SPD_BUS_NUM 1 +#define SPD_EEPROM_ADDRESS 0x52 + +#define CONFIG_MEM_INIT_VALUE 0xDeadBeef + +#ifndef __ASSEMBLY__ +extern unsigned long get_sdram_size(void); +#endif +#define CONFIG_SYS_SDRAM_SIZE get_sdram_size() /* DDR size */ +#define CONFIG_SYS_DDR_SDRAM_BASE 0x00000000 +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE + +#define CONFIG_DIMM_SLOTS_PER_CTLR 1 +#define CONFIG_CHIP_SELECTS_PER_CTRL 1 + +/* DDR3 Controller Settings */ +#define CONFIG_SYS_DDR_CS0_BNDS 0x0000003f +#define CONFIG_SYS_DDR_CS0_CONFIG 0x80014302 +#define CONFIG_SYS_DDR_CS0_CONFIG_2 0x00000000 +#define CONFIG_SYS_DDR_DATA_INIT 0xdeadbeef +#define CONFIG_SYS_DDR_INIT_ADDR 0x00000000 +#define CONFIG_SYS_DDR_INIT_EXT_ADDR 0x00000000 +#define CONFIG_SYS_DDR_MODE_CONTROL 0x00000000 + +#define CONFIG_SYS_DDR_ZQ_CONTROL 0x89080600 +#define CONFIG_SYS_DDR_SR_CNTR 0x00000000 +#define CONFIG_SYS_DDR_RCW_1 0x00000000 +#define CONFIG_SYS_DDR_RCW_2 0x00000000 +#define CONFIG_SYS_DDR_CONTROL 0x470C0000 /* Type = DDR3 */ +#define CONFIG_SYS_DDR_CONTROL_2 0x04401010 +#define CONFIG_SYS_DDR_TIMING_4 0x00000001 +#define CONFIG_SYS_DDR_TIMING_5 0x03402400 + +#define CONFIG_SYS_DDR_TIMING_3_800 0x00020000 +#define CONFIG_SYS_DDR_TIMING_0_800 0x00330004 +#define CONFIG_SYS_DDR_TIMING_1_800 0x6f6B4644 +#define CONFIG_SYS_DDR_TIMING_2_800 0x0FA888CF +#define CONFIG_SYS_DDR_CLK_CTRL_800 0x03000000 +#define CONFIG_SYS_DDR_MODE_1_800 0x40461520 +#define CONFIG_SYS_DDR_MODE_2_800 0x8000c000 +#define CONFIG_SYS_DDR_INTERVAL_800 0x0C300100 +#define CONFIG_SYS_DDR_WRLVL_CONTROL_800 0x8655A608 + +/* settings for DDR3 at 667MT/s */ +#define CONFIG_SYS_DDR_TIMING_3_667 0x00010000 +#define CONFIG_SYS_DDR_TIMING_0_667 0x00110004 +#define CONFIG_SYS_DDR_TIMING_1_667 0x5d59e544 +#define CONFIG_SYS_DDR_TIMING_2_667 0x0FA890CD +#define CONFIG_SYS_DDR_CLK_CTRL_667 0x03000000 +#define CONFIG_SYS_DDR_MODE_1_667 0x00441210 +#define CONFIG_SYS_DDR_MODE_2_667 0x00000000 +#define CONFIG_SYS_DDR_INTERVAL_667 0x0a280000 +#define CONFIG_SYS_DDR_WRLVL_CONTROL_667 0x8675F608 + +#define CONFIG_SYS_CCSRBAR 0xffe00000 +#define CONFIG_SYS_CCSRBAR_PHYS_LOW CONFIG_SYS_CCSRBAR + +/* + * Memory map + * + * 0x0000_0000 0x3fff_ffff DDR 1G cacheable + * 0x8000_0000 0xbfff_ffff PCI Express Mem 1.5G non-cacheable + * 0xffc0_0000 0xffc3_ffff PCI IO range 256k non-cacheable + * + * Localbus non-cacheable + * 0xff80_0000 0xff8f_ffff NAND Flash 1M non-cacheable + * 0xffb0_0000 0xffbf_ffff Board CPLD 1M non-cacheable + * 0xffd0_0000 0xffd0_3fff L1 for stack 16K Cacheable TLB0 + * 0xffe0_0000 0xffef_ffff CCSR 1M non-cacheable + */ + +/* In case of SD card boot, IFC interface is not available because of muxing */ +#ifdef CONFIG_SDCARD +#define CONFIG_SYS_NO_FLASH +#else +/* + * IFC Definitions + */ +/* NOR Flash on IFC */ +#define CONFIG_SYS_FLASH_BASE 0xee000000 +#define CONFIG_SYS_MAX_FLASH_SECT 256 /* 32M */ + +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_FLASH_BASE_PHYS (0xf00000000ull | CONFIG_SYS_FLASH_BASE) +#else +#define CONFIG_SYS_FLASH_BASE_PHYS CONFIG_SYS_FLASH_BASE +#endif + +#define CONFIG_SYS_NOR_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR_AMASK IFC_AMASK(32*1024*1024) +#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(7) +/* NOR Flash Timing Params */ +#define CONFIG_SYS_NOR_FTIM0 FTIM0_NOR_TACSE(0x4) | \ + FTIM0_NOR_TEADC(0x5) | \ + FTIM0_NOR_TEAHC(0x5) +#define CONFIG_SYS_NOR_FTIM1 FTIM1_NOR_TACO(0x1e) | \ + FTIM1_NOR_TRAD_NOR(0x0f) +#define CONFIG_SYS_NOR_FTIM2 FTIM2_NOR_TCS(0x4) | \ + FTIM2_NOR_TCH(0x4) | \ + FTIM2_NOR_TWP(0x1c) +#define CONFIG_SYS_NOR_FTIM3 0x0 + +#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE_PHYS} +#define CONFIG_SYS_FLASH_QUIET_TEST +#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ +#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */ + +#undef CONFIG_SYS_FLASH_CHECKSUM +#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +/* CFI for NOR Flash */ +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_EMPTY_INFO +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE + +/* NAND Flash on IFC */ +#define CONFIG_SYS_NAND_BASE 0xff800000 +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_NAND_BASE_PHYS 0xfff800000ull +#else +#define CONFIG_SYS_NAND_BASE_PHYS CONFIG_SYS_NAND_BASE +#endif + +#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \ + | CSPR_PORT_SIZE_8 \ + | CSPR_MSEL_NAND \ + | CSPR_V) +#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64*1024) +#define CONFIG_SYS_NAND_CSOR (CSOR_NAND_ECC_ENC_EN /* ECC on encode */ \ + | CSOR_NAND_ECC_DEC_EN /* ECC on decode */ \ + | CSOR_NAND_ECC_MODE_4 /* 4-bit ECC */ \ + | CSOR_NAND_RAL_2 /* RAL = 2 Bytes */ \ + | CSOR_NAND_PGS_512 /* Page Size = 512b */ \ + | CSOR_NAND_SPRZ_16 /* Spare size = 16 */ \ + | CSOR_NAND_PB(32)) /* 32 Pages Per Block */ + +/* NAND Flash Timing Params */ +#define CONFIG_SYS_NAND_FTIM0 FTIM0_NAND_TCCST(0x01) | \ + FTIM0_NAND_TWP(0x0C) | \ + FTIM0_NAND_TWCHT(0x04) | \ + FTIM0_NAND_TWH(0x05) +#define CONFIG_SYS_NAND_FTIM1 FTIM1_NAND_TADLE(0x1d) | \ + FTIM1_NAND_TWBE(0x1d) | \ + FTIM1_NAND_TRR(0x07) | \ + FTIM1_NAND_TRP(0x0c) +#define CONFIG_SYS_NAND_FTIM2 FTIM2_NAND_TRAD(0x0c) | \ + FTIM2_NAND_TREH(0x05) | \ + FTIM2_NAND_TWHRE(0x0f) +#define CONFIG_SYS_NAND_FTIM3 FTIM3_NAND_TWW(0x04) + +#define CONFIG_SYS_NAND_DDR_LAW 11 + +/* Set up IFC registers for boot location NOR/NAND */ +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR1 CONFIG_SYS_NAND_CSPR +#define CONFIG_SYS_AMASK1 CONFIG_SYS_NAND_AMASK +#define CONFIG_SYS_CSOR1 CONFIG_SYS_NAND_CSOR +#define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_NAND_FTIM0 +#define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NAND_FTIM1 +#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NAND_FTIM2 +#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NAND_FTIM3 + +/* CPLD on IFC */ +#define CONFIG_SYS_CPLD_BASE 0xffb00000 + +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_CPLD_BASE_PHYS 0xfffb00000ull +#else +#define CONFIG_SYS_CPLD_BASE_PHYS CONFIG_SYS_CPLD_BASE +#endif + +#define CONFIG_SYS_CSPR3 (CSPR_PHYS_ADDR(CONFIG_SYS_CPLD_BASE_PHYS) \ + | CSPR_PORT_SIZE_8 \ + | CSPR_MSEL_GPCM \ + | CSPR_V) +#define CONFIG_SYS_AMASK3 IFC_AMASK(64*1024) +#define CONFIG_SYS_CSOR3 0x0 +/* CPLD Timing parameters for IFC CS3 */ +#define CONFIG_SYS_CS3_FTIM0 (FTIM0_GPCM_TACSE(0x0e) | \ + FTIM0_GPCM_TEADC(0x0e) | \ + FTIM0_GPCM_TEAHC(0x0e)) +#define CONFIG_SYS_CS3_FTIM1 (FTIM1_GPCM_TACO(0x0e) | \ + FTIM1_GPCM_TRAD(0x1f)) +#define CONFIG_SYS_CS3_FTIM2 (FTIM2_GPCM_TCS(0x0e) | \ + FTIM2_GPCM_TCH(0x0) | \ + FTIM2_GPCM_TWP(0x1f)) +#define CONFIG_SYS_CS3_FTIM3 0x0 +#endif /* CONFIG_SDCARD */ + +#if defined(CONFIG_RAMBOOT_SDCARD) || defined(CONFIG_RAMBOOT_SPIFLASH) || \ + defined(CONFIG_RAMBOOT_NAND) +#define CONFIG_SYS_RAMBOOT +#define CONFIG_SYS_EXTRA_ENV_RELOC +#else +#undef CONFIG_SYS_RAMBOOT +#endif + +#define CONFIG_BOARD_EARLY_INIT_F /* Call board_pre_init */ +#define CONFIG_BOARD_EARLY_INIT_R + +#define CONFIG_SYS_INIT_RAM_LOCK +#define CONFIG_SYS_INIT_RAM_ADDR 0xffd00000 /* stack in RAM */ +#define CONFIG_SYS_INIT_RAM_END 0x00004000 /* End of used area in RAM */ + +#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END \ + - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET + +#define CONFIG_SYS_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon*/ +#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) /* Reserved for malloc*/ + +/* Serial Port */ +#define CONFIG_CONS_INDEX 1 +#undef CONFIG_SERIAL_SOFTWARE_FIFO +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE 1 +#define CONFIG_SYS_NS16550_CLK get_bus_freq(0) + +#define CONFIG_SERIAL_MULTI /* Enable both serial ports */ +#define CONFIG_SYS_CONSOLE_IS_IN_ENV /* determine from environment */ + +#define CONFIG_SYS_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200} + +#define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_CCSRBAR+0x4500) +#define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_CCSRBAR+0x4600) + +/* Use the HUSH parser */ +#define CONFIG_SYS_HUSH_PARSER +#ifdef CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#endif + +/* + * Pass open firmware flat tree + */ +#define CONFIG_OF_LIBFDT +#define CONFIG_OF_BOARD_SETUP +#define CONFIG_OF_STDOUT_VIA_ALIAS + +/* new uImage format support */ +#define CONFIG_FIT +#define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */ + +#define CONFIG_FSL_I2C /* Use FSL common I2C driver */ +#define CONFIG_HARD_I2C /* I2C with hardware support */ +#undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CONFIG_I2C_MULTI_BUS +#define CONFIG_I2C_CMD_TREE +#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address*/ +#define CONFIG_SYS_I2C_SLAVE 0x7F +#define CONFIG_SYS_I2C_OFFSET 0x3000 +#define CONFIG_SYS_I2C2_OFFSET 0x3100 + +/* I2C EEPROM */ +#undef CONFIG_ID_EEPROM +/* enable read and write access to EEPROM */ +#define CONFIG_CMD_EEPROM +#define CONFIG_SYS_I2C_MULTI_EEPROMS +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5 + +/* RTC */ +#define CONFIG_RTC_PT7C4338 +#define CONFIG_SYS_I2C_RTC_ADDR 0x68 + +#define CONFIG_CMD_I2C + +/* + * SPI interface will not be available in case of NAND boot SPI CS0 will be + * used for SLIC + */ +/* eSPI - Enhanced SPI */ +#define CONFIG_FSL_ESPI +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_SPANSION +#define CONFIG_CMD_SF +#define CONFIG_SF_DEFAULT_SPEED 10000000 +#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 + +#if defined(CONFIG_TSEC_ENET) +#ifndef CONFIG_NET_MULTI +#define CONFIG_NET_MULTI +#endif + +#define CONFIG_MII /* MII PHY management */ +#define CONFIG_MII_DEFAULT_TSEC 1 /* Allow unregistered phys */ +#define CONFIG_TSEC1 1 +#define CONFIG_TSEC1_NAME "eTSEC1" +#define CONFIG_TSEC2 1 +#define CONFIG_TSEC2_NAME "eTSEC2" +#define CONFIG_TSEC3 1 +#define CONFIG_TSEC3_NAME "eTSEC3" + +#define TSEC1_PHY_ADDR 1 +#define TSEC2_PHY_ADDR 0 +#define TSEC3_PHY_ADDR 2 + +#define TSEC1_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC2_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC3_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) + +#define TSEC1_PHYIDX 0 +#define TSEC2_PHYIDX 0 +#define TSEC3_PHYIDX 0 + +#define CONFIG_ETHPRIME "eTSEC1" + +#define CONFIG_PHY_GIGE /* Include GbE speed/duplex detection */ + +/* TBI PHY configuration for SGMII mode */ +#define CONFIG_TSEC_TBICR_SETTINGS ( \ + TBICR_PHY_RESET \ + | TBICR_ANEG_ENABLE \ + | TBICR_FULL_DUPLEX \ + | TBICR_SPEED1_SET \ + ) + +#endif /* CONFIG_TSEC_ENET */ + + +/* SATA */ +#define CONFIG_FSL_SATA +#define CONFIG_LIBATA + +#ifdef CONFIG_FSL_SATA +#define CONFIG_SYS_SATA_MAX_DEVICE 2 +#define CONFIG_SATA1 +#define CONFIG_SYS_SATA1 CONFIG_SYS_MPC85xx_SATA1_ADDR +#define CONFIG_SYS_SATA1_FLAGS FLAGS_DMA +#define CONFIG_SATA2 +#define CONFIG_SYS_SATA2 CONFIG_SYS_MPC85xx_SATA2_ADDR +#define CONFIG_SYS_SATA2_FLAGS FLAGS_DMA + +#define CONFIG_CMD_SATA +#define CONFIG_LBA48 +#endif /* #ifdef CONFIG_FSL_SATA */ + +/* SD interface will only be available in case of SD boot */ +#ifdef CONFIG_SDCARD +#define CONFIG_MMC +#define CONFIG_DEF_HWCONFIG esdhc +#endif + +#ifdef CONFIG_MMC +#define CONFIG_CMD_MMC +#define CONFIG_DOS_PARTITION +#define CONFIG_FSL_ESDHC +#define CONFIG_GENERIC_MMC +#define CONFIG_SYS_FSL_ESDHC_ADDR CONFIG_SYS_MPC85xx_ESDHC_ADDR +#endif + +#define CONFIG_USB_EHCI + +#ifdef CONFIG_USB_EHCI +#define CONFIG_CMD_USB +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET +#define CONFIG_USB_EHCI_FSL +#define CONFIG_USB_STORAGE +#define CONFIG_HAS_FSL_DR_USB +#endif + +/* + * Environment + */ +#if defined(CONFIG_SYS_RAMBOOT) +#if defined(CONFIG_RAMBOOT_SDCARD) +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_ENV_SIZE 0x2000 +#elif defined(CONFIG_RAMBOOT_SPIFLASH) +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_SPI_BUS 0 +#define CONFIG_ENV_SPI_CS 0 +#define CONFIG_ENV_SPI_MAX_HZ 10000000 +#define CONFIG_ENV_SPI_MODE 0 +#define CONFIG_ENV_OFFSET 0x100000 /* 1MB */ +#define CONFIG_ENV_SECT_SIZE 0x10000 +#define CONFIG_ENV_SIZE 0x2000 +#else +#define CONFIG_ENV_IS_NOWHERE /* Store ENV in memory only */ +#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - 0x1000) +#define CONFIG_ENV_SIZE 0x2000 +#endif +#else +#define CONFIG_ENV_IS_IN_FLASH +#if CONFIG_SYS_MONITOR_BASE > 0xfff80000 +#define CONFIG_ENV_ADDR 0xfff80000 +#else +#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SECT_SIZE) +#endif +#define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K (one sector) */ +#endif + +#define CONFIG_LOADS_ECHO /* echo on for serial download */ +#define CONFIG_SYS_LOADS_BAUD_CHANGE /* allow baudrate change */ + +/* + * Command line configuration. + */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_DATE +#define CONFIG_CMD_ERRATA +#define CONFIG_CMD_ELF +#define CONFIG_CMD_IRQ +#define CONFIG_CMD_MII +#define CONFIG_CMD_PING +#define CONFIG_CMD_SETEXPR +#define CONFIG_CMD_REGINFO + +#undef CONFIG_WATCHDOG /* watchdog disabled */ + +#if defined(CONFIG_MMC) || defined(CONFIG_USB_EHCI) \ + || defined(CONFIG_FSL_SATA) +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_DOS_PARTITION +#endif + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_CMDLINE_EDITING /* Command-line editing */ +#define CONFIG_AUTO_COMPLETE /* add autocompletion support */ +#define CONFIG_SYS_LOAD_ADDR 0x2000000 /* default load address */ +#define CONFIG_SYS_PROMPT "=> " /* Monitor Command Prompt */ + +#if defined(CONFIG_CMD_KGDB) +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) + /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE/* Boot Argument Buffer Size */ +#define CONFIG_SYS_HZ 1000 /* dec freq: 1ms ticks */ + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 64 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CONFIG_SYS_BOOTMAPSZ (64 << 20) /* Initial Memory map for Linux */ +#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* Increase max gunzip size */ + +#if defined(CONFIG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/* + * Environment Configuration + */ + +#if defined(CONFIG_TSEC_ENET) +#define CONFIG_HAS_ETH0 +#define CONFIG_HAS_ETH1 +#define CONFIG_HAS_ETH2 +#endif + +#define CONFIG_HOSTNAME P1010RDB +#define CONFIG_ROOTPATH /opt/nfsroot +#define CONFIG_BOOTFILE uImage +#define CONFIG_UBOOTPATH u-boot.bin/* U-Boot image on TFTP server */ + +/* default location for tftp and bootm */ +#define CONFIG_LOADADDR 1000000 + +#define CONFIG_BOOTDELAY 10 /* -1 disables auto-boot */ +#undef CONFIG_BOOTARGS /* the boot command will set bootargs */ + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "hwconfig=" MK_STR(CONFIG_DEF_HWCONFIG) "\0" \ + "netdev=eth0\0" \ + "uboot=" MK_STR(CONFIG_UBOOTPATH) "\0" \ + "loadaddr=1000000\0" \ + "consoledev=ttyS0\0" \ + "ramdiskaddr=2000000\0" \ + "ramdiskfile=rootfs.ext2.gz.uboot\0" \ + "fdtaddr=c00000\0" \ + "fdtfile=p1010rdb.dtb\0" \ + "bdev=sda1\0" \ + "hwconfig=usb1:dr_mode=host,phy_type=utmi\0" \ + "othbootargs=ramdisk_size=600000\0" \ + "usbfatboot=setenv bootargs root=/dev/ram rw " \ + "console=$consoledev,$baudrate $othbootargs; " \ + "usb start;" \ + "fatload usb 0:2 $loadaddr $bootfile;" \ + "fatload usb 0:2 $fdtaddr $fdtfile;" \ + "fatload usb 0:2 $ramdiskaddr $ramdiskfile;" \ + "bootm $loadaddr $ramdiskaddr $fdtaddr\0" \ + "usbext2boot=setenv bootargs root=/dev/ram rw " \ + "console=$consoledev,$baudrate $othbootargs; " \ + "usb start;" \ + "ext2load usb 0:4 $loadaddr $bootfile;" \ + "ext2load usb 0:4 $fdtaddr $fdtfile;" \ + "ext2load usb 0:4 $ramdiskaddr $ramdiskfile;" \ + "bootm $loadaddr $ramdiskaddr $fdtaddr\0" \ + +#define CONFIG_RAMBOOTCOMMAND \ + "setenv bootargs root=/dev/ram rw " \ + "console=$consoledev,$baudrate $othbootargs; " \ + "tftp $ramdiskaddr $ramdiskfile;" \ + "tftp $loadaddr $bootfile;" \ + "tftp $fdtaddr $fdtfile;" \ + "bootm $loadaddr $ramdiskaddr $fdtaddr" + +#define CONFIG_BOOTCOMMAND CONFIG_RAMBOOTCOMMAND + +#endif /* __CONFIG_H */

From: Dipen Dudhat Dipen.Dudhat@freescale.com
Add NAND support (including spl) on IFC, such as is found on the p1010.
Note that using hardware ECC on IFC with small-page NAND (which is what comes on the p1010rdb reference board) means there will be insufficient OOB space for JFFS2, since IFC does not support 1-bit ECC. UBI should work, as it does not use OOB for anything but ECC.
When hardware ECC is not enabled in CSOR, software ECC is now used.
Signed-off-by: Dipen Dudhat Dipen.Dudhat@freescale.com [scottwood@freescale.com: ECC rework and misc fixes] Signed-off-by: Scott Wood scottwood@freescale.com --- arch/powerpc/cpu/mpc85xx/cpu_init_nand.c | 10 + arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds | 18 +- arch/powerpc/include/asm/fsl_ifc.h | 6 +- drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/fsl_ifc_nand.c | 850 ++++++++++++++++++++++++++ nand_spl/nand_boot_fsl_ifc.c | 271 ++++++++ 6 files changed, 1149 insertions(+), 7 deletions(-) create mode 100644 drivers/mtd/nand/fsl_ifc_nand.c create mode 100644 nand_spl/nand_boot_fsl_ifc.c
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c index 796d398..6d01479 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c @@ -21,10 +21,12 @@ */
#include <common.h> +#include <asm/fsl_ifc.h> #include <asm/io.h>
void cpu_init_f(void) { +#ifdef CONFIG_FSL_LBC fsl_lbc_t *lbc = LBC_BASE_ADDR;
/* @@ -39,6 +41,14 @@ void cpu_init_f(void) #else #error CONFIG_SYS_NAND_BR_PRELIM, CONFIG_SYS_NAND_OR_PRELIM must be defined #endif +#endif +#ifdef CONFIG_FSL_IFC +#if defined(CONFIG_SYS_CSPR0) && defined(CONFIG_SYS_CSOR0) + set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0); + set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); + set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); +#endif +#endif
#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L2_ADDR) ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR; diff --git a/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds b/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds index 8410bd7..852f9aa 100644 --- a/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds +++ b/arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds @@ -23,6 +23,8 @@ * MA 02111-1307 USA */
+#include "config.h" /* CONFIG_BOARDDIR */ + OUTPUT_ARCH(powerpc) SECTIONS { @@ -52,8 +54,18 @@ SECTIONS . = ALIGN(8); __init_begin = .; __init_end = .; - - .resetvec ADDR(.text) + 0xffc : { +#if defined(CONFIG_FSL_IFC) /* Restrict bootpg at 4K boundry for IFC */ + .bootpg ADDR(.text) + 0x1000 : + { + start.o (.bootpg) + } +#define RESET_VECTOR_OFFSET 0x1ffc /* IFC has 8K sram */ +#elif defined(CONFIG_FSL_ELBC) +#define RESET_VECTOR_OFFSET 0xffc /* LBC has 4k sram */ +#else +#error unknown NAND controller +#endif + .resetvec ADDR(.text) + RESET_VECTOR_OFFSET : { KEEP(*(.resetvec)) } = 0xffff
@@ -64,4 +76,4 @@ SECTIONS } __bss_end__ = .; } -ASSERT(__init_end <= 0xfff00ffc, "NAND bootstrap too big"); +ASSERT(__init_end <= (0xfff00000 + RESET_VECTOR_OFFSET), "NAND bootstrap too big"); diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h index d4d9809..fb12363 100644 --- a/arch/powerpc/include/asm/fsl_ifc.h +++ b/arch/powerpc/include/asm/fsl_ifc.h @@ -69,6 +69,7 @@ */ /* Enable ECC Encoder */ #define CSOR_NAND_ECC_ENC_EN 0x80000000 +#define CSOR_NAND_ECC_MODE_MASK 0x30000000 /* 4 bit correction per 520 Byte sector */ #define CSOR_NAND_ECC_MODE_4 0x00000000 /* 8 bit correction per 528 Byte sector */ @@ -857,10 +858,7 @@ struct fsl_ifc_nand { u32 res19[0x10]; u32 nand_fsr; u32 res20; - u32 nand_eccstat0; - u32 nand_eccstat1; - u32 nand_eccstat2; - u32 nand_eccstat3; + u32 nand_eccstat[4]; u32 res21[0x20]; u32 nanndcr; u32 res22[0x2]; diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 8b598f6..3353dcd 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -37,6 +37,7 @@ COBJS-$(CONFIG_NAND_ATMEL) += atmel_nand.o COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o COBJS-$(CONFIG_NAND_DAVINCI) += davinci_nand.o COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o +COBJS-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c new file mode 100644 index 0000000..b3f3c3c --- /dev/null +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -0,0 +1,850 @@ +/* Integrated Flash Controller NAND Machine Driver + * + * Copyright (c) 2011 Freescale Semiconductor, Inc + * + * Authors: Dipen Dudhat Dipen.Dudhat@freescale.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <common.h> +#include <malloc.h> + +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/nand_ecc.h> + +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/fsl_ifc.h> + +#define MAX_BANKS 4 +#define ERR_BYTE 0xFF /* Value returned for read bytes + when read failed */ +#define IFC_TIMEOUT_MSECS 10 /* Maximum number of mSecs to wait for IFC + NAND Machine */ + +struct fsl_ifc_ctrl; + +/* mtd information per set */ +struct fsl_ifc_mtd { + struct mtd_info mtd; + struct nand_chip chip; + struct fsl_ifc_ctrl *ctrl; + + struct device *dev; + int bank; /* Chip select bank number */ + unsigned int bufnum_mask; /* bufnum = page & bufnum_mask */ + u8 __iomem *vbase; /* Chip select base virtual address */ +}; + +/* overview of the fsl ifc controller */ +struct fsl_ifc_ctrl { + struct nand_hw_control controller; + struct fsl_ifc_mtd *chips[MAX_BANKS]; + + /* device info */ + struct fsl_ifc *regs; + uint8_t __iomem *addr; /* Address of assigned IFC buffer */ + unsigned int cs_nand; /* On which chipsel NAND is connected */ + unsigned int page; /* Last page written to / read from */ + unsigned int read_bytes; /* Number of bytes read during command */ + unsigned int column; /* Saved column from SEQIN */ + unsigned int index; /* Pointer to next byte to 'read' */ + unsigned int status; /* status read from NEESR after last op */ + unsigned int oob; /* Non zero if operating on OOB data */ + unsigned int eccread; /* Non zero for a full-page ECC read */ +}; + +static struct fsl_ifc_ctrl *ifc_ctrl; + +/* 512-byte page with 4-bit ECC, 8-bit */ +static struct nand_ecclayout oob_512_8bit_ecc4 = { + .eccbytes = 8, + .eccpos = {8, 9, 10, 11, 12, 13, 14, 15}, + .oobfree = { {0, 5}, {6, 2} }, +}; + +/* 512-byte page with 4-bit ECC, 16-bit */ +static struct nand_ecclayout oob_512_16bit_ecc4 = { + .eccbytes = 8, + .eccpos = {8, 9, 10, 11, 12, 13, 14, 15}, + .oobfree = { {2, 6}, }, +}; + +/* 2048-byte page size with 4-bit ECC */ +static struct nand_ecclayout oob_2048_ecc4 = { + .eccbytes = 32, + .eccpos = { + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + }, + .oobfree = { {2, 6}, {40, 24} }, +}; + +/* 4096-byte page size with 4-bit ECC */ +static struct nand_ecclayout oob_4096_ecc4 = { + .eccbytes = 64, + .eccpos = { + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + }, + .oobfree = { {2, 6}, {72, 56} }, +}; + +/* 4096-byte page size with 8-bit ECC -- requires 218-byte OOB */ +static struct nand_ecclayout oob_4096_ecc8 = { + .eccbytes = 128, + .eccpos = { + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + }, + .oobfree = { {2, 6}, {136, 82} }, +}; + + +/* + * Generic flash bbt descriptors + */ +static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; +static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; + +static struct nand_bbt_descr bbt_main_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION, + .offs = 2, /* 0 on 8-bit small page */ + .len = 4, + .veroffs = 6, + .maxblocks = 4, + .pattern = bbt_pattern, +}; + +static struct nand_bbt_descr bbt_mirror_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION, + .offs = 2, /* 0 on 8-bit small page */ + .len = 4, + .veroffs = 6, + .maxblocks = 4, + .pattern = mirror_pattern, +}; + +/* + * Set up the IFC hardware block and page address fields, and the ifc nand + * structure addr field to point to the correct IFC buffer in memory + */ +static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + struct fsl_ifc *ifc = ctrl->regs; + int buf_num; + + ctrl->page = page_addr; + + /* Program ROW0/COL0 */ + out_be32(&ifc->ifc_nand.row0, page_addr); + out_be32(&ifc->ifc_nand.col0, (oob ? IFC_NAND_COL_MS : 0) | column); + + buf_num = page_addr & priv->bufnum_mask; + + ctrl->addr = priv->vbase + buf_num * (mtd->writesize * 2); + ctrl->index = column; + + /* for OOB data point to the second half of the buffer */ + if (oob) + ctrl->index += mtd->writesize; +} + +static int is_blank(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, + unsigned int bufnum) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_ifc_mtd *priv = chip->priv; + u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2); + u32 __iomem *main = (u32 *)addr; + u8 __iomem *oob = addr + mtd->writesize; + int i; + + for (i = 0; i < mtd->writesize / 4; i++) { + if (__raw_readl(&main[i]) != 0xffffffff) + return 0; + } + + for (i = 0; i < chip->ecc.layout->eccbytes; i++) { + int pos = chip->ecc.layout->eccpos[i]; + + if (__raw_readb(&oob[pos]) != 0xff) + return 0; + } + + return 1; +} + +/* returns nonzero if entire page is blank */ +static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, + u32 *eccstat, unsigned int bufnum) +{ + u32 reg = eccstat[bufnum / 4]; + int errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; + + if (errors == 15) { /* uncorrectable */ + /* Blank pages fail hw ECC checks */ + if (is_blank(mtd, ctrl, bufnum)) + return 1; + + /* + * We disable ECCER reporting in hardware due to + * erratum IFC-A002770 -- so report it now if we + * see an uncorrectable error in ECCSTAT. + */ + ctrl->status |= IFC_NAND_EVTER_STAT_ECCER; + } else if (errors > 0) { + mtd->ecc_stats.corrected += errors; + } + + return 0; +} + +/* + * execute IFC NAND command and wait for it to complete + */ +static int fsl_ifc_run_command(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + struct fsl_ifc *ifc = ctrl->regs; + long long end_tick; + u32 eccstat[4]; + int i; + + /* set the chip select for NAND Transaction */ + out_be32(&ifc->ifc_nand.nand_csel, ifc_ctrl->cs_nand); + + /* start read/write seq */ + out_be32(&ifc->ifc_nand.nandseq_strt, + IFC_NAND_SEQ_STRT_FIR_STRT); + + /* wait for NAND Machine complete flag or timeout */ + end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks(); + + while (end_tick > get_ticks()) { + ctrl->status = in_be32(&ifc->ifc_nand.nand_evter_stat); + + if (ctrl->status & IFC_NAND_EVTER_STAT_OPC) + break; + } + + out_be32(&ifc->ifc_nand.nand_evter_stat, ctrl->status); + + if (ctrl->status & IFC_NAND_EVTER_STAT_FTOER) + printf("%s: Flash Time Out Error\n", __func__); + if (ctrl->status & IFC_NAND_EVTER_STAT_WPER) + printf("%s: Write Protect Error\n", __func__); + + if (ctrl->eccread) { + int bufperpage = mtd->writesize / 512; + int bufnum = (ctrl->page & priv->bufnum_mask) * bufperpage; + int bufnum_end = bufnum + bufperpage - 1; + + for (i = bufnum / 4; i <= bufnum_end / 4; i++) + eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]); + + for (i = bufnum; i <= bufnum_end; i++) { + if (check_read_ecc(mtd, ctrl, eccstat, i)) + break; + } + + ctrl->eccread = 0; + } + + /* returns 0 on success otherwise non-zero) */ + return ctrl->status == IFC_NAND_EVTER_STAT_OPC ? 0 : -EIO; +} + +static void fsl_ifc_do_read(struct nand_chip *chip, + int oob, + struct mtd_info *mtd) +{ + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + struct fsl_ifc *ifc = ctrl->regs; + + /* Program FIR/IFC_NAND_FCR0 for Small/Large page */ + if (mtd->writesize > 512) { + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | + (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | + (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP3_SHIFT) | + (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP4_SHIFT)); + out_be32(&ifc->ifc_nand.nand_fir1, 0x0); + + out_be32(&ifc->ifc_nand.nand_fcr0, + (NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) | + (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT)); + } else { + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | + (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | + (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP3_SHIFT)); + + if (oob) + out_be32(&ifc->ifc_nand.nand_fcr0, + NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT); + else + out_be32(&ifc->ifc_nand.nand_fcr0, + NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT); + } +} + +/* cmdfunc send commands to the IFC NAND Machine */ +static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, + int column, int page_addr) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + struct fsl_ifc *ifc = ctrl->regs; + + /* clear the read buffer */ + ctrl->read_bytes = 0; + if (command != NAND_CMD_PAGEPROG) + ctrl->index = 0; + + switch (command) { + /* READ0 read the entire buffer to use hardware ECC. */ + case NAND_CMD_READ0: { + out_be32(&ifc->ifc_nand.nand_fbcr, 0); + set_addr(mtd, 0, page_addr, 0); + + ctrl->read_bytes = mtd->writesize + mtd->oobsize; + ctrl->index += column; + + if (chip->ecc.mode == NAND_ECC_HW) + ctrl->eccread = 1; + + fsl_ifc_do_read(chip, 0, mtd); + fsl_ifc_run_command(mtd); + return; + } + + /* READOOB reads only the OOB because no ECC is performed. */ + case NAND_CMD_READOOB: + out_be32(&ifc->ifc_nand.nand_fbcr, mtd->oobsize - column); + set_addr(mtd, column, page_addr, 1); + + ctrl->read_bytes = mtd->writesize + mtd->oobsize; + + fsl_ifc_do_read(chip, 1, mtd); + fsl_ifc_run_command(mtd); + + return; + + /* READID must read all possible bytes while CEB is active */ + case NAND_CMD_READID: + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | + (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT)); + out_be32(&ifc->ifc_nand.nand_fcr0, + NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT); + /* 4 bytes for manuf, device and exts */ + out_be32(&ifc->ifc_nand.nand_fbcr, 4); + ctrl->read_bytes = 4; + + set_addr(mtd, 0, 0, 0); + fsl_ifc_run_command(mtd); + return; + + /* ERASE1 stores the block and page address */ + case NAND_CMD_ERASE1: + set_addr(mtd, 0, page_addr, 0); + return; + + /* ERASE2 uses the block and page address from ERASE1 */ + case NAND_CMD_ERASE2: + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP1_SHIFT) | + (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP2_SHIFT)); + + out_be32(&ifc->ifc_nand.nand_fcr0, + (NAND_CMD_ERASE1 << IFC_NAND_FCR0_CMD0_SHIFT) | + (NAND_CMD_ERASE2 << IFC_NAND_FCR0_CMD1_SHIFT)); + + out_be32(&ifc->ifc_nand.nand_fbcr, 0); + ctrl->read_bytes = 0; + fsl_ifc_run_command(mtd); + return; + + /* SEQIN sets up the addr buffer and all registers except the length */ + case NAND_CMD_SEQIN: { + u32 nand_fcr0; + ctrl->column = column; + ctrl->oob = 0; + + if (mtd->writesize > 512) { + nand_fcr0 = + (NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) | + (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD1_SHIFT); + + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | + (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | + (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP3_SHIFT) | + (IFC_FIR_OP_CW1 << IFC_NAND_FIR0_OP4_SHIFT)); + out_be32(&ifc->ifc_nand.nand_fir1, 0); + } else { + nand_fcr0 = ((NAND_CMD_PAGEPROG << + IFC_NAND_FCR0_CMD1_SHIFT) | + (NAND_CMD_SEQIN << + IFC_NAND_FCR0_CMD2_SHIFT)); + + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP1_SHIFT) | + (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP2_SHIFT) | + (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) | + (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT)); + out_be32(&ifc->ifc_nand.nand_fir1, + (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT)); + + if (column >= mtd->writesize) { + /* OOB area --> READOOB */ + column -= mtd->writesize; + nand_fcr0 |= NAND_CMD_READOOB << + IFC_NAND_FCR0_CMD0_SHIFT; + ctrl->oob = 1; + } else if (column < 256) { + /* First 256 bytes --> READ0 */ + nand_fcr0 |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; + } else { + /* Second 256 bytes --> READ1 */ + nand_fcr0 |= NAND_CMD_READ1 << FCR_CMD0_SHIFT; + } + } + + out_be32(&ifc->ifc_nand.nand_fcr0, nand_fcr0); + set_addr(mtd, column, page_addr, ctrl->oob); + return; + } + + /* PAGEPROG reuses all of the setup from SEQIN and adds the length */ + case NAND_CMD_PAGEPROG: + if (ctrl->oob) + out_be32(&ifc->ifc_nand.nand_fbcr, ctrl->index); + else + out_be32(&ifc->ifc_nand.nand_fbcr, 0); + + fsl_ifc_run_command(mtd); + return; + + case NAND_CMD_STATUS: + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP1_SHIFT)); + out_be32(&ifc->ifc_nand.nand_fcr0, + NAND_CMD_STATUS << IFC_NAND_FCR0_CMD0_SHIFT); + out_be32(&ifc->ifc_nand.nand_fbcr, 1); + set_addr(mtd, 0, 0, 0); + ctrl->read_bytes = 1; + + fsl_ifc_run_command(mtd); + + /* Chip sometimes reporting write protect even when it's not */ + out_8(ctrl->addr, in_8(ctrl->addr) | NAND_STATUS_WP); + return; + + case NAND_CMD_RESET: + out_be32(&ifc->ifc_nand.nand_fir0, + IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT); + out_be32(&ifc->ifc_nand.nand_fcr0, + NAND_CMD_RESET << IFC_NAND_FCR0_CMD0_SHIFT); + fsl_ifc_run_command(mtd); + return; + + default: + printf("%s: error, unsupported command 0x%x.\n", + __func__, command); + } +} + +/* + * Write buf to the IFC NAND Controller Data Buffer + */ +static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + unsigned int bufsize = mtd->writesize + mtd->oobsize; + + if (len <= 0) { + printf("%s of %d bytes", __func__, len); + ctrl->status = 0; + return; + } + + if ((unsigned int)len > bufsize - ctrl->index) { + printf("%s beyond end of buffer " + "(%d requested, %u available)\n", + __func__, len, bufsize - ctrl->index); + len = bufsize - ctrl->index; + } + + memcpy_toio(&ctrl->addr[ctrl->index], buf, len); + ctrl->index += len; +} + +/* + * read a byte from either the IFC hardware buffer if it has any data left + * otherwise issue a command to read a single byte. + */ +static u8 fsl_ifc_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + + /* If there are still bytes in the IFC buffer, then use the + * next byte. */ + if (ctrl->index < ctrl->read_bytes) + return in_8(&ctrl->addr[ctrl->index++]); + + printf("%s beyond end of buffer\n", __func__); + return ERR_BYTE; +} + +/* + * Read two bytes from the IFC hardware buffer + * read function for 16-bit buswith + */ +static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + uint16_t data; + + /* + * If there are still bytes in the IFC buffer, then use the + * next byte. + */ + if (ctrl->index < ctrl->read_bytes) { + data = in_be16((uint16_t *)&ctrl-> + addr[ctrl->index]); + ctrl->index += 2; + return (uint8_t)data; + } + + printf("%s beyond end of buffer\n", __func__); + return ERR_BYTE; +} + +/* + * Read from the IFC Controller Data Buffer + */ +static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + int avail; + + if (len < 0) + return; + + avail = min((unsigned int)len, ctrl->read_bytes - ctrl->index); + memcpy_fromio(buf, &ctrl->addr[ctrl->index], avail); + ctrl->index += avail; + + if (len > avail) + printf("%s beyond end of buffer " + "(%d requested, %d available)\n", + __func__, len, avail); +} + +/* + * Verify buffer against the IFC Controller Data Buffer + */ +static int fsl_ifc_verify_buf(struct mtd_info *mtd, + const u_char *buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + int i; + + if (len < 0) { + printf("%s of %d bytes", __func__, len); + return -EINVAL; + } + + if ((unsigned int)len > ctrl->read_bytes - ctrl->index) { + printf("%s beyond end of buffer " + "(%d requested, %u available)\n", + __func__, len, ctrl->read_bytes - ctrl->index); + + ctrl->index = ctrl->read_bytes; + return -EINVAL; + } + + for (i = 0; i < len; i++) + if (in_8(&ctrl->addr[ctrl->index + i]) != buf[i]) + break; + + ctrl->index += len; + return i == len && ctrl->status == IFC_NAND_EVTER_STAT_OPC ? 0 : -EIO; +} + +/* This function is called after Program and Erase Operations to + * check for success or failure. + */ +static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) +{ + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + struct fsl_ifc *ifc = ctrl->regs; + u32 nand_fsr; + + if (ctrl->status != IFC_NAND_EVTER_STAT_OPC) + return NAND_STATUS_FAIL; + + /* Use READ_STATUS command, but wait for the device to be ready */ + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_RDSTAT << IFC_NAND_FIR0_OP1_SHIFT)); + out_be32(&ifc->ifc_nand.nand_fcr0, NAND_CMD_STATUS << + IFC_NAND_FCR0_CMD0_SHIFT); + out_be32(&ifc->ifc_nand.nand_fbcr, 1); + set_addr(mtd, 0, 0, 0); + ctrl->read_bytes = 1; + + fsl_ifc_run_command(mtd); + + if (ctrl->status != IFC_NAND_EVTER_STAT_OPC) + return NAND_STATUS_FAIL; + + nand_fsr = in_be32(&ifc->ifc_nand.nand_fsr); + + /* Chip sometimes reporting write protect even when it's not */ + nand_fsr = nand_fsr | NAND_STATUS_WP; + return nand_fsr; +} + +static int fsl_ifc_read_page(struct mtd_info *mtd, + struct nand_chip *chip, + uint8_t *buf, int page) +{ + struct fsl_ifc_mtd *priv = chip->priv; + struct fsl_ifc_ctrl *ctrl = priv->ctrl; + + fsl_ifc_read_buf(mtd, buf, mtd->writesize); + fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize); + + if (ctrl->status != IFC_NAND_EVTER_STAT_OPC) + mtd->ecc_stats.failed++; + + return 0; +} + +/* ECC will be calculated automatically, and errors will be detected in + * waitfunc. + */ +static void fsl_ifc_write_page(struct mtd_info *mtd, + struct nand_chip *chip, + const uint8_t *buf) +{ + fsl_ifc_write_buf(mtd, buf, mtd->writesize); + fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize); +} + +static void fsl_ifc_ctrl_init(void) +{ + ifc_ctrl = kzalloc(sizeof(*ifc_ctrl), GFP_KERNEL); + if (!ifc_ctrl) + return; + + ifc_ctrl->regs = IFC_BASE_ADDR; + + /* clear event registers */ + out_be32(&ifc_ctrl->regs->ifc_nand.nand_evter_stat, ~0U); + out_be32(&ifc_ctrl->regs->ifc_nand.pgrdcmpl_evt_stat, ~0U); + + /* Enable error and event for any detected errors */ + out_be32(&ifc_ctrl->regs->ifc_nand.nand_evter_en, + IFC_NAND_EVTER_EN_OPC_EN | + IFC_NAND_EVTER_EN_PGRDCMPL_EN | + IFC_NAND_EVTER_EN_FTOER_EN | + IFC_NAND_EVTER_EN_WPER_EN); + + out_be32(&ifc_ctrl->regs->ifc_nand.ncfgr, 0x0); +} + +static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip) +{ +} + +int board_nand_init(struct nand_chip *nand) +{ + struct fsl_ifc_mtd *priv; + struct nand_ecclayout *layout; + uint32_t cspr = 0, csor = 0; + + if (!ifc_ctrl) { + fsl_ifc_ctrl_init(); + if (!ifc_ctrl) + return -1; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->ctrl = ifc_ctrl; + priv->vbase = nand->IO_ADDR_R; + + /* Find which chip select it is connected to. + */ + for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) { + phys_addr_t base_addr = virt_to_phys(nand->IO_ADDR_R); + + cspr = in_be32(&ifc_ctrl->regs->cspr_cs[priv->bank].cspr); + csor = in_be32(&ifc_ctrl->regs->csor_cs[priv->bank].csor); + + if ((cspr & CSPR_V) && (cspr & CSPR_MSEL) == CSPR_MSEL_NAND && + (cspr & CSPR_BA) == CSPR_PHYS_ADDR(base_addr)) { + ifc_ctrl->cs_nand = priv->bank << IFC_NAND_CSEL_SHIFT; + break; + } + } + + if (priv->bank >= MAX_BANKS) { + printf("%s: address did not match any " + "chip selects\n", __func__); + return -ENODEV; + } + + ifc_ctrl->chips[priv->bank] = priv; + + /* fill in nand_chip structure */ + /* set up function call table */ + + nand->write_buf = fsl_ifc_write_buf; + nand->read_buf = fsl_ifc_read_buf; + nand->verify_buf = fsl_ifc_verify_buf; + nand->select_chip = fsl_ifc_select_chip; + nand->cmdfunc = fsl_ifc_cmdfunc; + nand->waitfunc = fsl_ifc_wait; + + /* set up nand options */ + nand->bbt_td = &bbt_main_descr; + nand->bbt_md = &bbt_mirror_descr; + + /* set up nand options */ + nand->options = NAND_NO_READRDY | NAND_NO_AUTOINCR | + NAND_USE_FLASH_BBT; + + if (cspr & CSPR_PORT_SIZE_16) { + nand->read_byte = fsl_ifc_read_byte16; + nand->options |= NAND_BUSWIDTH_16; + } else { + nand->read_byte = fsl_ifc_read_byte; + } + + nand->controller = &ifc_ctrl->controller; + nand->priv = priv; + + nand->ecc.read_page = fsl_ifc_read_page; + nand->ecc.write_page = fsl_ifc_write_page; + + /* Hardware generates ECC per 512 Bytes */ + nand->ecc.size = 512; + nand->ecc.bytes = 8; + + switch (csor & CSOR_NAND_PGS_MASK) { + case CSOR_NAND_PGS_512: + if (nand->options & NAND_BUSWIDTH_16) { + layout = &oob_512_16bit_ecc4; + } else { + layout = &oob_512_8bit_ecc4; + + /* Avoid conflict with bad block marker */ + bbt_main_descr.offs = 0; + bbt_mirror_descr.offs = 0; + } + + priv->bufnum_mask = 15; + break; + + case CSOR_NAND_PGS_2K: + layout = &oob_2048_ecc4; + priv->bufnum_mask = 3; + break; + + case CSOR_NAND_PGS_4K: + if ((csor & CSOR_NAND_ECC_MODE_MASK) == + CSOR_NAND_ECC_MODE_4) { + layout = &oob_4096_ecc4; + } else { + layout = &oob_4096_ecc8; + nand->ecc.bytes = 16; + } + + priv->bufnum_mask = 1; + break; + + default: + printf("ifc nand: bad csor %#x: bad page size\n", csor); + return -ENODEV; + } + + /* Must also set CSOR_NAND_ECC_ENC_EN if DEC_EN set */ + if (csor & CSOR_NAND_ECC_DEC_EN) { + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.layout = layout; + } else { + nand->ecc.mode = NAND_ECC_SOFT; + } + + return 0; +} diff --git a/nand_spl/nand_boot_fsl_ifc.c b/nand_spl/nand_boot_fsl_ifc.c new file mode 100644 index 0000000..44972c5 --- /dev/null +++ b/nand_spl/nand_boot_fsl_ifc.c @@ -0,0 +1,271 @@ +/* + * NAND boot for FSL Integrated Flash Controller, NAND Flash Control Machine + * + * Copyright 2011 Freescale Semiconductor, Inc. + * Author: Dipen Dudhat dipen.dudhat@freescale.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/fsl_ifc.h> +#include <linux/mtd/nand.h> + +static inline int is_blank(uchar *addr, int page_size) +{ + int i; + + for (i = 0; i < page_size; i++) { + if (__raw_readb(&addr[i]) != 0xff) + return 0; + } + + /* + * For the SPL, don't worry about uncorrectable errors + * where the main area is all FFs but shouldn't be. + */ + return 1; +} + +/* returns nonzero if entire page is blank */ +static inline int check_read_ecc(uchar *buf, u32 *eccstat, + unsigned int bufnum, int page_size) +{ + u32 reg = eccstat[bufnum / 4]; + int errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; + + if (errors == 15) { /* uncorrectable */ + /* Blank pages fail hw ECC checks */ + if (is_blank(buf, page_size)) + return 1; + + puts("ecc error\n"); + for (;;) + ; + } + + return 0; +} + +static inline void nand_wait(uchar *buf, int bufnum, int page_size) +{ + struct fsl_ifc *ifc = IFC_BASE_ADDR; + u32 status; + u32 eccstat[4]; + int bufperpage = page_size / 512; + int bufnum_end, i; + + bufnum *= bufperpage; + bufnum_end = bufnum + bufperpage - 1; + + do { + status = in_be32(&ifc->ifc_nand.nand_evter_stat); + } while (!(status & IFC_NAND_EVTER_STAT_OPC)); + + if (status & IFC_NAND_EVTER_STAT_FTOER) { + puts("flash time out error\n"); + for (;;) + ; + } + + for (i = bufnum / 4; i <= bufnum_end / 4; i++) + eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]); + + for (i = bufnum; i <= bufnum_end; i++) { + if (check_read_ecc(buf, eccstat, i, page_size)) + break; + } + + out_be32(&ifc->ifc_nand.nand_evter_stat, status); +} + +static inline int bad_block(uchar *marker, int port_size) +{ + if (port_size == 8) + return __raw_readb(marker) != 0xff; + else + return __raw_readw((u16 *)marker) != 0xffff; +} + +static void nand_load(unsigned int offs, int uboot_size, uchar *dst) +{ + struct fsl_ifc *ifc = IFC_BASE_ADDR; + uchar *buf = (uchar *)CONFIG_SYS_NAND_BASE; + int page_size; + int port_size; + int pages_per_blk; + int blk_size; + int bad_marker = 0; + int bufnum_mask, bufnum; + + int csor, cspr; + int pos = 0; + int j = 0; + + int sram_addr; + int pg_no; + + /* Get NAND Flash configuration */ + csor = CONFIG_SYS_NAND_CSOR; + cspr = CONFIG_SYS_NAND_CSPR; + + if (!(csor & CSOR_NAND_ECC_DEC_EN)) { + /* soft ECC in SPL is unimplemented */ + puts("WARNING: soft ECC not checked in SPL\n"); + } else { + u32 hwcsor; + + /* make sure board is configured with ECC on boot */ + hwcsor = in_be32(&ifc->csor_cs[0].csor); + if (!(hwcsor & CSOR_NAND_ECC_DEC_EN)) + puts("WARNING: ECC not checked in SPL, " + "check board cfg\n"); + } + + port_size = (cspr & CSPR_PORT_SIZE_16) ? 16 : 8; + + if (csor & CSOR_NAND_PGS_4K) { + page_size = 4096; + bufnum_mask = 1; + } else if (csor & CSOR_NAND_PGS_2K) { + page_size = 2048; + bufnum_mask = 3; + } else { + page_size = 512; + bufnum_mask = 15; + + if (port_size == 8) + bad_marker = 5; + } + + pages_per_blk = + 32 << ((csor & CSOR_NAND_PB_MASK) >> CSOR_NAND_PB_SHIFT); + + blk_size = pages_per_blk * page_size; + + /* Open Full SRAM mapping for spare are access */ + out_be32(&ifc->ifc_nand.ncfgr, 0x0); + + /* Clear Boot events */ + out_be32(&ifc->ifc_nand.nand_evter_stat, 0xffffffff); + + /* Program FIR/FCR for Large/Small page */ + if (page_size > 512) { + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | + (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | + (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP3_SHIFT) | + (IFC_FIR_OP_BTRD << IFC_NAND_FIR0_OP4_SHIFT)); + out_be32(&ifc->ifc_nand.nand_fir1, 0x0); + + out_be32(&ifc->ifc_nand.nand_fcr0, + (NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) | + (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT)); + } else { + out_be32(&ifc->ifc_nand.nand_fir0, + (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | + (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | + (IFC_FIR_OP_BTRD << IFC_NAND_FIR0_OP3_SHIFT)); + out_be32(&ifc->ifc_nand.nand_fir1, 0x0); + + out_be32(&ifc->ifc_nand.nand_fcr0, + NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT); + } + + /* Program FBCR = 0 for full page read */ + out_be32(&ifc->ifc_nand.nand_fbcr, 0); + + /* Read and copy u-boot on SDRAM from NAND device, In parallel + * check for Bad block if found skip it and read continue to + * next Block + */ + while (pos < uboot_size) { + int i = 0; + do { + pg_no = offs / page_size; + bufnum = pg_no & bufnum_mask; + sram_addr = bufnum * page_size * 2; + + out_be32(&ifc->ifc_nand.row0, pg_no); + out_be32(&ifc->ifc_nand.col0, 0); + /* start read */ + out_be32(&ifc->ifc_nand.nandseq_strt, + IFC_NAND_SEQ_STRT_FIR_STRT); + + /* wait for read to complete */ + nand_wait(&buf[sram_addr], bufnum, page_size); + + /* + * If either of the first two pages are marked bad, + * continue to the next block. + */ + if (i++ < 2 && + bad_block(&buf[sram_addr + page_size + bad_marker], + port_size)) { + puts("skipping\n"); + offs = (offs + blk_size) & ~(blk_size - 1); + pos &= ~(blk_size - 1); + break; + } + + for (j = 0; j < page_size; j++) + dst[pos + j] = __raw_readb(&buf[sram_addr + j]); + + pos += page_size; + offs += page_size; + } while ((offs & (blk_size - 1)) && (pos < uboot_size)); + } +} + +/* + * Main entrypoint for NAND Boot. It's necessary that SDRAM is already + * configured and available since this code loads the main U-boot image + * from NAND into SDRAM and starts from there. + */ +void nand_boot(void) +{ + __attribute__((noreturn)) void (*uboot)(void); + + /* + * Load U-Boot image from NAND into RAM + */ + nand_load(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE, + (uchar *)CONFIG_SYS_NAND_U_BOOT_DST); + +#ifdef CONFIG_NAND_ENV_DST + nand_load(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, + (uchar *)CONFIG_NAND_ENV_DST); + +#ifdef CONFIG_ENV_OFFSET_REDUND + nand_load(CONFIG_ENV_OFFSET_REDUND, CONFIG_ENV_SIZE, + (uchar *)CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE); +#endif +#endif + + /* + * Jump to U-Boot image + */ + /* + * Clean d-cache and invalidate i-cache, to + * make sure that no stale data is executed. + */ + flush_cache(CONFIG_SYS_NAND_U_BOOT_DST, CONFIG_SYS_NAND_U_BOOT_SIZE); + uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START; + uboot(); +}

From: Dipen Dudhat Dipen.Dudhat@freescale.com
And various defines to enable NAND support and NAND spl code for the P1010RDB platform.
Signed-off-by: Dipen Dudhat Dipen.Dudhat@freescale.com Signed-off-by: Scott Wood scottwood@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org --- boards.cfg | 2 + include/configs/P1010RDB.h | 59 ++++++++++ nand_spl/board/freescale/p1010rdb/Makefile | 141 +++++++++++++++++++++++++ nand_spl/board/freescale/p1010rdb/nand_boot.c | 130 +++++++++++++++++++++++ 4 files changed, 332 insertions(+), 0 deletions(-) create mode 100644 nand_spl/board/freescale/p1010rdb/Makefile create mode 100644 nand_spl/board/freescale/p1010rdb/nand_boot.c
diff --git a/boards.cfg b/boards.cfg index 1dead8e..e07978c 100644 --- a/boards.cfg +++ b/boards.cfg @@ -581,6 +581,8 @@ MPC8572DS_36BIT powerpc mpc85xx mpc8572ds freesca MPC8572DS_NAND powerpc mpc85xx mpc8572ds freescale - MPC8572DS:NAND P1010RDB_NOR powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB P1010RDB_36BIT_NOR powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,36BIT +P1010RDB_NAND powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,NAND +P1010RDB_36BIT_NAND powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,36BIT,NAND P1010RDB_SDCARD powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,SDCARD P1010RDB_SPIFLASH powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,SPIFLASH P1010RDB_36BIT_SDCARD powerpc mpc85xx p1010rdb freescale - P1010RDB:P1010RDB,36BIT,SDCARD diff --git a/include/configs/P1010RDB.h b/include/configs/P1010RDB.h index 4171805..fe3def6 100644 --- a/include/configs/P1010RDB.h +++ b/include/configs/P1010RDB.h @@ -33,6 +33,7 @@
#ifdef CONFIG_P1010RDB #define CONFIG_P1010 +#define CONFIG_NAND_FSL_IFC #endif
#ifdef CONFIG_SDCARD @@ -47,6 +48,17 @@ #define CONFIG_RESET_VECTOR_ADDRESS 0x1107fffc #endif
+#ifdef CONFIG_NAND /* NAND Boot */ +#define CONFIG_RAMBOOT_NAND +#define CONFIG_NAND_U_BOOT +#define CONFIG_SYS_TEXT_BASE_SPL 0xff800000 +#ifdef CONFIG_NAND_SPL +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE_SPL +#else +#define CONFIG_SYS_TEXT_BASE 0x11001000 +#endif /* CONFIG_NAND_SPL */ +#endif + #ifndef CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_TEXT_BASE 0xeff80000 #endif @@ -221,6 +233,11 @@ extern unsigned long get_sdram_size(void); #define CONFIG_SYS_CCSRBAR 0xffe00000 #define CONFIG_SYS_CCSRBAR_PHYS_LOW CONFIG_SYS_CCSRBAR
+/* Don't relocate CCSRBAR while in NAND_SPL */ +#ifdef CONFIG_NAND_SPL +#define CONFIG_SYS_CCSR_DO_NOT_RELOCATE +#endif + /* * Memory map * @@ -305,6 +322,12 @@ extern unsigned long get_sdram_size(void); | CSOR_NAND_SPRZ_16 /* Spare size = 16 */ \ | CSOR_NAND_PB(32)) /* 32 Pages Per Block */
+#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE } +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_MTD_NAND_VERIFY_WRITE +#define CONFIG_CMD_NAND +#define CONFIG_SYS_NAND_BLOCK_SIZE (16 * 1024) + /* NAND Flash Timing Params */ #define CONFIG_SYS_NAND_FTIM0 FTIM0_NAND_TCCST(0x01) | \ FTIM0_NAND_TWP(0x0C) | \ @@ -322,6 +345,22 @@ extern unsigned long get_sdram_size(void); #define CONFIG_SYS_NAND_DDR_LAW 11
/* Set up IFC registers for boot location NOR/NAND */ +#ifdef CONFIG_NAND_U_BOOT +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NAND_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NAND_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NAND_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NAND_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NAND_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NAND_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NAND_FTIM3 +#define CONFIG_SYS_CSPR1 CONFIG_SYS_NOR_CSPR +#define CONFIG_SYS_AMASK1 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR1 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NOR_FTIM3 +#else #define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR_CSPR #define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK #define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR @@ -336,6 +375,16 @@ extern unsigned long get_sdram_size(void); #define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NAND_FTIM1 #define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NAND_FTIM2 #define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NAND_FTIM3 +#endif + +/* NAND boot: 8K NAND loader config */ +#define CONFIG_SYS_NAND_SPL_SIZE 0x2000 +#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 << 10) +#define CONFIG_SYS_NAND_U_BOOT_DST (0x11000000 - CONFIG_SYS_NAND_SPL_SIZE) +#define CONFIG_SYS_NAND_U_BOOT_START 0x11000000 +#define CONFIG_SYS_NAND_U_BOOT_OFFS (0) +#define CONFIG_SYS_NAND_U_BOOT_RELOC 0x10000 +#define CONFIG_SYS_NAND_U_BOOT_RELOC_SP (CONFIG_SYS_NAND_U_BOOT_RELOC + 0x10000)
/* CPLD on IFC */ #define CONFIG_SYS_CPLD_BASE 0xffb00000 @@ -393,6 +442,9 @@ extern unsigned long get_sdram_size(void); #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE 1 #define CONFIG_SYS_NS16550_CLK get_bus_freq(0) +#ifdef CONFIG_NAND_SPL +#define CONFIG_NS16550_MIN_FUNCTIONS +#endif
#define CONFIG_SERIAL_MULTI /* Enable both serial ports */ #define CONFIG_SYS_CONSOLE_IS_IN_ENV /* determine from environment */ @@ -449,6 +501,7 @@ extern unsigned long get_sdram_size(void); * SPI interface will not be available in case of NAND boot SPI CS0 will be * used for SLIC */ +#ifndef CONFIG_NAND_U_BOOT /* eSPI - Enhanced SPI */ #define CONFIG_FSL_ESPI #define CONFIG_SPI_FLASH @@ -456,6 +509,7 @@ extern unsigned long get_sdram_size(void); #define CONFIG_CMD_SF #define CONFIG_SF_DEFAULT_SPEED 10000000 #define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 +#endif
#if defined(CONFIG_TSEC_ENET) #ifndef CONFIG_NET_MULTI @@ -556,6 +610,11 @@ extern unsigned long get_sdram_size(void); #define CONFIG_ENV_OFFSET 0x100000 /* 1MB */ #define CONFIG_ENV_SECT_SIZE 0x10000 #define CONFIG_ENV_SIZE 0x2000 +#elif defined(CONFIG_NAND_U_BOOT) +#define CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_SIZE CONFIG_SYS_NAND_BLOCK_SIZE +#define CONFIG_ENV_OFFSET CONFIG_SYS_NAND_U_BOOT_SIZE +#define CONFIG_ENV_RANGE (3 * CONFIG_ENV_SIZE) #else #define CONFIG_ENV_IS_NOWHERE /* Store ENV in memory only */ #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - 0x1000) diff --git a/nand_spl/board/freescale/p1010rdb/Makefile b/nand_spl/board/freescale/p1010rdb/Makefile new file mode 100644 index 0000000..8d240ea --- /dev/null +++ b/nand_spl/board/freescale/p1010rdb/Makefile @@ -0,0 +1,141 @@ +# +# (C) Copyright 2007 +# Stefan Roese, DENX Software Engineering, sr@denx.de. +# +# Copyright 2011 Freescale Semiconductor, Inc. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +NAND_SPL := y +CONFIG_SYS_TEXT_BASE_SPL := 0xff800000 +PAD_TO := 0xff802000 + +include $(TOPDIR)/config.mk + +nandobj := $(OBJTREE)/nand_spl/ + +LDSCRIPT= $(TOPDIR)/$(CPUDIR)/u-boot-nand_spl.lds +LDFLAGS := -T $(nandobj)u-boot-nand_spl.lds -Ttext $(CONFIG_SYS_TEXT_BASE_SPL) $(LDFLAGS) \ + $(LDFLAGS_FINAL) +AFLAGS += -DCONFIG_NAND_SPL +CFLAGS += -DCONFIG_NAND_SPL + +SOBJS = start.o resetvec.o ticks.o +COBJS = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \ + nand_boot.o nand_boot_fsl_ifc.o ns16550.o tlb.o tlb_table.o + +SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +__OBJS := $(SOBJS) $(COBJS) +LNDIR := $(nandobj)board/$(BOARDDIR) + +ALL = $(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin + +all: $(obj).depend $(ALL) + +$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl + $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $< $@ + +$(nandobj)u-boot-spl.bin: $(nandobj)u-boot-spl + $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ + +$(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot-nand_spl.lds + cd $(LNDIR) && $(LD) $(LDFLAGS) $(__OBJS) $(PLATFORM_LIBS) \ + -Map $(nandobj)u-boot-spl.map \ + -o $(nandobj)u-boot-spl + +$(nandobj)u-boot-nand_spl.lds: $(LDSCRIPT) + $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@ + +# create symbolic links for common files + +$(obj)cache.c: + @rm -f $(obj)cache.c + ln -sf $(SRCTREE)/arch/powerpc/lib/cache.c $(obj)cache.c + +$(obj)cpu_init_early.c: + @rm -f $(obj)cpu_init_early.c + ln -sf $(SRCTREE)/$(CPUDIR)/cpu_init_early.c $(obj)cpu_init_early.c + +$(obj)cpu_init_nand.c: + @rm -f $(obj)cpu_init_nand.c + ln -sf $(SRCTREE)/$(CPUDIR)/cpu_init_nand.c $(obj)cpu_init_nand.c + +$(obj)fsl_law.c: + @rm -f $(obj)fsl_law.c + ln -sf $(SRCTREE)/drivers/misc/fsl_law.c $(obj)fsl_law.c + +$(obj)law.c: + @rm -f $(obj)law.c + ln -sf $(SRCTREE)/board/$(BOARDDIR)/law.c $(obj)law.c + +$(obj)nand_boot_fsl_ifc.c: + @rm -f $(obj)nand_boot_fsl_ifc.c + ln -sf $(SRCTREE)/nand_spl/nand_boot_fsl_ifc.c \ + $(obj)nand_boot_fsl_ifc.c + +$(obj)ns16550.c: + @rm -f $(obj)ns16550.c + ln -sf $(SRCTREE)/drivers/serial/ns16550.c $(obj)ns16550.c + +$(obj)resetvec.S: + @rm -f $(obj)resetvec.S + ln -s $(SRCTREE)/$(CPUDIR)/resetvec.S $(obj)resetvec.S + +$(obj)fixed_ivor.S: + @rm -f $(obj)fixed_ivor.S + ln -sf $(SRCTREE)/$(CPUDIR)/fixed_ivor.S $(obj)fixed_ivor.S + +$(obj)start.S: $(obj)fixed_ivor.S + @rm -f $(obj)start.S + ln -sf $(SRCTREE)/$(CPUDIR)/start.S $(obj)start.S + +$(obj)ticks.S: + @rm -f $(obj)ticks.S + ln -sf $(SRCTREE)/arch/powerpc/lib/ticks.S $(obj)ticks.S + +$(obj)tlb.c: + @rm -f $(obj)tlb.c + ln -sf $(SRCTREE)/$(CPUDIR)/tlb.c $(obj)tlb.c + +$(obj)tlb_table.c: + @rm -f $(obj)tlb_table.c + ln -sf $(SRCTREE)/board/$(BOARDDIR)/tlb.c $(obj)tlb_table.c + +ifneq ($(OBJTREE), $(SRCTREE)) +$(obj)nand_boot.c: + @rm -f $(obj)nand_boot.c + ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c +endif + +######################################################################### + +$(obj)%.o: $(obj)%.S + $(CC) $(AFLAGS) -c -o $@ $< + +$(obj)%.o: $(obj)%.c + $(CC) $(CFLAGS) -c -o $@ $< + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/nand_spl/board/freescale/p1010rdb/nand_boot.c b/nand_spl/board/freescale/p1010rdb/nand_boot.c new file mode 100644 index 0000000..16eeb61 --- /dev/null +++ b/nand_spl/board/freescale/p1010rdb/nand_boot.c @@ -0,0 +1,130 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ +#include <common.h> +#include <mpc85xx.h> +#include <asm/io.h> +#include <ns16550.h> +#include <nand.h> +#include <asm/mmu.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_ddr_sdram.h> +#include <asm/fsl_law.h> + +#define udelay(x) { int j; for (j = 0; j < x * 10000; j++) isync(); } + +unsigned long ddr_freq_mhz; + +void sdram_init(void) +{ + ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR; + + out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL | SDRAM_CFG_32_BE); + out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS); + out_be32(&ddr->cs0_config, CONFIG_SYS_DDR_CS0_CONFIG); + out_be32(&ddr->sdram_cfg_2, CONFIG_SYS_DDR_CONTROL_2); + out_be32(&ddr->sdram_data_init, CONFIG_SYS_DDR_DATA_INIT); + + if (ddr_freq_mhz < 700) { + out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3_667); + out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0_667); + out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1_667); + out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2_667); + out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1_667); + out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2_667); + out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL_667); + out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL_667); + out_be32(&ddr->ddr_wrlvl_cntl, + CONFIG_SYS_DDR_WRLVL_CONTROL_667); + } else { + out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3_800); + out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0_800); + out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1_800); + out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2_800); + out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1_800); + out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2_800); + out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL_800); + out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL_800); + out_be32(&ddr->ddr_wrlvl_cntl, + CONFIG_SYS_DDR_WRLVL_CONTROL_800); + } + + out_be32(&ddr->timing_cfg_4, CONFIG_SYS_DDR_TIMING_4); + out_be32(&ddr->timing_cfg_5, CONFIG_SYS_DDR_TIMING_5); + out_be32(&ddr->ddr_zq_cntl, CONFIG_SYS_DDR_ZQ_CONTROL); + + /* mimic 500us delay, with busy isync() loop */ + udelay(100); + + /* Let the controller go */ + out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN); + + set_next_law(CONFIG_SYS_NAND_DDR_LAW, LAW_SIZE_1G, LAW_TRGT_IF_DDR_1); +} + +void board_init_f(ulong bootflag) +{ + u32 plat_ratio, ddr_ratio; + unsigned long bus_clk; + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + + /* initialize selected port with appropriate baud rate */ + plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; + plat_ratio >>= 1; + bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; + + ddr_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO; + ddr_ratio = ddr_ratio >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; + ddr_freq_mhz = (CONFIG_SYS_CLK_FREQ * ddr_ratio) / 0x1000000; + + NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, + bus_clk / 16 / CONFIG_BAUDRATE); + + puts("\nNAND boot... "); + + /* Initialize the DDR3 */ + sdram_init(); + + /* copy code to RAM and jump to it - this should not return */ + /* NOTE - code has to be copied out of NAND buffer before + * other blocks can be read. + */ + relocate_code(CONFIG_SYS_NAND_U_BOOT_RELOC_SP, 0, + CONFIG_SYS_NAND_U_BOOT_RELOC); +} + +void board_init_r(gd_t *gd, ulong dest_addr) +{ + nand_boot(); +} + +void putc(char c) +{ + if (c == '\n') + NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, '\r'); + + NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, c); +} + +void puts(const char *str) +{ + while (*str) + putc(*str++); +}

From: Poonam Aggrwal poonam.aggrwal@freescale.com
For an IFC Erratum (A-003399) we will need to access IFC registers in cpu_init_early_f() so expand the TLB covering CCSR to 1M.
Since we need a TLB to cover 1M we move to using TLB1 array for all the early mappings so we can cover various sizes beyond 4k.
Additionally removed volatile from ccsr_virt declaration as its not needed for IO accessors
Signed-off-by: Poonam Aggrwal poonam.aggrwal@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org --- arch/powerpc/cpu/mpc85xx/cpu_init_early.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c index 64eda94..359f03e 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c @@ -21,6 +21,7 @@ #include <asm/processor.h> #include <asm/mmu.h> #include <asm/fsl_law.h> +#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -40,8 +41,8 @@ void cpu_init_early_f(void) for (i = 0; i < sizeof(gd_t); i++) ((char *)gd)[i] = 0;
- mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(0); - mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_4K); + mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(13); + mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_1M); mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G); mas3 = FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS, 0, MAS3_SW|MAS3_SR); mas7 = FSL_BOOKE_MAS7(CONFIG_SYS_CCSRBAR_PHYS); @@ -49,6 +50,6 @@ void cpu_init_early_f(void) write_tlb(mas0, mas1, mas2, mas3, mas7);
init_laws(); - invalidate_tlb(0); + invalidate_tlb(1); init_tlbs(); }

From: Poonam Aggrwal poonam.aggrwal@freescale.com
Issue: The NOR-FCM does not support access to unaligned addresses for 16 bit port size
Impact: When 16 bit port size is used, accesses not aligned to 16 bit address boundary will result in incorrect data
Workaround: The workaround is to switch to GPCM mode for NOR Flash access.
Signed-off-by: Poonam Aggrwal poonam.aggrwal@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org --- arch/powerpc/cpu/mpc85xx/cmd_errata.c | 3 +++ arch/powerpc/include/asm/config_mpc85xx.h | 2 ++ arch/powerpc/include/asm/fsl_ifc.h | 5 +++++ 3 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 7b9f773..446f759 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -87,6 +87,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) puts("Work-around for Erratum DDR111 enabled\n"); puts("Work-around for Erratum DDR134 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769 + puts("Work-around for Erratum IFC-A002769 enabled\n"); +#endif return 0; }
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 691c075..f334645 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -112,6 +112,7 @@ #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY +#define CONFIG_SYS_FSL_ERRATUM_IFC_A002769
/* P1011 is single core version of P1020 */ #elif defined(CONFIG_P1011) @@ -160,6 +161,7 @@ #define CONFIG_NUM_DDR_CONTROLLERS 1 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY +#define CONFIG_SYS_FSL_ERRATUM_IFC_A002769
/* P1015 is single core version of P1024 */ #elif defined(CONFIG_P1015) diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h index fb12363..7d95eb4 100644 --- a/arch/powerpc/include/asm/fsl_ifc.h +++ b/arch/powerpc/include/asm/fsl_ifc.h @@ -951,5 +951,10 @@ struct fsl_ifc { struct fsl_ifc_gpcm ifc_gpcm; };
+#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769 +#undef CSPR_MSEL_NOR +#define CSPR_MSEL_NOR CSPR_MSEL_GPCM +#endif + #endif /* __ASSEMBLY__ */ #endif /* __ASM_PPC_FSL_IFC_H */

From: Poonam Aggrwal poonam.aggrwal@freescale.com
Issue: Peripheral connected to IFC_CS3 may hamper booting from IFC.
Impact: Boot from IFC may not be successful if IFC_CS3 is used.
Workaround: If IFC_CS3 is used, gate IFC_CS3 while booting from NAND or NOR. Also Software should select IFC_CS3 using PMUXCR[26:27] = 0x01.
Signed-off-by: Poonam Aggrwal poonam.aggrwal@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org --- arch/powerpc/cpu/mpc85xx/cmd_errata.c | 3 +++ arch/powerpc/cpu/mpc85xx/cpu_init_early.c | 12 ++++++++++++ arch/powerpc/include/asm/config_mpc85xx.h | 2 ++ 3 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 446f759..c2fb5b8 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -90,6 +90,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769 puts("Work-around for Erratum IFC-A002769 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 + puts("Work-around for Erratum P1010-A003549 enabled\n"); +#endif return 0; }
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c index 359f03e..c42efb1 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c @@ -30,6 +30,9 @@ void cpu_init_early_f(void) { u32 mas0, mas1, mas2, mas3, mas7; int i; +#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +#endif
/* Pointer is writable since we allocated a register for it */ gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); @@ -49,6 +52,15 @@ void cpu_init_early_f(void)
write_tlb(mas0, mas1, mas2, mas3, mas7);
+/* + * Work Around for IFC Erratum A-003549. This issue is P1010 + * specific. LCLK(a free running clk signal) is muxed with IFC_CS3 on P1010 SOC + * Hence specifically selecting CS3. + */ +#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 + setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_LCLK_IFC_CS3); +#endif + init_laws(); invalidate_tlb(1); init_tlbs(); diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index f334645..61c19ea 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -113,6 +113,7 @@ #define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_IFC_A002769 +#define CONFIG_SYS_FSL_ERRATUM_P1010_A003549
/* P1011 is single core version of P1020 */ #elif defined(CONFIG_P1011) @@ -162,6 +163,7 @@ #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_IFC_A002769 +#define CONFIG_SYS_FSL_ERRATUM_P1010_A003549
/* P1015 is single core version of P1024 */ #elif defined(CONFIG_P1015)

From: Poonam Aggrwal poonam.aggrwal@freescale.com
Issue: Address masking doesn't work properly. When sum of the base address, defined by BA, and memory bank size, defined by AM, exceeds 4GB (0xffff_ffff) then AMASKn[AM] doesn't mask CSPRn[BA] bits.
Impact: This will impact booting when we are reprogramming CSPR0(BA) and AMASK0(AMASK) while executing from NOR Flash.
Workaround: Re-programming of CSPR(BA) and AMASK is done while not executing from NOR Flash. The code which programs the BA and AMASK is executed from L2-SRAM.
Signed-off-by: Poonam Aggrwal poonam.aggrwal@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org --- arch/powerpc/cpu/mpc85xx/cmd_errata.c | 3 + arch/powerpc/cpu/mpc85xx/cpu_init_early.c | 86 +++++++++++++++++++++++++++++ arch/powerpc/cpu/mpc85xx/cpu_init_nand.c | 2 + arch/powerpc/cpu/mpc8xxx/fsl_ifc.c | 2 + arch/powerpc/include/asm/config_mpc85xx.h | 2 + 5 files changed, 95 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index c2fb5b8..0478ec1 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -93,6 +93,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 puts("Work-around for Erratum P1010-A003549 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A003399 + puts("Work-around for Erratum IFC A-003399 enabled\n"); +#endif return 0; }
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c index c42efb1..a04f5c1 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c @@ -25,6 +25,42 @@
DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) +void setup_ifc(void) +{ + struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; + u32 _mas0, _mas1, _mas2, _mas3, _mas7; + phys_addr_t flash_phys = CONFIG_SYS_FLASH_BASE_PHYS; + + /* + * Adjust the TLB we were running out of to match the phys addr of the + * chip select we are adjusting and will return to. + */ + flash_phys += (~CONFIG_SYS_AMASK0) + 1 - 4*1024*1024; + + _mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(15); + _mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_IPROT | + MAS1_TSIZE(BOOKE_PAGESZ_4M); + _mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_TEXT_BASE, MAS2_I|MAS2_G); + _mas3 = FSL_BOOKE_MAS3(flash_phys, 0, MAS3_SW|MAS3_SR|MAS3_SX); + _mas7 = FSL_BOOKE_MAS7(flash_phys); + + mtspr(MAS0, _mas0); + mtspr(MAS1, _mas1); + mtspr(MAS2, _mas2); + mtspr(MAS3, _mas3); + mtspr(MAS7, _mas7); + + asm volatile("isync;msync;tlbwe;isync"); + + out_be32(&(ifc_regs->cspr_cs[0].cspr), CONFIG_SYS_CSPR0); + out_be32(&(ifc_regs->csor_cs[0].csor), CONFIG_SYS_CSOR0); + out_be32(&(ifc_regs->amask_cs[0].amask), CONFIG_SYS_AMASK0); + + return ; +} +#endif + /* We run cpu_init_early_f in AS = 1 */ void cpu_init_early_f(void) { @@ -33,6 +69,11 @@ void cpu_init_early_f(void) #ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #endif +#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) + ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR; + u32 *l2srbar, *dst, *src; + void (*setup_ifc_sram)(void); +#endif
/* Pointer is writable since we allocated a register for it */ gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); @@ -62,6 +103,51 @@ void cpu_init_early_f(void) #endif
init_laws(); + +/* + * Work Around for IFC Erratum A003399, issue will hit only when execution + * from NOR Flash + */ +#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) +#define SRAM_BASE_ADDR (0x00000000) + /* TLB for SRAM */ + mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(9); + mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | + MAS1_TSIZE(BOOKE_PAGESZ_1M); + mas2 = FSL_BOOKE_MAS2(SRAM_BASE_ADDR, MAS2_I); + mas3 = FSL_BOOKE_MAS3(SRAM_BASE_ADDR, 0, MAS3_SX|MAS3_SW|MAS3_SR); + mas7 = FSL_BOOKE_MAS7(0); + + write_tlb(mas0, mas1, mas2, mas3, mas7); + + out_be32(&l2cache->l2srbar0, SRAM_BASE_ADDR); + + out_be32(&l2cache->l2errdis, + (MPC85xx_L2ERRDIS_MBECC | MPC85xx_L2ERRDIS_SBECC)); + + out_be32(&l2cache->l2ctl, + (MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2SRAM_ENTIRE)); + + /* + * Copy the code in setup_ifc to L2SRAM. Do a word copy + * because NOR Flash on P1010 does not support byte + * access (Erratum IFC-A002769) + */ + setup_ifc_sram = (void *)SRAM_BASE_ADDR; + dst = (u32 *) SRAM_BASE_ADDR; + src = (u32 *) setup_ifc; + for (i = 0; i < 1024; i++) + *l2srbar++ = *src++; + + setup_ifc_sram(); + + /* CLEANUP */ + clrbits_be32(&l2cache->l2ctl, + (MPC85xx_L2CTL_L2E | + MPC85xx_L2CTL_L2SRAM_ENTIRE)); + out_be32(&l2cache->l2srbar0, 0x0); +#endif + invalidate_tlb(1); init_tlbs(); } diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c index 6d01479..f33db02 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c @@ -43,12 +43,14 @@ void cpu_init_f(void) #endif #endif #ifdef CONFIG_FSL_IFC +#ifndef CONFIG_SYS_FSL_ERRATUM_IFC_A003399 #if defined(CONFIG_SYS_CSPR0) && defined(CONFIG_SYS_CSOR0) set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0); set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); #endif #endif +#endif
#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L2_ADDR) ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR; diff --git a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c index e794821..6682496 100644 --- a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c +++ b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c @@ -43,10 +43,12 @@ void init_early_memctl_regs(void) set_ifc_ftim(IFC_CS0, IFC_FTIM2, CONFIG_SYS_CS0_FTIM2); set_ifc_ftim(IFC_CS0, IFC_FTIM3, CONFIG_SYS_CS0_FTIM3);
+#if !defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) || defined(CONFIG_SYS_RAMBOOT) set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0); set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); #endif +#endif
#if defined(CONFIG_SYS_CSPR1) && defined(CONFIG_SYS_CSOR1) set_ifc_ftim(IFC_CS1, IFC_FTIM0, CONFIG_SYS_CS1_FTIM0); diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 61c19ea..f9bf80d 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -114,6 +114,7 @@ #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_IFC_A002769 #define CONFIG_SYS_FSL_ERRATUM_P1010_A003549 +#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399
/* P1011 is single core version of P1020 */ #elif defined(CONFIG_P1011) @@ -164,6 +165,7 @@ #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_IFC_A002769 #define CONFIG_SYS_FSL_ERRATUM_P1010_A003549 +#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399
/* P1015 is single core version of P1024 */ #elif defined(CONFIG_P1015)

Dear Kumar Gala,
In message 1312555480-13401-8-git-send-email-galak@kernel.crashing.org you wrote:
From: Poonam Aggrwal poonam.aggrwal@freescale.com
Issue: Address masking doesn't work properly. When sum of the base address, defined by BA, and memory bank size, defined by AM, exceeds 4GB (0xffff_ffff) then AMASKn[AM] doesn't mask CSPRn[BA] bits.
Impact: This will impact booting when we are reprogramming CSPR0(BA) and AMASK0(AMASK) while executing from NOR Flash.
Workaround: Re-programming of CSPR(BA) and AMASK is done while not executing from NOR Flash. The code which programs the BA and AMASK is executed from L2-SRAM.
Signed-off-by: Poonam Aggrwal poonam.aggrwal@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org
This commit introdces new build warnings for the following boards:
P1010RDB_36BIT_NOR P1010RDB_NOR P1010RDB_36BIT_NOR_SECBOOT P1010RDB_NOR_SECBOOT
For example:
Configuring for P1010RDB_NOR - Board: P1010RDB, Options: P1010RDB cpu_init_early.c: In function 'cpu_init_early_f': cpu_init_early.c:74: warning: 'l2srbar' may be used uninitialized in this function
Please fix!
Kumar, Poonam - I'm really p*ssed off. Both of you have more than enough of experience to know that you should not submit untested patches. especially here, where I already had to reject this patch because it did not even pass checkpatch:
I wrote in message 20110804212403.3D53221C695@gemini.denx.de:
| Dear Kumar Gala, | | In message 08144324-BE32-4A54-BC2D-B920F18F3D43@kernel.crashing.org | you wrote: | > | > > Kumar, could you __please__ get used to running your patches | > > throuch | > > checkpatch __before__ submitting? Thanks. | > | > I try to, but not all of them are by me ;) | | I know. But you submitted them, so you are responsible.
This level of neglect is really disappointing.
Wolfgang Denk

On Oct 18, 2011, at 1:35 AM, Wolfgang Denk wrote:
Dear Kumar Gala,
In message 1312555480-13401-8-git-send-email-galak@kernel.crashing.org you wrote:
From: Poonam Aggrwal poonam.aggrwal@freescale.com
Issue: Address masking doesn't work properly. When sum of the base address, defined by BA, and memory bank size, defined by AM, exceeds 4GB (0xffff_ffff) then AMASKn[AM] doesn't mask CSPRn[BA] bits.
Impact: This will impact booting when we are reprogramming CSPR0(BA) and AMASK0(AMASK) while executing from NOR Flash.
Workaround: Re-programming of CSPR(BA) and AMASK is done while not executing from NOR Flash. The code which programs the BA and AMASK is executed from L2-SRAM.
Signed-off-by: Poonam Aggrwal poonam.aggrwal@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org
This commit introdces new build warnings for the following boards:
P1010RDB_36BIT_NOR P1010RDB_NOR P1010RDB_36BIT_NOR_SECBOOT P1010RDB_NOR_SECBOOT
For example:
Configuring for P1010RDB_NOR - Board: P1010RDB, Options: P1010RDB cpu_init_early.c: In function 'cpu_init_early_f': cpu_init_early.c:74: warning: 'l2srbar' may be used uninitialized in this function
Please fix!
Kumar, Poonam - I'm really p*ssed off. Both of you have more than enough of experience to know that you should not submit untested patches. especially here, where I already had to reject this patch because it did not even pass checkpatch:
I wrote in message 20110804212403.3D53221C695@gemini.denx.de:
| Dear Kumar Gala, | | In message 08144324-BE32-4A54-BC2D-B920F18F3D43@kernel.crashing.org | you wrote: | > | > > Kumar, could you __please__ get used to running your patches | > > throuch | > > checkpatch __before__ submitting? Thanks. | > | > I try to, but not all of them are by me ;) | | I know. But you submitted them, so you are responsible.
This level of neglect is really disappointing.
Wolfgang Denk
If you look at the code I have NO IDEA how to fix this for older GCC. Gripping at me about this isn't fair. I'm sure if I hack something to make gcc-4.2 happy I'm going to piss off gcc-4.6. We can't win.
At some point we have to move off gcc-4.2 as the baseline compiler w/regards to warning and code generation.
- k

Kumar, Wolfgang I think this is my mistake, I did not take care of checkpatch.
Please let me know , I can submit it again.
Regards Poonam
-----Original Message----- From: Kumar Gala [mailto:galak@kernel.crashing.org] Sent: Tuesday, October 18, 2011 5:18 PM To: Wolfgang Denk Cc: u-boot@lists.denx.de; Aggrwal Poonam-B10812 Subject: Re: [U-Boot] [PATCH 7/7][v2] fsl_ifc: Add the workaround for erratum IFC A-003399(enabled on P1010)
On Oct 18, 2011, at 1:35 AM, Wolfgang Denk wrote:
Dear Kumar Gala,
In message <1312555480-13401-8-git-send-email-
galak@kernel.crashing.org> you wrote:
From: Poonam Aggrwal poonam.aggrwal@freescale.com
Issue: Address masking doesn't work properly. When sum of the base address, defined by BA, and memory bank size, defined by AM, exceeds 4GB (0xffff_ffff) then AMASKn[AM] doesn't mask CSPRn[BA] bits.
Impact: This will impact booting when we are reprogramming CSPR0(BA) and AMASK0(AMASK) while executing from NOR Flash.
Workaround: Re-programming of CSPR(BA) and AMASK is done while not executing from NOR Flash. The code which programs the BA and AMASK is executed from
L2-SRAM.
Signed-off-by: Poonam Aggrwal poonam.aggrwal@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org
This commit introdces new build warnings for the following boards:
P1010RDB_36BIT_NOR P1010RDB_NOR P1010RDB_36BIT_NOR_SECBOOT P1010RDB_NOR_SECBOOT
For example:
Configuring for P1010RDB_NOR - Board: P1010RDB, Options: P1010RDB cpu_init_early.c: In function 'cpu_init_early_f': cpu_init_early.c:74: warning: 'l2srbar' may be used uninitialized in this function
Please fix!
Kumar, Poonam - I'm really p*ssed off. Both of you have more than enough of experience to know that you should not submit untested patches. especially here, where I already had to reject this patch because it did not even pass checkpatch:
I wrote in message 20110804212403.3D53221C695@gemini.denx.de:
| Dear Kumar Gala, | | In message | 08144324-BE32-4A54-BC2D-B920F18F3D43@kernel.crashing.org | you wrote: | > | > > Kumar, could you __please__ get used to running your patches | > > throuch checkpatch __before__ submitting? Thanks. | > | > I try to, but not all of them are by me ;) | | I know. But you submitted them, so you are responsible.
This level of neglect is really disappointing.
Wolfgang Denk
If you look at the code I have NO IDEA how to fix this for older GCC. Gripping at me about this isn't fair. I'm sure if I hack something to make gcc-4.2 happy I'm going to piss off gcc-4.6. We can't win.
At some point we have to move off gcc-4.2 as the baseline compiler w/regards to warning and code generation.
- k

Dear Kumar,
In message C9025279-8F82-453E-8B43-A5D2270A0BCA@kernel.crashing.org you wrote:
If you look at the code I have NO IDEA how to fix this for older GCC.
Maybe you have to explain the code to me. LIke the compiler, I wonder where l2srbar gets initialized:
Here is the declaration:
... 74 u32 *l2srbar, *dst, *src; ...
First use of this variable is here:
... 139 for (i = 0; i < 1024; i++) 140 *l2srbar++ = *src++; ...
Where is the initialization?
Best regards,
Wolfgang Denk

On Oct 18, 2011, at 3:18 PM, Wolfgang Denk wrote:
Dear Kumar,
In message C9025279-8F82-453E-8B43-A5D2270A0BCA@kernel.crashing.org you wrote:
If you look at the code I have NO IDEA how to fix this for older GCC.
Maybe you have to explain the code to me. LIke the compiler, I wonder where l2srbar gets initialized:
Here is the declaration:
... 74 u32 *l2srbar, *dst, *src; ...
First use of this variable is here:
... 139 for (i = 0; i < 1024; i++) 140 *l2srbar++ = *src++; ...
Where is the initialization?
I apologize, now that I look at this I question what in the world is going on.
Poonam,
What's going on whit this code:
dst = (u32 *) SRAM_BASE_ADDR; src = (u32 *) setup_ifc; for (i = 0; i < 1024; i++) *l2srbar++ = *src++;
we don't use 'dst' as far as I can tell and 'l2srbar' is never initialized so what in the world are we writing to?
- k

-----Original Message----- From: Kumar Gala [mailto:galak@kernel.crashing.org] Sent: Wednesday, October 19, 2011 11:52 AM To: Aggrwal Poonam-B10812 Cc: u-boot@lists.denx.de List; Wolfgang Denk Subject: Re: [U-Boot] [PATCH 7/7][v2] fsl_ifc: Add the workaround for erratum IFC A-003399(enabled on P1010)
On Oct 18, 2011, at 3:18 PM, Wolfgang Denk wrote:
Dear Kumar,
In message C9025279-8F82-453E-8B43-A5D2270A0BCA@kernel.crashing.org
you wrote:
If you look at the code I have NO IDEA how to fix this for older GCC.
Maybe you have to explain the code to me. LIke the compiler, I wonder where l2srbar gets initialized:
Here is the declaration:
... 74 u32 *l2srbar, *dst, *src; ...
First use of this variable is here:
... 139 for (i = 0; i < 1024; i++) 140 *l2srbar++ = *src++; ...
Where is the initialization?
I apologize, now that I look at this I question what in the world is going on.
Poonam,
What's going on whit this code:
dst = (u32 *) SRAM_BASE_ADDR; src = (u32 *) setup_ifc; for (i = 0; i < 1024; i++) *l2srbar++ = *src++;
we don't use 'dst' as far as I can tell and 'l2srbar' is never initialized so what in the world are we writing to?
Hello Kumar, Wolfgang
This is a mistake, I admit. Extremely sorry for this. I will send a new patch.
- k

Hello.
On 05-08-2011 18:44, Kumar Gala wrote:
From: Poonam Aggrwalpoonam.aggrwal@freescale.com
For an IFC Erratum (A-003399) we will need to access IFC registers in cpu_init_early_f() so expand the TLB covering CCSR to 1M.
Since we need a TLB to cover 1M we move to using TLB1 array for all the early mappings so we can cover various sizes beyond 4k.
Additionally removed volatile from ccsr_virt declaration as its not needed for IO accessors
I don't see that change in the patch...
Signed-off-by: Poonam Aggrwalpoonam.aggrwal@freescale.com Signed-off-by: Kumar Galagalak@kernel.crashing.org
arch/powerpc/cpu/mpc85xx/cpu_init_early.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c index 64eda94..359f03e 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c @@ -21,6 +21,7 @@ #include <asm/processor.h> #include <asm/mmu.h> #include <asm/fsl_law.h> +#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -40,8 +41,8 @@ void cpu_init_early_f(void) for (i = 0; i< sizeof(gd_t); i++) ((char *)gd)[i] = 0;
- mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(0);
- mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_4K);
- mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(13);
- mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_1M); mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G); mas3 = FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS, 0, MAS3_SW|MAS3_SR); mas7 = FSL_BOOKE_MAS7(CONFIG_SYS_CCSRBAR_PHYS);
@@ -49,6 +50,6 @@ void cpu_init_early_f(void) write_tlb(mas0, mas1, mas2, mas3, mas7);
init_laws();
- invalidate_tlb(0);
- invalidate_tlb(1); init_tlbs();
}
WBR, Sergei

On Aug 7, 2011, at 6:52 AM, Sergei Shtylyov wrote:
Hello.
On 05-08-2011 18:44, Kumar Gala wrote:
From: Poonam Aggrwalpoonam.aggrwal@freescale.com
For an IFC Erratum (A-003399) we will need to access IFC registers in cpu_init_early_f() so expand the TLB covering CCSR to 1M.
Since we need a TLB to cover 1M we move to using TLB1 array for all the early mappings so we can cover various sizes beyond 4k.
Additionally removed volatile from ccsr_virt declaration as its not needed for IO accessors
I don't see that change in the patch...
oops, will update commit message (its stale)
- k
Signed-off-by: Poonam Aggrwalpoonam.aggrwal@freescale.com Signed-off-by: Kumar Galagalak@kernel.crashing.org
arch/powerpc/cpu/mpc85xx/cpu_init_early.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)

On Aug 5, 2011, at 9:44 AM, Kumar Gala wrote:
Patch series adds support for P1010RDB, NAND support (for IFC on P1010) and various errata fixes for P1010.
V2 changes:
- re-work based on CCSRBAR cleanup patches
- white space fixes
- checkpatch cleanup fixes
- rework 'dummy' udelay in nand spl code
applied 1-7, with commit message fix to 85xx next
- k
participants (4)
-
Aggrwal Poonam-B10812
-
Kumar Gala
-
Sergei Shtylyov
-
Wolfgang Denk