]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-arm
authorTom Rini <trini@ti.com>
Sat, 22 Jun 2013 11:38:12 +0000 (07:38 -0400)
committerTom Rini <trini@ti.com>
Sat, 22 Jun 2013 11:38:12 +0000 (07:38 -0400)
358 files changed:
Makefile
README
arch/arm/include/asm/arch-am33xx/omap.h
arch/arm/include/asm/arch-omap4/omap.h
arch/arm/include/asm/arch-omap5/omap.h
arch/arm/include/asm/omap_common.h
arch/mips/include/asm/errno.h
arch/mips/include/asm/io.h
arch/powerpc/cpu/mpc8260/commproc.c
arch/powerpc/cpu/mpc8260/cpu.c
arch/powerpc/cpu/mpc8260/i2c.c
arch/powerpc/cpu/mpc8260/serial_smc.c
arch/powerpc/cpu/mpc8260/spi.c
arch/powerpc/cpu/mpc85xx/Makefile
arch/powerpc/cpu/mpc85xx/cmd_errata.c
arch/powerpc/cpu/mpc85xx/cpu.c
arch/powerpc/cpu/mpc85xx/cpu_init.c
arch/powerpc/cpu/mpc85xx/cpu_init_early.c
arch/powerpc/cpu/mpc85xx/fdt.c
arch/powerpc/cpu/mpc85xx/mpc8536_serdes.c
arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c
arch/powerpc/cpu/mpc85xx/mpc8548_serdes.c
arch/powerpc/cpu/mpc85xx/mpc8568_serdes.c
arch/powerpc/cpu/mpc85xx/mpc8569_serdes.c
arch/powerpc/cpu/mpc85xx/mpc8572_serdes.c
arch/powerpc/cpu/mpc85xx/p1010_serdes.c
arch/powerpc/cpu/mpc85xx/p1021_serdes.c
arch/powerpc/cpu/mpc85xx/p1022_serdes.c
arch/powerpc/cpu/mpc85xx/p1023_serdes.c
arch/powerpc/cpu/mpc85xx/p2020_serdes.c
arch/powerpc/cpu/mpc85xx/p2041_serdes.c
arch/powerpc/cpu/mpc85xx/p3041_serdes.c
arch/powerpc/cpu/mpc85xx/p4080_serdes.c
arch/powerpc/cpu/mpc85xx/p5020_serdes.c
arch/powerpc/cpu/mpc85xx/p5040_serdes.c
arch/powerpc/cpu/mpc85xx/start.S
arch/powerpc/cpu/mpc85xx/t1040_serdes.c
arch/powerpc/cpu/mpc85xx/u-boot-spl.lds
arch/powerpc/cpu/mpc85xx/u-boot.lds
arch/powerpc/cpu/mpc86xx/cpu.c
arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c
arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c
arch/powerpc/cpu/mpc8xx/cpu.c
arch/powerpc/cpu/mpc8xxx/fsl_ifc.c
arch/powerpc/cpu/mpc8xxx/srio.c
arch/powerpc/include/asm/8xx_immap.h
arch/powerpc/include/asm/config_mpc85xx.h
arch/powerpc/include/asm/fsl_ifc.h
arch/powerpc/include/asm/fsl_law.h
arch/powerpc/include/asm/immap_8260.h
arch/powerpc/include/asm/immap_85xx.h
board/ait/cam_enc_4xx/cam_enc_4xx.c
board/freescale/b4860qds/tlb.c
board/freescale/bsc9131rdb/Makefile
board/freescale/bsc9131rdb/README
board/freescale/bsc9131rdb/law.c
board/freescale/bsc9131rdb/spl_minimal.c [new file with mode: 0644]
board/freescale/bsc9131rdb/tlb.c
board/freescale/bsc9132qds/Makefile
board/freescale/bsc9132qds/bsc9132qds.c
board/freescale/bsc9132qds/law.c
board/freescale/bsc9132qds/spl_minimal.c [new file with mode: 0644]
board/freescale/bsc9132qds/tlb.c
board/freescale/common/Makefile
board/freescale/common/pixis.c
board/freescale/p1010rdb/Makefile
board/freescale/p1010rdb/spl_minimal.c [moved from nand_spl/board/freescale/p1010rdb/nand_boot.c with 95% similarity]
board/freescale/p1010rdb/tlb.c
board/freescale/p1023rdb/Makefile [new file with mode: 0644]
board/freescale/p1023rdb/ddr.c [new file with mode: 0644]
board/freescale/p1023rdb/law.c [moved from drivers/tpm/slb9635_i2c/compatibility.h with 51% similarity]
board/freescale/p1023rdb/p1023rdb.c [new file with mode: 0644]
board/freescale/p1023rdb/tlb.c [new file with mode: 0644]
board/freescale/t4qds/tlb.c
board/raspberrypi/rpi_b/rpi_b.c
board/ti/am335x/board.c
boards.cfg
common/Makefile
common/board_f.c
common/board_r.c
common/cmd_bootm.c
common/cmd_fitupd.c
common/cmd_immap.c
common/cmd_nand.c
common/cmd_onenand.c
common/cmd_sf.c
common/env_mmc.c
common/env_onenand.c
common/fdt_support.c
common/image-fdt.c
common/image-fit.c
common/image.c
common/lcd.c
common/main.c
common/spl/spl_mmc.c
common/usb_hub.c
common/usb_kbd.c
disk/part_efi.c
doc/README.srio-pcie-boot-corenet
doc/device-tree-bindings/video/simple-framebuffer.txt [new file with mode: 0644]
drivers/input/key_matrix.c
drivers/mmc/fsl_esdhc.c
drivers/mmc/mmc.c
drivers/mmc/sdhci.c
drivers/mtd/Makefile
drivers/mtd/cfi_mtd.c
drivers/mtd/mtdconcat.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdpart.c
drivers/mtd/nand/Makefile
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/bfin_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_ifc_nand.c
drivers/mtd/nand/fsl_ifc_spl.c [moved from nand_spl/nand_boot_fsl_ifc.c with 88% similarity]
drivers/mtd/nand/fsmc_nand.c
drivers/mtd/nand/jz4740_nand.c
drivers/mtd/nand/mpc5121_nfc.c
drivers/mtd/nand/mxc_nand.c
drivers/mtd/nand/mxs_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_ids.c
drivers/mtd/nand/nand_util.c
drivers/mtd/nand/ndfc.c
drivers/mtd/nand/nomadik.c
drivers/mtd/nand/omap_gpmc.c
drivers/mtd/nand/s3c2410_nand.c
drivers/mtd/nand/tegra_nand.c
drivers/mtd/nand/tegra_nand.h
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/onenand_bbt.c
drivers/mtd/spi/spansion.c
drivers/mtd/spi/spi_flash.c
drivers/mtd/spi/winbond.c
drivers/mtd/ubi/build.c
drivers/mtd/ubi/eba.c
drivers/mtd/ubi/io.c
drivers/mtd/ubi/kapi.c
drivers/mtd/ubi/misc.c
drivers/mtd/ubi/vtbl.c
drivers/pci/Makefile
drivers/pci/fsl_pci_init.c
drivers/spi/armada100_spi.c
drivers/spi/exynos_spi.c
drivers/spi/tegra114_spi.c
drivers/spi/tegra20_sflash.c
drivers/tpm/Makefile
drivers/tpm/tis_i2c.c
drivers/tpm/tpm.c [moved from drivers/tpm/slb9635_i2c/tpm.c with 63% similarity]
drivers/tpm/tpm_private.h [moved from drivers/tpm/slb9635_i2c/tpm.h with 71% similarity]
drivers/tpm/tpm_tis_i2c.c [moved from drivers/tpm/slb9635_i2c/tpm_tis_i2c.c with 59% similarity]
drivers/tpm/tpm_tis_lpc.c [moved from drivers/tpm/generic_lpc_tpm.c with 100% similarity]
drivers/usb/eth/asix.c
drivers/usb/gadget/Makefile
drivers/usb/gadget/composite.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/fotg210.c [new file with mode: 0644]
drivers/usb/gadget/gadget_chips.h
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/host/Makefile
drivers/usb/host/ehci-faraday.c [new file with mode: 0644]
drivers/usb/host/ehci-hcd.c
drivers/video/cfb_console.c
examples/standalone/mem_to_mem_idma2intr.c
fs/yaffs2/yaffs_mtdif.c
fs/yaffs2/yaffs_mtdif2.c
include/asm-generic/global_data.h
include/bootstage.h
include/common.h
include/commproc.h
include/configs/A3000.h
include/configs/APC405.h
include/configs/AR405.h
include/configs/ASH405.h
include/configs/B4860QDS.h
include/configs/BSC9131RDB.h
include/configs/BSC9132QDS.h
include/configs/CATcenter.h
include/configs/CPC45.h
include/configs/CPCI2DP.h
include/configs/CPCI405.h
include/configs/CPCI4052.h
include/configs/CPCI405AB.h
include/configs/CPCI405DT.h
include/configs/CPCIISER4.h
include/configs/CPU87.h
include/configs/CU824.h
include/configs/DU440.h
include/configs/ELPPC.h
include/configs/G2000.h
include/configs/HH405.h
include/configs/HIDDEN_DRAGON.h
include/configs/HWW1U1A.h
include/configs/JSE.h
include/configs/KAREF.h
include/configs/MERGERBOX.h
include/configs/METROBOX.h
include/configs/MIP405.h
include/configs/MOUSSE.h
include/configs/MPC8260ADS.h
include/configs/MPC8266ADS.h
include/configs/MPC8308RDB.h
include/configs/MPC8313ERDB.h
include/configs/MPC8315ERDB.h
include/configs/MPC8323ERDB.h
include/configs/MPC832XEMDS.h
include/configs/MPC8349EMDS.h
include/configs/MPC8349ITX.h
include/configs/MPC8360EMDS.h
include/configs/MPC8360ERDK.h
include/configs/MPC837XEMDS.h
include/configs/MPC837XERDB.h
include/configs/MPC8536DS.h
include/configs/MPC8540ADS.h
include/configs/MPC8541CDS.h
include/configs/MPC8544DS.h
include/configs/MPC8548CDS.h
include/configs/MPC8555CDS.h
include/configs/MPC8560ADS.h
include/configs/MPC8568MDS.h
include/configs/MPC8569MDS.h
include/configs/MPC8572DS.h
include/configs/MPC8610HPCD.h
include/configs/MPC8641HPCN.h
include/configs/MUSENKI.h
include/configs/MVBLM7.h
include/configs/MVBLUE.h
include/configs/OCRTC.h
include/configs/ORSG.h
include/configs/P1010RDB.h
include/configs/P1022DS.h
include/configs/P1023RDB.h [new file with mode: 0644]
include/configs/P1023RDS.h
include/configs/P1_P2_RDB.h
include/configs/P2020COME.h
include/configs/P2020DS.h
include/configs/P2041RDB.h
include/configs/P3041DS.h
include/configs/P4080DS.h
include/configs/P5020DS.h
include/configs/PCI405.h
include/configs/PIP405.h
include/configs/PLU405.h
include/configs/PM826.h
include/configs/PM828.h
include/configs/PMC405.h
include/configs/PMC405DE.h
include/configs/PMC440.h
include/configs/PN62.h
include/configs/PPChameleonEVB.h
include/configs/SIMPC8313.h
include/configs/Sandpoint8240.h
include/configs/Sandpoint8245.h
include/configs/TQM8272.h
include/configs/TQM834x.h
include/configs/VOH405.h
include/configs/W7OLMC.h
include/configs/W7OLMG.h
include/configs/WUH405.h
include/configs/a3m071.h
include/configs/adp-ag102.h
include/configs/alpr.h
include/configs/am335x_evm.h
include/configs/aria.h
include/configs/atc.h
include/configs/bamboo.h
include/configs/beaver.h
include/configs/bubinga.h
include/configs/canyonlands.h
include/configs/cardhu.h
include/configs/coreboot.h
include/configs/corenet_ds.h
include/configs/csb272.h
include/configs/csb472.h
include/configs/dalmore.h
include/configs/debris.h
include/configs/devkit8000.h
include/configs/eXalion.h
include/configs/ebony.h
include/configs/ep82xxm.h
include/configs/exynos5250-dt.h
include/configs/gdppc440etx.h
include/configs/icon.h
include/configs/igep0033.h
include/configs/intip.h
include/configs/katmai.h
include/configs/kilauea.h
include/configs/korat.h
include/configs/kvme080.h
include/configs/linkstation.h
include/configs/luan.h
include/configs/makalu.h
include/configs/mpc5121ads.h
include/configs/mpc8308_p1m.h
include/configs/ocotea.h
include/configs/p1_p2_rdb_pc.h
include/configs/p3p440.h
include/configs/paz00.h
include/configs/pcm051.h
include/configs/pcs440ep.h
include/configs/pm9263.h
include/configs/ppmc7xx.h
include/configs/rpi_b.h
include/configs/sbc405.h
include/configs/sbc8349.h
include/configs/sbc8548.h
include/configs/sbc8641d.h
include/configs/sc3.h
include/configs/seaboard.h
include/configs/sequoia.h
include/configs/socrates.h
include/configs/stxssa.h
include/configs/t3corp.h
include/configs/t4qds.h
include/configs/taihu.h
include/configs/taishan.h
include/configs/utx8245.h
include/configs/ve8313.h
include/configs/ventana.h
include/configs/vme8349.h
include/configs/walnut.h
include/configs/whistler.h
include/configs/xpedite1000.h
include/configs/xpedite517x.h
include/configs/xpedite520x.h
include/configs/xpedite537x.h
include/configs/xpedite550x.h
include/configs/yosemite.h
include/configs/yucca.h
include/environment.h
include/fdtdec.h
include/image.h
include/lcd.h
include/linux/mtd/bbm.h
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/string.h
include/linux/usb/ch9.h
include/mmc.h
include/mtd/mtd-abi.h [moved from include/linux/mtd/mtd-abi.h with 65% similarity]
include/nand.h
include/net.h
include/pci.h
include/spi.h
include/usb/fotg210.h [new file with mode: 0644]
include/usb/fusbh200.h [new file with mode: 0644]
lib/Makefile
lib/fdtdec.c
lib/string.c
nand_spl/board/freescale/p1010rdb/Makefile [deleted file]
net/net.c
test/image/test-fit.py [new file with mode: 0755]
tools/checkpatch.pl
tools/mkimage.h
tools/pblimage.c

index b1e5d5f52ea9dcca2e6751df9d7c0f851784469e..fdaddb93936bc0e4134d1c309ffeb4aae9b7554e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,9 +22,9 @@
 #
 
 VERSION = 2013
-PATCHLEVEL = 04
+PATCHLEVEL = 07
 SUBLEVEL =
-EXTRAVERSION =
+EXTRAVERSION = -rc1
 ifneq "$(SUBLEVEL)" ""
 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 else
diff --git a/README b/README
index b1b3e1788ec92d8ba088dab91175dfb1a44e2e26..e8359f847d5da916f75fd4467a7fe3e2e46bbc80 100644 (file)
--- a/README
+++ b/README
@@ -413,11 +413,22 @@ The following options need to be configured:
                See Freescale App Note 4493 for more information about
                this erratum.
 
+               CONFIG_A003399_NOR_WORKAROUND
+               Enables a workaround for IFC erratum A003399. It is only
+               requred during NOR boot.
+
                CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY
 
                This is the value to write into CCSR offset 0x18600
                according to the A004510 workaround.
 
+               CONFIG_SYS_FSL_DSP_M2_RAM_ADDR
+               This value denotes start offset of M2 memory
+               which is directly connected to the DSP core.
+
+               CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT
+               This value denotes start offset of DSP CCSR space.
+
 - Generic CPU options:
                CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN
 
@@ -1209,7 +1220,23 @@ The following options need to be configured:
                        If this option is set, the driver enables cache flush.
 
 - TPM Support:
-               CONFIG_GENERIC_LPC_TPM
+               CONFIG_TPM
+               Support TPM devices.
+
+               CONFIG_TPM_TIS_I2C
+               Support for i2c bus TPM devices. Only one device
+               per system is supported at this time.
+
+                       CONFIG_TPM_TIS_I2C_BUS_NUMBER
+                       Define the the i2c bus number for the TPM device
+
+                       CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS
+                       Define the TPM's address on the i2c bus
+
+                       CONFIG_TPM_TIS_I2C_BURST_LIMITATION
+                       Define the burst count bytes upper limit
+
+               CONFIG_TPM_TIS_LPC
                Support for generic parallel port TPM devices. Only one device
                per system is supported at this time.
 
@@ -1245,6 +1272,9 @@ The following options need to be configured:
                CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
                txfilltuning field in the EHCI controller on reset.
 
+               CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum
+               interval for usb hub power-on delay.(minimum 100msec)
+
 - USB Device:
                Define the below if you wish to use the USB console.
                Once firmware is rebuilt from a serial console issue the
@@ -2916,12 +2946,30 @@ FIT uImage format:
                Address, size and partition on the MMC to load U-Boot from
                when the MMC is being used in raw mode.
 
+               CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR
+               Sector to load kernel uImage from when MMC is being
+               used in raw mode (for Falcon mode)
+
+               CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
+               CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS
+               Sector and number of sectors to load kernel argument
+               parameters from when MMC is being used in raw mode
+               (for falcon mode)
+
                CONFIG_SPL_FAT_SUPPORT
                Support for fs/fat/libfat.o in SPL binary
 
                CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
                Filename to read to load U-Boot when reading from FAT
 
+               CONFIG_SPL_FAT_LOAD_KERNEL_NAME
+               Filename to read to load kernel uImage when reading
+               from FAT (for Falcon mode)
+
+               CONFIG_SPL_FAT_LOAD_ARGS_NAME
+               Filename to read to load kernel argument parameters
+               when reading from FAT (for Falcon mode)
+
                CONFIG_SPL_MPC83XX_WAIT_FOR_NAND
                Set this for NAND SPL on PPC mpc83xx targets, so that
                start.S waits for the rest of the SPL to load before
@@ -2985,6 +3033,14 @@ FIT uImage format:
                CONFIG_SPL_LIBGENERIC_SUPPORT
                Support for lib/libgeneric.o in SPL binary
 
+               CONFIG_SPL_ENV_SUPPORT
+               Support for the environment operating in SPL binary
+
+               CONFIG_SPL_NET_SUPPORT
+               Support for the net/libnet.o in SPL binary.
+               It conflicts with SPL env from storage medium specified by
+               CONFIG_ENV_IS_xxx but CONFIG_ENV_IS_NOWHERE
+
                CONFIG_SPL_PAD_TO
                Image offset to which the SPL should be padded before appending
                the SPL payload. By default, this is defined as
@@ -3611,6 +3667,57 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface.
          You will probably want to define these to avoid a really noisy system
          when storing the env in UBI.
 
+- CONFIG_ENV_IS_IN_MMC:
+
+       Define this if you have an MMC device which you want to use for the
+       environment.
+
+       - CONFIG_SYS_MMC_ENV_DEV:
+
+         Specifies which MMC device the environment is stored in.
+
+       - CONFIG_SYS_MMC_ENV_PART (optional):
+
+         Specifies which MMC partition the environment is stored in. If not
+         set, defaults to partition 0, the user area. Common values might be
+         1 (first MMC boot partition), 2 (second MMC boot partition).
+
+       - CONFIG_ENV_OFFSET:
+       - CONFIG_ENV_SIZE:
+
+         These two #defines specify the offset and size of the environment
+         area within the specified MMC device.
+
+         If offset is positive (the usual case), it is treated as relative to
+         the start of the MMC partition. If offset is negative, it is treated
+         as relative to the end of the MMC partition. This can be useful if
+         your board may be fitted with different MMC devices, which have
+         different sizes for the MMC partitions, and you always want the
+         environment placed at the very end of the partition, to leave the
+         maximum possible space before it, to store other data.
+
+         These two values are in units of bytes, but must be aligned to an
+         MMC sector boundary.
+
+       - CONFIG_ENV_OFFSET_REDUND (optional):
+
+         Specifies a second storage area, of CONFIG_ENV_SIZE size, used to
+         hold a redundant copy of the environment data. This provides a
+         valid backup copy in case the other copy is corrupted, e.g. due
+         to a power failure during a "saveenv" operation.
+
+         This value may also be positive or negative; this is handled in the
+         same way as CONFIG_ENV_OFFSET.
+
+         This value is also in units of bytes, but must also be aligned to
+         an MMC sector boundary.
+
+       - CONFIG_ENV_SIZE_REDUND (optional):
+
+         This value need not be set, even when CONFIG_ENV_OFFSET_REDUND is
+         set. If this value is set, it must be set to the same value as
+         CONFIG_ENV_SIZE.
+
 - CONFIG_SYS_SPI_INIT_OFFSET
 
        Defines offset to the initial SPI buffer area in DPRAM. The
@@ -3864,6 +3971,9 @@ Low Level (hardware related) configuration options:
                a second time.  Useful for platforms that are pre-booted
                by coreboot or similar.
 
+- CONFIG_PCI_INDIRECT_BRIDGE:
+               Enable support for indirect PCI bridges.
+
 - CONFIG_SYS_SRIO:
                Chip has SRIO or not
 
@@ -3873,6 +3983,9 @@ Low Level (hardware related) configuration options:
 - CONFIG_SRIO2:
                Board has SRIO 2 port available
 
+- CONFIG_SRIO_PCIE_BOOT_MASTER
+               Board can support master function for Boot from SRIO and PCIE
+
 - CONFIG_SYS_SRIOn_MEM_VIRT:
                Virtual Address of SRIO port 'n' memory region
 
@@ -3983,6 +4096,11 @@ Low Level (hardware related) configuration options:
                that is executed before the actual U-Boot. E.g. when
                compiling a NAND SPL.
 
+- CONFIG_SYS_MPC85XX_NO_RESETVEC
+               Only for 85xx systems. If this variable is specified, the section
+               .resetvec is not kept and the section .bootpg is placed in the
+               previous 4k of the .text section.
+
 - CONFIG_ARCH_MAP_SYSMEM
                Generally U-Boot (and in particular the md command) uses
                effective address. It is therefore not necessary to regard
index db151596439e9d68880c2b788447b81ccc5027e9..e7576c110631c971aae8f0ab831de7d517dc7283 100644 (file)
 #ifdef CONFIG_AM33XX
 #define NON_SECURE_SRAM_START  0x402F0400
 #define NON_SECURE_SRAM_END    0x40310000
+#define SRAM_SCRATCH_SPACE_ADDR        0x4030C000
 #elif defined(CONFIG_TI814X)
 #define NON_SECURE_SRAM_START  0x40300000
 #define NON_SECURE_SRAM_END    0x40320000
+#define SRAM_SCRATCH_SPACE_ADDR        0x4031B800
 #endif
 #endif
index 66afd924927a4bdcf8a1a3ed43d18b95b7c0e33b..9fd00ff2aa431502eb92608fb3706047063758fe 100644 (file)
@@ -127,6 +127,7 @@ struct s32ktimer {
  */
 #define NON_SECURE_SRAM_START  0x40304000
 #define NON_SECURE_SRAM_END    0x4030E000      /* Not inclusive */
+#define SRAM_SCRATCH_SPACE_ADDR        NON_SECURE_SRAM_START
 /* base address for indirect vectors (internal boot mode) */
 #define SRAM_ROM_VECT_BASE     0x4030D000
 
index 817c1ff27fc599b10811d743e5e260557b0c2390..5e6d82e51f106e5362667a7e25125d3dd89df944 100644 (file)
@@ -176,6 +176,7 @@ struct s32ktimer {
 #define NON_SECURE_SRAM_START  0x40300000
 #define NON_SECURE_SRAM_END    0x40320000      /* Not inclusive */
 #endif
+#define SRAM_SCRATCH_SPACE_ADDR        NON_SECURE_SRAM_START
 
 /* base address for indirect vectors (internal boot mode) */
 #define SRAM_ROM_VECT_BASE     0x4031F000
index 787e614ecb0da881f18028971c7f258453f25a74..0dbe81b59c64c1d9c0b1b0a6077b569e68e7e28f 100644 (file)
@@ -642,7 +642,6 @@ static inline u8 is_omap54xx(void)
 /*
  * SRAM scratch space entries
  */
-#define SRAM_SCRATCH_SPACE_ADDR                NON_SECURE_SRAM_START
 #define OMAP_SRAM_SCRATCH_OMAP_REV     SRAM_SCRATCH_SPACE_ADDR
 #define OMAP_SRAM_SCRATCH_EMIF_SIZE    (SRAM_SCRATCH_SPACE_ADDR + 0x4)
 #define OMAP_SRAM_SCRATCH_EMIF_T_NUM   (SRAM_SCRATCH_SPACE_ADDR + 0xC)
index 1665a63a8120bba59b888d871b0c8b5fb2bfa61b..4c82b503d92ffabcc6eb558a50ae5d6dba8a5f7c 100644 (file)
@@ -1,143 +1 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1995, 1999, 2001, 2002 by Ralf Baechle
- */
-#ifndef _ASM_MIPS_ERRNO_H
-#define _ASM_MIPS_ERRNO_H
-
-/*
- * These first 34 error codes are from Linux 2.6, <asm-generic/errno-base.h>
- */
-#define        EPERM            1      /* Operation not permitted */
-#define        ENOENT           2      /* No such file or directory */
-#define        ESRCH            3      /* No such process */
-#define        EINTR            4      /* Interrupted system call */
-#define        EIO              5      /* I/O error */
-#define        ENXIO            6      /* No such device or address */
-#define        E2BIG            7      /* Argument list too long */
-#define        ENOEXEC          8      /* Exec format error */
-#define        EBADF            9      /* Bad file number */
-#define        ECHILD          10      /* No child processes */
-#define        EAGAIN          11      /* Try again */
-#define        ENOMEM          12      /* Out of memory */
-#define        EACCES          13      /* Permission denied */
-#define        EFAULT          14      /* Bad address */
-#define        ENOTBLK         15      /* Block device required */
-#define        EBUSY           16      /* Device or resource busy */
-#define        EEXIST          17      /* File exists */
-#define        EXDEV           18      /* Cross-device link */
-#define        ENODEV          19      /* No such device */
-#define        ENOTDIR         20      /* Not a directory */
-#define        EISDIR          21      /* Is a directory */
-#define        EINVAL          22      /* Invalid argument */
-#define        ENFILE          23      /* File table overflow */
-#define        EMFILE          24      /* Too many open files */
-#define        ENOTTY          25      /* Not a typewriter */
-#define        ETXTBSY         26      /* Text file busy */
-#define        EFBIG           27      /* File too large */
-#define        ENOSPC          28      /* No space left on device */
-#define        ESPIPE          29      /* Illegal seek */
-#define        EROFS           30      /* Read-only file system */
-#define        EMLINK          31      /* Too many links */
-#define        EPIPE           32      /* Broken pipe */
-#define        EDOM            33      /* Math argument out of domain of func */
-#define        ERANGE          34      /* Math result not representable */
-
-/*
- * These error numbers are intended to be MIPS ABI compatible
- */
-#define        ENOMSG          35      /* No message of desired type */
-#define        EIDRM           36      /* Identifier removed */
-#define        ECHRNG          37      /* Channel number out of range */
-#define        EL2NSYNC        38      /* Level 2 not synchronized */
-#define        EL3HLT          39      /* Level 3 halted */
-#define        EL3RST          40      /* Level 3 reset */
-#define        ELNRNG          41      /* Link number out of range */
-#define        EUNATCH         42      /* Protocol driver not attached */
-#define        ENOCSI          43      /* No CSI structure available */
-#define        EL2HLT          44      /* Level 2 halted */
-#define        EDEADLK         45      /* Resource deadlock would occur */
-#define        ENOLCK          46      /* No record locks available */
-#define        EBADE           50      /* Invalid exchange */
-#define        EBADR           51      /* Invalid request descriptor */
-#define        EXFULL          52      /* Exchange full */
-#define        ENOANO          53      /* No anode */
-#define        EBADRQC         54      /* Invalid request code */
-#define        EBADSLT         55      /* Invalid slot */
-#define        EDEADLOCK       56      /* File locking deadlock error */
-#define        EBFONT          59      /* Bad font file format */
-#define        ENOSTR          60      /* Device not a stream */
-#define        ENODATA         61      /* No data available */
-#define        ETIME           62      /* Timer expired */
-#define        ENOSR           63      /* Out of streams resources */
-#define        ENONET          64      /* Machine is not on the network */
-#define        ENOPKG          65      /* Package not installed */
-#define        EREMOTE         66      /* Object is remote */
-#define        ENOLINK         67      /* Link has been severed */
-#define        EADV            68      /* Advertise error */
-#define        ESRMNT          69      /* Srmount error */
-#define        ECOMM           70      /* Communication error on send */
-#define        EPROTO          71      /* Protocol error */
-#define        EDOTDOT         73      /* RFS specific error */
-#define        EMULTIHOP       74      /* Multihop attempted */
-#define        EBADMSG         77      /* Not a data message */
-#define        ENAMETOOLONG    78      /* File name too long */
-#define        EOVERFLOW       79      /* Value too large for defined data type */
-#define        ENOTUNIQ        80      /* Name not unique on network */
-#define        EBADFD          81      /* File descriptor in bad state */
-#define        EREMCHG         82      /* Remote address changed */
-#define        ELIBACC         83      /* Can not access a needed shared library */
-#define        ELIBBAD         84      /* Accessing a corrupted shared library */
-#define        ELIBSCN         85      /* .lib section in a.out corrupted */
-#define        ELIBMAX         86      /* Attempting to link in too many shared libraries */
-#define        ELIBEXEC        87      /* Cannot exec a shared library directly */
-#define        EILSEQ          88      /* Illegal byte sequence */
-#define        ENOSYS          89      /* Function not implemented */
-#define        ELOOP           90      /* Too many symbolic links encountered */
-#define        ERESTART        91      /* Interrupted system call should be restarted */
-#define        ESTRPIPE        92      /* Streams pipe error */
-#define        ENOTEMPTY       93      /* Directory not empty */
-#define        EUSERS          94      /* Too many users */
-#define        ENOTSOCK        95      /* Socket operation on non-socket */
-#define        EDESTADDRREQ    96      /* Destination address required */
-#define        EMSGSIZE        97      /* Message too long */
-#define        EPROTOTYPE      98      /* Protocol wrong type for socket */
-#define        ENOPROTOOPT     99      /* Protocol not available */
-#define        EPROTONOSUPPORT 120     /* Protocol not supported */
-#define        ESOCKTNOSUPPORT 121     /* Socket type not supported */
-#define        EOPNOTSUPP      122     /* Operation not supported on transport endpoint */
-#define        EPFNOSUPPORT    123     /* Protocol family not supported */
-#define        EAFNOSUPPORT    124     /* Address family not supported by protocol */
-#define        EADDRINUSE      125     /* Address already in use */
-#define        EADDRNOTAVAIL   126     /* Cannot assign requested address */
-#define        ENETDOWN        127     /* Network is down */
-#define        ENETUNREACH     128     /* Network is unreachable */
-#define        ENETRESET       129     /* Network dropped connection because of reset */
-#define        ECONNABORTED    130     /* Software caused connection abort */
-#define        ECONNRESET      131     /* Connection reset by peer */
-#define        ENOBUFS         132     /* No buffer space available */
-#define        EISCONN         133     /* Transport endpoint is already connected */
-#define        ENOTCONN        134     /* Transport endpoint is not connected */
-#define        EUCLEAN         135     /* Structure needs cleaning */
-#define        ENOTNAM         137     /* Not a XENIX named type file */
-#define        ENAVAIL         138     /* No XENIX semaphores available */
-#define        EISNAM          139     /* Is a named type file */
-#define        EREMOTEIO       140     /* Remote I/O error */
-#define EINIT          141     /* Reserved */
-#define EREMDEV                142     /* Error 142 */
-#define        ESHUTDOWN       143     /* Cannot send after transport endpoint shutdown */
-#define        ETOOMANYREFS    144     /* Too many references: cannot splice */
-#define        ETIMEDOUT       145     /* Connection timed out */
-#define        ECONNREFUSED    146     /* Connection refused */
-#define        EHOSTDOWN       147     /* Host is down */
-#define        EHOSTUNREACH    148     /* No route to host */
-#define        EWOULDBLOCK     EAGAIN  /* Operation would block */
-#define        EALREADY        149     /* Operation already in progress */
-#define        EINPROGRESS     150     /* Operation now in progress */
-#define        ESTALE          151     /* Stale NFS file handle */
-#define ECANCELED      158     /* AIO operation canceled */
-
-#endif /* _ASM_MIPS_ERRNO_H */
+#include <asm-generic/errno.h>
index 3864c804c0500b2322fe25fb0ca296f728130fee..50a882ca5a2df44036ab92d469162a5a9899e5aa 100644 (file)
@@ -184,19 +184,19 @@ extern void iounmap(void *addr);
  * 24-31 on SNI.
  * XXX more SNI hacks.
  */
-#define readb(addr) (*(volatile unsigned char *)(addr))
-#define readw(addr) __ioswab16((*(volatile unsigned short *)(addr)))
-#define readl(addr) __ioswab32((*(volatile unsigned int *)(addr)))
-#define __raw_readb readb
-#define __raw_readw readw
-#define __raw_readl readl
-
-#define writeb(b,addr) (*(volatile unsigned char *)(addr)) = (b)
-#define writew(b,addr) (*(volatile unsigned short *)(addr)) = (__ioswab16(b))
-#define writel(b,addr) (*(volatile unsigned int *)(addr)) = (__ioswab32(b))
-#define __raw_writeb writeb
-#define __raw_writew writew
-#define __raw_writel writel
+#define __raw_readb(addr) (*(volatile unsigned char *)(addr))
+#define __raw_readw(addr) (*(volatile unsigned short *)(addr))
+#define __raw_readl(addr) (*(volatile unsigned int *)(addr))
+#define readb(addr) __raw_readb((addr))
+#define readw(addr) __ioswab16(__raw_readw((addr)))
+#define readl(addr) __ioswab32(__raw_readl((addr)))
+
+#define __raw_writeb(b, addr) (*(volatile unsigned char *)(addr)) = (b)
+#define __raw_writew(b, addr) (*(volatile unsigned short *)(addr)) = (b)
+#define __raw_writel(b, addr) (*(volatile unsigned int *)(addr)) = (b)
+#define writeb(b, addr) __raw_writeb((b), (addr))
+#define writew(b, addr) __raw_writew(__ioswab16(b), (addr))
+#define writel(b, addr) __raw_writel(__ioswab32(b), (addr))
 
 #define memset_io(a,b,c)       memset((void *)(a),(b),(c))
 #define memcpy_fromio(a,b,c)   memcpy((a),(void *)(b),(c))
index 22cef3e9839e96101b9bba3212e7068bb6d93acc..484bd177451c3a36b1ba5c7c30152fe3c8275b0f 100644 (file)
@@ -43,7 +43,7 @@ m8260_cpm_reset(void)
        } while ((immr->im_cpm.cp_cpcr & CPM_CR_FLG) && ++count < 1000000);
 
 #ifdef CONFIG_HARD_I2C
-       *((unsigned short*)(&immr->im_dprambase[PROFF_I2C_BASE])) = 0;
+       immr->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)] = 0;
 #endif
 }
 
index f8bc5a9834b861b54e25f9391ddea6d08cd8949c..22e1a23a2adcedae47df34f5a1a67f4bec8dae40 100644 (file)
@@ -106,7 +106,7 @@ int checkcpu (void)
         * in the mask.
         */
        m = immr & (IMMR_PARTNUM_MSK | IMMR_MASKNUM_MSK);
-       k = *((ushort *) & immap->im_dprambase[PROFF_REVNUM]);
+       k = immap->im_dprambase16[PROFF_REVNUM / sizeof(u16)];
 
        switch (m) {
        case 0x0000:
index b720b1fb882b1b4261939a18479a08e2b2243a2d..e2341e9c39c46cff86594d7f4e5ad15f8846d84a 100644 (file)
@@ -221,14 +221,14 @@ void i2c_init(int speed, int slaveadd)
        i2c_init_board();
 #endif
 
-       dpaddr = *((unsigned short *) (&immap->im_dprambase[PROFF_I2C_BASE]));
+       dpaddr = immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)];
        if (dpaddr == 0) {
                /* need to allocate dual port ram */
                dpaddr = m8260_cpm_dpalloc(64 +
                                        (NUM_RX_BDS * sizeof(I2C_BD)) +
                                        (NUM_TX_BDS * sizeof(I2C_BD)) +
                                        MAX_TX_SPACE, 64);
-               *((unsigned short *)(&immap->im_dprambase[PROFF_I2C_BASE])) =
+               immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)] =
                        dpaddr;
        }
 
@@ -305,7 +305,7 @@ void i2c_newio(i2c_state_t *state)
 
        debug("[I2C] i2c_newio\n");
 
-       dpaddr = *((unsigned short *)(&immap->im_dprambase[PROFF_I2C_BASE]));
+       dpaddr = immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)];
        iip = (iic_t *)&immap->im_dprambase[dpaddr];
        state->rx_idx = 0;
        state->tx_idx = 0;
@@ -480,7 +480,7 @@ int i2c_doio(i2c_state_t *state)
                return I2CERR_QUEUE_EMPTY;
        }
 
-       dpaddr = *((unsigned short *)(&immap->im_dprambase[PROFF_I2C_BASE]));
+       dpaddr = immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)];
        iip = (iic_t *)&immap->im_dprambase[dpaddr];
        iip->iic_rbptr = iip->iic_rbase;
        iip->iic_tbptr = iip->iic_tbase;
index feba1f63d260b3a1465e6a2f742b7db23df94a8e..9410e4c3b2bf7bf2ce57598deec529b87419b48d 100644 (file)
@@ -105,7 +105,7 @@ static int mpc8260_smc_serial_init(void)
        /* initialize pointers to SMC */
 
        sp = (smc_t *) &(im->im_smc[SMC_INDEX]);
-       *(ushort *)(&im->im_dprambase[PROFF_SMC_BASE]) = PROFF_SMC;
+       im->im_dprambase16[PROFF_SMC_BASE / sizeof(u16)] = PROFF_SMC;
        up = (smc_uart_t *)&im->im_dprambase[PROFF_SMC];
 
        /* Disable transmitter/receiver. */
@@ -331,7 +331,7 @@ kgdb_serial_init (void)
        /* initialize pointers to SMC */
 
        sp = (smc_t *) &(im->im_smc[KGDB_SMC_INDEX]);
-       *(ushort *)(&im->im_dprambase[KGDB_PROFF_SMC_BASE]) = KGDB_PROFF_SMC;
+       im->im_dprambase16[KGDB_PROFF_SMC_BASE / sizeof(u16)] = KGDB_PROFF_SMC;
        up = (smc_uart_t *)&im->im_dprambase[KGDB_PROFF_SMC];
 
        /* Disable transmitter/receiver. */
index dc98ea73f2673d64c2f36050e18282f889378306..01b492e8e48a1d8c9dfe1f929aa88dfee16fd021 100644 (file)
@@ -146,7 +146,7 @@ void spi_init_f (void)
        immr = (immap_t *)  CONFIG_SYS_IMMR;
        cp   = (cpm8260_t *) &immr->im_cpm;
 
-       *(ushort *)(&immr->im_dprambase[PROFF_SPI_BASE]) = PROFF_SPI;
+       immr->im_dprambase16[PROFF_SPI_BASE / sizeof(u16)] = PROFF_SPI;
        spi  = (spi_t *)&immr->im_dprambase[PROFF_SPI];
 
 /* 1 */
index 2318064a4786fbb31a408dba45c2ebd651f554ce..4669883a3caf54bd89cd5b089e3b055e39e3265c 100644 (file)
@@ -73,6 +73,7 @@ COBJS-$(CONFIG_P1014) += ddr-gen3.o
 COBJS-$(CONFIG_P1020)  += ddr-gen3.o
 COBJS-$(CONFIG_P1021)  += ddr-gen3.o
 COBJS-$(CONFIG_P1022)  += ddr-gen3.o
+COBJS-$(CONFIG_P1023)  += ddr-gen3.o
 COBJS-$(CONFIG_P1024)  += ddr-gen3.o
 COBJS-$(CONFIG_P1025)  += ddr-gen3.o
 COBJS-$(CONFIG_P2010)  += ddr-gen3.o
index 422782ca8f209e764dc9d9c9c103609dba593a1e..a7ed87769e4cfbf19ce766ba75e4d10062f9a1b2 100644 (file)
@@ -257,6 +257,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #endif
 #ifdef CONFIG_SYS_FSL_ERRATUM_USB14
        puts("Work-around for Erratum USB14 enabled\n");
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006593
+       puts("Work-around for Erratum A006593 enabled\n");
 #endif
        return 0;
 }
index 6ce483e17ae46eb69a29101f676af2c9f7420fe4..fbee753903fde00b21e1562f9929c43f78855c09 100644 (file)
@@ -121,16 +121,16 @@ int checkcpu (void)
        switch(ver) {
        case PVR_VER_E500_V1:
        case PVR_VER_E500_V2:
-               puts("E500");
+               puts("e500");
                break;
        case PVR_VER_E500MC:
-               puts("E500MC");
+               puts("e500mc");
                break;
        case PVR_VER_E5500:
-               puts("E5500");
+               puts("e5500");
                break;
        case PVR_VER_E6500:
-               puts("E6500");
+               puts("e6500");
                break;
        default:
                puts("Unknown");
@@ -341,7 +341,7 @@ phys_size_t initdram(int board_type)
 #if defined(CONFIG_SPD_EEPROM) || defined(CONFIG_DDR_SPD)
        return fsl_ddr_sdram_size();
 #else
-       return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
+       return (phys_size_t)CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
 #endif
 }
 #else /* CONFIG_SYS_RAMBOOT */
index 4067f053757a66cf21e2868ffd0808d40593153f..3c8f59cdb363ce151572bcd00a75d8b765cbcd4c 100644 (file)
@@ -172,6 +172,9 @@ static void enable_cpc(void)
 #ifdef CONFIG_SYS_FSL_ERRATUM_CPC_A003
                setbits_be32(&cpc->cpchdbcr0, CPC_HDBCR0_DATA_ECC_SCRUB_DIS);
 #endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006593
+               setbits_be32(&cpc->cpchdbcr0, 1 << (31 - 21));
+#endif
 
                out_be32(&cpc->cpccsr0, CPC_CSR0_CE | CPC_CSR0_PE);
                /* Read back to sync write */
@@ -564,7 +567,7 @@ skip_l2:
 
 #ifdef CONFIG_SYS_SRIO
        srio_init();
-#ifdef CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER 
+#ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
        char *s = getenv("bootmaster");
        if (s) {
                if (!strcmp(s, "SRIO1")) {
index 234fde48465bfcedb2eefb22ff4625f2a9a64cd3..837c034be90e5fecf9bfc9946b18ace5c05e8cd0 100644 (file)
@@ -25,7 +25,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT)
+#ifdef CONFIG_A003399_NOR_WORKAROUND
 void setup_ifc(void)
 {
        struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
@@ -99,7 +99,7 @@ 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)
+#ifdef CONFIG_A003399_NOR_WORKAROUND
        ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR;
        u32  *dst, *src;
        void (*setup_ifc_sram)(void);
@@ -138,7 +138,7 @@ void cpu_init_early_f(void)
  * 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)
+#ifdef CONFIG_A003399_NOR_WORKAROUND
 #define SRAM_BASE_ADDR (0x00000000)
        /* TLB for SRAM */
        mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(9);
@@ -180,5 +180,9 @@ void cpu_init_early_f(void)
 
        invalidate_tlb(1);
 
+#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_NAND_SPL)
+       disable_tlb(CONFIG_SYS_PPC_E500_DEBUG_TLB);
+#endif
+
        init_tlbs();
 }
index 288f7b28603641470d2464d8bea4f9397dd6685f..bb95f3d5008ce1a355e19b97afc1f9f1706e1f86 100644 (file)
@@ -663,7 +663,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 #ifdef CONFIG_FSL_CORENET
        do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-1.0",
                "clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
-       do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-2",
+       do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-2.0",
                "clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
        do_fixup_by_compat_u32(blob, "fsl,mpic",
                "clock-frequency", get_bus_freq(0)/2, 1);
index 6dadeb8cabc7d9fc3a3d9c133d63a47b959b0a07..ec96e81ed5ecf5c5c35b00e3dd5b8be485230724 100644 (file)
@@ -228,7 +228,7 @@ void fsl_serdes_init(void)
                break;
        }
 
-       if (srds1_io_sel > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds1_io_sel >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[SRDS1_IO_SEL] = %d\n", srds1_io_sel);
                return;
        }
@@ -237,7 +237,7 @@ void fsl_serdes_init(void)
                serdes1_prtcl_map |= (1 << lane_prtcl);
        }
 
-       if (srds2_io_sel > ARRAY_SIZE(serdes2_cfg_tbl)) {
+       if (srds2_io_sel >= ARRAY_SIZE(serdes2_cfg_tbl)) {
                printf("Invalid PORDEVSR[SRDS2_IO_SEL] = %d\n", srds2_io_sel);
                return;
        }
index 7c490972a55f9388c0f4027d31dfd0b8ee8fccf4..3483366e6d08da1116c7f925d696ac6e90ab6339 100644 (file)
@@ -68,7 +68,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
@@ -77,7 +77,7 @@ void fsl_serdes_init(void)
                serdes1_prtcl_map |= (1 << lane_prtcl);
        }
 
-       if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index 76288cd568e648eeb9ea4f76fcb7022e9af779d3..c9eea15d3cd4a097602b419fb03302a926fdbfc7 100644 (file)
@@ -53,7 +53,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL] = %x\n", srds1_cfg);
 
-       if (srds1_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds1_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL] = %d\n", srds1_cfg);
                return ;
        }
index 258263739f2770045f3d49f6e178ffa8f0022e47..49a02906202def52cbfe4e7f5152f7ce7f5c8249 100644 (file)
@@ -53,7 +53,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index f480c2609d6b629ac4a8e1cc2a1003ef3582cea9..7af6aff25957ee94639d15cb325e6277ec0f9a1b 100644 (file)
@@ -62,7 +62,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index 2ff5d9a060afc74016eac18f6e7241974d179c3b..fcccb52b68281c97b9e86bfbd89f9db807cddcca 100644 (file)
@@ -57,7 +57,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index e8a0387ca0aab0ca08855938c692e9f606b36a26..1f7dba0d6f7a57b4882d563c90e9e453cf6dd031 100644 (file)
@@ -54,7 +54,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
@@ -63,7 +63,7 @@ void fsl_serdes_init(void)
                serdes1_prtcl_map |= (1 << lane_prtcl);
        }
 
-       if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index 1849c1642cf284d94187f8fe8021a67ba1e59058..d6d2696e0702a7cca22e35d80d1a9c559470a213 100644 (file)
@@ -73,7 +73,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index e4c9c2210054a9346efe9059b6a42cb745aca487..ed4992053c031cf1c82a4117f325d927a1a9887c 100644 (file)
@@ -93,7 +93,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
@@ -102,7 +102,7 @@ void fsl_serdes_init(void)
                serdes1_prtcl_map |= (1 << lane_prtcl);
        }
 
-       if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index c8ab5d6f339a7aea12d20571a646e867f0a730a4..0b4ae90c242707be12580c2123197faded35d25a 100644 (file)
@@ -41,7 +41,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index 389ff6bd2804bebb916b0b0b5b000965b936e412..01af3337063b6e660f156c36529c89a24d3b9967 100644 (file)
@@ -61,7 +61,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index eec4ffe516ad8acdf189524649b5009e4ccf9922..87335c9444d7766c068f8e5c1d2771ca7dd3f94f 100644 (file)
@@ -90,7 +90,7 @@ int is_serdes_prtcl_valid(u32 prtcl)
        u32 svr = get_svr();
        u32 ver = SVR_SOC_VER(svr);
 
-       if (prtcl > ARRAY_SIZE(serdes_cfg_tbl))
+       if (prtcl >= ARRAY_SIZE(serdes_cfg_tbl))
                return 0;
 
        /* P2040[e] does not support XAUI */
index fba9ff245fdb5755a1edbd71bedba498acb2825e..a36dcd542697080df9871ccdc5116e6949f56888 100644 (file)
@@ -139,7 +139,7 @@ enum srds_prtcl serdes_get_prtcl(int cfg, int lane)
 int is_serdes_prtcl_valid(u32 prtcl) {
        int i;
 
-       if (prtcl > ARRAY_SIZE(serdes_cfg_tbl))
+       if (prtcl >= ARRAY_SIZE(serdes_cfg_tbl))
                return 0;
 
        for (i = 0; i < SRDS_MAX_LANES; i++) {
index 87bd7952930d87ed93e5c555e16c4bae5c188365..94ec445037248fa438b7e59ae2088580244221ad 100644 (file)
@@ -86,7 +86,7 @@ enum srds_prtcl serdes_get_prtcl(int cfg, int lane)
 int is_serdes_prtcl_valid(u32 prtcl) {
        int i;
 
-       if (prtcl > ARRAY_SIZE(serdes_cfg_tbl))
+       if (prtcl >= ARRAY_SIZE(serdes_cfg_tbl))
                return 0;
 
        for (i = 0; i < SRDS_MAX_LANES; i++) {
index fba9ff245fdb5755a1edbd71bedba498acb2825e..a36dcd542697080df9871ccdc5116e6949f56888 100644 (file)
@@ -139,7 +139,7 @@ enum srds_prtcl serdes_get_prtcl(int cfg, int lane)
 int is_serdes_prtcl_valid(u32 prtcl) {
        int i;
 
-       if (prtcl > ARRAY_SIZE(serdes_cfg_tbl))
+       if (prtcl >= ARRAY_SIZE(serdes_cfg_tbl))
                return 0;
 
        for (i = 0; i < SRDS_MAX_LANES; i++) {
index 890b88e4e337233e575923de2f8c2f98f57e1463..d646e8561c46583dceb8c5c86c8b9c969159ee14 100644 (file)
@@ -105,7 +105,7 @@ int is_serdes_prtcl_valid(u32 prtcl)
 {
        int i;
 
-       if (prtcl > ARRAY_SIZE(serdes_cfg_tbl))
+       if (prtcl >= ARRAY_SIZE(serdes_cfg_tbl))
                return 0;
 
        for (i = 0; i < SRDS_MAX_LANES; i++) {
index 4f0480b768960e9d0913bd1ae6fba8d36e920476..2657982a45b9917a32adcc2a87fb8516a3464000 100644 (file)
@@ -1795,7 +1795,7 @@ clear_bss:
        stw     r0,0(r3)
        addi    r3,r3,4
        cmplw   0,r3,r4
-       bne     5b
+       blt     5b
 6:
 
        mr      r3,r9           /* Init Data pointer            */
index 8261e034767d77a023a406b5b76720832b0cf0ab..19add9f96c0a7f6705e0bb363e43330a40d59ce3 100644 (file)
@@ -81,7 +81,7 @@ int is_serdes_prtcl_valid(int serdes, u32 prtcl)
 {
        int i;
 
-       if (prtcl > (ARRAY_SIZE(serdes_cfg_tbl[serdes])))
+       if (prtcl >= ARRAY_SIZE(serdes_cfg_tbl[serdes]))
                return 0;
 
        for (i = 0; i < SRDS_MAX_LANES; i++) {
index f2b7bffdabefeda1d6862df45aae7c6f3c6918e6..20284ed5a59569789242eee37759e02ede6281d5 100644 (file)
 #include "config.h"    /* CONFIG_BOARDDIR */
 
 OUTPUT_ARCH(powerpc)
+#ifdef CONFIG_SYS_MPC85XX_NO_RESETVEC
+PHDRS
+{
+       text PT_LOAD;
+       bss PT_LOAD;
+}
+#endif
 SECTIONS
 {
        . = CONFIG_SPL_TEXT_BASE;
@@ -60,7 +67,7 @@ SECTIONS
 #if defined(CONFIG_FSL_IFC) /* Restrict bootpg at 4K boundry for IFC */
        .bootpg ADDR(.text) + 0x1000 :
        {
-               start.o (.bootpg)
+               arch/powerpc/cpu/mpc85xx/start.o (.bootpg)
        }
 #define RESET_VECTOR_OFFSET 0x1ffc /* IFC has 8K sram */
 #elif defined(CONFIG_FSL_ELBC)
@@ -68,9 +75,16 @@ SECTIONS
 #else
 #error unknown NAND controller
 #endif
+#ifdef CONFIG_SYS_MPC85XX_NO_RESETVEC
+       .bootpg ADDR(.text) - 0x1000 :
+       {
+               KEEP(*(.bootpg))
+       } :text = 0xffff
+#else
        .resetvec ADDR(.text) + RESET_VECTOR_OFFSET : {
                KEEP(*(.resetvec))
        } = 0xffff
+#endif
 
        /*
         * Make sure that the bss segment isn't linked at 0x0, otherwise its
@@ -78,10 +92,12 @@ SECTIONS
         */
        . |= 0x10;
 
+       . = ALIGN(4);
        __bss_start = .;
        .bss : {
                *(.sbss*)
                *(.bss*)
        }
+       . = ALIGN(4);
        __bss_end = .;
 }
index 0503dce5ae4345edf6221b8d169720c05c5231e3..2643563d4dadcce2f5b9f08f4a7864ba10896ea4 100644 (file)
@@ -95,6 +95,13 @@ SECTIONS
   . = ALIGN(256);
   __init_end = .;
 
+#ifdef CONFIG_SYS_MPC85XX_NO_RESETVEC
+  .bootpg ADDR(.text) - 0x1000 :
+  {
+    KEEP(arch/powerpc/cpu/mpc85xx/start.o (.bootpg))
+  } :text = 0xffff
+  . = ADDR(.text) + 0x80000;
+#else
   .bootpg RESET_VECTOR_ADDRESS - 0xffc :
   {
     arch/powerpc/cpu/mpc85xx/start.o   (.bootpg)
@@ -116,6 +123,7 @@ SECTIONS
    */
 #if (RESET_VECTOR_ADDRESS == 0xfffffffc)
   . |= 0x10;
+#endif
 #endif
 
   __bss_start = .;
index c553415b555a5a122b5f4966d97c9915ad2efc1e..5ed3eb24f2393df830dacfdfcbc28391b988ee1b 100644 (file)
@@ -78,7 +78,7 @@ checkcpu(void)
        major = PVR_E600_MAJ(pvr);
        minor = PVR_E600_MIN(pvr);
 
-       printf("E600 Core %d", (msscr0 & 0x20) ? 1 : 0 );
+       printf("e600 Core %d", (msscr0 & 0x20) ? 1 : 0);
        if (gur->pordevsr & MPC86xx_PORDEVSR_CORE1TE)
                puts("\n    Core1Translation Enabled");
        debug(" (MSSCR0=%x, PORDEVSR=%x)", msscr0, gur->pordevsr);
index 0dc1975bf9b271445d08cc56797a9016f93ce269..0342e34654e2a5cabb580d686e623f693b588e5a 100644 (file)
@@ -64,7 +64,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
@@ -73,7 +73,7 @@ void fsl_serdes_init(void)
                serdes1_prtcl_map |= (1 << lane_prtcl);
        }
 
-       if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index 3ae9069f1b81418b96821b936c8459b6e5c27f28..21c5ddbfacc983aaef7615f6003020ac50b3e2c0 100644 (file)
@@ -73,7 +73,7 @@ void fsl_serdes_init(void)
 
        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 
-       if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
@@ -82,7 +82,7 @@ void fsl_serdes_init(void)
                serdes1_prtcl_map |= (1 << lane_prtcl);
        }
 
-       if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) {
+       if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
                return;
        }
index b6b733d77fd356b6231c958f2da326c3468c3855..dc33eb3d108fbffca80a63760c128ff78178000a 100644 (file)
@@ -78,7 +78,8 @@ static int check_CPU (long clock, uint pvr, uint immr)
        if ((pvr >> 16) != 0x0050)
                return -1;
 
-       k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+       k = (immr << 16) |
+               immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)];
        m = 0;
        suf = "";
 
@@ -194,7 +195,8 @@ static int check_CPU (long clock, uint pvr, uint immr)
        if ((pvr >> 16) != 0x0050)
                return -1;
 
-       k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+       k = (immr << 16) |
+               immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)];
        m = 0;
 
        switch (k) {
@@ -253,7 +255,8 @@ static int check_CPU (long clock, uint pvr, uint immr)
        if ((pvr >> 16) != 0x0050)
                return -1;
 
-       k = (immr << 16) | in_be16((ushort *)&immap->im_cpm.cp_dparam[0xB0]);
+       k = (immr << 16) |
+               in_be16(&immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)]);
        m = 0;
 
        switch (k) {
@@ -312,7 +315,8 @@ static int check_CPU (long clock, uint pvr, uint immr)
        if ((pvr >> 16) != 0x0050)
                return -1;
 
-       k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
+       k = (immr << 16) |
+               immap->im_cpm.cp_dparam16[PROFF_REVNUM / sizeof(u16)];
        m = 0;
 
        switch (k) {
index 56b319f5d4bfe28ec7c10709d0b2a44bd1ffa432..4e8a4415f5c0f4b0c00c6d30b8f0e9f61c4833d8 100644 (file)
@@ -26,7 +26,7 @@ void print_ifc_regs(void)
        int i, j;
 
        printf("IFC Controller Registers\n");
-       for (i = 0; i < FSL_IFC_BANK_COUNT; i++) {
+       for (i = 0; i < CONFIG_SYS_FSL_IFC_BANK_COUNT; i++) {
                printf("CSPR%d:0x%08X\tAMASK%d:0x%08X\tCSOR%d:0x%08X\n",
                        i, get_ifc_cspr(i), i, get_ifc_amask(i),
                        i, get_ifc_csor(i));
@@ -43,7 +43,7 @@ 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)
+#ifndef CONFIG_A003399_NOR_WORKAROUND
 #ifdef CONFIG_SYS_CSPR0_EXT
        set_ifc_cspr_ext(IFC_CS0, CONFIG_SYS_CSPR0_EXT);
 #endif
@@ -94,4 +94,60 @@ void init_early_memctl_regs(void)
        set_ifc_amask(IFC_CS3, CONFIG_SYS_AMASK3);
        set_ifc_csor(IFC_CS3, CONFIG_SYS_CSOR3);
 #endif
+
+#ifdef CONFIG_SYS_CSPR4_EXT
+       set_ifc_cspr_ext(IFC_CS4, CONFIG_SYS_CSPR4_EXT);
+#endif
+#if defined(CONFIG_SYS_CSPR4) && defined(CONFIG_SYS_CSOR4)
+       set_ifc_ftim(IFC_CS4, IFC_FTIM0, CONFIG_SYS_CS4_FTIM0);
+       set_ifc_ftim(IFC_CS4, IFC_FTIM1, CONFIG_SYS_CS4_FTIM1);
+       set_ifc_ftim(IFC_CS4, IFC_FTIM2, CONFIG_SYS_CS4_FTIM2);
+       set_ifc_ftim(IFC_CS4, IFC_FTIM3, CONFIG_SYS_CS4_FTIM3);
+
+       set_ifc_cspr(IFC_CS4, CONFIG_SYS_CSPR4);
+       set_ifc_amask(IFC_CS4, CONFIG_SYS_AMASK4);
+       set_ifc_csor(IFC_CS4, CONFIG_SYS_CSOR4);
+#endif
+
+#ifdef CONFIG_SYS_CSPR5_EXT
+       set_ifc_cspr_ext(IFC_CS5, CONFIG_SYS_CSPR5_EXT);
+#endif
+#if defined(CONFIG_SYS_CSPR5) && defined(CONFIG_SYS_CSOR5)
+       set_ifc_ftim(IFC_CS5, IFC_FTIM0, CONFIG_SYS_CS5_FTIM0);
+       set_ifc_ftim(IFC_CS5, IFC_FTIM1, CONFIG_SYS_CS5_FTIM1);
+       set_ifc_ftim(IFC_CS5, IFC_FTIM2, CONFIG_SYS_CS5_FTIM2);
+       set_ifc_ftim(IFC_CS5, IFC_FTIM3, CONFIG_SYS_CS5_FTIM3);
+
+       set_ifc_cspr(IFC_CS5, CONFIG_SYS_CSPR5);
+       set_ifc_amask(IFC_CS5, CONFIG_SYS_AMASK5);
+       set_ifc_csor(IFC_CS5, CONFIG_SYS_CSOR5);
+#endif
+
+#ifdef CONFIG_SYS_CSPR6_EXT
+       set_ifc_cspr_ext(IFC_CS6, CONFIG_SYS_CSPR6_EXT);
+#endif
+#if defined(CONFIG_SYS_CSPR6) && defined(CONFIG_SYS_CSOR6)
+       set_ifc_ftim(IFC_CS6, IFC_FTIM0, CONFIG_SYS_CS6_FTIM0);
+       set_ifc_ftim(IFC_CS6, IFC_FTIM1, CONFIG_SYS_CS6_FTIM1);
+       set_ifc_ftim(IFC_CS6, IFC_FTIM2, CONFIG_SYS_CS6_FTIM2);
+       set_ifc_ftim(IFC_CS6, IFC_FTIM3, CONFIG_SYS_CS6_FTIM3);
+
+       set_ifc_cspr(IFC_CS6, CONFIG_SYS_CSPR6);
+       set_ifc_amask(IFC_CS6, CONFIG_SYS_AMASK6);
+       set_ifc_csor(IFC_CS6, CONFIG_SYS_CSOR6);
+#endif
+
+#ifdef CONFIG_SYS_CSPR7_EXT
+       set_ifc_cspr_ext(IFC_CS7, CONFIG_SYS_CSPR7_EXT);
+#endif
+#if defined(CONFIG_SYS_CSPR7) && defined(CONFIG_SYS_CSOR7)
+       set_ifc_ftim(IFC_CS7, IFC_FTIM0, CONFIG_SYS_CS7_FTIM0);
+       set_ifc_ftim(IFC_CS7, IFC_FTIM1, CONFIG_SYS_CS7_FTIM1);
+       set_ifc_ftim(IFC_CS7, IFC_FTIM2, CONFIG_SYS_CS7_FTIM2);
+       set_ifc_ftim(IFC_CS7, IFC_FTIM3, CONFIG_SYS_CS7_FTIM3);
+
+       set_ifc_cspr(IFC_CS7, CONFIG_SYS_CSPR7);
+       set_ifc_amask(IFC_CS7, CONFIG_SYS_AMASK7);
+       set_ifc_csor(IFC_CS7, CONFIG_SYS_CSOR7);
+#endif
 }
index 6e6f7dcc3fd927a96383b6b457620f82d1d49296..90d1065deb23eb591703226952436d9e09e7824d 100644 (file)
@@ -24,7 +24,7 @@
 #include <asm/fsl_srio.h>
 #include <asm/errno.h>
 
-#ifdef CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
+#ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
 #define SRIO_PORT_ACCEPT_ALL 0x10000001
 #define SRIO_IB_ATMU_AR 0x80f55000
 #define SRIO_OB_ATMU_AR_MAINT 0x80077000
@@ -299,7 +299,7 @@ void srio_init(void)
        }
 }
 
-#ifdef CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
+#ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
 void srio_boot_master(int port)
 {
        struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR;
index 40679cb2b068e6f228fa8f7ecd47cfddcb952784..01129ed4f0e745aeea3bd56808abaf0b787ddbc7 100644 (file)
@@ -485,7 +485,12 @@ typedef struct comm_proc {
         * Some processors don't have all of it populated.
         */
        u_char  cp_dpmem[0x1C00];       /* BD / Data / ucode */
-       u_char  cp_dparam[0x400];       /* Parameter RAM */
+
+       /* Parameter RAM */
+       union {
+               u_char  cp_dparam[0x400];
+               u16     cp_dparam16[0x200];
+       };
 } cpm8xx_t;
 
 /* Internal memory map.
index 1009a31b33954693fc2de55a5636dee22f9ea2a1..1d46b1423012a242a6f6752390207f06c8e36a82 100644 (file)
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_NUM_DDR_CONTROLLERS     1
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT  4
 #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_CPU_A003999
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
-#define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS  2
 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5
 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
-#define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS  2
 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5
 #define CONFIG_SYS_P4080_ERRATUM_SERDES_A005
 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
-#define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS  2
 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5
 #define CONFIG_SYS_FSL_ERRATUM_USB14
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
-#define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS  2
 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5
 #define CONFIG_TSECV2
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
 #define CONFIG_NUM_DDR_CONTROLLERS     1
+#define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR 0xb0000000
+#define CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT     0xff600000
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT  3
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_NAND_FSL_IFC
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_TSECV2
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
 #define CONFIG_NUM_DDR_CONTROLLERS     2
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT  3
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_NAND_FSL_IFC
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
 #define CONFIG_SYS_NUM_FMAN            2
 #define CONFIG_SYS_FSL_DDR_VER         FSL_DDR_VER_4_7
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT  8
 #define CONFIG_SYS_FMAN_V3
 #define CONFIG_SYS_FM_MURAM_SIZE       0x60000
 #define CONFIG_SYS_FSL_TBCLK_DIV       16
 #define CONFIG_SYS_FSL_ERRATUM_A004468
 #define CONFIG_SYS_FSL_ERRATUM_A_004934
 #define CONFIG_SYS_FSL_ERRATUM_A005871
+#define CONFIG_SYS_FSL_ERRATUM_A006593
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xfe000000
 #define CONFIG_SYS_FSL_PCI_VER_3_X
 
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
 #define CONFIG_SYS_NUM_FMAN            1
 #define CONFIG_SYS_FSL_DDR_VER         FSL_DDR_VER_4_7
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT  4
 #define CONFIG_SYS_FMAN_V3
 #define CONFIG_SYS_FM_MURAM_SIZE       0x60000
 #define CONFIG_SYS_FSL_TBCLK_DIV       16
 #define CONFIG_SYS_FSL_USB1_PHY_ENABLE
 #define CONFIG_SYS_FSL_ERRATUM_A_004934
 #define CONFIG_SYS_FSL_ERRATUM_A005871
+#define CONFIG_SYS_FSL_ERRATUM_A006593
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xfe000000
 
 #ifdef CONFIG_PPC_B4860
index ba41b73cc0389b149e4c13fdc1d176a31088a9c1..3baf4ccbae4577ecd16924059d37e3cd1c9a7f08 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef __ASM_PPC_FSL_IFC_H
 #define __ASM_PPC_FSL_IFC_H
 
+#ifdef CONFIG_FSL_IFC
 #include <config.h>
 #include <common.h>
 
@@ -798,13 +799,15 @@ extern void init_early_memctl_regs(void);
 #define set_ifc_ftim(i, j, v) \
                        (out_be32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j], v))
 
-#define FSL_IFC_BANK_COUNT     4
-
 enum ifc_chip_sel {
        IFC_CS0,
        IFC_CS1,
        IFC_CS2,
        IFC_CS3,
+       IFC_CS4,
+       IFC_CS5,
+       IFC_CS6,
+       IFC_CS7,
 };
 
 enum ifc_ftims {
@@ -907,6 +910,49 @@ struct fsl_ifc_gpcm {
        u32 res4[0x1F3];
 };
 
+#ifdef CONFIG_SYS_FSL_IFC_BANK_COUNT
+#if (CONFIG_SYS_FSL_IFC_BANK_COUNT <= 8)
+#define IFC_CSPR_REG_LEN       148
+#define IFC_AMASK_REG_LEN      144
+#define IFC_CSOR_REG_LEN       144
+#define IFC_FTIM_REG_LEN       576
+
+#define IFC_CSPR_USED_LEN      sizeof(struct fsl_ifc_cspr) * \
+                                       CONFIG_SYS_FSL_IFC_BANK_COUNT
+#define IFC_AMASK_USED_LEN     sizeof(struct fsl_ifc_amask) * \
+                                       CONFIG_SYS_FSL_IFC_BANK_COUNT
+#define IFC_CSOR_USED_LEN      sizeof(struct fsl_ifc_csor) * \
+                                       CONFIG_SYS_FSL_IFC_BANK_COUNT
+#define IFC_FTIM_USED_LEN      sizeof(struct fsl_ifc_ftim) * \
+                                       CONFIG_SYS_FSL_IFC_BANK_COUNT
+#else
+#error IFC BANK count not vaild
+#endif
+#else
+#error IFC BANK count not defined
+#endif
+
+struct fsl_ifc_cspr {
+       u32 cspr_ext;
+       u32 cspr;
+       u32 res;
+};
+
+struct fsl_ifc_amask {
+       u32 amask;
+       u32 res[0x2];
+};
+
+struct fsl_ifc_csor {
+       u32 csor;
+       u32 csor_ext;
+       u32 res;
+};
+
+struct fsl_ifc_ftim {
+       u32 ftim[4];
+       u32 res[0x8];
+};
 
 /*
  * IFC Controller Registers
@@ -914,44 +960,30 @@ struct fsl_ifc_gpcm {
 struct fsl_ifc {
        u32 ifc_rev;
        u32 res1[0x2];
-       struct {
-               u32 cspr_ext;
-               u32 cspr;
-               u32 res2;
-       } cspr_cs[FSL_IFC_BANK_COUNT];
-       u32 res3[0x19];
-       struct {
-               u32 amask;
-               u32 res4[0x2];
-       } amask_cs[FSL_IFC_BANK_COUNT];
-       u32 res5[0x17];
-       struct {
-               u32 csor_ext;
-               u32 csor;
-               u32 res6;
-       } csor_cs[FSL_IFC_BANK_COUNT];
-       u32 res7[0x19];
-       struct {
-               u32 ftim[4];
-               u32 res8[0x8];
-       } ftim_cs[FSL_IFC_BANK_COUNT];
-       u32 res9[0x60];
+       struct fsl_ifc_cspr cspr_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT];
+       u8 res2[IFC_CSPR_REG_LEN - IFC_CSPR_USED_LEN];
+       struct fsl_ifc_amask amask_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT];
+       u8 res3[IFC_AMASK_REG_LEN - IFC_AMASK_USED_LEN];
+       struct fsl_ifc_csor csor_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT];
+       u8 res4[IFC_CSOR_REG_LEN - IFC_CSOR_USED_LEN];
+       struct fsl_ifc_ftim ftim_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT];
+       u8 res5[IFC_FTIM_REG_LEN - IFC_FTIM_USED_LEN];
        u32 rb_stat;
-       u32 res10[0x2];
+       u32 res6[0x2];
        u32 ifc_gcr;
-       u32 res11[0x2];
+       u32 res7[0x2];
        u32 cm_evter_stat;
-       u32 res12[0x2];
+       u32 res8[0x2];
        u32 cm_evter_en;
-       u32 res13[0x2];
+       u32 res9[0x2];
        u32 cm_evter_intr_en;
-       u32 res14[0x2];
+       u32 res10[0x2];
        u32 cm_erattr0;
        u32 cm_erattr1;
-       u32 res15[0x2];
+       u32 res11[0x2];
        u32 ifc_ccr;
        u32 ifc_csr;
-       u32 res16[0x2EB];
+       u32 res12[0x2EB];
        struct fsl_ifc_nand ifc_nand;
        struct fsl_ifc_nor ifc_nor;
        struct fsl_ifc_gpcm ifc_gpcm;
@@ -961,6 +993,7 @@ struct fsl_ifc {
 #undef CSPR_MSEL_NOR
 #define CSPR_MSEL_NOR  CSPR_MSEL_GPCM
 #endif
+#endif /* CONFIG_FSL_IFC */
 
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_PPC_FSL_IFC_H */
index 90b264d35e7292c505cc06a9a08e837639edeb7c..bea1636768d04ec12bba2d7f2a368c71a9d33618 100644 (file)
@@ -82,11 +82,16 @@ enum law_trgt_if {
 #ifndef CONFIG_MPC8641
        LAW_TRGT_IF_PCIE_1 = 0x02,
 #endif
+#if defined(CONFIG_BSC9131)
+       LAW_TRGT_IF_OCN_DSP = 0x03,
+#else
 #if !defined(CONFIG_MPC8572) && !defined(CONFIG_P2020)
        LAW_TRGT_IF_PCIE_3 = 0x03,
+#endif
 #endif
        LAW_TRGT_IF_LBC = 0x04,
        LAW_TRGT_IF_CCSR = 0x08,
+       LAW_TRGT_IF_DSP_CCSR = 0x09,
        LAW_TRGT_IF_DDR_INTRLV = 0x0b,
        LAW_TRGT_IF_RIO = 0x0c,
        LAW_TRGT_IF_RIO_2 = 0x0d,
index 4974ae56fcbb418acaa43bd37a0d377b9a8e2f79..c7021a7095b7e224ba60fede5c969717c7ca5e87 100644 (file)
@@ -526,13 +526,18 @@ typedef struct immap {
        /* Some references are into the unique and known dpram spaces,
         * others are from the generic base.
         */
-#define im_dprambase   im_dpram1
-       u_char          im_dpram1[16*1024];
-       char            res1[16*1024];
-       u_char          im_dpram2[4*1024];
-       char            res2[8*1024];
-       u_char          im_dpram3[4*1024];
-       char            res3[16*1024];
+       union {
+               struct {
+                       u_char          im_dpram1[16 * 1024];
+                       char            res1[16 * 1024];
+                       u_char          im_dpram2[4 * 1024];
+                       char            res2[8 * 1024];
+                       u_char          im_dpram3[4 * 1024];
+                       char            res3[16 * 1024];
+               };
+               u8      im_dprambase[64 * 1024];
+               u16     im_dprambase16[32 * 1024];
+       };
 
        sysconf8260_t   im_siu_conf;    /* SIU Configuration */
        memctl8260_t    im_memctl;      /* Memory Controller */
index 4052037f56f92d5851c52e6f097f971a28ff31b7..db70d048f5bed5d6f7501b4b1ed766d1eae67d44 100644 (file)
@@ -1839,11 +1839,13 @@ typedef struct ccsr_gur {
 #define FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT  11
 #define FSL_CORENET2_RCWSR4_SRDS4_PRTCL                0x000000f8
 #define FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT  3
+#define FSL_CORENET_RCWSR6_BOOT_LOC    0x0f800000
 #elif defined(CONFIG_PPC_B4860) || defined(CONFIG_PPC_B4420)
 #define FSL_CORENET2_RCWSR4_SRDS1_PRTCL        0xfe000000
 #define FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT  25
 #define FSL_CORENET2_RCWSR4_SRDS2_PRTCL        0x00ff0000
 #define FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT  16
+#define FSL_CORENET_RCWSR6_BOOT_LOC    0x0f800000
 #elif defined(CONFIG_PPC_T1040)
 #define FSL_CORENET2_RCWSR4_SRDS1_PRTCL        0xff000000
 #define FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT  24
@@ -2160,7 +2162,7 @@ typedef struct ccsr_gur {
        u32     porbmsr;        /* POR boot mode status */
 #define MPC85xx_PORBMSR_HA             0x00070000
 #define MPC85xx_PORBMSR_HA_SHIFT       16
-#define MPC85XX_PORBMSR_ROMLOC_SHIFT   24
+#define MPC85xx_PORBMSR_ROMLOC_SHIFT   24
 #define PORBMSR_ROMLOC_SPI     0x6
 #define PORBMSR_ROMLOC_SDHC    0x7
 #define PORBMSR_ROMLOC_NAND_2K 0x9
index 644c445693b740936d43e8d1c6e5cfec5451ab03..80a78221b1f8be7d72cabe4dc3ded88e8b492dac 100644 (file)
@@ -120,7 +120,7 @@ int board_eth_init(bd_t *bis)
 #ifdef CONFIG_NAND_DAVINCI
 static int
 davinci_std_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
-                                  uint8_t *buf, int page)
+                                  uint8_t *buf, int oob_required, int page)
 {
        struct nand_chip *this = mtd->priv;
        int i, eccsize = chip->ecc.size;
@@ -167,8 +167,9 @@ davinci_std_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
        return 0;
 }
 
-static void davinci_std_write_page_syndrome(struct mtd_info *mtd,
-                                   struct nand_chip *chip, const uint8_t *buf)
+static int davinci_std_write_page_syndrome(struct mtd_info *mtd,
+                                   struct nand_chip *chip, const uint8_t *buf,
+                                   int oob_required)
 {
        unsigned char davinci_ecc_buf[NAND_MAX_OOBSIZE];
        struct nand_chip *this = mtd->priv;
@@ -218,6 +219,7 @@ static void davinci_std_write_page_syndrome(struct mtd_info *mtd,
        i = mtd->oobsize - (oob - chip->oob_poi);
        if (i)
                chip->write_buf(mtd, oob, i);
+       return 0;
 }
 
 static int davinci_std_write_oob_syndrome(struct mtd_info *mtd,
@@ -239,7 +241,7 @@ static int davinci_std_write_oob_syndrome(struct mtd_info *mtd,
 }
 
 static int davinci_std_read_oob_syndrome(struct mtd_info *mtd,
-       struct nand_chip *chip, int page, int sndcmd)
+       struct nand_chip *chip, int page)
 {
        struct nand_chip *this = mtd->priv;
        uint8_t *buf = chip->oob_poi;
@@ -249,7 +251,7 @@ static int davinci_std_read_oob_syndrome(struct mtd_info *mtd,
 
        chip->read_buf(mtd, bufpoi, mtd->oobsize);
 
-       return 1;
+       return 0;
 }
 
 static void nand_dm365evm_select_chip(struct mtd_info *mtd, int chip)
index 29cc41bfaf0e14528d270ae7703ae0993e8e8e0e..1416f98dc6e13bbe5ee982c51a92279384eeef90 100644 (file)
@@ -52,6 +52,15 @@ struct fsl_e_tlb_entry tlb_table[] = {
        SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_ADDR, CONFIG_SYS_INIT_L3_ADDR,
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 0, BOOKE_PAGESZ_1M, 1),
+#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
+       /*
+        * SRIO_PCIE_BOOT-SLAVE. When slave boot, the address of the
+        * space is at 0xfff00000, it covered the 0xfffff000.
+        */
+       SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR,
+                     CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G,
+                     0, 0, BOOKE_PAGESZ_1M, 1),
 #else
        SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000,
                      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
@@ -137,6 +146,16 @@ struct fsl_e_tlb_entry tlb_table[] = {
                MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                      0, 16, BOOKE_PAGESZ_256M, 1),
 #endif
+#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
+       /*
+        * SRIO_PCIE_BOOT-SLAVE. 1M space from 0xffe00000 for
+        * fetching ucode and ENV from master
+        */
+       SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR,
+                     CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_G,
+                     0, 17, BOOKE_PAGESZ_1M, 1),
+#endif
 };
 
 int num_tlb_entries = ARRAY_SIZE(tlb_table);
index 6f4cb268f1d4ffb70542e9f2f86e228742c7213b..2e829ad2e225930b5f5ad3d5b02f02c9c1f2c2f1 100644 (file)
@@ -24,12 +24,28 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+
+COBJS-y        += spl_minimal.o tlb.o law.o
+
+else
+
 COBJS-y        += $(BOARD).o
 COBJS-y        += ddr.o
 COBJS-y        += law.o
 COBJS-y        += tlb.o
 #COBJS-y               += bsc9131rdb_mux.o
 
+endif
+
 SRCS   := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS-y))
 SOBJS  := $(addprefix $(obj),$(SOBJS))
index 065faa378d1ff1ee3a17297d464cde498eedad6a..4902b98ba1250c79757638c8875dee9646339911 100644 (file)
@@ -89,10 +89,14 @@ NAND boot
 Building U-boot
 --------------
 To build the u-boot for BSC9131RDB:
-1. NAND Flash
+1. NAND Flash with sysclk 66MHz(J16 on RDB closed, default)
        make BSC9131RDB_NAND
-2. SPI Flash
+2. NAND Flash with sysclk 100MHz(J16 on RDB open)
+       make BSC9131RDB_NAND_SYSCLK100
+3. SPI Flash with sysclk 66MHz(J16 on RDB closed, default)
        make BSC9131RDB_SPIFLASH
+4. SPI Flash with sysclk 100MHz(J16 on RDB open)
+       make BSC9131RDB_SPIFLASH_SYSCLK100
 
 Memory map
 -----------
@@ -107,6 +111,16 @@ Memory map
  0xFF70_0000   0xFF7F_FFFF     PA CCSR                 1M
  0xFF80_0000   0xFFFF_FFFF     Boot Page & NAND Buffer 8M
 
+DDR Memory map
+---------------
+ 0x0000_0000   0x36FF_FFFF     Memory passed onto Linux
+ 0x3700_0000   0x37FF_FFFF     PowerPC-DSP shared control area
+ 0x3800_0000   0x4FFF_FFFF     DSP Private area
+
+ Out of 880M, passed onto Linux, 1hugetlb page of 256M is reserved for
+ data communcation between PowerPC and DSP core.
+ Rest is PowerPC private area.
+
 Flashing Images
 ---------------
 To place a new u-boot image in the NAND flash and then boot
index 201c1470795d1b1dc754ef5d9f36aa39bae454bd..0432780f947417235e74f11b3660a4e6068e777d 100644 (file)
 
 struct law_entry law_table[] = {
        SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_IFC),
+       SET_LAW(CONFIG_SYS_FSL_DSP_CCSRBAR_PHYS, LAW_SIZE_1M,
+               LAW_TRGT_IF_DSP_CCSR),
+       SET_LAW(CONFIG_SYS_FSL_DSP_M2_RAM_ADDR, LAW_SIZE_16M,
+               LAW_TRGT_IF_OCN_DSP),
 };
 
 int num_law_entries = ARRAY_SIZE(law_table);
diff --git a/board/freescale/bsc9131rdb/spl_minimal.c b/board/freescale/bsc9131rdb/spl_minimal.c
new file mode 100644 (file)
index 0000000..301115e
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2013 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 <ns16550.h>
+#include <asm/io.h>
+#include <nand.h>
+#include <linux/compiler.h>
+#include <asm/fsl_law.h>
+#include <asm/fsl_ddr_sdram.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Fixed sdram init -- doesn't use serial presence detect.
+ */
+static void sdram_init(void)
+{
+       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
+
+       __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds);
+       __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config);
+#if CONFIG_CHIP_SELECTS_PER_CTRL > 1
+       __raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds);
+       __raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config);
+#endif
+       __raw_writel(CONFIG_SYS_DDR_TIMING_3_800, &ddr->timing_cfg_3);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_0_800, &ddr->timing_cfg_0);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_1_800, &ddr->timing_cfg_1);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_2_800, &ddr->timing_cfg_2);
+
+       __raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2);
+       __raw_writel(CONFIG_SYS_DDR_MODE_1_800, &ddr->sdram_mode);
+       __raw_writel(CONFIG_SYS_DDR_MODE_2_800, &ddr->sdram_mode_2);
+
+       __raw_writel(CONFIG_SYS_DDR_INTERVAL_800, &ddr->sdram_interval);
+       __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init);
+       __raw_writel(CONFIG_SYS_DDR_CLK_CTRL_800, &ddr->sdram_clk_cntl);
+
+       __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_800, &ddr->ddr_wrlvl_cntl);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5);
+       __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl);
+
+       /* Set, but do not enable the memory */
+       __raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN, &ddr->sdram_cfg);
+
+       asm volatile("sync;isync");
+       udelay(500);
+
+       /* 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;
+       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;
+       gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio;
+
+       NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1,
+                    gd->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_SPL_RELOC_STACK, 0, CONFIG_SPL_RELOC_TEXT_BASE);
+}
+
+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++);
+}
index 5b68f4af3cc443be4f9b59cbbc879ac77e13830d..c05a556a3dcc69ba36ebbdfea96ed95e02c6f943 100644 (file)
@@ -44,15 +44,26 @@ struct fsl_e_tlb_entry tlb_table[] = {
        /* 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),
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 0, BOOKE_PAGESZ_4K, 1),
+#ifdef CONFIG_SPL_NAND_MINIMAL
+       SET_TLB_ENTRY(1, 0xffffe000, 0xffffe000,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 10, BOOKE_PAGESZ_4K, 1),
+#endif
 
        /* *I*G* - CCSRBAR (PA) */
        SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS,
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 1, BOOKE_PAGESZ_1M, 1),
 
-#if defined(CONFIG_SYS_RAMBOOT)
+       /* CCSRBAR (DSP) */
+       SET_TLB_ENTRY(1, CONFIG_SYS_FSL_DSP_CCSRBAR,
+                     CONFIG_SYS_FSL_DSP_CCSRBAR_PHYS,
+                     MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 2, BOOKE_PAGESZ_1M, 1),
+
+#if  defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
        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),
index 267400becb14a2be4ccd82d49f7338bf6cbd45e5..72b19174bf691d4462a2df9b59b524f2a12ab69e 100644 (file)
@@ -24,11 +24,28 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+
+COBJS-y        += spl_minimal.o tlb.o law.o
+
+else
+
+
 COBJS-y        += $(BOARD).o
 COBJS-y        += ddr.o
 COBJS-y        += law.o
 COBJS-y        += tlb.o
 
+endif
+
 SRCS   := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS-y))
 SOBJS  := $(addprefix $(obj),$(SOBJS))
index 6e1b55816f21c21885ab48faf22d4d87eddd5520..ddc9d0a16a4fb8f63a049f0d4a297bb753494b7f 100644 (file)
@@ -258,7 +258,7 @@ int misc_init_r(void)
        u8 val;
        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
        u32 porbmsr = in_be32(&gur->porbmsr);
-       u32 romloc = (porbmsr >> MPC85XX_PORBMSR_ROMLOC_SHIFT) & 0xf;
+       u32 romloc = (porbmsr >> MPC85xx_PORBMSR_ROMLOC_SHIFT) & 0xf;
 
        /*Configure 1588 clock-in source from RF Card*/
        val = QIXIS_READ_I2C(brdcfg[5]);
@@ -360,7 +360,7 @@ void ft_board_setup(void *blob, bd_t *bd)
 
        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
        u32 porbmsr = in_be32(&gur->porbmsr);
-       u32 romloc = (porbmsr >> MPC85XX_PORBMSR_ROMLOC_SHIFT) & 0xf;
+       u32 romloc = (porbmsr >> MPC85xx_PORBMSR_ROMLOC_SHIFT) & 0xf;
 
        if (!(hwconfig("uart2") && hwconfig("usb1"))) {
                /* If uart2 is there in hwconfig remove usb node from
index dc2365851b49f974fb71806d5a30029dc8914de1..b4bce99d3d945cdec4c200615d736846785672aa 100644 (file)
 #include <asm/mmu.h>
 
 struct law_entry law_table[] = {
-#ifndef CONFIG_SYS_NO_FLASH
        SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_128M, LAW_TRGT_IF_IFC),
-#endif
+#ifdef CONFIG_SYS_NAND_BASE_PHYS
        SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_IFC),
+#endif
+#ifdef CONFIG_SYS_FPGA_BASE_PHYS
        SET_LAW(CONFIG_SYS_FPGA_BASE_PHYS, LAW_SIZE_128K, LAW_TRGT_IF_IFC),
+#endif
 };
 
 int num_law_entries = ARRAY_SIZE(law_table);
diff --git a/board/freescale/bsc9132qds/spl_minimal.c b/board/freescale/bsc9132qds/spl_minimal.c
new file mode 100644 (file)
index 0000000..62dee52
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2013 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 <ns16550.h>
+#include <asm/io.h>
+#include <nand.h>
+#include <linux/compiler.h>
+#include <asm/fsl_law.h>
+#include <asm/fsl_ddr_sdram.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void sdram_init(void)
+{
+       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
+#if CONFIG_DDR_CLK_FREQ == 100000000
+       __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds);
+       __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config);
+       __raw_writel(CONFIG_SYS_DDR_CONTROL_800 | SDRAM_CFG_32_BE, &ddr->sdram_cfg);
+       __raw_writel(CONFIG_SYS_DDR_CONTROL_2_800, &ddr->sdram_cfg_2);
+       __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init);
+
+       __raw_writel(CONFIG_SYS_DDR_TIMING_3_800, &ddr->timing_cfg_3);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_0_800, &ddr->timing_cfg_0);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_1_800, &ddr->timing_cfg_1);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_2_800, &ddr->timing_cfg_2);
+       __raw_writel(CONFIG_SYS_DDR_MODE_1_800, &ddr->sdram_mode);
+       __raw_writel(CONFIG_SYS_DDR_MODE_2_800, &ddr->sdram_mode_2);
+       __raw_writel(CONFIG_SYS_DDR_INTERVAL_800, &ddr->sdram_interval);
+       __raw_writel(CONFIG_SYS_DDR_CLK_CTRL_800, &ddr->sdram_clk_cntl);
+       __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_800, &ddr->ddr_wrlvl_cntl);
+
+       __raw_writel(CONFIG_SYS_DDR_TIMING_4_800, &ddr->timing_cfg_4);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_5_800, &ddr->timing_cfg_5);
+       __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl);
+#elif CONFIG_DDR_CLK_FREQ == 133000000
+       __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds);
+       __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config);
+       __raw_writel(CONFIG_SYS_DDR_CONTROL_1333 | SDRAM_CFG_32_BE, &ddr->sdram_cfg);
+       __raw_writel(CONFIG_SYS_DDR_CONTROL_2_1333, &ddr->sdram_cfg_2);
+       __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init);
+
+       __raw_writel(CONFIG_SYS_DDR_TIMING_3_1333, &ddr->timing_cfg_3);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_0_1333, &ddr->timing_cfg_0);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_1_1333, &ddr->timing_cfg_1);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_2_1333, &ddr->timing_cfg_2);
+       __raw_writel(CONFIG_SYS_DDR_MODE_1_1333, &ddr->sdram_mode);
+       __raw_writel(CONFIG_SYS_DDR_MODE_2_1333, &ddr->sdram_mode_2);
+       __raw_writel(CONFIG_SYS_DDR_INTERVAL_1333, &ddr->sdram_interval);
+       __raw_writel(CONFIG_SYS_DDR_CLK_CTRL_1333, &ddr->sdram_clk_cntl);
+       __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_1333, &ddr->ddr_wrlvl_cntl);
+
+       __raw_writel(CONFIG_SYS_DDR_TIMING_4_1333, &ddr->timing_cfg_4);
+       __raw_writel(CONFIG_SYS_DDR_TIMING_5_1333, &ddr->timing_cfg_5);
+       __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl);
+#else
+       puts("Not a valid DDR Freq Found! Please Reset\n");
+#endif
+       asm volatile("sync;isync");
+       udelay(500);
+
+       /* 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;
+       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;
+       gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio;
+
+       NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1,
+                    gd->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_SPL_RELOC_STACK, 0, CONFIG_SPL_RELOC_TEXT_BASE);
+}
+
+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++);
+}
index 0e4545fb12856b8d0d038827d1b9fa962c5cc2fe..0ec9a851aba6ad55a0ad5b5ce68ab9a20759a602 100644 (file)
@@ -44,14 +44,20 @@ struct fsl_e_tlb_entry tlb_table[] = {
        /* 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),
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 0, BOOKE_PAGESZ_4K, 1),
+#ifdef CONFIG_SPL_NAND_MINIMAL
+       SET_TLB_ENTRY(1, 0xffffe000, 0xffffe000,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 10, BOOKE_PAGESZ_4K, 1),
+#endif
 
        /* *I*G* - CCSRBAR (PA) */
        SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS,
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 1, BOOKE_PAGESZ_1M, 1),
 
+#ifndef CONFIG_SPL_BUILD
        SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
                        MAS3_SX|MAS3_SR, MAS2_W|MAS2_G,
                        0, 3, BOOKE_PAGESZ_64M, 1),
@@ -61,12 +67,6 @@ struct fsl_e_tlb_entry tlb_table[] = {
                        MAS3_SX|MAS3_SR, MAS2_W|MAS2_G,
                        0, 4, BOOKE_PAGESZ_64M, 1),
 
-#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
-
 #ifdef CONFIG_PCI
        /* *I*G* - PCI */
        SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS,
@@ -78,15 +78,26 @@ struct fsl_e_tlb_entry tlb_table[] = {
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 7, BOOKE_PAGESZ_64K, 1),
 #endif
+#endif
+
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
+       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
 
+#ifdef CONFIG_SYS_FPGA_BASE
                /* *I*G - Board FPGA  */
        SET_TLB_ENTRY(1, CONFIG_SYS_FPGA_BASE, CONFIG_SYS_FPGA_BASE_PHYS,
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 9, BOOKE_PAGESZ_256K, 1),
+#endif
 
+#ifdef CONFIG_SYS_NAND_BASE_PHYS
        SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 5, BOOKE_PAGESZ_1M, 1),
+#endif
 };
 
 int num_tlb_entries = ARRAY_SIZE(tlb_table);
index 72bb56cac4bc8ac0cb45c96a9fbdee21ec192828..37236d072b6d05a1a0821cb9c7d18895016d0f89 100644 (file)
@@ -29,6 +29,15 @@ endif
 
 LIB    = $(obj)libfreescale.o
 
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifndef MINIMAL
 COBJS-$(CONFIG_FSL_CADMUS)     += cadmus.o
 COBJS-$(CONFIG_FSL_VIA)                += cds_via.o
 COBJS-$(CONFIG_FMAN_ENET)      += fman.o
@@ -68,6 +77,7 @@ SUBLIB-$(CONFIG_P3041DS)      += p_corenet/libp_corenet.o
 SUBLIB-$(CONFIG_P4080DS)       += p_corenet/libp_corenet.o
 SUBLIB-$(CONFIG_P5020DS)       += p_corenet/libp_corenet.o
 SUBLIB-$(CONFIG_P5040DS)       += p_corenet/libp_corenet.o
+endif
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS-y))
index 8d07061c36f36a67481484719ab44436eb4a9b02..fbb709de14a2faef74f04ba06d057f30af8425cd 100644 (file)
@@ -480,6 +480,7 @@ static int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const ar
            ||  unknown_param) {
 #ifdef CONFIG_SYS_LONGHELP
                puts(cmdtp->help);
+               putc('\n');
 #endif
                return 1;
        }
@@ -512,6 +513,7 @@ static int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const ar
                      && set_px_mpxpll(mpxpll))) {
 #ifdef CONFIG_SYS_LONGHELP
                        puts(cmdtp->help);
+                       putc('\n');
 #endif
                        return 1;
                }
index 4c705b627e622e2892006a6ecf1628faea6620fc..e6563be098901f03132c623842a435d99443e55c 100644 (file)
@@ -24,11 +24,27 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+
+COBJS-y        += spl_minimal.o tlb.o law.o
+
+else
+
 COBJS-y        += $(BOARD).o
 COBJS-y        += ddr.o
 COBJS-y        += law.o
 COBJS-y        += tlb.o
 
+endif
+
 SRCS   := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS-y))
 SOBJS  := $(addprefix $(obj),$(SOBJS))
similarity index 95%
rename from nand_spl/board/freescale/p1010rdb/nand_boot.c
rename to board/freescale/p1010rdb/spl_minimal.c
index 3c7bc2bc6536d55c2725a522346e3ae0f3d444b1..c909e0ee314b5f038dda3f91d18ee38ae6a5dd61 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-unsigned long ddr_freq_mhz;
 
 void sdram_init(void)
 {
        ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
+       ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
+       u32 ddr_ratio;
+       unsigned long ddr_freq_mhz;
+
+       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;
+
        /* mask off E bit */
        u32 svr = SVR_SOC_VER(mfspr(SPRN_SVR));
 
@@ -81,6 +88,7 @@ void sdram_init(void)
                __raw_writel((CONFIG_SYS_DDR_CS0_BNDS >> 1) & 0x0fff0fff, &ddr->cs0_bnds);
        }
 
+       asm volatile("sync;isync");
        udelay(500);
 
        /* Let the controller go */
@@ -91,7 +99,7 @@ void sdram_init(void)
 
 void board_init_f(ulong bootflag)
 {
-       u32 plat_ratio, ddr_ratio;
+       u32 plat_ratio;
        ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
 
        /* initialize selected port with appropriate baud rate */
@@ -99,10 +107,6 @@ void board_init_f(ulong bootflag)
        plat_ratio >>= 1;
        gd->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,
                        gd->bus_clk / 16 / CONFIG_BAUDRATE);
 
@@ -115,8 +119,8 @@ void board_init_f(ulong bootflag)
        /* 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);
+
+       relocate_code(CONFIG_SPL_RELOC_STACK, 0, CONFIG_SPL_RELOC_TEXT_BASE);
 }
 
 void board_init_r(gd_t *gd, ulong dest_addr)
index 4256bf4e5707aec43b6cbc4bed5afed3aa8e493d..078717a5b9875a1ab0ff6bfe2ac33c208455839c 100644 (file)
@@ -44,15 +44,20 @@ struct fsl_e_tlb_entry tlb_table[] = {
        /* 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),
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 0, BOOKE_PAGESZ_4K, 1),
+#ifdef CONFIG_SPL_NAND_MINIMAL
+       SET_TLB_ENTRY(1, 0xffffe000, 0xffffe000,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 10, BOOKE_PAGESZ_4K, 1),
+#endif
 
        /* *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_SPL_BUILD
 #ifndef CONFIG_SDCARD
        SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
                        MAS3_SX|MAS3_SR, MAS2_W|MAS2_G,
@@ -88,7 +93,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
                        0, 7, BOOKE_PAGESZ_1M, 1),
 #endif
 
-#if defined(CONFIG_SYS_RAMBOOT)
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
        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)
diff --git a/board/freescale/p1023rdb/Makefile b/board/freescale/p1023rdb/Makefile
new file mode 100644 (file)
index 0000000..45c4f8b
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# Copyright 2013 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.
+#
+
+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))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/freescale/p1023rdb/ddr.c b/board/freescale/p1023rdb/ddr.c
new file mode 100644 (file)
index 0000000..7ed275a
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2013 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;
+
+/* CONFIG_SYS_DDR_RAW_TIMING */
+/*
+ * Hynix H5TQ1G83TFR-H9C
+ */
+dimm_params_t ddr_raw_timing = {
+       .n_ranks = 1,
+       .rank_density = 536870912u,
+       .capacity = 536870912u,
+       .primary_sdram_width = 32,
+       .ec_sdram_width = 0,
+       .registered_dimm = 0,
+       .mirrored_dimm = 0,
+       .n_row_addr = 14,
+       .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 = 18000,
+       .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)
+{
+       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;
+
+       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;
+       }
+}
+
similarity index 51%
rename from drivers/tpm/slb9635_i2c/compatibility.h
rename to board/freescale/p1023rdb/law.c
index 62dc9fa964608ff5c2fed1d265ed90039ff2664f..331662cfc6b0b174d1822096044b8d7c4452427d 100644 (file)
@@ -1,10 +1,5 @@
 /*
- * Copyright (C) 2011 Infineon Technologies
- *
- * Authors:
- * Peter Huewe <huewe.external@infineon.com>
- *
- * Version: 2.1.1
+ * Copyright 2013 Freescale Semiconductor, Inc.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
  * MA 02111-1307 USA
  */
 
-#ifndef _COMPATIBILITY_H_
-#define _COMPATIBILITY_H_
-
-/* all includes from U-Boot */
-#include <linux/types.h>
-#include <linux/unaligned/be_byteshift.h>
-#include <asm-generic/errno.h>
-#include <compiler.h>
 #include <common.h>
+#include <asm/fsl_law.h>
+#include <asm/mmu.h>
 
-/* extended error numbers from linux (see errno.h) */
-#define        ECANCELED       125     /* Operation Canceled */
-
-#define msleep(t) udelay((t)*1000)
-
-/* Timer frequency. Corresponds to msec timer resolution*/
-#define HZ             1000
-
-#define dev_dbg(dev, format, arg...) debug(format, ##arg)
-#define dev_err(dev, format, arg...) printf(format, ##arg)
-#define dev_info(dev, format, arg...) debug(format, ##arg)
-#define dbg_printf debug
+struct law_entry law_table[] = {
+       SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC),
+       SET_LAW(CONFIG_SYS_QMAN_MEM_PHYS, LAW_SIZE_4M,
+               LAW_TRGT_IF_DPAA_SWP_SRAM),
+       SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC),
+};
 
-#endif
+int num_law_entries = ARRAY_SIZE(law_table);
diff --git a/board/freescale/p1023rdb/p1023rdb.c b/board/freescale/p1023rdb/p1023rdb.c
new file mode 100644 (file)
index 0000000..918398b
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * Authors:  Roy Zang <tie-fei.zang@freescale.com>
+ *           Chunhe Lan <Chunhe.Lan@freescale.com>
+ *
+ * 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 <command.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <asm/cache.h>
+#include <asm/processor.h>
+#include <asm/mmu.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_pci.h>
+#include <asm/fsl_ddr_sdram.h>
+#include <asm/fsl_portals.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <netdev.h>
+#include <malloc.h>
+#include <fm_eth.h>
+#include <fsl_mdio.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <asm/fsl_dtsec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_early_init_f(void)
+{
+       fsl_lbc_t *lbc = LBC_BASE_ADDR;
+
+       /* Set ABSWP to implement conversion of addresses in the LBC */
+       setbits_be32(&lbc->lbcr, CONFIG_SYS_LBC_LBCR);
+
+       return 0;
+}
+
+int checkboard(void)
+{
+       printf("Board: P1023 RDB\n");
+
+       return 0;
+}
+
+#ifdef CONFIG_PCI
+void pci_init_board(void)
+{
+       fsl_pcie_init_board(0);
+}
+#endif
+
+int board_early_init_r(void)
+{
+       const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
+       const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
+
+       /*
+        * Remap Boot flash + PROMJET 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 + promjet */
+       disable_tlb(flash_esel);
+
+       set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
+               MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+               0, flash_esel, BOOKE_PAGESZ_256M, 1);
+
+       setup_portals();
+
+       return 0;
+}
+
+unsigned long get_board_sys_clk(ulong dummy)
+{
+       return gd->bus_clk;
+}
+
+unsigned long get_board_ddr_clk(ulong dummy)
+{
+       return gd->mem_clk;
+}
+
+int board_eth_init(bd_t *bis)
+{
+       ccsr_gur_t *gur = (ccsr_gur_t *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
+       struct fsl_pq_mdio_info dtsec_mdio_info;
+
+       /*
+        * Need to set dTSEC 1 pin multiplexing to TSEC. The default setting
+        * is not correct.
+        */
+       setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_TSEC1_1);
+
+       dtsec_mdio_info.regs =
+               (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
+       dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
+
+       /* Register the 1G MDIO bus */
+       fsl_pq_mdio_init(bis, &dtsec_mdio_info);
+
+       fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR);
+       fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR);
+
+       fm_info_set_mdio(FM1_DTSEC1,
+                        miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME));
+       fm_info_set_mdio(FM1_DTSEC2,
+                        miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME));
+
+#ifdef CONFIG_FMAN_ENET
+       cpu_eth_init(bis);
+#endif
+
+       return pci_eth_init(bis);
+}
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+void ft_board_setup(void *blob, bd_t *bd)
+{
+       phys_addr_t base;
+       phys_size_t size;
+
+       ft_cpu_setup(blob, bd);
+
+       base = getenv_bootm_low();
+       size = getenv_bootm_size();
+
+       fdt_fixup_memory(blob, (u64)base, (u64)size);
+
+#ifdef CONFIG_HAS_FSL_DR_USB
+       fdt_fixup_dr_usb(blob, bd);
+#endif
+
+       fdt_fixup_fman_ethernet(blob);
+}
+#endif
diff --git a/board/freescale/p1023rdb/tlb.c b/board/freescale/p1023rdb/tlb.c
new file mode 100644 (file)
index 0000000..3417c0f
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2013 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,
+                     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_4M, 1),
+
+       /* W**G* - Flash, localbus */
+       /* This will be changed to *I*G* after relocation to RAM. */
+       SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G,
+                     0, 2, BOOKE_PAGESZ_256M, 1),
+
+       /* *I*G* - PCI */
+       SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_MEM_VIRT, CONFIG_SYS_PCIE3_MEM_PHYS,
+                     MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 3, BOOKE_PAGESZ_1G, 1),
+
+       /* *I*G* - PCI */
+       SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_MEM_VIRT + 0x40000000,
+                     CONFIG_SYS_PCIE3_MEM_PHYS + 0x40000000,
+                     MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 4, BOOKE_PAGESZ_256M, 1),
+
+       SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_MEM_VIRT + 0x50000000,
+                     CONFIG_SYS_PCIE3_MEM_PHYS + 0x50000000,
+                     MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 5, BOOKE_PAGESZ_256M, 1),
+
+       /* *I*G* - PCI I/O */
+       SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_IO_VIRT, CONFIG_SYS_PCIE3_IO_PHYS,
+                     MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 6, BOOKE_PAGESZ_256K, 1),
+
+       /* Bman/Qman */
+       SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE, CONFIG_SYS_BMAN_MEM_PHYS,
+                     MAS3_SW|MAS3_SR, 0,
+                     0, 7, BOOKE_PAGESZ_1M, 1),
+       SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE + 0x00100000,
+                     CONFIG_SYS_BMAN_MEM_PHYS + 0x00100000,
+                     MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 8, BOOKE_PAGESZ_1M, 1),
+       SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE, CONFIG_SYS_QMAN_MEM_PHYS,
+                     MAS3_SW|MAS3_SR, MAS2_M,
+                     0, 9, BOOKE_PAGESZ_1M, 1),
+       SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE + 0x00100000,
+                     CONFIG_SYS_QMAN_MEM_PHYS + 0x00100000,
+                     MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 10, BOOKE_PAGESZ_1M, 1),
+
+       SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
+                     MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 11, BOOKE_PAGESZ_16K, 1),
+
+#ifdef 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, 12, BOOKE_PAGESZ_256M, 1),
+
+       SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000,
+                     CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000,
+                     MAS3_SX|MAS3_SW|MAS3_SR, 0,
+                     0, 13, BOOKE_PAGESZ_256M, 1),
+#endif
+};
+
+int num_tlb_entries = ARRAY_SIZE(tlb_table);
index 92c01cf95c72a18f614a52d85355abab11592079..a138d5a9e6f4bd986c3b6615043f235cc6a937e1 100644 (file)
@@ -55,6 +55,15 @@ struct fsl_e_tlb_entry tlb_table[] = {
        SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_ADDR, CONFIG_SYS_INIT_L3_ADDR,
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 0, BOOKE_PAGESZ_1M, 1),
+#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
+       /*
+        * SRIO_PCIE_BOOT-SLAVE. When slave boot, the address of the
+        * space is at 0xfff00000, it covered the 0xfffff000.
+        */
+       SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR,
+                     CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G,
+                     0, 0, BOOKE_PAGESZ_1M, 1),
 #else
        SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000,
                      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
@@ -130,6 +139,16 @@ struct fsl_e_tlb_entry tlb_table[] = {
        SET_TLB_ENTRY(1, QIXIS_BASE, QIXIS_BASE_PHYS,
                      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                      0, 17, BOOKE_PAGESZ_4K, 1),
+#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
+       /*
+        * SRIO_PCIE_BOOT-SLAVE. 1M space from 0xffe00000 for
+        * fetching ucode and ENV from master
+        */
+       SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR,
+                     CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_G,
+                     0, 18, BOOKE_PAGESZ_1M, 1),
+#endif
 
 };
 
index 6b3e095ba89bcb96ae5c7b8e3708ca7b92787bd2..16d442aa625f344e9674df812f1f195625d9891f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2012 Stephen Warren
+ * (C) Copyright 2012-2013 Stephen Warren
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -15,6 +15,8 @@
  */
 
 #include <common.h>
+#include <config.h>
+#include <lcd.h>
 #include <asm/arch/mbox.h>
 #include <asm/arch/sdhci.h>
 #include <asm/global_data.h>
@@ -77,3 +79,13 @@ int board_mmc_init(void)
        return bcm2835_sdhci_init(BCM2835_SDHCI_BASE,
                                  msg_clk->get_clock_rate.body.resp.rate_hz);
 }
+
+void ft_board_setup(void *blob, bd_t *bd)
+{
+       /*
+        * For now, we simply always add the simplefb DT node. Later, we
+        * should be more intelligent, and e.g. only do this if no enabled DT
+        * node exists for the "real" graphics driver.
+        */
+       lcd_dt_simplefb_add_node(blob);
+}
index fb98df0f847e5235cb05bd23df52857f3a724323..fdbe26cde116b81e0bf7e1c41d233cd3d36e5f87 100644 (file)
@@ -273,6 +273,15 @@ static struct emif_regs ddr3_evm_emif_reg_data = {
        .emif_ddr_phy_ctlr_1 = MT41J512M8RH125_EMIF_READ_LATENCY |
                                PHY_EN_DYN_PWRDN,
 };
+
+#ifdef CONFIG_SPL_OS_BOOT
+int spl_start_uboot(void)
+{
+       /* break into full u-boot on 'c' */
+       return (serial_tstc() && serial_getc() == 'c');
+}
+#endif
+
 #endif
 
 /*
index 1e598cb7e2f17a0c01234a9f40e4d1eda349353e..c0c428262b2f1d8f57f46cf63724d041f6a4958d 100644 (file)
@@ -831,6 +831,7 @@ P1022DS_36BIT_SPIFLASH       powerpc     mpc85xx     p1022ds             freesca
 P1022DS_SDCARD               powerpc     mpc85xx     p1022ds             freescale     -           P1022DS:SDCARD
 P1022DS_36BIT_SDCARD         powerpc     mpc85xx     p1022ds             freescale     -           P1022DS:36BIT,SDCARD
 P1022DS_36BIT                powerpc     mpc85xx     p1022ds             freescale      -           P1022DS:36BIT
+P1023RDB                     powerpc     mpc85xx     p1023rdb            freescale      -           P1023RDB
 P1023RDS                     powerpc     mpc85xx     p1023rds            freescale      -           P1023RDS
 P1023RDS_NAND                powerpc     mpc85xx     p1023rds            freescale      -           P1023RDS:NAND
 P1024RDB                     powerpc     mpc85xx     p1_p2_rdb_pc        freescale      -           p1_p2_rdb_pc:P1024RDB
@@ -900,8 +901,13 @@ P5040DS_NAND                    powerpc     mpc85xx     corenet_ds          freescale      -
 P5040DS_SDCARD              powerpc     mpc85xx     corenet_ds          freescale      -           P5040DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000
 P5040DS_SPIFLASH            powerpc     mpc85xx     corenet_ds          freescale      -           P5040DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000
 BSC9131RDB_SPIFLASH          powerpc     mpc85xx     bsc9131rdb          freescale      -           BSC9131RDB:BSC9131RDB,SPIFLASH
+BSC9131RDB_SPIFLASH_SYSCLK100 powerpc     mpc85xx     bsc9131rdb          freescale      -           BSC9131RDB:BSC9131RDB,SPIFLASH,SYS_CLK_100
+BSC9131RDB_NAND              powerpc     mpc85xx     bsc9131rdb          freescale      -           BSC9131RDB:BSC9131RDB,NAND
+BSC9131RDB_NAND_SYSCLK100    powerpc     mpc85xx     bsc9131rdb          freescale      -           BSC9131RDB:BSC9131RDB,NAND,SYS_CLK_100
 BSC9132QDS_NOR_DDRCLK100     powerpc     mpc85xx     bsc9132qds          freescale      -           BSC9132QDS:BSC9132QDS,SYS_CLK_100_DDR_100
 BSC9132QDS_NOR_DDRCLK133     powerpc     mpc85xx     bsc9132qds          freescale      -           BSC9132QDS:BSC9132QDS,SYS_CLK_100_DDR_133
+BSC9132QDS_NAND_DDRCLK100    powerpc     mpc85xx     bsc9132qds          freescale      -           BSC9132QDS:BSC9132QDS,NAND,SYS_CLK_100_DDR_100
+BSC9132QDS_NAND_DDRCLK133    powerpc     mpc85xx     bsc9132qds          freescale      -           BSC9132QDS:BSC9132QDS,NAND,SYS_CLK_100_DDR_133
 BSC9132QDS_SDCARD_DDRCLK100  powerpc     mpc85xx     bsc9132qds          freescale      -           BSC9132QDS:BSC9132QDS,SDCARD,SYS_CLK_100_DDR_100
 BSC9132QDS_SDCARD_DDRCLK133  powerpc     mpc85xx     bsc9132qds          freescale      -           BSC9132QDS:BSC9132QDS,SDCARD,SYS_CLK_100_DDR_133
 BSC9132QDS_SPIFLASH_DDRCLK100 powerpc    mpc85xx     bsc9132qds          freescale      -           BSC9132QDS:BSC9132QDS,SPIFLASH,SYS_CLK_100_DDR_100
@@ -912,12 +918,14 @@ stxssa_4M                    powerpc     mpc85xx     stxssa              stx
 T4240QDS                     powerpc     mpc85xx     t4qds               freescale      -           T4240QDS:PPC_T4240
 T4240QDS_SDCARD              powerpc     mpc85xx     t4qds               freescale     -           T4240QDS:PPC_T4240,RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000
 T4240QDS_SPIFLASH            powerpc     mpc85xx     t4qds               freescale     -           T4240QDS:PPC_T4240,RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000
+T4240QDS_SRIO_PCIE_BOOT             powerpc     mpc85xx     t4qds               freescale      -           T4240QDS:PPC_T4240,SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000
 T4160QDS                     powerpc     mpc85xx     t4qds               freescale      -           T4240QDS:PPC_T4160
 T4160QDS_SDCARD              powerpc     mpc85xx     t4qds               freescale     -           T4240QDS:PPC_T4160,RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000
 T4160QDS_SPIFLASH            powerpc     mpc85xx     t4qds               freescale     -           T4240QDS:PPC_T4160,RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000
 B4860QDS                     powerpc     mpc85xx     b4860qds            freescale      -           B4860QDS:PPC_B4860
 B4860QDS_NAND               powerpc     mpc85xx     b4860qds            freescale      -           B4860QDS:PPC_B4860,RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000
 B4860QDS_SPIFLASH            powerpc     mpc85xx     b4860qds            freescale     -           B4860QDS:PPC_B4860,RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000
+B4860QDS_SRIO_PCIE_BOOT             powerpc     mpc85xx     b4860qds            freescale      -           B4860QDS:PPC_B4860,SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000
 B4420QDS                     powerpc     mpc85xx     b4860qds            freescale     -           B4860QDS:PPC_B4420
 B4420QDS_NAND               powerpc     mpc85xx     b4860qds            freescale      -           B4860QDS:PPC_B4420,RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000
 B4420QDS_SPIFLASH            powerpc     mpc85xx     b4860qds            freescale     -           B4860QDS:PPC_B4420,RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000
index 3ba431626336189d93c4e2823c6b79b653f4f7aa..35816037ecf73ee589fd6d32be3a81f831b325c9 100644 (file)
@@ -44,13 +44,11 @@ COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
 COBJS-y += cmd_boot.o
 COBJS-$(CONFIG_CMD_BOOTM) += cmd_bootm.o
 COBJS-y += cmd_help.o
-COBJS-y += cmd_nvedit.o
 COBJS-y += cmd_version.o
 
 # environment
 COBJS-y += env_attr.o
 COBJS-y += env_callback.o
-COBJS-y += env_common.o
 COBJS-y += env_flags.o
 COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o
 COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o
@@ -191,14 +189,6 @@ COBJS-$(CONFIG_CMD_ZIP) += cmd_zip.o
 COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o
 
 # others
-ifdef CONFIG_DDR_SPD
-SPD := y
-endif
-ifdef CONFIG_SPD_EEPROM
-SPD := y
-endif
-COBJS-$(SPD) += ddr_spd.o
-COBJS-$(CONFIG_HWCONFIG) += hwconfig.o
 COBJS-$(CONFIG_BOOTSTAGE) += bootstage.o
 COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
 COBJS-y += flash.o
@@ -216,18 +206,36 @@ COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
 endif
 
 ifdef CONFIG_SPL_BUILD
-COBJS-y += cmd_nvedit.o
-COBJS-y += env_common.o
 COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
-COBJS-$(CONFIG_SPL_NET_SUPPORT) += cmd_nvedit.o
-COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_attr.o
-COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_callback.o
-COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_common.o
-COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_flags.o
-COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_nowhere.o
 COBJS-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o
+# environment
+COBJS-$(CONFIG_SPL_ENV_SUPPORT) += env_attr.o
+COBJS-$(CONFIG_SPL_ENV_SUPPORT) += env_flags.o
+COBJS-$(CONFIG_SPL_ENV_SUPPORT) += env_callback.o
+ifneq ($(CONFIG_SPL_NET_SUPPORT),y)
+COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
+COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o
+COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
+COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
+COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
+else
+COBJS-y += env_nowhere.o
+endif
 endif
+# core command
+COBJS-y += cmd_nvedit.o
+#environment
+COBJS-y += env_common.o
+#others
+ifdef CONFIG_DDR_SPD
+SPD := y
+endif
+ifdef CONFIG_SPD_EEPROM
+SPD := y
+endif
+COBJS-$(SPD) += ddr_spd.o
+COBJS-$(CONFIG_HWCONFIG) += hwconfig.o
 COBJS-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o
 COBJS-y += console.o
 COBJS-y += dlmalloc.o
index 81edbdf8e45b5899cab64d798d4c9f510afa3809..8efdb6365577e519c62ef4b56fa41919b4ee94d1 100644 (file)
@@ -421,19 +421,18 @@ static int setup_dest_addr(void)
 #endif
        gd->ram_top += get_effective_memsize();
        gd->ram_top = board_get_usable_ram_top(gd->mon_len);
-       gd->dest_addr = gd->ram_top;
+       gd->relocaddr = gd->ram_top;
        debug("Ram top: %08lX\n", (ulong)gd->ram_top);
 #if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
        /*
         * We need to make sure the location we intend to put secondary core
         * boot code is reserved and not used by any part of u-boot
         */
-       if (gd->dest_addr > determine_mp_bootpg(NULL)) {
-               gd->dest_addr = determine_mp_bootpg(NULL);
-               debug("Reserving MP boot page to %08lx\n", gd->dest_addr);
+       if (gd->relocaddr > determine_mp_bootpg(NULL)) {
+               gd->relocaddr = determine_mp_bootpg(NULL);
+               debug("Reserving MP boot page to %08lx\n", gd->relocaddr);
        }
 #endif
-       gd->dest_addr_sp = gd->dest_addr;
        return 0;
 }
 
@@ -441,9 +440,9 @@ static int setup_dest_addr(void)
 static int reserve_logbuffer(void)
 {
        /* reserve kernel log buffer */
-       gd->dest_addr -= LOGBUFF_RESERVE;
+       gd->relocaddr -= LOGBUFF_RESERVE;
        debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN,
-               gd->dest_addr);
+               gd->relocaddr);
        return 0;
 }
 #endif
@@ -455,9 +454,9 @@ static int reserve_pram(void)
        ulong reg;
 
        reg = getenv_ulong("pram", 10, CONFIG_PRAM);
-       gd->dest_addr -= (reg << 10);           /* size is in kB */
+       gd->relocaddr -= (reg << 10);           /* size is in kB */
        debug("Reserving %ldk for protected RAM at %08lx\n", reg,
-             gd->dest_addr);
+             gd->relocaddr);
        return 0;
 }
 #endif /* CONFIG_PRAM */
@@ -465,7 +464,7 @@ static int reserve_pram(void)
 /* Round memory pointer down to next 4 kB limit */
 static int reserve_round_4k(void)
 {
-       gd->dest_addr &= ~(4096 - 1);
+       gd->relocaddr &= ~(4096 - 1);
        return 0;
 }
 
@@ -475,12 +474,12 @@ static int reserve_mmu(void)
 {
        /* reserve TLB table */
        gd->arch.tlb_size = 4096 * 4;
-       gd->dest_addr -= gd->arch.tlb_size;
+       gd->relocaddr -= gd->arch.tlb_size;
 
        /* round down to next 64 kB limit */
-       gd->dest_addr &= ~(0x10000 - 1);
+       gd->relocaddr &= ~(0x10000 - 1);
 
-       gd->arch.tlb_addr = gd->dest_addr;
+       gd->arch.tlb_addr = gd->relocaddr;
        debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr,
              gd->arch.tlb_addr + gd->arch.tlb_size);
        return 0;
@@ -494,8 +493,8 @@ static int reserve_lcd(void)
        gd->fb_base = CONFIG_FB_ADDR;
 #else
        /* reserve memory for LCD display (always full pages) */
-       gd->dest_addr = lcd_setmem(gd->dest_addr);
-       gd->fb_base = gd->dest_addr;
+       gd->relocaddr = lcd_setmem(gd->relocaddr);
+       gd->fb_base = gd->relocaddr;
 #endif /* CONFIG_FB_ADDR */
        return 0;
 }
@@ -506,8 +505,8 @@ static int reserve_lcd(void)
 static int reserve_video(void)
 {
        /* reserve memory for video display (always full pages) */
-       gd->dest_addr = video_setmem(gd->dest_addr);
-       gd->fb_base = gd->dest_addr;
+       gd->relocaddr = video_setmem(gd->relocaddr);
+       gd->fb_base = gd->relocaddr;
 
        return 0;
 }
@@ -519,15 +518,18 @@ static int reserve_uboot(void)
         * reserve memory for U-Boot code, data & bss
         * round down to next 4 kB limit
         */
-       gd->dest_addr -= gd->mon_len;
-       gd->dest_addr &= ~(4096 - 1);
+       gd->relocaddr -= gd->mon_len;
+       gd->relocaddr &= ~(4096 - 1);
 #ifdef CONFIG_E500
        /* round down to next 64 kB limit so that IVPR stays aligned */
-       gd->dest_addr &= ~(65536 - 1);
+       gd->relocaddr &= ~(65536 - 1);
 #endif
 
        debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10,
-             gd->dest_addr);
+             gd->relocaddr);
+
+       gd->start_addr_sp = gd->relocaddr;
+
        return 0;
 }
 
@@ -535,20 +537,20 @@ static int reserve_uboot(void)
 /* reserve memory for malloc() area */
 static int reserve_malloc(void)
 {
-       gd->dest_addr_sp = gd->dest_addr - TOTAL_MALLOC_LEN;
+       gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;
        debug("Reserving %dk for malloc() at: %08lx\n",
-                       TOTAL_MALLOC_LEN >> 10, gd->dest_addr_sp);
+                       TOTAL_MALLOC_LEN >> 10, gd->start_addr_sp);
        return 0;
 }
 
 /* (permanently) allocate a Board Info struct */
 static int reserve_board(void)
 {
-       gd->dest_addr_sp -= sizeof(bd_t);
-       gd->bd = (bd_t *)map_sysmem(gd->dest_addr_sp, sizeof(bd_t));
+       gd->start_addr_sp -= sizeof(bd_t);
+       gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t));
        memset(gd->bd, '\0', sizeof(bd_t));
        debug("Reserving %zu Bytes for Board Info at: %08lx\n",
-                       sizeof(bd_t), gd->dest_addr_sp);
+                       sizeof(bd_t), gd->start_addr_sp);
        return 0;
 }
 #endif
@@ -563,10 +565,10 @@ static int setup_machine(void)
 
 static int reserve_global_data(void)
 {
-       gd->dest_addr_sp -= sizeof(gd_t);
-       gd->new_gd = (gd_t *)map_sysmem(gd->dest_addr_sp, sizeof(gd_t));
+       gd->start_addr_sp -= sizeof(gd_t);
+       gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t));
        debug("Reserving %zu Bytes for Global Data at: %08lx\n",
-                       sizeof(gd_t), gd->dest_addr_sp);
+                       sizeof(gd_t), gd->start_addr_sp);
        return 0;
 }
 
@@ -580,10 +582,10 @@ static int reserve_fdt(void)
        if (gd->fdt_blob) {
                gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
 
-               gd->dest_addr_sp -= gd->fdt_size;
-               gd->new_fdt = map_sysmem(gd->dest_addr_sp, gd->fdt_size);
+               gd->start_addr_sp -= gd->fdt_size;
+               gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
                debug("Reserving %lu Bytes for FDT at: %08lx\n",
-                     gd->fdt_size, gd->dest_addr_sp);
+                     gd->fdt_size, gd->start_addr_sp);
        }
 
        return 0;
@@ -593,8 +595,8 @@ static int reserve_stacks(void)
 {
 #ifdef CONFIG_SPL_BUILD
 # ifdef CONFIG_ARM
-       gd->dest_addr_sp -= 128;        /* leave 32 words for abort-stack */
-       gd->irq_sp = gd->dest_addr_sp;
+       gd->start_addr_sp -= 128;       /* leave 32 words for abort-stack */
+       gd->irq_sp = gd->start_addr_sp;
 # endif
 #else
 # ifdef CONFIG_PPC
@@ -602,9 +604,9 @@ static int reserve_stacks(void)
 # endif
 
        /* setup stack pointer for exceptions */
-       gd->dest_addr_sp -= 16;
-       gd->dest_addr_sp &= ~0xf;
-       gd->irq_sp = gd->dest_addr_sp;
+       gd->start_addr_sp -= 16;
+       gd->start_addr_sp &= ~0xf;
+       gd->irq_sp = gd->start_addr_sp;
 
        /*
         * Handle architecture-specific things here
@@ -613,18 +615,18 @@ static int reserve_stacks(void)
         */
 # ifdef CONFIG_ARM
 #  ifdef CONFIG_USE_IRQ
-       gd->dest_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
+       gd->start_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
        debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
-               CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->dest_addr_sp);
+               CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->start_addr_sp);
 
        /* 8-byte alignment for ARM ABI compliance */
-       gd->dest_addr_sp &= ~0x07;
+       gd->start_addr_sp &= ~0x07;
 #  endif
        /* leave 3 words for abort-stack, plus 1 for alignment */
-       gd->dest_addr_sp -= 16;
+       gd->start_addr_sp -= 16;
 # elif defined(CONFIG_PPC)
        /* Clear initial stack frame */
-       s = (ulong *) gd->dest_addr_sp;
+       s = (ulong *) gd->start_addr_sp;
        *s = 0; /* Terminate back chain */
        *++s = 0; /* NULL return address */
 # endif /* Architecture specific code */
@@ -635,7 +637,7 @@ static int reserve_stacks(void)
 
 static int display_new_sp(void)
 {
-       debug("New Stack Pointer is: %08lx\n", gd->dest_addr_sp);
+       debug("New Stack Pointer is: %08lx\n", gd->start_addr_sp);
 
        return 0;
 }
@@ -757,15 +759,13 @@ static int reloc_fdt(void)
 
 static int setup_reloc(void)
 {
-       gd->relocaddr = gd->dest_addr;
-       gd->start_addr_sp = gd->dest_addr_sp;
-       gd->reloc_off = gd->dest_addr - CONFIG_SYS_TEXT_BASE;
+       gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
        memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
 
        debug("Relocation Offset is: %08lx\n", gd->reloc_off);
        debug("Relocating to %08lx, new gd at %08lx, sp at %08lx\n",
-             gd->dest_addr, (ulong)map_to_sysmem(gd->new_gd),
-             gd->dest_addr_sp);
+             gd->relocaddr, (ulong)map_to_sysmem(gd->new_gd),
+             gd->start_addr_sp);
 
        return 0;
 }
@@ -794,7 +794,7 @@ static int jump_to_copy(void)
 #elif defined(CONFIG_SANDBOX)
        board_init_r(gd->new_gd, 0);
 #else
-       relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr);
+       relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr);
 #endif
 
        return 0;
@@ -851,12 +851,6 @@ static init_fnc_t init_sequence_f[] = {
 #ifdef CONFIG_ARM
        timer_init,             /* initialize timer */
 #endif
-#ifdef CONFIG_BOARD_POSTCLK_INIT
-       board_postclk_init,
-#endif
-#ifdef CONFIG_FSL_ESDHC
-       get_clocks,
-#endif
 #ifdef CONFIG_SYS_ALLOC_DPRAM
 #if !defined(CONFIG_CPM2)
        dpram_init,
@@ -864,6 +858,9 @@ static init_fnc_t init_sequence_f[] = {
 #endif
 #if defined(CONFIG_BOARD_POSTCLK_INIT)
        board_postclk_init,
+#endif
+#ifdef CONFIG_FSL_ESDHC
+       get_clocks,
 #endif
        env_init,               /* initialize environment */
 #if defined(CONFIG_8xx_CPUCLK_DEFAULT)
index fd1fd319b6351cfce2c4dff0b6a4860259d7b3e8..f5649c95f16f5291cecee4dc5fdf70e56fb4c759 100644 (file)
@@ -137,7 +137,7 @@ static int initr_reloc_global_data(void)
 #ifdef CONFIG_SYS_SYM_OFFSETS
        monitor_flash_len = _end_ofs;
 #elif !defined(CONFIG_SANDBOX)
-       monitor_flash_len = (ulong)&__init_end - gd->dest_addr;
+       monitor_flash_len = (ulong)&__init_end - gd->relocaddr;
 #endif
 #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
        /*
@@ -145,7 +145,7 @@ static int initr_reloc_global_data(void)
         * We need to update it to point to the same CPU entry in RAM.
         * TODO: why not just add gd->reloc_ofs?
         */
-       gd->arch.cpu += gd->dest_addr - CONFIG_SYS_MONITOR_BASE;
+       gd->arch.cpu += gd->relocaddr - CONFIG_SYS_MONITOR_BASE;
 
        /*
         * If we didn't know the cpu mask & # cores, we can save them of
@@ -161,7 +161,7 @@ static int initr_reloc_global_data(void)
         * in SRAM mode and initialize that cache from SRAM mode back to being
         * a cache in cpu_init_r.
         */
-       gd->env_addr += gd->dest_addr - CONFIG_SYS_MONITOR_BASE;
+       gd->env_addr += gd->relocaddr - CONFIG_SYS_MONITOR_BASE;
 #endif
        return 0;
 }
@@ -178,7 +178,7 @@ static int initr_trap(void)
        /*
         * Setup trap handlers
         */
-       trap_init(gd->dest_addr);
+       trap_init(gd->relocaddr);
 
        return 0;
 }
@@ -263,7 +263,7 @@ static int initr_malloc(void)
        ulong malloc_start;
 
        /* The malloc area is immediately below the monitor copy in DRAM */
-       malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN;
+       malloc_start = gd->relocaddr - TOTAL_MALLOC_LEN;
        mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN),
                        TOTAL_MALLOC_LEN);
        return 0;
@@ -276,7 +276,7 @@ __weak int power_init_board(void)
 
 static int initr_announce(void)
 {
-       debug("Now running in RAM - U-Boot at: %08lx\n", gd->dest_addr);
+       debug("Now running in RAM - U-Boot at: %08lx\n", gd->relocaddr);
        return 0;
 }
 
index 15f4599d45f28f5f005403abb9908c8cd07e0317..05130b69364c900d380e45fac9c5d27712ad52e7 100644 (file)
@@ -93,11 +93,6 @@ static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 static void fixup_silent_linux(void);
 #endif
 
-static image_header_t *image_get_kernel(ulong img_addr, int verify);
-#if defined(CONFIG_FIT)
-static int fit_check_kernel(const void *fit, int os_noffset, int verify);
-#endif
-
 static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
                                char * const argv[], bootm_headers_t *images,
                                ulong *os_data, ulong *os_len);
@@ -306,7 +301,7 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
 
 #if defined(CONFIG_OF_LIBFDT)
                /* find flattened device tree */
-               ret = boot_get_fdt(flag, argc, argv, &images,
+               ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
                                   &images.ft_addr, &images.ft_len);
                if (ret) {
                        puts("Could not find a valid device tree\n");
@@ -336,12 +331,15 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
        ulong image_len = os.image_len;
        __maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
        int no_overlap = 0;
+       void *load_buf, *image_buf;
 #if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
        int ret;
 #endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */
 
        const char *type_name = genimg_get_type_name(os.type);
 
+       load_buf = map_sysmem(load, image_len);
+       image_buf = map_sysmem(image_start, image_len);
        switch (comp) {
        case IH_COMP_NONE:
                if (load == blob_start || load == image_start) {
@@ -349,8 +347,7 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
                        no_overlap = 1;
                } else {
                        printf("   Loading %s ... ", type_name);
-                       memmove_wd((void *)load, (void *)image_start,
-                                       image_len, CHUNKSZ);
+                       memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
                }
                *load_end = load + image_len;
                puts("OK\n");
@@ -358,8 +355,7 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
 #ifdef CONFIG_GZIP
        case IH_COMP_GZIP:
                printf("   Uncompressing %s ... ", type_name);
-               if (gunzip((void *)load, unc_len,
-                               (uchar *)image_start, &image_len) != 0) {
+               if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
                        puts("GUNZIP: uncompress, out-of-mem or overwrite "
                                "error - must RESET board to recover\n");
                        if (boot_progress)
@@ -378,9 +374,9 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
                 * use slower decompression algorithm which requires
                 * at most 2300 KB of memory.
                 */
-               int i = BZ2_bzBuffToBuffDecompress((char *)load,
-                                       &unc_len, (char *)image_start, image_len,
-                                       CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
+               int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
+                       image_buf, image_len,
+                       CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
                if (i != BZ_OK) {
                        printf("BUNZIP2: uncompress or overwrite error %d "
                                "- must RESET board to recover\n", i);
@@ -397,9 +393,8 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
                SizeT lzma_len = unc_len;
                printf("   Uncompressing %s ... ", type_name);
 
-               ret = lzmaBuffToBuffDecompress(
-                       (unsigned char *)load, &lzma_len,
-                       (unsigned char *)image_start, image_len);
+               ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
+                                              image_buf, image_len);
                unc_len = lzma_len;
                if (ret != SZ_OK) {
                        printf("LZMA: uncompress or overwrite error %d "
@@ -415,9 +410,8 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
        case IH_COMP_LZO:
                printf("   Uncompressing %s ... ", type_name);
 
-               ret = lzop_decompress((const unsigned char *)image_start,
-                                         image_len, (unsigned char *)load,
-                                         &unc_len);
+               ret = lzop_decompress(image_buf, image_len, load_buf,
+                                     &unc_len);
                if (ret != LZO_E_OK) {
                        printf("LZO: uncompress or overwrite error %d "
                              "- must RESET board to recover\n", ret);
@@ -796,54 +790,6 @@ static image_header_t *image_get_kernel(ulong img_addr, int verify)
        return hdr;
 }
 
-/**
- * fit_check_kernel - verify FIT format kernel subimage
- * @fit_hdr: pointer to the FIT image header
- * os_noffset: kernel subimage node offset within FIT image
- * @verify: data CRC verification flag
- *
- * fit_check_kernel() verifies integrity of the kernel subimage and from
- * specified FIT image.
- *
- * returns:
- *     1, on success
- *     0, on failure
- */
-#if defined(CONFIG_FIT)
-static int fit_check_kernel(const void *fit, int os_noffset, int verify)
-{
-       fit_image_print(fit, os_noffset, "   ");
-
-       if (verify) {
-               puts("   Verifying Hash Integrity ... ");
-               if (!fit_image_verify(fit, os_noffset)) {
-                       puts("Bad Data Hash\n");
-                       bootstage_error(BOOTSTAGE_ID_FIT_CHECK_HASH);
-                       return 0;
-               }
-               puts("OK\n");
-       }
-       bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_ARCH);
-
-       if (!fit_image_check_target_arch(fit, os_noffset)) {
-               puts("Unsupported Architecture\n");
-               bootstage_error(BOOTSTAGE_ID_FIT_CHECK_ARCH);
-               return 0;
-       }
-
-       bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
-       if (!fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL) &&
-           !fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL_NOLOAD)) {
-               puts("Not a kernel image\n");
-               bootstage_error(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
-               return 0;
-       }
-
-       bootstage_mark(BOOTSTAGE_ID_FIT_CHECKED);
-       return 1;
-}
-#endif /* CONFIG_FIT */
-
 /**
  * boot_get_kernel - find kernel image
  * @os_data: pointer to a ulong variable, will hold os data start address
@@ -864,12 +810,8 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
        ulong           img_addr;
        const void *buf;
 #if defined(CONFIG_FIT)
-       const void      *fit_hdr;
        const char      *fit_uname_config = NULL;
        const char      *fit_uname_kernel = NULL;
-       const void      *data;
-       size_t          len;
-       int             cfg_noffset;
        int             os_noffset;
 #endif
 
@@ -946,84 +888,16 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
                break;
 #if defined(CONFIG_FIT)
        case IMAGE_FORMAT_FIT:
-               fit_hdr = buf;
-               printf("## Booting kernel from FIT Image at %08lx ...\n",
-                               img_addr);
-
-               if (!fit_check_format(fit_hdr)) {
-                       puts("Bad FIT kernel image format!\n");
-                       bootstage_error(BOOTSTAGE_ID_FIT_FORMAT);
+               os_noffset = fit_image_load(images, FIT_KERNEL_PROP,
+                               img_addr,
+                               &fit_uname_kernel, fit_uname_config,
+                               IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
+                               BOOTSTAGE_ID_FIT_KERNEL_START,
+                               FIT_LOAD_IGNORED, os_data, os_len);
+               if (os_noffset < 0)
                        return NULL;
-               }
-               bootstage_mark(BOOTSTAGE_ID_FIT_FORMAT);
-
-               if (!fit_uname_kernel) {
-                       /*
-                        * no kernel image node unit name, try to get config
-                        * node first. If config unit node name is NULL
-                        * fit_conf_get_node() will try to find default config
-                        * node
-                        */
-                       bootstage_mark(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
-#ifdef CONFIG_FIT_BEST_MATCH
-                       if (fit_uname_config)
-                               cfg_noffset =
-                                       fit_conf_get_node(fit_hdr,
-                                                         fit_uname_config);
-                       else
-                               cfg_noffset =
-                                       fit_conf_find_compat(fit_hdr,
-                                                            gd->fdt_blob);
-#else
-                       cfg_noffset = fit_conf_get_node(fit_hdr,
-                                                       fit_uname_config);
-#endif
-                       if (cfg_noffset < 0) {
-                               bootstage_error(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
-                               return NULL;
-                       }
-                       /* save configuration uname provided in the first
-                        * bootm argument
-                        */
-                       images->fit_uname_cfg = fdt_get_name(fit_hdr,
-                                                               cfg_noffset,
-                                                               NULL);
-                       printf("   Using '%s' configuration\n",
-                               images->fit_uname_cfg);
-                       bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
-
-                       os_noffset = fit_conf_get_kernel_node(fit_hdr,
-                                                               cfg_noffset);
-                       fit_uname_kernel = fit_get_name(fit_hdr, os_noffset,
-                                                       NULL);
-               } else {
-                       /* get kernel component image node offset */
-                       bootstage_mark(BOOTSTAGE_ID_FIT_UNIT_NAME);
-                       os_noffset = fit_image_get_node(fit_hdr,
-                                                       fit_uname_kernel);
-               }
-               if (os_noffset < 0) {
-                       bootstage_error(BOOTSTAGE_ID_FIT_CONFIG);
-                       return NULL;
-               }
-
-               printf("   Trying '%s' kernel subimage\n", fit_uname_kernel);
-
-               bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE);
-               if (!fit_check_kernel(fit_hdr, os_noffset, images->verify))
-                       return NULL;
-
-               /* get kernel image data address and length */
-               if (fit_image_get_data(fit_hdr, os_noffset, &data, &len)) {
-                       puts("Could not find kernel subimage data!\n");
-                       bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR);
-                       return NULL;
-               }
-               bootstage_mark(BOOTSTAGE_ID_FIT_KERNEL_INFO);
 
-               *os_len = len;
-               *os_data = (ulong)data;
-               images->fit_hdr_os = (void *)fit_hdr;
+               images->fit_hdr_os = map_sysmem(img_addr, 0);
                images->fit_uname_os = fit_uname_kernel;
                images->fit_noffset_os = os_noffset;
                break;
@@ -1820,7 +1694,7 @@ static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,
 
 #if defined(CONFIG_OF_LIBFDT)
        /* find flattened device tree */
-       ret = boot_get_fdt(flag, argc, argv, images,
+       ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, images,
                           &images->ft_addr, &images->ft_len);
        if (ret) {
                puts("Could not find a valid device tree\n");
index 7a3789e3ed4bc312926e81c0002fc580c8422217..618ff7c8d62ba36601db5f9b0c967b23d72d01be 100644 (file)
@@ -8,13 +8,12 @@
 
 #include <common.h>
 #include <command.h>
+#include <net.h>
 
 #if !defined(CONFIG_UPDATE_TFTP)
 #error "CONFIG_UPDATE_TFTP required"
 #endif
 
-extern int update_tftp(ulong addr);
-
 static int do_fitupd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        ulong addr = 0UL;
index fdf9489b2e99270921240cf265c558b6afc81895..bb15795e22ef567970f7600ba25e3f7ee3d9d26b 100644 (file)
@@ -535,7 +535,7 @@ do_i2cinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        volatile iic_t *iip;
        uint dpaddr;
 
-       dpaddr = *((unsigned short *) (&immap->im_dprambase[PROFF_I2C_BASE]));
+       dpaddr = immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)];
        if (dpaddr == 0)
                iip = NULL;
        else
index e9d3d3c1bf6238d20ad3abc310cbc306fab473dd..8b1e01ae8094f9a4236f6d9897a8e341121f987c 100644 (file)
@@ -62,8 +62,8 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat)
        ops.oobbuf = oobbuf;
        ops.len = nand->writesize;
        ops.ooblen = nand->oobsize;
-       ops.mode = MTD_OOB_RAW;
-       i = nand->read_oob(nand, addr, &ops);
+       ops.mode = MTD_OPS_RAW;
+       i = mtd_read_oob(nand, addr, &ops);
        if (i < 0) {
                printf("Error (%d) reading page %08lx\n", i, off);
                free(datbuf);
@@ -404,13 +404,13 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,
                        .oobbuf = ((u8 *)addr) + nand->writesize,
                        .len = nand->writesize,
                        .ooblen = nand->oobsize,
-                       .mode = MTD_OOB_RAW
+                       .mode = MTD_OPS_RAW
                };
 
                if (read)
-                       ret = nand->read_oob(nand, off, &ops);
+                       ret = mtd_read_oob(nand, off, &ops);
                else
-                       ret = nand->write_oob(nand, off, &ops);
+                       ret = mtd_write_oob(nand, off, &ops);
 
                if (ret) {
                        printf("%s: error at offset %llx, ret %d\n",
@@ -425,6 +425,31 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,
        return ret;
 }
 
+/* Adjust a chip/partition size down for bad blocks so we don't
+ * read/write/erase past the end of a chip/partition by accident.
+ */
+static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev)
+{
+       /* We grab the nand info object here fresh because this is usually
+        * called after arg_off_size() which can change the value of dev.
+        */
+       nand_info_t *nand = &nand_info[dev];
+       loff_t maxoffset = offset + *size;
+       int badblocks = 0;
+
+       /* count badblocks in NAND from offset to offset + size */
+       for (; offset < maxoffset; offset += nand->erasesize) {
+               if (nand_block_isbad(nand, offset))
+                       badblocks++;
+       }
+       /* adjust size if any bad blocks found */
+       if (badblocks) {
+               *size -= badblocks * nand->erasesize;
+               printf("size adjusted to 0x%llx (%d bad blocks)\n",
+                      (unsigned long long)*size, badblocks);
+       }
+}
+
 static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        int i, ret = 0;
@@ -521,6 +546,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                int scrub = !strncmp(cmd, "scrub", 5);
                int spread = 0;
                int args = 2;
+               int adjust_size = 0;
                const char *scrub_warn =
                        "Warning: "
                        "scrub option will erase all factory set bad blocks!\n"
@@ -537,8 +563,10 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                                spread = 1;
                        } else if (!strcmp(&cmd[5], ".part")) {
                                args = 1;
+                               adjust_size = 1;
                        } else if (!strcmp(&cmd[5], ".chip")) {
                                args = 0;
+                               adjust_size = 1;
                        } else {
                                goto usage;
                        }
@@ -558,6 +586,10 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                                 &maxsize) != 0)
                        return 1;
 
+               /* size is unspecified */
+               if (adjust_size && !scrub)
+                       adjust_size_for_badblocks(&size, off, dev);
+
                nand = &nand_info[dev];
 
                memset(&opts, 0, sizeof(opts));
@@ -642,6 +674,9 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                                                &off, &size, &maxsize) != 0)
                                return 1;
 
+                       /* size is unspecified */
+                       if (argc < 5)
+                               adjust_size_for_badblocks(&size, off, dev);
                        rwsize = size;
                }
 
@@ -680,13 +715,13 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        mtd_oob_ops_t ops = {
                                .oobbuf = (u8 *)addr,
                                .ooblen = rwsize,
-                               .mode = MTD_OOB_RAW
+                               .mode = MTD_OPS_RAW
                        };
 
                        if (read)
-                               ret = nand->read_oob(nand, off, &ops);
+                               ret = mtd_read_oob(nand, off, &ops);
                        else
-                               ret = nand->write_oob(nand, off, &ops);
+                               ret = mtd_write_oob(nand, off, &ops);
                } else if (raw) {
                        ret = raw_access(nand, addr, off, pagecount, read);
                } else {
@@ -729,7 +764,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                while (argc > 0) {
                        addr = simple_strtoul(*argv, NULL, 16);
 
-                       if (nand->block_markbad(nand, addr)) {
+                       if (mtd_block_markbad(nand, addr)) {
                                printf("block 0x%08lx NOT marked "
                                        "as bad! ERROR %d\n",
                                        addr, ret);
index a0d25e55212a0c9633e89d62331f3ed223c694df..06cc1405675a64f6d3c6dd637e9562817527e5ac 100644 (file)
@@ -83,7 +83,7 @@ static int onenand_block_read(loff_t from, size_t len,
                ops.len = blocksize;
 
        while (blocks) {
-               ret = mtd->block_isbad(mtd, ofs);
+               ret = mtd_block_isbad(mtd, ofs);
                if (ret) {
                        printk("Bad blocks %d at 0x%x\n",
                               (u32)(ofs >> this->erase_shift), (u32)ofs);
@@ -97,7 +97,7 @@ static int onenand_block_read(loff_t from, size_t len,
                        ops.datbuf = buf;
 
                ops.retlen = 0;
-               ret = mtd->read_oob(mtd, ofs, &ops);
+               ret = mtd_read_oob(mtd, ofs, &ops);
                if (ret) {
                        printk("Read failed 0x%x, %d\n", (u32)ofs, ret);
                        ofs += blocksize;
@@ -118,7 +118,7 @@ static int onenand_write_oneblock_withoob(loff_t to, const u_char * buf,
        struct mtd_oob_ops ops = {
                .len = mtd->writesize,
                .ooblen = mtd->oobsize,
-               .mode = MTD_OOB_AUTO,
+               .mode = MTD_OPS_AUTO_OOB,
        };
        int page, ret = 0;
        for (page = 0; page < (mtd->erasesize / mtd->writesize); page ++) {
@@ -126,7 +126,7 @@ static int onenand_write_oneblock_withoob(loff_t to, const u_char * buf,
                buf += mtd->writesize;
                ops.oobbuf = (u_char *)buf;
                buf += mtd->oobsize;
-               ret = mtd->write_oob(mtd, to, &ops);
+               ret = mtd_write_oob(mtd, to, &ops);
                if (ret)
                        break;
                to += mtd->writesize;
@@ -156,7 +156,7 @@ static int onenand_block_write(loff_t to, size_t len,
        ofs = to;
 
        while (blocks) {
-               ret = mtd->block_isbad(mtd, ofs);
+               ret = mtd_block_isbad(mtd, ofs);
                if (ret) {
                        printk("Bad blocks %d at 0x%x\n",
                               (u32)(ofs >> this->erase_shift), (u32)ofs);
@@ -165,7 +165,7 @@ static int onenand_block_write(loff_t to, size_t len,
                }
 
                if (!withoob)
-                       ret = mtd->write(mtd, ofs, blocksize, &_retlen, buf);
+                       ret = mtd_write(mtd, ofs, blocksize, &_retlen, buf);
                else
                        ret = onenand_write_oneblock_withoob(ofs, buf, &_retlen);
                if (ret) {
@@ -195,7 +195,7 @@ static int onenand_block_erase(u32 start, u32 size, int force)
        int blocksize = 1 << this->erase_shift;
 
        for (ofs = start; ofs < (start + size); ofs += blocksize) {
-               ret = mtd->block_isbad(mtd, ofs);
+               ret = mtd_block_isbad(mtd, ofs);
                if (ret && !force) {
                        printf("Skip erase bad block %d at 0x%x\n",
                               (u32)(ofs >> this->erase_shift), (u32)ofs);
@@ -206,7 +206,7 @@ static int onenand_block_erase(u32 start, u32 size, int force)
                instr.len = blocksize;
                instr.priv = force;
                instr.mtd = mtd;
-               ret = mtd->erase(mtd, &instr);
+               ret = mtd_erase(mtd, &instr);
                if (ret) {
                        printf("erase failed block %d at 0x%x\n",
                               (u32)(ofs >> this->erase_shift), (u32)ofs);
@@ -261,7 +261,7 @@ static int onenand_block_test(u32 start, u32 size)
        while (blocks < end_block) {
                printf("\rTesting block %d at 0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs);
 
-               ret = mtd->block_isbad(mtd, ofs);
+               ret = mtd_block_isbad(mtd, ofs);
                if (ret) {
                        printf("Skip erase bad block %d at 0x%x\n",
                               (u32)(ofs >> this->erase_shift), (u32)ofs);
@@ -270,19 +270,19 @@ static int onenand_block_test(u32 start, u32 size)
 
                instr.addr = ofs;
                instr.len = blocksize;
-               ret = mtd->erase(mtd, &instr);
+               ret = mtd_erase(mtd, &instr);
                if (ret) {
                        printk("Erase failed 0x%x, %d\n", (u32)ofs, ret);
                        goto next;
                }
 
-               ret = mtd->write(mtd, ofs, blocksize, &retlen, buf);
+               ret = mtd_write(mtd, ofs, blocksize, &retlen, buf);
                if (ret) {
                        printk("Write failed 0x%x, %d\n", (u32)ofs, ret);
                        goto next;
                }
 
-               ret = mtd->read(mtd, ofs, blocksize, &retlen, verify_buf);
+               ret = mtd_read(mtd, ofs, blocksize, &retlen, verify_buf);
                if (ret) {
                        printk("Read failed 0x%x, %d\n", (u32)ofs, ret);
                        goto next;
@@ -324,7 +324,7 @@ static int onenand_dump(struct mtd_info *mtd, ulong off, int only_oob)
        ops.len = mtd->writesize;
        ops.ooblen = mtd->oobsize;
        ops.retlen = 0;
-       i = mtd->read_oob(mtd, addr, &ops);
+       i = mtd_read_oob(mtd, addr, &ops);
        if (i < 0) {
                printf("Error (%d) reading page %08lx\n", i, off);
                free(datbuf);
@@ -373,7 +373,7 @@ static int do_onenand_bad(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar
        /* Currently only one OneNAND device is supported */
        printf("\nDevice %d bad blocks:\n", 0);
        for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) {
-               if (mtd->block_isbad(mtd, ofs))
+               if (mtd_block_isbad(mtd, ofs))
                        printf("  %08x\n", (u32)ofs);
        }
 
@@ -530,7 +530,7 @@ static int do_onenand_markbad(cmd_tbl_t * cmdtp, int flag, int argc, char * cons
        while (argc > 0) {
                addr = simple_strtoul(*argv, NULL, 16);
 
-               if (mtd->block_markbad(mtd, addr)) {
+               if (mtd_block_markbad(mtd, addr)) {
                        printf("block 0x%08lx NOT marked "
                                "as bad! ERROR %d\n",
                                addr, ret);
index 0a17782d662c1f950029935970bf661b56387b23..19b0dc9f433c9cc5dc7357aadda3d3c00dc87f9b 100644 (file)
@@ -234,7 +234,7 @@ static int do_spi_flash_read_write(int argc, char * const argv[])
        unsigned long len;
        void *buf;
        char *endp;
-       int ret;
+       int ret = 1;
 
        if (argc < 4)
                return -1;
@@ -264,19 +264,23 @@ static int do_spi_flash_read_write(int argc, char * const argv[])
 
        if (strcmp(argv[0], "update") == 0)
                ret = spi_flash_update(flash, offset, len, buf);
-       else if (strcmp(argv[0], "read") == 0)
-               ret = spi_flash_read(flash, offset, len, buf);
-       else
-               ret = spi_flash_write(flash, offset, len, buf);
+       else if (strncmp(argv[0], "read", 4) == 0 ||
+                       strncmp(argv[0], "write", 5) == 0) {
+               int read;
+
+               read = strncmp(argv[0], "read", 4) == 0;
+               if (read)
+                       ret = spi_flash_read(flash, offset, len, buf);
+               else
+                       ret = spi_flash_write(flash, offset, len, buf);
+
+               printf("SF: %zu bytes @ %#x %s: %s\n", (size_t)len, (u32)offset,
+                       read ? "Read" : "Written", ret ? "ERROR" : "OK");
+       }
 
        unmap_physmem(buf, len);
 
-       if (ret) {
-               printf("SPI flash %s failed\n", argv[0]);
-               return 1;
-       }
-
-       return 0;
+       return ret == 0 ? 0 : 1;
 }
 
 static int do_spi_flash_erase(int argc, char * const argv[])
@@ -305,12 +309,10 @@ static int do_spi_flash_erase(int argc, char * const argv[])
        }
 
        ret = spi_flash_erase(flash, offset, len);
-       if (ret) {
-               printf("SPI flash %s failed\n", argv[0]);
-               return 1;
-       }
+       printf("SF: %zu bytes @ %#x Erased: %s\n", (size_t)len, (u32)offset,
+                       ret ? "ERROR" : "OK");
 
-       return 0;
+       return ret == 0 ? 0 : 1;
 }
 
 #ifdef CONFIG_CMD_SF_TEST
index 9ca098fa674dbb56911ed1ab3517152d6db84f3c..5d3a769db0e94ae05912568a3edd2c88b8be36b1 100644 (file)
@@ -53,11 +53,19 @@ DECLARE_GLOBAL_DATA_PTR;
 
 __weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
 {
-       *env_addr = CONFIG_ENV_OFFSET;
+       s64 offset;
+
+       offset = CONFIG_ENV_OFFSET;
 #ifdef CONFIG_ENV_OFFSET_REDUND
        if (copy)
-               *env_addr = CONFIG_ENV_OFFSET_REDUND;
+               offset = CONFIG_ENV_OFFSET_REDUND;
 #endif
+
+       if (offset < 0)
+               offset += mmc->capacity;
+
+       *env_addr = offset;
+
        return 0;
 }
 
index faa903d2f0251cd2459daef22d6d6514124dc86c..e8bde37266adb9553e192cea11c2341b58bf2103 100644 (file)
@@ -68,7 +68,7 @@ void env_relocate_spec(void)
        /* Check OneNAND exist */
        if (mtd->writesize)
                /* Ignore read fail */
-               mtd->read(mtd, env_addr, ONENAND_MAX_ENV_SIZE,
+               mtd_read(mtd, env_addr, ONENAND_MAX_ENV_SIZE,
                                &retlen, (u_char *)buf);
        else
                mtd->writesize = MAX_ONENAND_PAGESIZE;
@@ -113,12 +113,12 @@ int saveenv(void)
 #endif
        instr.addr = env_addr;
        instr.mtd = mtd;
-       if (mtd->erase(mtd, &instr)) {
+       if (mtd_erase(mtd, &instr)) {
                printf("OneNAND: erase failed at 0x%08llx\n", env_addr);
                return 1;
        }
 
-       if (mtd->write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen,
+       if (mtd_write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen,
                        (u_char *)&env_new)) {
                printf("OneNAND: write failed at 0x%llx\n", instr.addr);
                return 2;
index 416100e394dc92d3c61f143aa807681b1a5c84ce..9a6f6b7d8b16c822496c53a62df26d3850081b29 100644 (file)
@@ -458,7 +458,7 @@ void fdt_fixup_ethernet(void *fdt)
 {
        int node, i, j;
        char enet[16], *tmp, *end;
-       char mac[16] = "ethaddr";
+       char mac[16];
        const char *path;
        unsigned char mac_addr[6];
 
@@ -467,6 +467,7 @@ void fdt_fixup_ethernet(void *fdt)
                return;
 
        i = 0;
+       strcpy(mac, "ethaddr");
        while ((tmp = getenv(mac)) != NULL) {
                sprintf(enet, "ethernet%d", i);
                path = fdt_getprop(fdt, node, enet, NULL);
index 158c9cfbf57de7f5437038740d0489649ab87dfb..0d421d92fb66b55423b269eeca9e0d425d1f5fa2 100644 (file)
@@ -211,51 +211,11 @@ error:
        return 1;
 }
 
-#if defined(CONFIG_FIT)
-/**
- * fit_check_fdt - verify FIT format FDT subimage
- * @fit_hdr: pointer to the FIT  header
- * fdt_noffset: FDT subimage node offset within FIT image
- * @verify: data CRC verification flag
- *
- * fit_check_fdt() verifies integrity of the FDT subimage and from
- * specified FIT image.
- *
- * returns:
- *     1, on success
- *     0, on failure
- */
-static int fit_check_fdt(const void *fit, int fdt_noffset, int verify)
-{
-       fit_image_print(fit, fdt_noffset, "   ");
-
-       if (verify) {
-               puts("   Verifying Hash Integrity ... ");
-               if (!fit_image_verify(fit, fdt_noffset)) {
-                       fdt_error("Bad Data Hash");
-                       return 0;
-               }
-               puts("OK\n");
-       }
-
-       if (!fit_image_check_type(fit, fdt_noffset, IH_TYPE_FLATDT)) {
-               fdt_error("Not a FDT image");
-               return 0;
-       }
-
-       if (!fit_image_check_comp(fit, fdt_noffset, IH_COMP_NONE)) {
-               fdt_error("FDT image is compressed");
-               return 0;
-       }
-
-       return 1;
-}
-#endif
-
 /**
  * boot_get_fdt - main fdt handling routine
  * @argc: command argument count
  * @argv: command argument list
+ * @arch: architecture (IH_ARCH_...)
  * @images: pointer to the bootm images structure
  * @of_flat_tree: pointer to a char* variable, will hold fdt start address
  * @of_size: pointer to a ulong variable, will hold fdt length
@@ -273,24 +233,20 @@ static int fit_check_fdt(const void *fit, int fdt_noffset, int verify)
  *     1, if fdt image is found but corrupted
  *     of_flat_tree and of_size are set to 0 if no fdt exists
  */
-int boot_get_fdt(int flag, int argc, char * const argv[],
+int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
                bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
 {
        const image_header_t *fdt_hdr;
        ulong           fdt_addr;
        char            *fdt_blob = NULL;
        ulong           image_start, image_data, image_end;
-       ulong           load_start, load_end;
+       ulong           load, load_end;
        void            *buf;
 #if defined(CONFIG_FIT)
-       void            *fit_hdr;
        const char      *fit_uname_config = NULL;
        const char      *fit_uname_fdt = NULL;
        ulong           default_addr;
-       int             cfg_noffset;
        int             fdt_noffset;
-       const void      *data;
-       size_t          size;
 #endif
 
        *of_flat_tree = NULL;
@@ -333,31 +289,15 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
                         * command argument
                         */
                        fdt_addr = map_to_sysmem(images->fit_hdr_os);
-                       fit_uname_config = images->fit_uname_cfg;
-                       debug("*  fdt: using config '%s' from image at 0x%08lx\n",
-                             fit_uname_config, fdt_addr);
-
-                       /*
-                        * Check whether configuration has FDT blob defined,
-                        * if not quit silently.
-                        */
-                       fit_hdr = images->fit_hdr_os;
-                       cfg_noffset = fit_conf_get_node(fit_hdr,
-                                       fit_uname_config);
-                       if (cfg_noffset < 0) {
-                               debug("*  fdt: no such config\n");
+                       fdt_noffset = fit_get_node_from_config(images,
+                                                              FIT_FDT_PROP,
+                                                              fdt_addr);
+                       if (fdt_noffset == -ENOLINK)
                                return 0;
-                       }
-
-                       fdt_noffset = fit_conf_get_fdt_node(fit_hdr,
-                                       cfg_noffset);
-                       if (fdt_noffset < 0) {
-                               debug("*  fdt: no fdt in config\n");
-                               return 0;
-                       }
+                       else if (fdt_noffset < 0)
+                               return 1;
                }
 #endif
-
                debug("## Checking for 'FDT'/'FDT Image' at %08lx\n",
                      fdt_addr);
 
@@ -387,29 +327,28 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
                        image_data = (ulong)image_get_data(fdt_hdr);
                        image_end = image_get_image_end(fdt_hdr);
 
-                       load_start = image_get_load(fdt_hdr);
-                       load_end = load_start + image_get_data_size(fdt_hdr);
+                       load = image_get_load(fdt_hdr);
+                       load_end = load + image_get_data_size(fdt_hdr);
 
-                       if (load_start == image_start ||
-                           load_start == image_data) {
+                       if (load == image_start ||
+                           load == image_data) {
                                fdt_blob = (char *)image_data;
                                break;
                        }
 
-                       if ((load_start < image_end) &&
-                           (load_end > image_start)) {
+                       if ((load < image_end) && (load_end > image_start)) {
                                fdt_error("fdt overwritten");
                                goto error;
                        }
 
                        debug("   Loading FDT from 0x%08lx to 0x%08lx\n",
-                             image_data, load_start);
+                             image_data, load);
 
-                       memmove((void *)load_start,
+                       memmove((void *)load,
                                (void *)image_data,
                                image_get_data_size(fdt_hdr));
 
-                       fdt_blob = (char *)load_start;
+                       fdt_addr = load;
                        break;
                case IMAGE_FORMAT_FIT:
                        /*
@@ -420,107 +359,20 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
 #if defined(CONFIG_FIT)
                        /* check FDT blob vs FIT blob */
                        if (fit_check_format(buf)) {
-                               /*
-                                * FIT image
-                                */
-                               fit_hdr = buf;
-                               printf("## Flattened Device Tree from FIT Image at %08lx\n",
-                                      fdt_addr);
-
-                               if (!fit_uname_fdt) {
-                                       /*
-                                        * no FDT blob image node unit name,
-                                        * try to get config node first. If
-                                        * config unit node name is NULL
-                                        * fit_conf_get_node() will try to
-                                        * find default config node
-                                        */
-                                       cfg_noffset = fit_conf_get_node(fit_hdr,
-                                                       fit_uname_config);
-
-                                       if (cfg_noffset < 0) {
-                                               fdt_error("Could not find configuration node\n");
-                                               goto error;
-                                       }
-
-                                       fit_uname_config = fdt_get_name(fit_hdr,
-                                                       cfg_noffset, NULL);
-                                       printf("   Using '%s' configuration\n",
-                                              fit_uname_config);
-
-                                       fdt_noffset = fit_conf_get_fdt_node(
-                                                       fit_hdr,
-                                                       cfg_noffset);
-                                       fit_uname_fdt = fit_get_name(fit_hdr,
-                                                       fdt_noffset, NULL);
-                               } else {
-                                       /*
-                                        * get FDT component image node
-                                        * offset
-                                        */
-                                       fdt_noffset = fit_image_get_node(
-                                                               fit_hdr,
-                                                               fit_uname_fdt);
-                               }
-                               if (fdt_noffset < 0) {
-                                       fdt_error("Could not find subimage node\n");
-                                       goto error;
-                               }
-
-                               printf("   Trying '%s' FDT blob subimage\n",
-                                      fit_uname_fdt);
-
-                               if (!fit_check_fdt(fit_hdr, fdt_noffset,
-                                                  images->verify))
-                                       goto error;
-
-                               /* get ramdisk image data address and length */
-                               if (fit_image_get_data(fit_hdr, fdt_noffset,
-                                                      &data, &size)) {
-                                       fdt_error("Could not find FDT subimage data");
-                                       goto error;
-                               }
+                               ulong load, len;
 
-                               /*
-                                * verify that image data is a proper FDT
-                                * blob
-                                */
-                               if (fdt_check_header((char *)data) != 0) {
-                                       fdt_error("Subimage data is not a FTD");
-                                       goto error;
-                               }
-
-                               /*
-                                * move image data to the load address,
-                                * make sure we don't overwrite initial image
-                                */
-                               image_start = (ulong)fit_hdr;
-                               image_end = fit_get_end(fit_hdr);
-
-                               if (fit_image_get_load(fit_hdr, fdt_noffset,
-                                                      &load_start) == 0) {
-                                       load_end = load_start + size;
+                               fdt_noffset = fit_image_load(images,
+                                       FIT_FDT_PROP,
+                                       fdt_addr, &fit_uname_fdt,
+                                       fit_uname_config,
+                                       arch, IH_TYPE_FLATDT,
+                                       BOOTSTAGE_ID_FIT_FDT_START,
+                                       FIT_LOAD_OPTIONAL, &load, &len);
 
-                                       if ((load_start < image_end) &&
-                                           (load_end > image_start)) {
-                                               fdt_error("FDT overwritten");
-                                               goto error;
-                                       }
-
-                                       printf("   Loading FDT from 0x%08lx to 0x%08lx\n",
-                                              (ulong)data, load_start);
-
-                                       memmove((void *)load_start,
-                                               (void *)data, size);
-
-                                       fdt_blob = (char *)load_start;
-                               } else {
-                                       fdt_blob = (char *)data;
-                               }
-
-                               images->fit_hdr_fdt = fit_hdr;
+                               images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
                                images->fit_uname_fdt = fit_uname_fdt;
                                images->fit_noffset_fdt = fdt_noffset;
+                               fdt_addr = load;
                                break;
                        } else
 #endif
@@ -528,7 +380,6 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
                                /*
                                 * FDT blob
                                 */
-                               fdt_blob = buf;
                                debug("*  fdt: raw FDT blob\n");
                                printf("## Flattened Device Tree blob at %08lx\n",
                                       (long)fdt_addr);
@@ -539,8 +390,8 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
                        goto error;
                }
 
-               printf("   Booting using the fdt blob at 0x%p\n", fdt_blob);
-
+               printf("   Booting using the fdt blob at %#08lx\n", fdt_addr);
+               fdt_blob = map_sysmem(fdt_addr, 0);
        } else if (images->legacy_hdr_valid &&
                        image_check_type(&images->legacy_hdr_os_copy,
                                         IH_TYPE_MULTI)) {
index 254feecaad7cf807bf905aabfc49f806bc92f70c..f40f1603f316b277646afb26bd1d9ee19b9adc14 100644 (file)
@@ -31,6 +31,9 @@
 #include <time.h>
 #else
 #include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR;
 #endif /* !USE_HOSTCC*/
 
 #include <bootstage.h>
@@ -348,10 +351,13 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
 
 #ifndef USE_HOSTCC
        printf("%s  Data Start:   ", p);
-       if (ret)
+       if (ret) {
                printf("unavailable\n");
-       else
-               printf("0x%08lx\n", (ulong)data);
+       } else {
+               void *vdata = (void *)data;
+
+               printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
+       }
 #endif
 
        printf("%s  Data Size:    ", p);
@@ -1348,63 +1354,6 @@ int fit_conf_get_prop_node(const void *fit, int noffset,
        return fit_image_get_node(fit, uname);
 }
 
-/**
- * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
- * a given configuration
- * @fit: pointer to the FIT format image header
- * @noffset: configuration node offset
- *
- * fit_conf_get_kernel_node() retrives kernel image node unit name from
- * configuration FIT_KERNEL_PROP property and translates it to the node
- * offset.
- *
- * returns:
- *     image node offset when found (>=0)
- *     negative number on failure (FDT_ERR_* code)
- */
-int fit_conf_get_kernel_node(const void *fit, int noffset)
-{
-       return fit_conf_get_prop_node(fit, noffset, FIT_KERNEL_PROP);
-}
-
-/**
- * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
- * a given configuration
- * @fit: pointer to the FIT format image header
- * @noffset: configuration node offset
- *
- * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
- * configuration FIT_KERNEL_PROP property and translates it to the node
- * offset.
- *
- * returns:
- *     image node offset when found (>=0)
- *     negative number on failure (FDT_ERR_* code)
- */
-int fit_conf_get_ramdisk_node(const void *fit, int noffset)
-{
-       return fit_conf_get_prop_node(fit, noffset, FIT_RAMDISK_PROP);
-}
-
-/**
- * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
- * a given configuration
- * @fit: pointer to the FIT format image header
- * @noffset: configuration node offset
- *
- * fit_conf_get_fdt_node() retrives fdt image node unit name from
- * configuration FIT_KERNEL_PROP property and translates it to the node
- * offset.
- *
- * returns:
- *     image node offset when found (>=0)
- *     negative number on failure (FDT_ERR_* code)
- */
-int fit_conf_get_fdt_node(const void *fit, int noffset)
-{
-       return fit_conf_get_prop_node(fit, noffset, FIT_FDT_PROP);
-}
-
 /**
  * fit_conf_print - prints out the FIT configuration details
  * @fit: pointer to the FIT format image header
@@ -1448,22 +1397,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
                printf("%s  FDT:          %s\n", p, uname);
 }
 
-/**
- * fit_check_ramdisk - verify FIT format ramdisk subimage
- * @fit_hdr: pointer to the FIT ramdisk header
- * @rd_noffset: ramdisk subimage node offset within FIT image
- * @arch: requested ramdisk image architecture type
- * @verify: data CRC verification flag
- *
- * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
- * specified FIT image.
- *
- * returns:
- *     1, on success
- *     0, on failure
- */
-int fit_check_ramdisk(const void *fit, int rd_noffset, uint8_t arch,
-                       int verify)
+int fit_image_select(const void *fit, int rd_noffset, int verify)
 {
        fit_image_print(fit, rd_noffset, "   ");
 
@@ -1471,22 +1405,222 @@ int fit_check_ramdisk(const void *fit, int rd_noffset, uint8_t arch,
                puts("   Verifying Hash Integrity ... ");
                if (!fit_image_verify(fit, rd_noffset)) {
                        puts("Bad Data Hash\n");
-                       bootstage_error(BOOTSTAGE_ID_FIT_RD_HASH);
-                       return 0;
+                       return -EACCES;
                }
                puts("OK\n");
        }
 
-       bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
-       if (!fit_image_check_os(fit, rd_noffset, IH_OS_LINUX) ||
-           !fit_image_check_arch(fit, rd_noffset, arch) ||
-           !fit_image_check_type(fit, rd_noffset, IH_TYPE_RAMDISK)) {
-               printf("No Linux %s Ramdisk Image\n",
-                      genimg_get_arch_name(arch));
-               bootstage_error(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
-               return 0;
+       return 0;
+}
+
+int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
+                       ulong addr)
+{
+       int cfg_noffset;
+       void *fit_hdr;
+       int noffset;
+
+       debug("*  %s: using config '%s' from image at 0x%08lx\n",
+             prop_name, images->fit_uname_cfg, addr);
+
+       /* Check whether configuration has this property defined */
+       fit_hdr = map_sysmem(addr, 0);
+       cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
+       if (cfg_noffset < 0) {
+               debug("*  %s: no such config\n", prop_name);
+               return -ENOENT;
        }
 
-       bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK);
-       return 1;
+       noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
+       if (noffset < 0) {
+               debug("*  %s: no '%s' in config\n", prop_name, prop_name);
+               return -ENOLINK;
+       }
+
+       return noffset;
+}
+
+int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
+                  const char **fit_unamep, const char *fit_uname_config,
+                  int arch, int image_type, int bootstage_id,
+                  enum fit_load_op load_op, ulong *datap, ulong *lenp)
+{
+       int cfg_noffset, noffset;
+       const char *fit_uname;
+       const void *fit;
+       const void *buf;
+       size_t size;
+       int type_ok, os_ok;
+       ulong load, data, len;
+       int ret;
+
+       fit = map_sysmem(addr, 0);
+       fit_uname = fit_unamep ? *fit_unamep : NULL;
+       printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
+       if (!fit_check_format(fit)) {
+               printf("Bad FIT %s image format!\n", prop_name);
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
+               return -ENOEXEC;
+       }
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
+       if (fit_uname) {
+               /* get ramdisk component image node offset */
+               bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
+               noffset = fit_image_get_node(fit, fit_uname);
+       } else {
+               /*
+                * no image node unit name, try to get config
+                * node first. If config unit node name is NULL
+                * fit_conf_get_node() will try to find default config node
+                */
+               bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
+               if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) {
+                       cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
+               } else {
+                       cfg_noffset = fit_conf_get_node(fit,
+                                                       fit_uname_config);
+               }
+               if (cfg_noffset < 0) {
+                       puts("Could not find configuration node\n");
+                       bootstage_error(bootstage_id +
+                                       BOOTSTAGE_SUB_NO_UNIT_NAME);
+                       return -ENOENT;
+               }
+               fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
+               printf("   Using '%s' configuration\n", fit_uname_config);
+               if (image_type == IH_TYPE_KERNEL) {
+                       /* Remember (and possibly verify) this config */
+                       images->fit_uname_cfg = fit_uname_config;
+                       if (IMAGE_ENABLE_VERIFY && images->verify) {
+                               puts("   Verifying Hash Integrity ... ");
+                               if (!fit_config_verify(fit, cfg_noffset)) {
+                                       puts("Bad Data Hash\n");
+                                       bootstage_error(bootstage_id +
+                                               BOOTSTAGE_SUB_HASH);
+                                       return -EACCES;
+                               }
+                               puts("OK\n");
+                       }
+                       bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
+               }
+
+               noffset = fit_conf_get_prop_node(fit, cfg_noffset,
+                                                prop_name);
+               fit_uname = fit_get_name(fit, noffset, NULL);
+       }
+       if (noffset < 0) {
+               puts("Could not find subimage node\n");
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
+               return -ENOENT;
+       }
+
+       printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);
+
+       ret = fit_image_select(fit, noffset, images->verify);
+       if (ret) {
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
+               return ret;
+       }
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
+       if (!fit_image_check_target_arch(fit, noffset)) {
+               puts("Unsupported Architecture\n");
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
+               return -ENOEXEC;
+       }
+
+       if (image_type == IH_TYPE_FLATDT &&
+           !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
+               puts("FDT image is compressed");
+               return -EPROTONOSUPPORT;
+       }
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
+       type_ok = fit_image_check_type(fit, noffset, image_type) ||
+               (image_type == IH_TYPE_KERNEL &&
+                       fit_image_check_type(fit, noffset,
+                                            IH_TYPE_KERNEL_NOLOAD));
+       os_ok = image_type == IH_TYPE_FLATDT ||
+               fit_image_check_os(fit, noffset, IH_OS_LINUX);
+       if (!type_ok || !os_ok) {
+               printf("No Linux %s %s Image\n", genimg_get_arch_name(arch),
+                      genimg_get_type_name(image_type));
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
+               return -EIO;
+       }
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
+
+       /* get image data address and length */
+       if (fit_image_get_data(fit, noffset, &buf, &size)) {
+               printf("Could not find %s subimage data!\n", prop_name);
+               bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
+               return -ENOENT;
+       }
+       len = (ulong)size;
+
+       /* verify that image data is a proper FDT blob */
+       if (image_type == IH_TYPE_FLATDT && fdt_check_header((char *)buf)) {
+               puts("Subimage data is not a FDT");
+               return -ENOEXEC;
+       }
+
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
+
+       /*
+        * Work-around for eldk-4.2 which gives this warning if we try to
+        * case in the unmap_sysmem() call:
+        * warning: initialization discards qualifiers from pointer target type
+        */
+       {
+               void *vbuf = (void *)buf;
+
+               data = map_to_sysmem(vbuf);
+       }
+
+       if (load_op == FIT_LOAD_IGNORED) {
+               /* Don't load */
+       } else if (fit_image_get_load(fit, noffset, &load)) {
+               if (load_op == FIT_LOAD_REQUIRED) {
+                       printf("Can't get %s subimage load address!\n",
+                              prop_name);
+                       bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
+                       return -EBADF;
+               }
+       } else {
+               ulong image_start, image_end;
+               ulong load_end;
+               void *dst;
+
+               /*
+                * move image data to the load address,
+                * make sure we don't overwrite initial image
+                */
+               image_start = addr;
+               image_end = addr + fit_get_size(fit);
+
+               load_end = load + len;
+               if (image_type != IH_TYPE_KERNEL &&
+                   load < image_end && load_end > image_start) {
+                       printf("Error: %s overwritten\n", prop_name);
+                       return -EXDEV;
+               }
+
+               printf("   Loading %s from 0x%08lx to 0x%08lx\n",
+                      prop_name, data, load);
+
+               dst = map_sysmem(load, len);
+               memmove(dst, buf, len);
+               data = load;
+       }
+       bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
+
+       *datap = data;
+       *lenp = len;
+       if (fit_unamep)
+               *fit_unamep = (char *)fit_uname;
+
+       return noffset;
 }
index e91c89e1c5d61890bc6f9eee6476b566328b0b9d..f863502ab130d0bf08ab1f8cf8e526c31484956a 100644 (file)
@@ -51,6 +51,7 @@
 
 #include <u-boot/md5.h>
 #include <sha1.h>
+#include <asm/errno.h>
 #include <asm/io.h>
 
 #ifdef CONFIG_CMD_BDI
@@ -810,14 +811,10 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
        char *end;
 #endif
 #if defined(CONFIG_FIT)
-       void            *fit_hdr;
        const char      *fit_uname_config = NULL;
        const char      *fit_uname_ramdisk = NULL;
        ulong           default_addr;
        int             rd_noffset;
-       int             cfg_noffset;
-       const void      *data;
-       size_t          size;
 #endif
 
        *rd_start = 0;
@@ -865,32 +862,16 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
 #if defined(CONFIG_FIT)
                } else {
                        /* use FIT configuration provided in first bootm
-                        * command argument
+                        * command argument. If the property is not defined,
+                        * quit silently.
                         */
                        rd_addr = map_to_sysmem(images->fit_hdr_os);
-                       fit_uname_config = images->fit_uname_cfg;
-                       debug("*  ramdisk: using config '%s' from image "
-                                       "at 0x%08lx\n",
-                                       fit_uname_config, rd_addr);
-
-                       /*
-                        * Check whether configuration has ramdisk defined,
-                        * if not, don't try to use it, quit silently.
-                        */
-                       fit_hdr = images->fit_hdr_os;
-                       cfg_noffset = fit_conf_get_node(fit_hdr,
-                                                       fit_uname_config);
-                       if (cfg_noffset < 0) {
-                               debug("*  ramdisk: no such config\n");
-                               return 1;
-                       }
-
-                       rd_noffset = fit_conf_get_ramdisk_node(fit_hdr,
-                                                               cfg_noffset);
-                       if (rd_noffset < 0) {
-                               debug("*  ramdisk: no ramdisk in config\n");
+                       rd_noffset = fit_get_node_from_config(images,
+                                       FIT_RAMDISK_PROP, rd_addr);
+                       if (rd_noffset == -ENOLINK)
                                return 0;
-                       }
+                       else if (rd_noffset < 0)
+                               return 1;
                }
 #endif
 
@@ -921,87 +902,16 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
                        break;
 #if defined(CONFIG_FIT)
                case IMAGE_FORMAT_FIT:
-                       fit_hdr = buf;
-                       printf("## Loading init Ramdisk from FIT "
-                                       "Image at %08lx ...\n", rd_addr);
-
-                       bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT);
-                       if (!fit_check_format(fit_hdr)) {
-                               puts("Bad FIT ramdisk image format!\n");
-                               bootstage_error(
-                                       BOOTSTAGE_ID_FIT_RD_FORMAT);
+                       rd_noffset = fit_image_load(images, FIT_RAMDISK_PROP,
+                                       rd_addr, &fit_uname_ramdisk,
+                                       fit_uname_config, arch,
+                                       IH_TYPE_RAMDISK,
+                                       BOOTSTAGE_ID_FIT_RD_START,
+                                       FIT_LOAD_REQUIRED, &rd_data, &rd_len);
+                       if (rd_noffset < 0)
                                return 1;
-                       }
-                       bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT_OK);
-
-                       if (!fit_uname_ramdisk) {
-                               /*
-                                * no ramdisk image node unit name, try to get config
-                                * node first. If config unit node name is NULL
-                                * fit_conf_get_node() will try to find default config node
-                                */
-                               bootstage_mark(
-                                       BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME);
-                               cfg_noffset = fit_conf_get_node(fit_hdr,
-                                                       fit_uname_config);
-                               if (cfg_noffset < 0) {
-                                       puts("Could not find configuration "
-                                               "node\n");
-                                       bootstage_error(
-                                       BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME);
-                                       return 1;
-                               }
-                               fit_uname_config = fdt_get_name(fit_hdr,
-                                                       cfg_noffset, NULL);
-                               printf("   Using '%s' configuration\n",
-                                       fit_uname_config);
-
-                               rd_noffset = fit_conf_get_ramdisk_node(fit_hdr,
-                                                       cfg_noffset);
-                               fit_uname_ramdisk = fit_get_name(fit_hdr,
-                                                       rd_noffset, NULL);
-                       } else {
-                               /* get ramdisk component image node offset */
-                               bootstage_mark(
-                                       BOOTSTAGE_ID_FIT_RD_UNIT_NAME);
-                               rd_noffset = fit_image_get_node(fit_hdr,
-                                               fit_uname_ramdisk);
-                       }
-                       if (rd_noffset < 0) {
-                               puts("Could not find subimage node\n");
-                               bootstage_error(BOOTSTAGE_ID_FIT_RD_SUBNODE);
-                               return 1;
-                       }
-
-                       printf("   Trying '%s' ramdisk subimage\n",
-                               fit_uname_ramdisk);
-
-                       bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK);
-                       if (!fit_check_ramdisk(fit_hdr, rd_noffset, arch,
-                                               images->verify))
-                               return 1;
-
-                       /* get ramdisk image data address and length */
-                       if (fit_image_get_data(fit_hdr, rd_noffset, &data,
-                                               &size)) {
-                               puts("Could not find ramdisk subimage data!\n");
-                               bootstage_error(BOOTSTAGE_ID_FIT_RD_GET_DATA);
-                               return 1;
-                       }
-                       bootstage_mark(BOOTSTAGE_ID_FIT_RD_GET_DATA_OK);
-
-                       rd_data = (ulong)data;
-                       rd_len = size;
-
-                       if (fit_image_get_load(fit_hdr, rd_noffset, &rd_load)) {
-                               puts("Can't get ramdisk subimage load "
-                                       "address!\n");
-                               bootstage_error(BOOTSTAGE_ID_FIT_RD_LOAD);
-                               return 1;
-                       }
-                       bootstage_mark(BOOTSTAGE_ID_FIT_RD_LOAD);
 
-                       images->fit_hdr_rd = fit_hdr;
+                       images->fit_hdr_rd = map_sysmem(rd_addr, 0);
                        images->fit_uname_rd = fit_uname_ramdisk;
                        images->fit_noffset_rd = rd_noffset;
                        break;
index edae835fb0be1e6eb1fccdbf373b42dfc588ee31..3a60484eea615a4f20bd78109f738de26478c88f 100644 (file)
 #include <atmel_lcdc.h>
 #endif
 
+#if defined(CONFIG_LCD_DT_SIMPLEFB)
+#include <libfdt.h>
+#endif
+
 /************************************************************************/
 /* ** FONT DATA                                                                */
 /************************************************************************/
@@ -1182,3 +1186,86 @@ int lcd_get_screen_columns(void)
 {
        return CONSOLE_COLS;
 }
+
+#if defined(CONFIG_LCD_DT_SIMPLEFB)
+static int lcd_dt_simplefb_configure_node(void *blob, int off)
+{
+       u32 stride;
+       fdt32_t cells[2];
+       int ret;
+       const char format[] =
+#if LCD_BPP == LCD_COLOR16
+               "r5g6b5";
+#else
+               "";
+#endif
+
+       if (!format[0])
+               return -1;
+
+       stride = panel_info.vl_col * 2;
+
+       cells[0] = cpu_to_fdt32(gd->fb_base);
+       cells[1] = cpu_to_fdt32(stride * panel_info.vl_row);
+       ret = fdt_setprop(blob, off, "reg", cells, sizeof(cells[0]) * 2);
+       if (ret < 0)
+               return -1;
+
+       cells[0] = cpu_to_fdt32(panel_info.vl_col);
+       ret = fdt_setprop(blob, off, "width", cells, sizeof(cells[0]));
+       if (ret < 0)
+               return -1;
+
+       cells[0] = cpu_to_fdt32(panel_info.vl_row);
+       ret = fdt_setprop(blob, off, "height", cells, sizeof(cells[0]));
+       if (ret < 0)
+               return -1;
+
+       cells[0] = cpu_to_fdt32(stride);
+       ret = fdt_setprop(blob, off, "stride", cells, sizeof(cells[0]));
+       if (ret < 0)
+               return -1;
+
+       ret = fdt_setprop(blob, off, "format", format, strlen(format) + 1);
+       if (ret < 0)
+               return -1;
+
+       ret = fdt_delprop(blob, off, "status");
+       if (ret < 0)
+               return -1;
+
+       return 0;
+}
+
+int lcd_dt_simplefb_add_node(void *blob)
+{
+       const char compat[] = "simple-framebuffer";
+       const char disabled[] = "disabled";
+       int off, ret;
+
+       off = fdt_add_subnode(blob, 0, "framebuffer");
+       if (off < 0)
+               return -1;
+
+       ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled));
+       if (ret < 0)
+               return -1;
+
+       ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat));
+       if (ret < 0)
+               return -1;
+
+       return lcd_dt_simplefb_configure_node(blob, off);
+}
+
+int lcd_dt_simplefb_enable_existing_node(void *blob)
+{
+       int off;
+
+       off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer");
+       if (off < 0)
+               return -1;
+
+       return lcd_dt_simplefb_configure_node(blob, off);
+}
+#endif
index 953ef296b197fd7dcb8dbd692f8d437b63b7df7b..56da214b2660a2cae8bbe012c82d0339536fe880 100644 (file)
 /* #define     DEBUG   */
 
 #include <common.h>
-#include <watchdog.h>
 #include <command.h>
 #include <fdtdec.h>
-#include <malloc.h>
-#include <version.h>
-#ifdef CONFIG_MODEM_SUPPORT
-#include <malloc.h>            /* for free() prototype */
-#endif
-
-#ifdef CONFIG_SYS_HUSH_PARSER
 #include <hush.h>
-#endif
-
-#ifdef CONFIG_OF_CONTROL
-#include <fdtdec.h>
-#endif
-
+#include <malloc.h>
+#include <menu.h>
 #include <post.h>
+#include <version.h>
+#include <watchdog.h>
 #include <linux/ctype.h>
-#include <menu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -57,13 +46,18 @@ DECLARE_GLOBAL_DATA_PTR;
 void inline __show_boot_progress (int val) {}
 void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
 
-#if defined(CONFIG_UPDATE_TFTP)
-int update_tftp (ulong addr);
-#endif /* CONFIG_UPDATE_TFTP */
-
 #define MAX_DELAY_STOP_STR 32
 
-#undef DEBUG_PARSER
+#define DEBUG_PARSER   0       /* set to 1 to debug */
+
+#define debug_parser(fmt, args...)             \
+       debug_cond(DEBUG_PARSER, fmt, ##args)
+
+#ifndef DEBUG_BOOTKEYS
+#define DEBUG_BOOTKEYS 0
+#endif
+#define debug_bootkeys(fmt, args...)           \
+       debug_cond(DEBUG_BOOTKEYS, fmt, ##args)
 
 char        console_buffer[CONFIG_SYS_CBSIZE + 1];     /* console I/O buffer   */
 
@@ -93,10 +87,7 @@ extern void mdm_init(void); /* defined in board.c */
  */
 #if defined(CONFIG_BOOTDELAY)
 # if defined(CONFIG_AUTOBOOT_KEYED)
-#ifndef CONFIG_MENU
-static inline
-#endif
-int abortboot(int bootdelay)
+static int abortboot_keyed(int bootdelay)
 {
        int abort = 0;
        uint64_t etime = endtick(bootdelay);
@@ -152,11 +143,9 @@ int abortboot(int bootdelay)
                presskey_max = presskey_max > delaykey[i].len ?
                                    presskey_max : delaykey[i].len;
 
-#  if DEBUG_BOOTKEYS
-               printf("%s key:<%s>\n",
-                      delaykey[i].retry ? "delay" : "stop",
-                      delaykey[i].str ? delaykey[i].str : "NULL");
-#  endif
+               debug_bootkeys("%s key:<%s>\n",
+                              delaykey[i].retry ? "delay" : "stop",
+                              delaykey[i].str ? delaykey[i].str : "NULL");
        }
 
        /* In order to keep up with incoming data, check timeout only
@@ -181,10 +170,9 @@ int abortboot(int bootdelay)
                            memcmp (presskey + presskey_len - delaykey[i].len,
                                    delaykey[i].str,
                                    delaykey[i].len) == 0) {
-#  if DEBUG_BOOTKEYS
-                               printf("got %skey\n",
-                                      delaykey[i].retry ? "delay" : "stop");
-#  endif
+                               debug_bootkeys("got %skey\n",
+                                              delaykey[i].retry ? "delay" :
+                                              "stop");
 
 #  ifdef CONFIG_BOOT_RETRY_TIME
                                /* don't retry auto boot */
@@ -196,10 +184,8 @@ int abortboot(int bootdelay)
                }
        } while (!abort && get_ticks() <= etime);
 
-#  if DEBUG_BOOTKEYS
        if (!abort)
-               puts("key timeout\n");
-#  endif
+               debug_bootkeys("key timeout\n");
 
 #ifdef CONFIG_SILENT_CONSOLE
        if (abort)
@@ -215,10 +201,7 @@ int abortboot(int bootdelay)
 static int menukey = 0;
 #endif
 
-#ifndef CONFIG_MENU
-static inline
-#endif
-int abortboot(int bootdelay)
+static int abortboot_normal(int bootdelay)
 {
        int abort = 0;
        unsigned long ts;
@@ -275,6 +258,15 @@ int abortboot(int bootdelay)
        return abort;
 }
 # endif        /* CONFIG_AUTOBOOT_KEYED */
+
+static int abortboot(int bootdelay)
+{
+#ifdef CONFIG_AUTOBOOT_KEYED
+       return abortboot_keyed(bootdelay);
+#else
+       return abortboot_normal(bootdelay);
+#endif
+}
 #endif /* CONFIG_BOOTDELAY */
 
 /*
@@ -342,93 +334,35 @@ static void process_fdt_options(const void *blob)
 }
 #endif /* CONFIG_OF_CONTROL */
 
-
-/****************************************************************************/
-
-void main_loop (void)
+#ifdef CONFIG_BOOTDELAY
+static void process_boot_delay(void)
 {
-#ifndef CONFIG_SYS_HUSH_PARSER
-       static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
-       int len;
-       int rc = 1;
-       int flag;
-#endif
-#if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL)
+#ifdef CONFIG_OF_CONTROL
        char *env;
 #endif
-#if defined(CONFIG_BOOTDELAY)
        char *s;
        int bootdelay;
-#endif
-#ifdef CONFIG_PREBOOT
-       char *p;
-#endif
 #ifdef CONFIG_BOOTCOUNT_LIMIT
        unsigned long bootcount = 0;
        unsigned long bootlimit = 0;
-       char *bcs;
-       char bcs_set[16];
 #endif /* CONFIG_BOOTCOUNT_LIMIT */
 
-       bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
-
 #ifdef CONFIG_BOOTCOUNT_LIMIT
        bootcount = bootcount_load();
        bootcount++;
        bootcount_store (bootcount);
-       sprintf (bcs_set, "%lu", bootcount);
-       setenv ("bootcount", bcs_set);
-       bcs = getenv ("bootlimit");
-       bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0;
+       setenv_ulong("bootcount", bootcount);
+       bootlimit = getenv_ulong("bootlimit", 10, 0);
 #endif /* CONFIG_BOOTCOUNT_LIMIT */
 
-#ifdef CONFIG_MODEM_SUPPORT
-       debug ("DEBUG: main_loop:   do_mdm_init=%d\n", do_mdm_init);
-       if (do_mdm_init) {
-               char *str = strdup(getenv("mdm_cmd"));
-               setenv ("preboot", str);  /* set or delete definition */
-               if (str != NULL)
-                       free (str);
-               mdm_init(); /* wait for modem connection */
-       }
-#endif  /* CONFIG_MODEM_SUPPORT */
-
-#ifdef CONFIG_VERSION_VARIABLE
-       {
-               setenv ("ver", version_string);  /* set version variable */
-       }
-#endif /* CONFIG_VERSION_VARIABLE */
-
-#ifdef CONFIG_SYS_HUSH_PARSER
-       u_boot_hush_start ();
-#endif
-
-#if defined(CONFIG_HUSH_INIT_VAR)
-       hush_init_var ();
-#endif
-
-#ifdef CONFIG_PREBOOT
-       if ((p = getenv ("preboot")) != NULL) {
-# ifdef CONFIG_AUTOBOOT_KEYED
-               int prev = disable_ctrlc(1);    /* disable Control C checking */
-# endif
-
-               run_command_list(p, -1, 0);
-
-# ifdef CONFIG_AUTOBOOT_KEYED
-               disable_ctrlc(prev);    /* restore Control C checking */
-# endif
-       }
-#endif /* CONFIG_PREBOOT */
-
-#if defined(CONFIG_UPDATE_TFTP)
-       update_tftp (0UL);
-#endif /* CONFIG_UPDATE_TFTP */
-
-#if defined(CONFIG_BOOTDELAY)
        s = getenv ("bootdelay");
        bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
 
+#ifdef CONFIG_OF_CONTROL
+       bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay",
+                       bootdelay);
+#endif
+
        debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
 
 #if defined(CONFIG_MENU_SHOW)
@@ -474,26 +408,88 @@ void main_loop (void)
        debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
 
        if (bootdelay != -1 && s && !abortboot(bootdelay)) {
-# ifdef CONFIG_AUTOBOOT_KEYED
+#ifdef CONFIG_AUTOBOOT_KEYED
                int prev = disable_ctrlc(1);    /* disable Control C checking */
-# endif
+#endif
 
                run_command_list(s, -1, 0);
 
-# ifdef CONFIG_AUTOBOOT_KEYED
+#ifdef CONFIG_AUTOBOOT_KEYED
                disable_ctrlc(prev);    /* restore Control C checking */
-# endif
+#endif
        }
 
-# ifdef CONFIG_MENUKEY
+#ifdef CONFIG_MENUKEY
        if (menukey == CONFIG_MENUKEY) {
                s = getenv("menucmd");
                if (s)
                        run_command_list(s, -1, 0);
        }
 #endif /* CONFIG_MENUKEY */
+}
 #endif /* CONFIG_BOOTDELAY */
 
+void main_loop(void)
+{
+#ifndef CONFIG_SYS_HUSH_PARSER
+       static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
+       int len;
+       int rc = 1;
+       int flag;
+#endif
+#ifdef CONFIG_PREBOOT
+       char *p;
+#endif
+
+       bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
+
+#ifdef CONFIG_MODEM_SUPPORT
+       debug("DEBUG: main_loop:   do_mdm_init=%d\n", do_mdm_init);
+       if (do_mdm_init) {
+               char *str = strdup(getenv("mdm_cmd"));
+               setenv("preboot", str);  /* set or delete definition */
+               if (str != NULL)
+                       free(str);
+               mdm_init(); /* wait for modem connection */
+       }
+#endif  /* CONFIG_MODEM_SUPPORT */
+
+#ifdef CONFIG_VERSION_VARIABLE
+       {
+               setenv("ver", version_string);  /* set version variable */
+       }
+#endif /* CONFIG_VERSION_VARIABLE */
+
+#ifdef CONFIG_SYS_HUSH_PARSER
+       u_boot_hush_start();
+#endif
+
+#if defined(CONFIG_HUSH_INIT_VAR)
+       hush_init_var();
+#endif
+
+#ifdef CONFIG_PREBOOT
+       p = getenv("preboot");
+       if (p != NULL) {
+# ifdef CONFIG_AUTOBOOT_KEYED
+               int prev = disable_ctrlc(1);    /* disable Control C checking */
+# endif
+
+               run_command_list(p, -1, 0);
+
+# ifdef CONFIG_AUTOBOOT_KEYED
+               disable_ctrlc(prev);    /* restore Control C checking */
+# endif
+       }
+#endif /* CONFIG_PREBOOT */
+
+#if defined(CONFIG_UPDATE_TFTP)
+       update_tftp(0UL);
+#endif /* CONFIG_UPDATE_TFTP */
+
+#ifdef CONFIG_BOOTDELAY
+       process_boot_delay();
+#endif
        /*
         * Main Loop for Monitor Command Processing
         */
@@ -1080,20 +1076,20 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
                 * Special character handling
                 */
                switch (c) {
-               case '\r':                              /* Enter                */
+               case '\r':                      /* Enter                */
                case '\n':
                        *p = '\0';
                        puts ("\r\n");
-                       return (p - p_buf);
+                       return p - p_buf;
 
-               case '\0':                              /* nul                  */
+               case '\0':                      /* nul                  */
                        continue;
 
-               case 0x03:                              /* ^C - break           */
+               case 0x03:                      /* ^C - break           */
                        p_buf[0] = '\0';        /* discard input */
-                       return (-1);
+                       return -1;
 
-               case 0x15:                              /* ^U - erase line      */
+               case 0x15:                      /* ^U - erase line      */
                        while (col > plen) {
                                puts (erase_seq);
                                --col;
@@ -1102,15 +1098,15 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
                        n = 0;
                        continue;
 
-               case 0x17:                              /* ^W - erase word      */
+               case 0x17:                      /* ^W - erase word      */
                        p=delete_char(p_buf, p, &col, &n, plen);
                        while ((n > 0) && (*p != ' ')) {
                                p=delete_char(p_buf, p, &col, &n, plen);
                        }
                        continue;
 
-               case 0x08:                              /* ^H  - backspace      */
-               case 0x7F:                              /* DEL - backspace      */
+               case 0x08:                      /* ^H  - backspace      */
+               case 0x7F:                      /* DEL - backspace      */
                        p=delete_char(p_buf, p, &col, &n, plen);
                        continue;
 
@@ -1119,7 +1115,7 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
                         * Must be a normal character then
                         */
                        if (n < CONFIG_SYS_CBSIZE-2) {
-                               if (c == '\t') {        /* expand TABs          */
+                               if (c == '\t') {        /* expand TABs */
 #ifdef CONFIG_AUTO_COMPLETE
                                        /* if auto completion triggered just continue */
                                        *p = '\0';
@@ -1134,7 +1130,7 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
                                        char buf[2];
 
                                        /*
-                                        * Echo input using puts() to force am
+                                        * Echo input using puts() to force an
                                         * LCD flush if we are using an LCD
                                         */
                                        ++col;
@@ -1192,9 +1188,7 @@ int parse_line (char *line, char *argv[])
 {
        int nargs = 0;
 
-#ifdef DEBUG_PARSER
-       printf ("parse_line: \"%s\"\n", line);
-#endif
+       debug_parser("parse_line: \"%s\"\n", line);
        while (nargs < CONFIG_SYS_MAXARGS) {
 
                /* skip any white space */
@@ -1203,10 +1197,8 @@ int parse_line (char *line, char *argv[])
 
                if (*line == '\0') {    /* end of line, no more args    */
                        argv[nargs] = NULL;
-#ifdef DEBUG_PARSER
-               printf ("parse_line: nargs=%d\n", nargs);
-#endif
-                       return (nargs);
+                       debug_parser("parse_line: nargs=%d\n", nargs);
+                       return nargs;
                }
 
                argv[nargs++] = line;   /* begin of argument string     */
@@ -1217,10 +1209,8 @@ int parse_line (char *line, char *argv[])
 
                if (*line == '\0') {    /* end of line, no more args    */
                        argv[nargs] = NULL;
-#ifdef DEBUG_PARSER
-               printf ("parse_line: nargs=%d\n", nargs);
-#endif
-                       return (nargs);
+                       debug_parser("parse_line: nargs=%d\n", nargs);
+                       return nargs;
                }
 
                *line++ = '\0';         /* terminate current arg         */
@@ -1228,9 +1218,7 @@ int parse_line (char *line, char *argv[])
 
        printf ("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS);
 
-#ifdef DEBUG_PARSER
-       printf ("parse_line: nargs=%d\n", nargs);
-#endif
+       debug_parser("parse_line: nargs=%d\n", nargs);
        return (nargs);
 }
 
@@ -1248,12 +1236,10 @@ static void process_macros (const char *input, char *output)
        /* 1 = waiting for '(' or '{' */
        /* 2 = waiting for ')' or '}' */
        /* 3 = waiting for '''  */
-#ifdef DEBUG_PARSER
        char *output_start = output;
 
-       printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input),
-               input);
-#endif
+       debug_parser("[PROCESS_MACROS] INPUT len %zd: \"%s\"\n", strlen(input),
+                    input);
 
        prev = '\0';            /* previous character   */
 
@@ -1341,10 +1327,8 @@ static void process_macros (const char *input, char *output)
        else
                *(output - 1) = 0;
 
-#ifdef DEBUG_PARSER
-       printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
-               strlen (output_start), output_start);
-#endif
+       debug_parser("[PROCESS_MACROS] OUTPUT len %zd: \"%s\"\n",
+                    strlen(output_start), output_start);
 }
 
 /****************************************************************************
@@ -1375,12 +1359,12 @@ static int builtin_run_command(const char *cmd, int flag)
        int repeatable = 1;
        int rc = 0;
 
-#ifdef DEBUG_PARSER
-       printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
-       puts (cmd ? cmd : "NULL");      /* use puts - string may be loooong */
-       puts ("\"\n");
-#endif
-
+       debug_parser("[RUN_COMMAND] cmd[%p]=\"", cmd);
+       if (DEBUG_PARSER) {
+               /* use puts - string may be loooong */
+               puts(cmd ? cmd : "NULL");
+               puts("\"\n");
+       }
        clear_ctrlc();          /* forget any previous Control C */
 
        if (!cmd || !*cmd) {
@@ -1398,9 +1382,7 @@ static int builtin_run_command(const char *cmd, int flag)
         * repeatable commands
         */
 
-#ifdef DEBUG_PARSER
-       printf ("[PROCESS_SEPARATORS] %s\n", cmd);
-#endif
+       debug_parser("[PROCESS_SEPARATORS] %s\n", cmd);
        while (*str) {
 
                /*
@@ -1429,9 +1411,7 @@ static int builtin_run_command(const char *cmd, int flag)
                }
                else
                        str = sep;      /* no more commands for next pass */
-#ifdef DEBUG_PARSER
-               printf ("token: \"%s\"\n", token);
-#endif
+               debug_parser("token: \"%s\"\n", token);
 
                /* find macros in this token and replace them */
                process_macros (token, finaltoken);
index 7efdcb88b73412b7602c72af2e265f068031bb06..170fa3871a120190ce947cc55d6b8f2e22a4ddcd 100644 (file)
@@ -32,7 +32,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static void mmc_load_image_raw(struct mmc *mmc)
+static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector)
 {
        unsigned long err;
        u32 image_size_sectors;
@@ -42,10 +42,7 @@ static void mmc_load_image_raw(struct mmc *mmc)
                                                sizeof(struct image_header));
 
        /* read image header to find the image size & load address */
-       err = mmc->block_dev.block_read(0,
-                       CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1,
-                       header);
-
+       err = mmc->block_dev.block_read(0, sector, 1, header);
        if (err == 0)
                goto end;
 
@@ -56,19 +53,33 @@ static void mmc_load_image_raw(struct mmc *mmc)
                                mmc->read_bl_len;
 
        /* Read the header too to avoid extra memcpy */
-       err = mmc->block_dev.block_read(0,
-                       CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
-                       image_size_sectors, (void *)spl_image.load_addr);
+       err = mmc->block_dev.block_read(0, sector, image_size_sectors,
+                                       (void *)spl_image.load_addr);
 
 end:
-       if (err == 0) {
+       if (err == 0)
                printf("spl: mmc blk read err - %lu\n", err);
-               hang();
+
+       return (err == 0);
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+static int mmc_load_image_raw_os(struct mmc *mmc)
+{
+       if (!mmc->block_dev.block_read(0,
+                                      CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
+                                      CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
+                                      (void *)CONFIG_SYS_SPL_ARGS_ADDR)) {
+               printf("mmc args blk read error\n");
+               return -1;
        }
+
+       return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
 }
+#endif
 
 #ifdef CONFIG_SPL_FAT_SUPPORT
-static void mmc_load_image_fat(struct mmc *mmc)
+static int mmc_load_image_fat(struct mmc *mmc, const char *filename)
 {
        int err;
        struct image_header *header;
@@ -76,32 +87,41 @@ static void mmc_load_image_fat(struct mmc *mmc)
        header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
                                                sizeof(struct image_header));
 
-       err = fat_register_device(&mmc->block_dev,
-                               CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
-       if (err) {
-               printf("spl: fat register err - %d\n", err);
-               hang();
-       }
-
-       err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
-                               header, sizeof(struct image_header));
+       err = file_fat_read(filename, header, sizeof(struct image_header));
        if (err <= 0)
                goto end;
 
        spl_parse_image_header(header);
 
-       err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
-                               (u8 *)spl_image.load_addr, 0);
+       err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0);
 
 end:
+       if (err <= 0)
+               printf("spl: error reading image %s, err - %d\n",
+                      filename, err);
+
+       return (err <= 0);
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+static int mmc_load_image_fat_os(struct mmc *mmc)
+{
+       int err;
+
+       err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME,
+                           (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
        if (err <= 0) {
                printf("spl: error reading image %s, err - %d\n",
-                       CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err);
-               hang();
+                      CONFIG_SPL_FAT_LOAD_ARGS_NAME, err);
+               return -1;
        }
+
+       return mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_KERNEL_NAME);
 }
 #endif
 
+#endif
+
 void spl_mmc_load_image(void)
 {
        struct mmc *mmc;
@@ -121,17 +141,36 @@ void spl_mmc_load_image(void)
                printf("spl: mmc init failed: err - %d\n", err);
                hang();
        }
+
        boot_mode = spl_boot_mode();
        if (boot_mode == MMCSD_MODE_RAW) {
                debug("boot mode - RAW\n");
-               mmc_load_image_raw(mmc);
+#ifdef CONFIG_SPL_OS_BOOT
+               if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
+#endif
+               err = mmc_load_image_raw(mmc,
+                                        CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
 #ifdef CONFIG_SPL_FAT_SUPPORT
        } else if (boot_mode == MMCSD_MODE_FAT) {
                debug("boot mode - FAT\n");
-               mmc_load_image_fat(mmc);
+
+               err = fat_register_device(&mmc->block_dev,
+                                         CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
+               if (err) {
+                       printf("spl: fat register err - %d\n", err);
+                       hang();
+               }
+
+#ifdef CONFIG_SPL_OS_BOOT
+               if (spl_start_uboot() || mmc_load_image_fat_os(mmc))
+#endif
+               err = mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);
 #endif
        } else {
                puts("spl: wrong MMC boot mode\n");
                hang();
        }
+
+       if (err)
+               hang();
 }
index 0d79ec3ea84abfc8d61988cbfc30c8ba17cec60e..774ba6387aaa3f4ed26f674b7574495bd1c2186a 100644 (file)
 #include <asm/4xx_pci.h>
 #endif
 
+#ifndef CONFIG_USB_HUB_MIN_POWER_ON_DELAY
+#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY      100
+#endif
+
 #define USB_BUFSIZ     512
 
 static struct usb_hub_device hub_dev[USB_MAX_HUB];
@@ -148,8 +152,8 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
                debug("port %d returns %lX\n", i + 1, dev->status);
        }
 
-       /* Wait at least 100 msec for power to become stable */
-       mdelay(max(pgood_delay, (unsigned)100));
+       /* Wait for power to become stable */
+       mdelay(max(pgood_delay, CONFIG_USB_HUB_MIN_POWER_ON_DELAY));
 }
 
 void usb_hub_reset(void)
@@ -485,7 +489,11 @@ static int usb_hub_configure(struct usb_device *dev)
                              i + 1, portstatus);
                        usb_clear_port_feature(dev, i + 1,
                                                USB_PORT_FEAT_C_ENABLE);
-
+                       /*
+                        * The following hack causes a ghost device problem
+                        * to Faraday EHCI
+                        */
+#ifndef CONFIG_USB_EHCI_FARADAY
                        /* EM interference sometimes causes bad shielded USB
                         * devices to be shutdown by the hub, this hack enables
                         * them again. Works at least with mouse driver */
@@ -497,6 +505,7 @@ static int usb_hub_configure(struct usb_device *dev)
                                      "re-enabling...\n", i + 1);
                                      usb_hub_port_connect_change(dev, i);
                        }
+#endif
                }
                if (portstatus & USB_PORT_STAT_SUSPEND) {
                        debug("port %d suspend change\n", i + 1);
index b962849920a40c5cc1aefca9f2f1c0425e114d14..3174b5e1bf4b4a7b827edf825725f6f95c24cf9e 100644 (file)
@@ -461,8 +461,13 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
        usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0);
 
        debug("USB KBD: enable interrupt pipe...\n");
-       usb_submit_int_msg(dev, pipe, data->new, maxp > 8 ? 8 : maxp,
-                               ep->bInterval);
+       if (usb_submit_int_msg(dev, pipe, data->new, maxp > 8 ? 8 : maxp,
+                              ep->bInterval) < 0) {
+               printf("Failed to get keyboard state from device %04x:%04x\n",
+                      dev->descriptor.idVendor, dev->descriptor.idProduct);
+               /* Abort, we don't want to use that non-functional keyboard. */
+               return 0;
+       }
 
        /* Success. */
        return 1;
@@ -496,6 +501,7 @@ int drv_usb_kbd_init(void)
                if (old_dev) {
                        /* Already registered, just return ok. */
                        debug("USB KBD: is already registered.\n");
+                       usb_kbd_deregister();
                        return 1;
                }
 
index 59865897085c1750067a3c8f2712006cbe6c5abe..fb5e9f0477a59d8bf6cc4a17c7db94d9e17363f2 100644 (file)
@@ -372,7 +372,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
        u32 offset = (u32)le32_to_cpu(gpt_h->first_usable_lba);
        ulong start;
        int i, k;
-       size_t name_len;
+       size_t efiname_len, dosname_len;
 #ifdef CONFIG_PARTITION_UUIDS
        char *str_uuid;
 #endif
@@ -420,9 +420,14 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
                       sizeof(gpt_entry_attributes));
 
                /* partition name */
-               name_len = sizeof(gpt_e[i].partition_name)
+               efiname_len = sizeof(gpt_e[i].partition_name)
                        / sizeof(efi_char16_t);
-               for (k = 0; k < name_len; k++)
+               dosname_len = sizeof(partitions[i].name);
+
+               memset(gpt_e[i].partition_name, 0,
+                      sizeof(gpt_e[i].partition_name));
+
+               for (k = 0; k < min(dosname_len, efiname_len); k++)
                        gpt_e[i].partition_name[k] =
                                (efi_char16_t)(partitions[i].name[k]);
 
index cd7e7ee9b346e4c1323c33f731ee1cf035a650f0..2b1f76b8d0287a993df33f9c0d72c72564ffddd9 100644 (file)
@@ -21,13 +21,13 @@ Environment of the SRIO or PCIE boot:
        e) Slave's RCW should configure the SerDes for SRIO or PCIE boot port, set
           the boot location to SRIO or PCIE, and holdoff all the cores.
 
-       ----------        -----------             -----------
-       |                 |       |         |             |         |
-       |                 |       |         |             |         |
+       -----------       -----------             -----------
+       |         |       |         |             |         |
+       |         |       |         |             |         |
        | NorFlash|<----->| Master  |SRIO or PCIE |  Slave  |<---->[EEPROM]
-       |                 |       |         |<===========>|         |
-       |                 |       |         |             |         |
-       ----------        -----------             -----------
+       |         |       |         |<===========>|         |
+       |         |       |         |             |         |
+       -----------       -----------             -----------
 
 The example based on P4080DS platform:
        Two P4080DS platforms can be used to implement the boot from SRIO or PCIE.
@@ -87,26 +87,32 @@ How to use this feature:
           Please refer to the examples given above.
 
        2. U-Boot image's compilation.
-               For master, U-Boot image should be generated normally.
+          For master, U-Boot image should be generated normally.
 
-               For example, master U-Boot image used on P4080DS should be compiled with
+          For example, master U-Boot image used on P4080DS should be compiled with
 
                                make P4080DS_config.
 
-               For slave, U-Boot image should be generated specifically by
+          For slave, U-Boot image should be generated specifically by
 
                                make xxxx_SRIO_PCIE_BOOT_config.
 
-               For example, slave U-Boot image used on P4080DS should be compiled with
+          For example, slave U-Boot image used on P4080DS should be compiled with
 
                                make P4080DS_SRIO_PCIE_BOOT_config.
 
        3. Necessary modifications based on a specific environment.
-               For a specific environment, the addresses of the slave's U-Boot image,
-               UCode, ENV stored in master's NorFlash, and any other configurations
-               can be modified in the file:
-                                       include/configs/corenet_ds.h.
+          For a specific environment, the addresses of the slave's U-Boot image,
+          UCode, ENV stored in master's NorFlash, and any other configurations
+          can be modified in the file:
+                               include/configs/corenet_ds.h.
 
        4. Set and save the environment variable "bootmaster" with "SRIO1", "SRIO2"
           or "PCIE1", "PCIE2", "PCIE3" for master, and then restart it in order to
           perform the role as a master for boot from SRIO or PCIE.
+
+NOTE: When the Slave's ENV parameters are stored in Master's NorFlash,
+      it can fetch them through PCIE or SRIO interface. But the ENV
+      parameters can not be modified by "saveenv" or other commands under
+      the Slave's u-boot environment, because the Slave can not erase,
+      write Master's NorFlash by PCIE or SRIO link.
diff --git a/doc/device-tree-bindings/video/simple-framebuffer.txt b/doc/device-tree-bindings/video/simple-framebuffer.txt
new file mode 100644 (file)
index 0000000..3ea4605
--- /dev/null
@@ -0,0 +1,25 @@
+Simple Framebuffer
+
+A simple frame-buffer describes a raw memory region that may be rendered to,
+with the assumption that the display hardware has already been set up to scan
+out from that buffer.
+
+Required properties:
+- compatible: "simple-framebuffer"
+- reg: Should contain the location and size of the framebuffer memory.
+- width: The width of the framebuffer in pixels.
+- height: The height of the framebuffer in pixels.
+- stride: The number of bytes in each line of the framebuffer.
+- format: The format of the framebuffer surface. Valid values are:
+  - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b).
+
+Example:
+
+       framebuffer {
+               compatible = "simple-framebuffer";
+               reg = <0x1d385000 (1600 * 1200 * 2)>;
+               width = <1600>;
+               height = <1200>;
+               stride = <(1600 * 2)>;
+               format = "r5g6b5";
+       };
index 946a186a1ffaf2ad511cba5e0749efc53ddf8e16..c900e45d150b712ecbdbfc19257cf10a136463ab 100644 (file)
@@ -154,54 +154,42 @@ static uchar *create_keymap(struct key_matrix *config, u32 *data, int len,
        return map;
 }
 
-int key_matrix_decode_fdt(struct key_matrix *config, const void *blob,
-                         int node)
+int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, int node)
 {
        const struct fdt_property *prop;
-       const char prefix[] = "linux,";
-       int plen = sizeof(prefix) - 1;
-       int offset;
-
-       /* Check each property name for ones that we understand */
-       for (offset = fdt_first_property_offset(blob, node);
-                     offset > 0;
-                     offset = fdt_next_property_offset(blob, offset)) {
-               const char *name;
-               int len;
-
-               prop = fdt_get_property_by_offset(blob, offset, NULL);
-               name = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
-               len = strlen(name);
-
-               /* Name needs to match "1,<type>keymap" */
-               debug("%s: property '%s'\n", __func__, name);
-               if (strncmp(name, prefix, plen) ||
-                               len < plen + 6 ||
-                               strcmp(name + len - 6, "keymap"))
-                       continue;
+       int proplen;
+       uchar *plain_keycode;
 
-               len -= plen + 6;
-               if (len == 0) {
-                       config->plain_keycode = create_keymap(config,
-                               (u32 *)prop->data, fdt32_to_cpu(prop->len),
-                               KEY_FN, &config->fn_pos);
-               } else if (0 == strncmp(name + plen, "fn-", len)) {
-                       config->fn_keycode = create_keymap(config,
-                               (u32 *)prop->data, fdt32_to_cpu(prop->len),
-                               -1, NULL);
-               } else {
-                       debug("%s: unrecognised property '%s'\n", __func__,
-                             name);
-               }
+       prop = fdt_get_property(blob, node, "linux,keymap", &proplen);
+       /* Basic keymap is required */
+       if (!prop) {
+               debug("%s: cannot find keycode-plain map\n", __func__);
+               return -1;
        }
-       debug("%s: Decoded key maps %p, %p from fdt\n", __func__,
-             config->plain_keycode, config->fn_keycode);
 
-       if (!config->plain_keycode) {
-               debug("%s: cannot find keycode-plain map\n", __func__);
+       plain_keycode = create_keymap(config, (u32 *)prop->data,
+               proplen, KEY_FN, &config->fn_pos);
+       config->plain_keycode = plain_keycode;
+       /* Conversion error -> fail */
+       if (!config->plain_keycode)
+               return -1;
+
+       prop = fdt_get_property(blob, node, "linux,fn-keymap", &proplen);
+       /* fn keymap is optional */
+       if (!prop)
+               goto done;
+
+       config->fn_keycode = create_keymap(config, (u32 *)prop->data,
+               proplen, -1, NULL);
+       /* Conversion error -> fail */
+       if (!config->fn_keycode) {
+               free(plain_keycode);
                return -1;
        }
 
+done:
+       debug("%s: Decoded key maps %p, %p from fdt\n", __func__,
+             config->plain_keycode, config->fn_keycode);
        return 0;
 }
 
index 861f4b9d6ca52844cb76b341574d74342032b03d..973b19f337b59b9646f58cff06454b0182b85ae5 100644 (file)
@@ -178,7 +178,7 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
        int timeout;
        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
        struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
-#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
+#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
        uint wml_value;
 
        wml_value = data->blocksize/4;
@@ -310,6 +310,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
        /* Figure out the transfer arguments */
        xfertyp = esdhc_xfertyp(cmd, data);
 
+       /* Mask all irqs */
+       esdhc_write32(&regs->irqsigen, 0);
+
        /* Send the command */
        esdhc_write32(&regs->cmdarg, cmd->cmdarg);
 #if defined(CONFIG_FSL_USDHC)
@@ -320,15 +323,11 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
        esdhc_write32(&regs->xfertyp, xfertyp);
 #endif
 
-       /* Mask all irqs */
-       esdhc_write32(&regs->irqsigen, 0);
-
        /* Wait for the command to complete */
        while (!(esdhc_read32(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE)))
                ;
 
        irqstat = esdhc_read32(&regs->irqstat);
-       esdhc_write32(&regs->irqstat, irqstat);
 
        /* Reset CMD and DATA portions on error */
        if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) {
index a492bbb41f5faef7b0d6369de605a8bc5d163d91..83d2df7744465678d6f161b26d4d976251b77252 100644 (file)
@@ -301,10 +301,12 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
                return 0;
        }
 
-       if (blkcnt > 1)
-               cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
-       else
+       if (blkcnt == 0)
+               return 0;
+       else if (blkcnt == 1)
                cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
+       else
+               cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
 
        if (mmc->high_capacity)
                cmd.cmdarg = start;
@@ -700,16 +702,49 @@ static int mmc_change_freq(struct mmc *mmc)
        return 0;
 }
 
+static int mmc_set_capacity(struct mmc *mmc, int part_num)
+{
+       switch (part_num) {
+       case 0:
+               mmc->capacity = mmc->capacity_user;
+               break;
+       case 1:
+       case 2:
+               mmc->capacity = mmc->capacity_boot;
+               break;
+       case 3:
+               mmc->capacity = mmc->capacity_rpmb;
+               break;
+       case 4:
+       case 5:
+       case 6:
+       case 7:
+               mmc->capacity = mmc->capacity_gp[part_num - 4];
+               break;
+       default:
+               return -1;
+       }
+
+       mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
+
+       return 0;
+}
+
 int mmc_switch_part(int dev_num, unsigned int part_num)
 {
        struct mmc *mmc = find_mmc_device(dev_num);
+       int ret;
 
        if (!mmc)
                return -1;
 
-       return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
-                         (mmc->part_config & ~PART_ACCESS_MASK)
-                         | (part_num & PART_ACCESS_MASK));
+       ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
+                        (mmc->part_config & ~PART_ACCESS_MASK)
+                        | (part_num & PART_ACCESS_MASK));
+       if (ret)
+               return ret;
+
+       return mmc_set_capacity(mmc, part_num);
 }
 
 int mmc_getcd(struct mmc *mmc)
@@ -917,7 +952,7 @@ static void mmc_set_bus_width(struct mmc *mmc, uint width)
 
 static int mmc_startup(struct mmc *mmc)
 {
-       int err;
+       int err, i;
        uint mult, freq;
        u64 cmult, csize, capacity;
        struct mmc_cmd cmd;
@@ -1035,8 +1070,12 @@ static int mmc_startup(struct mmc *mmc)
                cmult = (mmc->csd[2] & 0x00038000) >> 15;
        }
 
-       mmc->capacity = (csize + 1) << (cmult + 2);
-       mmc->capacity *= mmc->read_bl_len;
+       mmc->capacity_user = (csize + 1) << (cmult + 2);
+       mmc->capacity_user *= mmc->read_bl_len;
+       mmc->capacity_boot = 0;
+       mmc->capacity_rpmb = 0;
+       for (i = 0; i < 4; i++)
+               mmc->capacity_gp[i] = 0;
 
        if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
                mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
@@ -1075,7 +1114,7 @@ static int mmc_startup(struct mmc *mmc)
                                        | ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
                        capacity *= MMC_MAX_BLOCK_LEN;
                        if ((capacity >> 20) > 2 * 1024)
-                               mmc->capacity = capacity;
+                               mmc->capacity_user = capacity;
                }
 
                switch (ext_csd[EXT_CSD_REV]) {
@@ -1117,8 +1156,25 @@ static int mmc_startup(struct mmc *mmc)
                if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
                    ext_csd[EXT_CSD_BOOT_MULT])
                        mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
+
+               mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
+
+               mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
+
+               for (i = 0; i < 4; i++) {
+                       int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
+                       mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
+                               (ext_csd[idx + 1] << 8) + ext_csd[idx];
+                       mmc->capacity_gp[i] *=
+                               ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
+                       mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
+               }
        }
 
+       err = mmc_set_capacity(mmc, mmc->part_num);
+       if (err)
+               return err;
+
        if (IS_SD(mmc))
                err = sd_change_freq(mmc);
        else
index 1eaea04ad108ac27fe5e4c954eed7fb1221384d2..c5631bff6721da8487e7b4bf79a595d55cb5260b 100644 (file)
@@ -486,8 +486,10 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
                mmc->voltages |= host->voltages;
 
        mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
-       if (caps & SDHCI_CAN_DO_8BIT)
-               mmc->host_caps |= MMC_MODE_8BIT;
+       if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) {
+               if (caps & SDHCI_CAN_DO_8BIT)
+                       mmc->host_caps |= MMC_MODE_8BIT;
+       }
        if (host->host_caps)
                mmc->host_caps |= host->host_caps;
 
index 543c845ff0173c6c6540a5827e1e4305e09c84a6..99f39fc752b902352036c85c679baab6f25245bb 100644 (file)
@@ -25,7 +25,9 @@ include $(TOPDIR)/config.mk
 
 LIB    := $(obj)libmtd.o
 
-COBJS-$(CONFIG_MTD_DEVICE) += mtdcore.o
+ifneq (,$(findstring y,$(CONFIG_MTD_DEVICE)$(CONFIG_CMD_NAND)$(CONFIG_CMD_ONENAND)))
+COBJS-y += mtdcore.o
+endif
 COBJS-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
 COBJS-$(CONFIG_MTD_CONCAT) += mtdconcat.o
 COBJS-$(CONFIG_HAS_DATAFLASH) += at45.o
index 8d74fa94128a7348de33a4051ba3ef3f13d805a6..bbb71a19e7d04c23bdd541b38c4a8fc8fd30bffc 100644 (file)
@@ -244,12 +244,12 @@ int cfi_mtd_init(void)
                mtd->size               = fi->size;
                mtd->writesize          = 1;
 
-               mtd->erase              = cfi_mtd_erase;
-               mtd->read               = cfi_mtd_read;
-               mtd->write              = cfi_mtd_write;
-               mtd->sync               = cfi_mtd_sync;
-               mtd->lock               = cfi_mtd_lock;
-               mtd->unlock             = cfi_mtd_unlock;
+               mtd->_erase             = cfi_mtd_erase;
+               mtd->_read              = cfi_mtd_read;
+               mtd->_write             = cfi_mtd_write;
+               mtd->_sync              = cfi_mtd_sync;
+               mtd->_lock              = cfi_mtd_lock;
+               mtd->_unlock            = cfi_mtd_unlock;
                mtd->priv               = fi;
 
                if (add_mtd_device(mtd))
index e6d938417ded948b498c41590fc85435db00dfec..31e4289b1601a4bb9de7cb2df4862258dc34bae8 100644 (file)
@@ -70,14 +70,14 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
                        /* Entire transaction goes into this subdev */
                        size = len;
 
-               err = subdev->read(subdev, from, size, &retsize, buf);
+               err = mtd_read(subdev, from, size, &retsize, buf);
 
                /* Save information about bitflips! */
                if (unlikely(err)) {
-                       if (err == -EBADMSG) {
+                       if (mtd_is_eccerr(err)) {
                                mtd->ecc_stats.failed++;
                                ret = err;
-                       } else if (err == -EUCLEAN) {
+                       } else if (mtd_is_bitflip(err)) {
                                mtd->ecc_stats.corrected++;
                                /* Do not overwrite -EBADMSG !! */
                                if (!ret)
@@ -105,9 +105,6 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
        int err = -EINVAL;
        int i;
 
-       if (!(mtd->flags & MTD_WRITEABLE))
-               return -EROFS;
-
        *retlen = 0;
 
        for (i = 0; i < concat->num_subdev; i++) {
@@ -124,11 +121,7 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
                else
                        size = len;
 
-               if (!(subdev->flags & MTD_WRITEABLE))
-                       err = -EROFS;
-               else
-                       err = subdev->write(subdev, to, size, &retsize, buf);
-
+               err = mtd_write(subdev, to, size, &retsize, buf);
                if (err)
                        break;
 
@@ -165,16 +158,16 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
                if (from + devops.len > subdev->size)
                        devops.len = subdev->size - from;
 
-               err = subdev->read_oob(subdev, from, &devops);
+               err = mtd_read_oob(subdev, from, &devops);
                ops->retlen += devops.retlen;
                ops->oobretlen += devops.oobretlen;
 
                /* Save information about bitflips! */
                if (unlikely(err)) {
-                       if (err == -EBADMSG) {
+                       if (mtd_is_eccerr(err)) {
                                mtd->ecc_stats.failed++;
                                ret = err;
-                       } else if (err == -EUCLEAN) {
+                       } else if (mtd_is_bitflip(err)) {
                                mtd->ecc_stats.corrected++;
                                /* Do not overwrite -EBADMSG !! */
                                if (!ret)
@@ -225,7 +218,7 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
                if (to + devops.len > subdev->size)
                        devops.len = subdev->size - to;
 
-               err = subdev->write_oob(subdev, to, &devops);
+               err = mtd_write_oob(subdev, to, &devops);
                ops->retlen += devops.retlen;
                if (err)
                        return err;
@@ -271,7 +264,7 @@ static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
         * FIXME: Allow INTERRUPTIBLE. Which means
         * not having the wait_queue head on the stack.
         */
-       err = mtd->erase(mtd, erase);
+       err = mtd_erase(mtd, erase);
        if (!err) {
                set_current_state(TASK_UNINTERRUPTIBLE);
                add_wait_queue(&waitq, &wait);
@@ -294,15 +287,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
        uint64_t length, offset = 0;
        struct erase_info *erase;
 
-       if (!(mtd->flags & MTD_WRITEABLE))
-               return -EROFS;
-
-       if (instr->addr > concat->mtd.size)
-               return -EINVAL;
-
-       if (instr->len + instr->addr > concat->mtd.size)
-               return -EINVAL;
-
        /*
         * Check for proper erase block alignment of the to-be-erased area.
         * It is easier to do this based on the super device's erase
@@ -350,8 +334,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
                        return -EINVAL;
        }
 
-       instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
-
        /* make a local copy of instr to avoid modifying the caller's struct */
        erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
 
@@ -390,10 +372,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
                else
                        erase->len = length;
 
-               if (!(subdev->flags & MTD_WRITEABLE)) {
-                       err = -EROFS;
-                       break;
-               }
                length -= erase->len;
                if ((err = concat_dev_erase(subdev, erase))) {
                        /* sanity check: should never happen since
@@ -429,9 +407,6 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        struct mtd_concat *concat = CONCAT(mtd);
        int i, err = -EINVAL;
 
-       if ((len + ofs) > mtd->size)
-               return -EINVAL;
-
        for (i = 0; i < concat->num_subdev; i++) {
                struct mtd_info *subdev = concat->subdev[i];
                uint64_t size;
@@ -446,7 +421,7 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
                else
                        size = len;
 
-               err = subdev->lock(subdev, ofs, size);
+               err = mtd_lock(subdev, ofs, size);
 
                if (err)
                        break;
@@ -467,9 +442,6 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        struct mtd_concat *concat = CONCAT(mtd);
        int i, err = 0;
 
-       if ((len + ofs) > mtd->size)
-               return -EINVAL;
-
        for (i = 0; i < concat->num_subdev; i++) {
                struct mtd_info *subdev = concat->subdev[i];
                uint64_t size;
@@ -484,7 +456,7 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
                else
                        size = len;
 
-               err = subdev->unlock(subdev, ofs, size);
+               err = mtd_unlock(subdev, ofs, size);
 
                if (err)
                        break;
@@ -507,7 +479,7 @@ static void concat_sync(struct mtd_info *mtd)
 
        for (i = 0; i < concat->num_subdev; i++) {
                struct mtd_info *subdev = concat->subdev[i];
-               subdev->sync(subdev);
+               mtd_sync(subdev);
        }
 }
 
@@ -516,12 +488,9 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
        struct mtd_concat *concat = CONCAT(mtd);
        int i, res = 0;
 
-       if (!concat->subdev[0]->block_isbad)
+       if (!mtd_can_have_bb(concat->subdev[0]))
                return res;
 
-       if (ofs > mtd->size)
-               return -EINVAL;
-
        for (i = 0; i < concat->num_subdev; i++) {
                struct mtd_info *subdev = concat->subdev[i];
 
@@ -530,7 +499,7 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
                        continue;
                }
 
-               res = subdev->block_isbad(subdev, ofs);
+               res = mtd_block_isbad(subdev, ofs);
                break;
        }
 
@@ -542,12 +511,9 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
        struct mtd_concat *concat = CONCAT(mtd);
        int i, err = -EINVAL;
 
-       if (!concat->subdev[0]->block_markbad)
+       if (!mtd_can_have_bb(concat->subdev[0]))
                return 0;
 
-       if (ofs > mtd->size)
-               return -EINVAL;
-
        for (i = 0; i < concat->num_subdev; i++) {
                struct mtd_info *subdev = concat->subdev[i];
 
@@ -556,7 +522,7 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
                        continue;
                }
 
-               err = subdev->block_markbad(subdev, ofs);
+               err = mtd_block_markbad(subdev, ofs);
                if (!err)
                        mtd->ecc_stats.badblocks++;
                break;
@@ -609,14 +575,14 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],     /* subdevices to c
        concat->mtd.subpage_sft = subdev[0]->subpage_sft;
        concat->mtd.oobsize = subdev[0]->oobsize;
        concat->mtd.oobavail = subdev[0]->oobavail;
-       if (subdev[0]->read_oob)
-               concat->mtd.read_oob = concat_read_oob;
-       if (subdev[0]->write_oob)
-               concat->mtd.write_oob = concat_write_oob;
-       if (subdev[0]->block_isbad)
-               concat->mtd.block_isbad = concat_block_isbad;
-       if (subdev[0]->block_markbad)
-               concat->mtd.block_markbad = concat_block_markbad;
+       if (subdev[0]->_read_oob)
+               concat->mtd._read_oob = concat_read_oob;
+       if (subdev[0]->_write_oob)
+               concat->mtd._write_oob = concat_write_oob;
+       if (subdev[0]->_block_isbad)
+               concat->mtd._block_isbad = concat_block_isbad;
+       if (subdev[0]->_block_markbad)
+               concat->mtd._block_markbad = concat_block_markbad;
 
        concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
 
@@ -653,8 +619,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],       /* subdevices to c
                if (concat->mtd.writesize   !=  subdev[i]->writesize ||
                    concat->mtd.subpage_sft != subdev[i]->subpage_sft ||
                    concat->mtd.oobsize    !=  subdev[i]->oobsize ||
-                   !concat->mtd.read_oob  != !subdev[i]->read_oob ||
-                   !concat->mtd.write_oob != !subdev[i]->write_oob) {
+                   !concat->mtd._read_oob  != !subdev[i]->_read_oob ||
+                   !concat->mtd._write_oob != !subdev[i]->_write_oob) {
                        kfree(concat);
                        printk("Incompatible OOB or ECC data on \"%s\"\n",
                               subdev[i]->name);
@@ -669,12 +635,12 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],     /* subdevices to c
        concat->num_subdev = num_devs;
        concat->mtd.name = name;
 
-       concat->mtd.erase = concat_erase;
-       concat->mtd.read = concat_read;
-       concat->mtd.write = concat_write;
-       concat->mtd.sync = concat_sync;
-       concat->mtd.lock = concat_lock;
-       concat->mtd.unlock = concat_unlock;
+       concat->mtd._erase = concat_erase;
+       concat->mtd._read = concat_read;
+       concat->mtd._write = concat_write;
+       concat->mtd._sync = concat_sync;
+       concat->mtd._lock = concat_lock;
+       concat->mtd._unlock = concat_unlock;
 
        /*
         * Combine the erase block size info of the subdevices:
index 3a81adaf60d5563d805e230515f12a3ca444439e..49c08145a7fa63296cdb79dc058af7108b64a72b 100644 (file)
@@ -25,6 +25,11 @@ int add_mtd_device(struct mtd_info *mtd)
                        mtd->index = i;
                        mtd->usecount = 0;
 
+                       /* default value if not set by driver */
+                       if (mtd->bitflip_threshold == 0)
+                               mtd->bitflip_threshold = mtd->ecc_strength;
+
+
                        /* No need to get a refcount on the module containing
                           the notifier, since we hold the mtd_table_mutex */
 
@@ -186,3 +191,189 @@ void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
        }
 }
 #endif /* defined(CONFIG_CMD_MTDPARTS_SPREAD) */
+
+ /*
+ * Erase is an asynchronous operation.  Device drivers are supposed
+ * to call instr->callback() whenever the operation completes, even
+ * if it completes with a failure.
+ * Callers are supposed to pass a callback function and wait for it
+ * to be called before writing to the block.
+ */
+int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+       if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr)
+               return -EINVAL;
+       if (!(mtd->flags & MTD_WRITEABLE))
+               return -EROFS;
+       instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
+       if (!instr->len) {
+               instr->state = MTD_ERASE_DONE;
+               mtd_erase_callback(instr);
+               return 0;
+       }
+       return mtd->_erase(mtd, instr);
+}
+
+int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
+            u_char *buf)
+{
+       if (from < 0 || from > mtd->size || len > mtd->size - from)
+               return -EINVAL;
+       if (!len)
+               return 0;
+       return mtd->_read(mtd, from, len, retlen, buf);
+}
+
+int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+             const u_char *buf)
+{
+       *retlen = 0;
+       if (to < 0 || to > mtd->size || len > mtd->size - to)
+               return -EINVAL;
+       if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE))
+               return -EROFS;
+       if (!len)
+               return 0;
+       return mtd->_write(mtd, to, len, retlen, buf);
+}
+
+/*
+ * In blackbox flight recorder like scenarios we want to make successful writes
+ * in interrupt context. panic_write() is only intended to be called when its
+ * known the kernel is about to panic and we need the write to succeed. Since
+ * the kernel is not going to be running for much longer, this function can
+ * break locks and delay to ensure the write succeeds (but not sleep).
+ */
+int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+                   const u_char *buf)
+{
+       *retlen = 0;
+       if (!mtd->_panic_write)
+               return -EOPNOTSUPP;
+       if (to < 0 || to > mtd->size || len > mtd->size - to)
+               return -EINVAL;
+       if (!(mtd->flags & MTD_WRITEABLE))
+               return -EROFS;
+       if (!len)
+               return 0;
+       return mtd->_panic_write(mtd, to, len, retlen, buf);
+}
+
+int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
+{
+       ops->retlen = ops->oobretlen = 0;
+       if (!mtd->_read_oob)
+               return -EOPNOTSUPP;
+       return mtd->_read_oob(mtd, from, ops);
+}
+
+/*
+ * Method to access the protection register area, present in some flash
+ * devices. The user data is one time programmable but the factory data is read
+ * only.
+ */
+int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
+                          size_t len)
+{
+       if (!mtd->_get_fact_prot_info)
+               return -EOPNOTSUPP;
+       if (!len)
+               return 0;
+       return mtd->_get_fact_prot_info(mtd, buf, len);
+}
+
+int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
+                          size_t *retlen, u_char *buf)
+{
+       *retlen = 0;
+       if (!mtd->_read_fact_prot_reg)
+               return -EOPNOTSUPP;
+       if (!len)
+               return 0;
+       return mtd->_read_fact_prot_reg(mtd, from, len, retlen, buf);
+}
+
+int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
+                          size_t len)
+{
+       if (!mtd->_get_user_prot_info)
+               return -EOPNOTSUPP;
+       if (!len)
+               return 0;
+       return mtd->_get_user_prot_info(mtd, buf, len);
+}
+
+int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
+                          size_t *retlen, u_char *buf)
+{
+       *retlen = 0;
+       if (!mtd->_read_user_prot_reg)
+               return -EOPNOTSUPP;
+       if (!len)
+               return 0;
+       return mtd->_read_user_prot_reg(mtd, from, len, retlen, buf);
+}
+
+int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
+                           size_t *retlen, u_char *buf)
+{
+       *retlen = 0;
+       if (!mtd->_write_user_prot_reg)
+               return -EOPNOTSUPP;
+       if (!len)
+               return 0;
+       return mtd->_write_user_prot_reg(mtd, to, len, retlen, buf);
+}
+
+int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
+{
+       if (!mtd->_lock_user_prot_reg)
+               return -EOPNOTSUPP;
+       if (!len)
+               return 0;
+       return mtd->_lock_user_prot_reg(mtd, from, len);
+}
+
+/* Chip-supported device locking */
+int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
+{
+       if (!mtd->_lock)
+               return -EOPNOTSUPP;
+       if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs)
+               return -EINVAL;
+       if (!len)
+               return 0;
+       return mtd->_lock(mtd, ofs, len);
+}
+
+int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
+{
+       if (!mtd->_unlock)
+               return -EOPNOTSUPP;
+       if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs)
+               return -EINVAL;
+       if (!len)
+               return 0;
+       return mtd->_unlock(mtd, ofs, len);
+}
+
+int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
+{
+       if (!mtd->_block_isbad)
+               return 0;
+       if (ofs < 0 || ofs > mtd->size)
+               return -EINVAL;
+       return mtd->_block_isbad(mtd, ofs);
+}
+
+int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+       if (!mtd->_block_markbad)
+               return -EOPNOTSUPP;
+       if (ofs < 0 || ofs > mtd->size)
+               return -EINVAL;
+       if (!(mtd->flags & MTD_WRITEABLE))
+               return -EROFS;
+       return mtd->_block_markbad(mtd, ofs);
+}
+
index cbfc6796c7d6a96b3c81d353c0c2a141ac80b62c..9dfe7bbc9a9244dbb7e56f328b3046d2d2c3fbe0 100644 (file)
@@ -52,17 +52,11 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
        int res;
 
        stats = part->master->ecc_stats;
-
-       if (from >= mtd->size)
-               len = 0;
-       else if (from + len > mtd->size)
-               len = mtd->size - from;
-       res = part->master->read(part->master, from + part->offset,
-                                  len, retlen, buf);
+       res = mtd_read(part->master, from + part->offset, len, retlen, buf);
        if (unlikely(res)) {
-               if (res == -EUCLEAN)
+               if (mtd_is_bitflip(res))
                        mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
-               if (res == -EBADMSG)
+               if (mtd_is_eccerr(res))
                        mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
        }
        return res;
@@ -78,12 +72,12 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
                return -EINVAL;
        if (ops->datbuf && from + ops->len > mtd->size)
                return -EINVAL;
-       res = part->master->read_oob(part->master, from + part->offset, ops);
+       res = mtd_read_oob(part->master, from + part->offset, ops);
 
        if (unlikely(res)) {
-               if (res == -EUCLEAN)
+               if (mtd_is_bitflip(res))
                        mtd->ecc_stats.corrected++;
-               if (res == -EBADMSG)
+               if (mtd_is_eccerr(res))
                        mtd->ecc_stats.failed++;
        }
        return res;
@@ -93,58 +87,35 @@ static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
                size_t len, size_t *retlen, u_char *buf)
 {
        struct mtd_part *part = PART(mtd);
-       return part->master->read_user_prot_reg(part->master, from,
-                                       len, retlen, buf);
+       return mtd_read_user_prot_reg(part->master, from, len, retlen, buf);
 }
 
 static int part_get_user_prot_info(struct mtd_info *mtd,
                struct otp_info *buf, size_t len)
 {
        struct mtd_part *part = PART(mtd);
-       return part->master->get_user_prot_info(part->master, buf, len);
+       return mtd_get_user_prot_info(part->master, buf, len);
 }
 
 static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
                size_t len, size_t *retlen, u_char *buf)
 {
        struct mtd_part *part = PART(mtd);
-       return part->master->read_fact_prot_reg(part->master, from,
-                                       len, retlen, buf);
+       return mtd_read_fact_prot_reg(part->master, from, len, retlen, buf);
 }
 
 static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
                size_t len)
 {
        struct mtd_part *part = PART(mtd);
-       return part->master->get_fact_prot_info(part->master, buf, len);
+       return mtd_get_fact_prot_info(part->master, buf, len);
 }
 
 static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
                size_t *retlen, const u_char *buf)
 {
        struct mtd_part *part = PART(mtd);
-       if (!(mtd->flags & MTD_WRITEABLE))
-               return -EROFS;
-       if (to >= mtd->size)
-               len = 0;
-       else if (to + len > mtd->size)
-               len = mtd->size - to;
-       return part->master->write(part->master, to + part->offset,
-                                   len, retlen, buf);
-}
-
-static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
-               size_t *retlen, const u_char *buf)
-{
-       struct mtd_part *part = PART(mtd);
-       if (!(mtd->flags & MTD_WRITEABLE))
-               return -EROFS;
-       if (to >= mtd->size)
-               len = 0;
-       else if (to + len > mtd->size)
-               len = mtd->size - to;
-       return part->master->panic_write(part->master, to + part->offset,
-                                   len, retlen, buf);
+       return mtd_write(part->master, to + part->offset, len, retlen, buf);
 }
 
 static int part_write_oob(struct mtd_info *mtd, loff_t to,
@@ -152,41 +123,34 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
 {
        struct mtd_part *part = PART(mtd);
 
-       if (!(mtd->flags & MTD_WRITEABLE))
-               return -EROFS;
-
        if (to >= mtd->size)
                return -EINVAL;
        if (ops->datbuf && to + ops->len > mtd->size)
                return -EINVAL;
-       return part->master->write_oob(part->master, to + part->offset, ops);
+       return mtd_write_oob(part->master, to + part->offset, ops);
 }
 
 static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
                size_t len, size_t *retlen, u_char *buf)
 {
        struct mtd_part *part = PART(mtd);
-       return part->master->write_user_prot_reg(part->master, from,
-                                       len, retlen, buf);
+       return mtd_write_user_prot_reg(part->master, from, len, retlen, buf);
 }
 
 static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
                size_t len)
 {
        struct mtd_part *part = PART(mtd);
-       return part->master->lock_user_prot_reg(part->master, from, len);
+       return mtd_lock_user_prot_reg(part->master, from, len);
 }
 
 static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
        struct mtd_part *part = PART(mtd);
        int ret;
-       if (!(mtd->flags & MTD_WRITEABLE))
-               return -EROFS;
-       if (instr->addr >= mtd->size)
-               return -EINVAL;
+
        instr->addr += part->offset;
-       ret = part->master->erase(part->master, instr);
+       ret = mtd_erase(part->master, instr);
        if (ret) {
                if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
                        instr->fail_addr -= part->offset;
@@ -197,7 +161,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 void mtd_erase_callback(struct erase_info *instr)
 {
-       if (instr->mtd->erase == part_erase) {
+       if (instr->mtd->_erase == part_erase) {
                struct mtd_part *part = PART(instr->mtd);
 
                if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
@@ -211,32 +175,26 @@ void mtd_erase_callback(struct erase_info *instr)
 static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
        struct mtd_part *part = PART(mtd);
-       if ((len + ofs) > mtd->size)
-               return -EINVAL;
-       return part->master->lock(part->master, ofs + part->offset, len);
+       return mtd_lock(part->master, ofs + part->offset, len);
 }
 
 static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
        struct mtd_part *part = PART(mtd);
-       if ((len + ofs) > mtd->size)
-               return -EINVAL;
-       return part->master->unlock(part->master, ofs + part->offset, len);
+       return mtd_unlock(part->master, ofs + part->offset, len);
 }
 
 static void part_sync(struct mtd_info *mtd)
 {
        struct mtd_part *part = PART(mtd);
-       part->master->sync(part->master);
+       mtd_sync(part->master);
 }
 
 static int part_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
        struct mtd_part *part = PART(mtd);
-       if (ofs >= mtd->size)
-               return -EINVAL;
        ofs += part->offset;
-       return part->master->block_isbad(part->master, ofs);
+       return mtd_block_isbad(part->master, ofs);
 }
 
 static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
@@ -244,12 +202,8 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
        struct mtd_part *part = PART(mtd);
        int res;
 
-       if (!(mtd->flags & MTD_WRITEABLE))
-               return -EROFS;
-       if (ofs >= mtd->size)
-               return -EINVAL;
        ofs += part->offset;
-       res = part->master->block_markbad(part->master, ofs);
+       res = mtd_block_markbad(part->master, ofs);
        if (!res)
                mtd->ecc_stats.badblocks++;
        return res;
@@ -303,39 +257,36 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
        slave->mtd.name = part->name;
        slave->mtd.owner = master->owner;
 
-       slave->mtd.read = part_read;
-       slave->mtd.write = part_write;
-
-       if (master->panic_write)
-               slave->mtd.panic_write = part_panic_write;
-
-       if (master->read_oob)
-               slave->mtd.read_oob = part_read_oob;
-       if (master->write_oob)
-               slave->mtd.write_oob = part_write_oob;
-       if (master->read_user_prot_reg)
-               slave->mtd.read_user_prot_reg = part_read_user_prot_reg;
-       if (master->read_fact_prot_reg)
-               slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
-       if (master->write_user_prot_reg)
-               slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
-       if (master->lock_user_prot_reg)
-               slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
-       if (master->get_user_prot_info)
-               slave->mtd.get_user_prot_info = part_get_user_prot_info;
-       if (master->get_fact_prot_info)
-               slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
-       if (master->sync)
-               slave->mtd.sync = part_sync;
-       if (master->lock)
-               slave->mtd.lock = part_lock;
-       if (master->unlock)
-               slave->mtd.unlock = part_unlock;
-       if (master->block_isbad)
-               slave->mtd.block_isbad = part_block_isbad;
-       if (master->block_markbad)
-               slave->mtd.block_markbad = part_block_markbad;
-       slave->mtd.erase = part_erase;
+       slave->mtd._read = part_read;
+       slave->mtd._write = part_write;
+
+       if (master->_read_oob)
+               slave->mtd._read_oob = part_read_oob;
+       if (master->_write_oob)
+               slave->mtd._write_oob = part_write_oob;
+       if (master->_read_user_prot_reg)
+               slave->mtd._read_user_prot_reg = part_read_user_prot_reg;
+       if (master->_read_fact_prot_reg)
+               slave->mtd._read_fact_prot_reg = part_read_fact_prot_reg;
+       if (master->_write_user_prot_reg)
+               slave->mtd._write_user_prot_reg = part_write_user_prot_reg;
+       if (master->_lock_user_prot_reg)
+               slave->mtd._lock_user_prot_reg = part_lock_user_prot_reg;
+       if (master->_get_user_prot_info)
+               slave->mtd._get_user_prot_info = part_get_user_prot_info;
+       if (master->_get_fact_prot_info)
+               slave->mtd._get_fact_prot_info = part_get_fact_prot_info;
+       if (master->_sync)
+               slave->mtd._sync = part_sync;
+       if (master->_lock)
+               slave->mtd._lock = part_lock;
+       if (master->_unlock)
+               slave->mtd._unlock = part_unlock;
+       if (master->_block_isbad)
+               slave->mtd._block_isbad = part_block_isbad;
+       if (master->_block_markbad)
+               slave->mtd._block_markbad = part_block_markbad;
+       slave->mtd._erase = part_erase;
        slave->master = master;
        slave->offset = part->offset;
        slave->index = partno;
@@ -416,12 +367,11 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
        }
 
        slave->mtd.ecclayout = master->ecclayout;
-       if (master->block_isbad) {
+       if (master->_block_isbad) {
                uint64_t offs = 0;
 
                while (offs < slave->mtd.size) {
-                       if (master->block_isbad(master,
-                                               offs + slave->offset))
+                       if (mtd_block_isbad(master, offs + slave->offset))
                                slave->mtd.ecc_stats.badblocks++;
                        offs += slave->mtd.erasesize;
                }
index 8821704911be69ab24e1e487a1f6c98903062e14..bb81e84113cfd4073525a0af1188c98e3f054cdc 100644 (file)
@@ -83,6 +83,7 @@ COBJS-$(CONFIG_NAND_DOCG4) += docg4.o
 else  # minimal SPL drivers
 
 COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
+COBJS-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
 COBJS-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
 
 endif # drivers
index 994dd9f0952516cf760b192841b9c9f0c04ec1ea..3bfbaf8ac9fc192297b3653f6254ef74143023ee 100644 (file)
@@ -489,7 +489,7 @@ normal_check:
 }
 
 static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
-       struct nand_chip *chip, uint8_t *buf, int page)
+       struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
 {
        struct atmel_nand_host *host = chip->priv;
        int eccsize = chip->ecc.size;
@@ -529,8 +529,9 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
        return 0;
 }
 
-static void atmel_nand_pmecc_write_page(struct mtd_info *mtd,
-               struct nand_chip *chip, const uint8_t *buf)
+static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
+               struct nand_chip *chip, const uint8_t *buf,
+               int oob_required)
 {
        struct atmel_nand_host *host = chip->priv;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
@@ -557,7 +558,7 @@ static void atmel_nand_pmecc_write_page(struct mtd_info *mtd,
 
        if (!timeout) {
                printk(KERN_ERR "atmel_nand : Timeout to read PMECC status, fail to write PMECC in oob\n");
-               return;
+               goto out;
        }
 
        for (i = 0; i < host->pmecc_sector_number; i++) {
@@ -570,6 +571,8 @@ static void atmel_nand_pmecc_write_page(struct mtd_info *mtd,
                }
        }
        chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+out:
+       return 0;
 }
 
 static void atmel_pmecc_core_init(struct mtd_info *mtd)
@@ -706,6 +709,7 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
 
        nand->ecc.read_page = atmel_nand_pmecc_read_page;
        nand->ecc.write_page = atmel_nand_pmecc_write_page;
+       nand->ecc.strength = cap;
 
        atmel_pmecc_core_init(mtd);
 
@@ -775,9 +779,10 @@ static int atmel_nand_calculate(struct mtd_info *mtd,
  * mtd:        mtd info structure
  * chip:       nand chip info structure
  * buf:        buffer to store read data
+ * oob_required:    caller expects OOB data read to chip->oob_poi
  */
-static int atmel_nand_read_page(struct mtd_info *mtd,
-               struct nand_chip *chip, uint8_t *buf, int page)
+static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+                               uint8_t *buf, int oob_required, int page)
 {
        int eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
index c7ddbb21d8ed95edd8463cbe69349df3e0d03b1a..7e755e8965aa54d6957576cbbaf224783ce949a0 100644 (file)
@@ -374,9 +374,11 @@ int board_nand_init(struct nand_chip *chip)
                if (!NAND_IS_512()) {
                        chip->ecc.bytes = 3;
                        chip->ecc.size = 256;
+                       chip->ecc.strength = 1;
                } else {
                        chip->ecc.bytes = 6;
                        chip->ecc.size = 512;
+                       chip->ecc.strength = 2;
                }
                chip->ecc.mode = NAND_ECC_HW;
                chip->ecc.calculate = bfin_nfc_calculate_ecc;
index e8506ddd9bdde79aac0acf6c9cddbda1858b2290..90f59857fd597f3021735030a06ff9c408c4a581 100644 (file)
@@ -607,12 +607,13 @@ void davinci_nand_init(struct nand_chip *nand)
 {
        nand->chip_delay  = 0;
 #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
-       nand->options     |= NAND_USE_FLASH_BBT;
+       nand->bbt_options         |= NAND_BBT_USE_FLASH;
 #endif
 #ifdef CONFIG_SYS_NAND_HW_ECC
        nand->ecc.mode = NAND_ECC_HW;
        nand->ecc.size = 512;
        nand->ecc.bytes = 3;
+       nand->ecc.strength = 1;
        nand->ecc.calculate = nand_davinci_calculate_ecc;
        nand->ecc.correct  = nand_davinci_correct_data;
        nand->ecc.hwctl  = nand_davinci_enable_hwecc;
@@ -623,6 +624,7 @@ void davinci_nand_init(struct nand_chip *nand)
        nand->ecc.mode = NAND_ECC_HW_OOB_FIRST;
        nand->ecc.size = 512;
        nand->ecc.bytes = 10;
+       nand->ecc.strength = 4;
        nand->ecc.calculate = nand_davinci_4bit_calculate_ecc;
        nand->ecc.correct = nand_davinci_4bit_correct_data;
        nand->ecc.hwctl = nand_davinci_4bit_enable_hwecc;
index edf3a099ba78d7148563e7328cf81e9251c1d0b0..4cd741ebbb48d2b03840b7d0e85f3db734da5fb9 100644 (file)
@@ -134,7 +134,7 @@ static struct rs_control *rs_decoder;
 
 /*
  * The HW decoder in the DoC ASIC's provides us a error syndrome,
- * which we must convert to a standard syndrom usable by the generic
+ * which we must convert to a standard syndrome usable by the generic
  * Reed-Solomon library code.
  *
  * Fabrice Bellard figured this out in the old docecc code. I added
@@ -154,7 +154,7 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
        ds[3] = ((ecc[3] & 0xc0) >> 6) | ((ecc[0] & 0xff) << 2);
        parity = ecc[1];
 
-       /* Initialize the syndrom buffer */
+       /* Initialize the syndrome buffer */
        for (i = 0; i < NROOTS; i++)
                s[i] = ds[0];
        /*
@@ -1033,7 +1033,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat,
                WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
        else
                WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-       if (no_ecc_failures && (ret == -EBADMSG)) {
+       if (no_ecc_failures && mtd_is_eccerr(ret)) {
                printk(KERN_ERR "suppressing ECC failure\n");
                ret = 0;
        }
@@ -1073,7 +1073,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch
        size_t retlen;
 
        for (offs = 0; offs < mtd->size; offs += mtd->erasesize) {
-               ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf);
+               ret = mtd_read(mtd, offs, mtd->writesize, &retlen, buf);
                if (retlen != mtd->writesize)
                        continue;
                if (ret) {
@@ -1098,7 +1098,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch
        /* Only one mediaheader was found.  We want buf to contain a
           mediaheader on return, so we'll have to re-read the one we found. */
        offs = doc->mh0_page << this->page_shift;
-       ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf);
+       ret = mtd_read(mtd, offs, mtd->writesize, &retlen, buf);
        if (retlen != mtd->writesize) {
                /* Insanity.  Give up. */
                printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n");
@@ -1658,7 +1658,8 @@ static int __init doc_probe(unsigned long physadr)
        nand->ecc.mode          = NAND_ECC_HW_SYNDROME;
        nand->ecc.size          = 512;
        nand->ecc.bytes         = 6;
-       nand->options           = NAND_USE_FLASH_BBT;
+       nand->ecc.strength      = 2;
+       nand->bbt_options       = NAND_BBT_USE_FLASH;
 
        doc->physadr            = physadr;
        doc->virtadr            = virtadr;
index 834a8a64983f35d01abdb1383cd928fbb155b6ff..0fa776ae91947541cfde27385b5b852403512122 100644 (file)
@@ -640,9 +640,8 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip)
        return fsl_elbc_read_byte(mtd);
 }
 
-static int fsl_elbc_read_page(struct mtd_info *mtd,
-                             struct nand_chip *chip,
-                             uint8_t *buf, int page)
+static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+                             uint8_t *buf, int oob_required, int page)
 {
        fsl_elbc_read_buf(mtd, buf, mtd->writesize);
        fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -656,12 +655,13 @@ static int fsl_elbc_read_page(struct mtd_info *mtd,
 /* ECC will be calculated automatically, and errors will be detected in
  * waitfunc.
  */
-static void fsl_elbc_write_page(struct mtd_info *mtd,
-                               struct nand_chip *chip,
-                               const uint8_t *buf)
+static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+                               const uint8_t *buf, int oob_required)
 {
        fsl_elbc_write_buf(mtd, buf, mtd->writesize);
        fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       return 0;
 }
 
 static struct fsl_elbc_ctrl *elbc_ctrl;
@@ -747,8 +747,8 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr)
        nand->bbt_md = &bbt_mirror_descr;
 
        /* set up nand options */
-       nand->options = NAND_NO_READRDY | NAND_NO_AUTOINCR |
-                       NAND_USE_FLASH_BBT | NAND_NO_SUBPAGE_WRITE;
+       nand->options = NAND_NO_SUBPAGE_WRITE;
+       nand->bbt_options = NAND_BBT_USE_FLASH;
 
        nand->controller = &elbc_ctrl->controller;
        nand->priv = priv;
@@ -756,20 +756,8 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr)
        nand->ecc.read_page = fsl_elbc_read_page;
        nand->ecc.write_page = fsl_elbc_write_page;
 
-#ifdef CONFIG_FSL_ELBC_FMR
-       priv->fmr = CONFIG_FSL_ELBC_FMR;
-#else
        priv->fmr = (15 << FMR_CWTO_SHIFT) | (2 << FMR_AL_SHIFT);
 
-       /*
-        * Hardware expects small page has ECCM0, large page has ECCM1
-        * when booting from NAND.  Board config can override if not
-        * booting from NAND.
-        */
-       if (or & OR_FCM_PGS)
-               priv->fmr |= FMR_ECCM;
-#endif
-
        /* If CS Base Register selects full hardware ECC then use it */
        if ((br & BR_DECC) == BR_DECC_CHK_GEN) {
                nand->ecc.mode = NAND_ECC_HW;
@@ -781,16 +769,32 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr)
                nand->ecc.size = 512;
                nand->ecc.bytes = 3;
                nand->ecc.steps = 1;
+               nand->ecc.strength = 1;
        } else {
                /* otherwise fall back to default software ECC */
                nand->ecc.mode = NAND_ECC_SOFT;
        }
 
+       ret = nand_scan_ident(mtd, 1, NULL);
+       if (ret)
+               return ret;
+
        /* Large-page-specific setup */
-       if (or & OR_FCM_PGS) {
+       if (mtd->writesize == 2048) {
+               setbits_be32(&elbc_ctrl->regs->bank[priv->bank].or,
+                            OR_FCM_PGS);
+               in_be32(&elbc_ctrl->regs->bank[priv->bank].or);
+
                priv->page_size = 1;
                nand->badblock_pattern = &largepage_memorybased;
 
+               /*
+                * Hardware expects small page has ECCM0, large page has
+                * ECCM1 when booting from NAND, and we follow that even
+                * when not booting from NAND.
+                */
+               priv->fmr |= FMR_ECCM;
+
                /* adjust ecc setup if needed */
                if ((br & BR_DECC) == BR_DECC_CHK_GEN) {
                        nand->ecc.steps = 4;
@@ -798,12 +802,14 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr)
                                           &fsl_elbc_oob_lp_eccm1 :
                                           &fsl_elbc_oob_lp_eccm0;
                }
+       } else if (mtd->writesize == 512) {
+               clrbits_be32(&elbc_ctrl->regs->bank[priv->bank].or,
+                            OR_FCM_PGS);
+               in_be32(&elbc_ctrl->regs->bank[priv->bank].or);
+       } else {
+               return -ENODEV;
        }
 
-       ret = nand_scan_ident(mtd, 1, NULL);
-       if (ret)
-               return ret;
-
        ret = nand_scan_tail(mtd);
        if (ret)
                return ret;
index b13d8a9303a9bea0410c0d9e039926366d5ab7c4..439822c5a24563cce7fa9bc1fee54436f1a30d88 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <common.h>
 #include <malloc.h>
+#include <nand.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
@@ -41,7 +42,6 @@ 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;
 
@@ -686,9 +686,8 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
        return nand_fsr;
 }
 
-static int fsl_ifc_read_page(struct mtd_info *mtd,
-                             struct nand_chip *chip,
-                             uint8_t *buf, int page)
+static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+                            uint8_t *buf, int oob_required, int page)
 {
        struct fsl_ifc_mtd *priv = chip->priv;
        struct fsl_ifc_ctrl *ctrl = priv->ctrl;
@@ -705,12 +704,13 @@ static int fsl_ifc_read_page(struct mtd_info *mtd,
 /* 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)
+static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+                              const uint8_t *buf, int oob_required)
 {
        fsl_ifc_write_buf(mtd, buf, mtd->writesize);
        fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       return 0;
 }
 
 static void fsl_ifc_ctrl_init(void)
@@ -794,11 +794,14 @@ static void fsl_ifc_sram_init(void)
        out_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, csor_ext);
 }
 
-int board_nand_init(struct nand_chip *nand)
+static int fsl_ifc_chip_init(int devnum, u8 *addr)
 {
+       struct mtd_info *mtd = &nand_info[devnum];
+       struct nand_chip *nand;
        struct fsl_ifc_mtd *priv;
        struct nand_ecclayout *layout;
        uint32_t cspr = 0, csor = 0, ver = 0;
+       int ret;
 
        if (!ifc_ctrl) {
                fsl_ifc_ctrl_init();
@@ -811,18 +814,18 @@ int board_nand_init(struct nand_chip *nand)
                return -ENOMEM;
 
        priv->ctrl = ifc_ctrl;
-       priv->vbase = nand->IO_ADDR_R;
+       priv->vbase = addr;
 
        /* 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);
+               phys_addr_t phys_addr = virt_to_phys(addr);
 
                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)) {
+                   (cspr & CSPR_BA) == CSPR_PHYS_ADDR(phys_addr)) {
                        ifc_ctrl->cs_nand = priv->bank << IFC_NAND_CSEL_SHIFT;
                        break;
                }
@@ -835,6 +838,9 @@ int board_nand_init(struct nand_chip *nand)
                return -ENODEV;
        }
 
+       nand = &priv->chip;
+       mtd->priv = nand;
+
        ifc_ctrl->chips[priv->bank] = priv;
 
        /* fill in nand_chip structure */
@@ -852,8 +858,8 @@ int board_nand_init(struct nand_chip *nand)
        nand->bbt_md = &bbt_mirror_descr;
 
        /* set up nand options */
-       nand->options = NAND_NO_READRDY | NAND_NO_AUTOINCR |
-                       NAND_USE_FLASH_BBT | NAND_NO_SUBPAGE_WRITE;
+       nand->options = NAND_NO_SUBPAGE_WRITE;
+       nand->bbt_options = NAND_BBT_USE_FLASH;
 
        if (cspr & CSPR_PORT_SIZE_16) {
                nand->read_byte = fsl_ifc_read_byte16;
@@ -884,11 +890,13 @@ int board_nand_init(struct nand_chip *nand)
                        bbt_mirror_descr.offs = 0;
                }
 
+               nand->ecc.strength = 4;
                priv->bufnum_mask = 15;
                break;
 
        case CSOR_NAND_PGS_2K:
                layout = &oob_2048_ecc4;
+               nand->ecc.strength = 4;
                priv->bufnum_mask = 3;
                break;
 
@@ -896,8 +904,10 @@ int board_nand_init(struct nand_chip *nand)
                if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
                    CSOR_NAND_ECC_MODE_4) {
                        layout = &oob_4096_ecc4;
+                       nand->ecc.strength = 4;
                } else {
                        layout = &oob_4096_ecc8;
+                       nand->ecc.strength = 8;
                        nand->ecc.bytes = 16;
                }
 
@@ -921,5 +931,31 @@ int board_nand_init(struct nand_chip *nand)
        if (ver == FSL_IFC_V1_1_0)
                fsl_ifc_sram_init();
 
+       ret = nand_scan_ident(mtd, 1, NULL);
+       if (ret)
+               return ret;
+
+       ret = nand_scan_tail(mtd);
+       if (ret)
+               return ret;
+
+       ret = nand_register(devnum);
+       if (ret)
+               return ret;
        return 0;
 }
+
+#ifndef CONFIG_SYS_NAND_BASE_LIST
+#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
+#endif
+
+static unsigned long base_address[CONFIG_SYS_MAX_NAND_DEVICE] =
+       CONFIG_SYS_NAND_BASE_LIST;
+
+void board_nand_init(void)
+{
+       int i;
+
+       for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
+               fsl_ifc_chip_init(i, (u8 *)base_address[i]);
+}
similarity index 88%
rename from nand_spl/nand_boot_fsl_ifc.c
rename to drivers/mtd/nand/fsl_ifc_spl.c
index 44972c5c09a8e678df44eef9a310f85daee33676..8537c4c6f573849631e164bbdcc390b9251ac964 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * NAND boot for FSL Integrated Flash Controller, NAND Flash Control Machine
+ * NAND boot for Freescale Integrated Flash Controller, NAND FCM
  *
  * Copyright 2011 Freescale Semiconductor, Inc.
  * Author: Dipen Dudhat <dipen.dudhat@freescale.com>
@@ -46,9 +46,9 @@ 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;
+       int errors = (reg >> ((3 - bufnum % 4) * 8)) & 0xf;
 
-       if (errors == 15) { /* uncorrectable */
+       if (errors == 0xf) { /* uncorrectable */
                /* Blank pages fail hw ECC checks */
                if (is_blank(buf, page_size))
                        return 1;
@@ -123,30 +123,17 @@ static void nand_load(unsigned int offs, int uboot_size, uchar *dst)
        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;
+               bufnum_mask = 0x1;
        } else if (csor & CSOR_NAND_PGS_2K) {
                page_size = 2048;
-               bufnum_mask = 3;
+               bufnum_mask = 0x3;
        } else {
                page_size = 512;
-               bufnum_mask = 15;
+               bufnum_mask = 0xf;
 
                if (port_size == 8)
                        bad_marker = 5;
@@ -174,8 +161,8 @@ static void nand_load(unsigned int offs, int uboot_size, uchar *dst)
                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));
+                        (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) |
@@ -185,7 +172,7 @@ static void nand_load(unsigned int offs, int uboot_size, uchar *dst)
                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_READ0 << IFC_NAND_FCR0_CMD0_SHIFT);
        }
 
        /* Program FBCR = 0 for full page read */
@@ -206,7 +193,7 @@ static void nand_load(unsigned int offs, int uboot_size, uchar *dst)
                        out_be32(&ifc->ifc_nand.col0, 0);
                        /* start read */
                        out_be32(&ifc->ifc_nand.nandseq_strt,
-                               IFC_NAND_SEQ_STRT_FIR_STRT);
+                                IFC_NAND_SEQ_STRT_FIR_STRT);
 
                        /* wait for read to complete */
                        nand_wait(&buf[sram_addr], bufnum, page_size);
@@ -241,7 +228,6 @@ static void nand_load(unsigned int offs, int uboot_size, uchar *dst)
 void nand_boot(void)
 {
        __attribute__((noreturn)) void (*uboot)(void);
-
        /*
         * Load U-Boot image from NAND into RAM
         */
@@ -257,15 +243,16 @@ void nand_boot(void)
                  (uchar *)CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE);
 #endif
 #endif
-
        /*
         * Jump to U-Boot image
         */
+#ifdef CONFIG_SPL_FLUSH_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);
+#endif
        uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
        uboot();
 }
index 7a61d88cc573232b2530159d7725505c34fd8eb0..fab2aebc313f69e51ff20ab3f81b61cd49978c55 100644 (file)
@@ -341,6 +341,7 @@ void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
+ * @oob_required:      caller expects OOB data read to chip->oob_poi
  * @page:      page number to read
  *
  * This routine is needed for fsmc verison 8 as reading from NAND chip has to be
@@ -350,7 +351,7 @@ void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
  * max of 8 bits)
  */
 static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
-                                uint8_t *buf, int page)
+                                uint8_t *buf, int oob_required, int page)
 {
        struct fsmc_eccplace *fsmc_eccpl;
        int i, j, s, stat, eccsize = chip->ecc.size;
@@ -452,6 +453,7 @@ int fsmc_nand_init(struct nand_chip *nand)
        switch (fsmc_version) {
        case FSMC_VER8:
                nand->ecc.bytes = 13;
+               nand->ecc.strength = 8;
                nand->ecc.correct = fsmc_bch8_correct_data;
                nand->ecc.read_page = fsmc_read_page_hwecc;
                if (mtd->writesize == 512)
@@ -466,6 +468,7 @@ int fsmc_nand_init(struct nand_chip *nand)
                break;
        default:
                nand->ecc.bytes = 3;
+               nand->ecc.strength = 1;
                nand->ecc.layout = &fsmc_ecc1_layout;
                nand->ecc.correct = nand_correct_data;
                break;
index 3ec34f3c9b1d71fda10160f80c62472cf5f28263..a691fbc40397d747df6acf11f8872e2da89ddedd 100644 (file)
@@ -253,6 +253,7 @@ int board_nand_init(struct nand_chip *nand)
        nand->ecc.mode          = NAND_ECC_HW_OOB_FIRST;
        nand->ecc.size          = CONFIG_SYS_NAND_ECCSIZE;
        nand->ecc.bytes         = CONFIG_SYS_NAND_ECCBYTES;
+       nand->ecc.strength      = 4;
        nand->ecc.layout        = &qi_lb60_ecclayout_2gb;
        nand->chip_delay        = 50;
        nand->options           = NAND_USE_FLASH_BBT;
index e6b7a706619ca1eb1c7c7eab2d0a910413cba86d..e53f341dcf81a2f809cc9532f8eb7b022f8474ea 100644 (file)
@@ -621,7 +621,7 @@ int board_nand_init(struct nand_chip *chip)
        chip->write_buf = mpc5121_nfc_write_buf;
        chip->verify_buf = mpc5121_nfc_verify_buf;
        chip->select_chip = mpc5121_nfc_select_chip;
-       chip->options = NAND_NO_AUTOINCR | NAND_USE_FLASH_BBT;
+       chip->bbt_options = NAND_BBT_USE_FLASH;
        chip->ecc.mode = NAND_ECC_SOFT;
 
        /* Reset NAND Flash controller */
index eeba521942b78e76e0887e7648c8681b9019172b..ac435f205045e8a5f1d55643f7cdea20af98beac 100644 (file)
@@ -396,7 +396,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 #if defined(MXC_NFC_V2_1) || defined(MXC_NFC_V3_2)
 static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd,
                                      struct nand_chip *chip,
-                                     int page, int sndcmd)
+                                     int page)
 {
        struct mxc_nand_host *host = chip->priv;
        uint8_t *buf = chip->oob_poi;
@@ -450,6 +450,7 @@ static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd,
 static int mxc_nand_read_page_raw_syndrome(struct mtd_info *mtd,
                                           struct nand_chip *chip,
                                           uint8_t *buf,
+                                          int oob_required,
                                           int page)
 {
        struct mxc_nand_host *host = chip->priv;
@@ -494,6 +495,7 @@ static int mxc_nand_read_page_raw_syndrome(struct mtd_info *mtd,
 static int mxc_nand_read_page_syndrome(struct mtd_info *mtd,
                                       struct nand_chip *chip,
                                       uint8_t *buf,
+                                      int oob_required,
                                       int page)
 {
        struct mxc_nand_host *host = chip->priv;
@@ -583,9 +585,10 @@ static int mxc_nand_write_oob_syndrome(struct mtd_info *mtd,
        return status & NAND_STATUS_FAIL ? -EIO : 0;
 }
 
-static void mxc_nand_write_page_raw_syndrome(struct mtd_info *mtd,
+static int mxc_nand_write_page_raw_syndrome(struct mtd_info *mtd,
                                             struct nand_chip *chip,
-                                            const uint8_t *buf)
+                                            const uint8_t *buf,
+                                            int oob_required)
 {
        struct mxc_nand_host *host = chip->priv;
        int eccsize = chip->ecc.size;
@@ -619,11 +622,13 @@ static void mxc_nand_write_page_raw_syndrome(struct mtd_info *mtd,
        size = mtd->oobsize - (oob - chip->oob_poi);
        if (size)
                chip->write_buf(mtd, oob, size);
+       return 0;
 }
 
-static void mxc_nand_write_page_syndrome(struct mtd_info *mtd,
+static int mxc_nand_write_page_syndrome(struct mtd_info *mtd,
                                         struct nand_chip *chip,
-                                        const uint8_t *buf)
+                                        const uint8_t *buf,
+                                        int oob_required)
 {
        struct mxc_nand_host *host = chip->priv;
        int i, n, eccsize = chip->ecc.size;
@@ -662,6 +667,7 @@ static void mxc_nand_write_page_syndrome(struct mtd_info *mtd,
        i = mtd->oobsize - (oob - chip->oob_poi);
        if (i)
                chip->write_buf(mtd, oob, i);
+       return 0;
 }
 
 static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
@@ -1188,7 +1194,7 @@ int board_nand_init(struct nand_chip *this)
 #endif
 
 #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
-       this->options |= NAND_USE_FLASH_BBT;
+       this->bbt_options |= NAND_BBT_USE_FLASH;
        this->bbt_td = &bbt_main_descr;
        this->bbt_md = &bbt_mirror_descr;
 #endif
@@ -1236,6 +1242,13 @@ int board_nand_init(struct nand_chip *this)
                this->ecc.mode = NAND_ECC_HW;
        }
 
+       if (this->ecc.mode == NAND_ECC_HW) {
+               if (is_mxc_nfc_1())
+                       this->ecc.strength = 1;
+               else
+                       this->ecc.strength = 4;
+       }
+
        host->pagesize_2k = 0;
 
        this->ecc.size = 512;
index 398e4ddc1558a8945bc53eb58b98c6c8c2fc1b4b..866cabd2765764ff29dbd84b9e2f9e58f6855ec0 100644 (file)
@@ -553,7 +553,8 @@ static uint8_t mxs_nand_read_byte(struct mtd_info *mtd)
  * Read a page from NAND.
  */
 static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
-                                       uint8_t *buf, int page)
+                                       uint8_t *buf, int oob_required,
+                                       int page)
 {
        struct mxs_nand_info *nand_info = nand->priv;
        struct mxs_dma_desc *d;
@@ -698,8 +699,9 @@ rtn:
 /*
  * Write a page to NAND.
  */
-static void mxs_nand_ecc_write_page(struct mtd_info *mtd,
-                               struct nand_chip *nand, const uint8_t *buf)
+static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
+                               struct nand_chip *nand, const uint8_t *buf,
+                               int oob_required)
 {
        struct mxs_nand_info *nand_info = nand->priv;
        struct mxs_dma_desc *d;
@@ -755,6 +757,7 @@ static void mxs_nand_ecc_write_page(struct mtd_info *mtd,
 
 rtn:
        mxs_nand_return_dma_descs(nand_info);
+       return 0;
 }
 
 /*
@@ -770,7 +773,7 @@ static int mxs_nand_hook_read_oob(struct mtd_info *mtd, loff_t from,
        struct mxs_nand_info *nand_info = chip->priv;
        int ret;
 
-       if (ops->mode == MTD_OOB_RAW)
+       if (ops->mode == MTD_OPS_RAW)
                nand_info->raw_oob_mode = 1;
        else
                nand_info->raw_oob_mode = 0;
@@ -795,7 +798,7 @@ static int mxs_nand_hook_write_oob(struct mtd_info *mtd, loff_t to,
        struct mxs_nand_info *nand_info = chip->priv;
        int ret;
 
-       if (ops->mode == MTD_OOB_RAW)
+       if (ops->mode == MTD_OPS_RAW)
                nand_info->raw_oob_mode = 1;
        else
                nand_info->raw_oob_mode = 0;
@@ -873,7 +876,7 @@ static int mxs_nand_hook_block_markbad(struct mtd_info *mtd, loff_t ofs)
  * what to do.
  */
 static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
-                               int page, int cmd)
+                               int page)
 {
        struct mxs_nand_info *nand_info = nand->priv;
 
@@ -1006,19 +1009,19 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd)
        writel(BCH_CTRL_COMPLETE_IRQ_EN, &bch_regs->hw_bch_ctrl_set);
 
        /* Hook some operations at the MTD level. */
-       if (mtd->read_oob != mxs_nand_hook_read_oob) {
-               nand_info->hooked_read_oob = mtd->read_oob;
-               mtd->read_oob = mxs_nand_hook_read_oob;
+       if (mtd->_read_oob != mxs_nand_hook_read_oob) {
+               nand_info->hooked_read_oob = mtd->_read_oob;
+               mtd->_read_oob = mxs_nand_hook_read_oob;
        }
 
-       if (mtd->write_oob != mxs_nand_hook_write_oob) {
-               nand_info->hooked_write_oob = mtd->write_oob;
-               mtd->write_oob = mxs_nand_hook_write_oob;
+       if (mtd->_write_oob != mxs_nand_hook_write_oob) {
+               nand_info->hooked_write_oob = mtd->_write_oob;
+               mtd->_write_oob = mxs_nand_hook_write_oob;
        }
 
-       if (mtd->block_markbad != mxs_nand_hook_block_markbad) {
-               nand_info->hooked_block_markbad = mtd->block_markbad;
-               mtd->block_markbad = mxs_nand_hook_block_markbad;
+       if (mtd->_block_markbad != mxs_nand_hook_block_markbad) {
+               nand_info->hooked_block_markbad = mtd->_block_markbad;
+               mtd->_block_markbad = mxs_nand_hook_block_markbad;
        }
 
        /* We use the reference implementation for bad block management. */
@@ -1172,6 +1175,7 @@ int board_nand_init(struct nand_chip *nand)
        nand->ecc.mode          = NAND_ECC_HW;
        nand->ecc.bytes         = 9;
        nand->ecc.size          = 512;
+       nand->ecc.strength      = 8;
 
        return 0;
 
index a2d06be99fcf4f3f0882671a514b36b4afecb7a3..9e05cef4179f3ddfc10e26f7e116f32c399364e2 100644 (file)
@@ -21,7 +21,7 @@
  *  TODO:
  *     Enable cached programming for 2k page size chips
  *     Check, if mtd->ecctype should be set to MTD_ECC_HW
- *     if we have HW ecc support.
+ *     if we have HW ECC support.
  *     The AG-AND chips have nice features for speed improvement,
  *     which are not supported yet. Read / program 4 pages in one go.
  *     BBT table is not serialized, has to be fixed
@@ -134,21 +134,14 @@ static int check_offs_len(struct mtd_info *mtd,
                ret = -EINVAL;
        }
 
-       /* Do not allow past end of device */
-       if (ofs + len > mtd->size) {
-               MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Past end of device\n",
-                                       __func__);
-               ret = -EINVAL;
-       }
-
        return ret;
 }
 
 /**
  * nand_release_device - [GENERIC] release chip
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Deselect, release chip lock and wake up anyone waiting on the device
+ * Deselect, release chip lock and wake up anyone waiting on the device.
  */
 static void nand_release_device(struct mtd_info *mtd)
 {
@@ -160,9 +153,9 @@ static void nand_release_device(struct mtd_info *mtd)
 
 /**
  * nand_read_byte - [DEFAULT] read one byte from the chip
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Default read function for 8bit buswith
+ * Default read function for 8bit buswidth.
  */
 uint8_t nand_read_byte(struct mtd_info *mtd)
 {
@@ -172,10 +165,11 @@ uint8_t nand_read_byte(struct mtd_info *mtd)
 
 /**
  * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
- * @mtd:       MTD device structure
+ * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
+ * @mtd: MTD device structure
+ *
+ * Default read function for 16bit buswidth with endianness conversion.
  *
- * Default read function for 16bit buswith with
- * endianess conversion
  */
 static uint8_t nand_read_byte16(struct mtd_info *mtd)
 {
@@ -185,10 +179,9 @@ static uint8_t nand_read_byte16(struct mtd_info *mtd)
 
 /**
  * nand_read_word - [DEFAULT] read one word from the chip
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Default read function for 16bit buswith without
- * endianess conversion
+ * Default read function for 16bit buswidth without endianness conversion.
  */
 static u16 nand_read_word(struct mtd_info *mtd)
 {
@@ -198,8 +191,8 @@ static u16 nand_read_word(struct mtd_info *mtd)
 
 /**
  * nand_select_chip - [DEFAULT] control CE line
- * @mtd:       MTD device structure
- * @chipnr:    chipnumber to select, -1 for deselect
+ * @mtd: MTD device structure
+ * @chipnr: chipnumber to select, -1 for deselect
  *
  * Default select function for 1 chip devices.
  */
@@ -221,11 +214,11 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr)
 
 /**
  * nand_write_buf - [DEFAULT] write buffer to chip
- * @mtd:       MTD device structure
- * @buf:       data buffer
- * @len:       number of bytes to write
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
  *
- * Default write function for 8bit buswith
+ * Default write function for 8bit buswidth.
  */
 void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -238,11 +231,11 @@ void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_read_buf - [DEFAULT] read chip data into buffer
- * @mtd:       MTD device structure
- * @buf:       buffer to store date
- * @len:       number of bytes to read
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
  *
- * Default read function for 8bit buswith
+ * Default read function for 8bit buswidth.
  */
 void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
@@ -255,11 +248,11 @@ void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 
 /**
  * nand_verify_buf - [DEFAULT] Verify chip data against buffer
- * @mtd:       MTD device structure
- * @buf:       buffer containing the data to compare
- * @len:       number of bytes to compare
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
  *
- * Default verify function for 8bit buswith
+ * Default verify function for 8bit buswidth.
  */
 static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -274,11 +267,11 @@ static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_write_buf16 - [DEFAULT] write buffer to chip
- * @mtd:       MTD device structure
- * @buf:       data buffer
- * @len:       number of bytes to write
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
  *
- * Default write function for 16bit buswith
+ * Default write function for 16bit buswidth.
  */
 void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -294,11 +287,11 @@ void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_read_buf16 - [DEFAULT] read chip data into buffer
- * @mtd:       MTD device structure
- * @buf:       buffer to store date
- * @len:       number of bytes to read
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
  *
- * Default read function for 16bit buswith
+ * Default read function for 16bit buswidth.
  */
 void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 {
@@ -313,11 +306,11 @@ void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 
 /**
  * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
- * @mtd:       MTD device structure
- * @buf:       buffer containing the data to compare
- * @len:       number of bytes to compare
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
  *
- * Default verify function for 16bit buswith
+ * Default verify function for 16bit buswidth.
  */
 static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -335,19 +328,19 @@ static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_block_bad - [DEFAULT] Read bad block marker from the chip
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
- * @getchip:   0, if the chip is already selected
+ * @mtd: MTD device structure
+ * @ofs: offset from device start
+ * @getchip: 0, if the chip is already selected
  *
  * Check, if the block is bad.
  */
 static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 {
-       int page, chipnr, res = 0;
+       int page, chipnr, res = 0, i = 0;
        struct nand_chip *chip = mtd->priv;
        u16 bad;
 
-       if (chip->options & NAND_BBT_SCANLASTPAGE)
+       if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
                ofs += mtd->erasesize - mtd->writesize;
 
        page = (int)(ofs >> chip->page_shift) & chip->pagemask;
@@ -361,23 +354,29 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
                chip->select_chip(mtd, chipnr);
        }
 
-       if (chip->options & NAND_BUSWIDTH_16) {
-               chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE,
-                             page);
-               bad = cpu_to_le16(chip->read_word(mtd));
-               if (chip->badblockpos & 0x1)
-                       bad >>= 8;
-               else
-                       bad &= 0xFF;
-       } else {
-               chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page);
-               bad = chip->read_byte(mtd);
-       }
+       do {
+               if (chip->options & NAND_BUSWIDTH_16) {
+                       chip->cmdfunc(mtd, NAND_CMD_READOOB,
+                                       chip->badblockpos & 0xFE, page);
+                       bad = cpu_to_le16(chip->read_word(mtd));
+                       if (chip->badblockpos & 0x1)
+                               bad >>= 8;
+                       else
+                               bad &= 0xFF;
+               } else {
+                       chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos,
+                                       page);
+                       bad = chip->read_byte(mtd);
+               }
 
-       if (likely(chip->badblockbits == 8))
-               res = bad != 0xFF;
-       else
-               res = hweight8(bad) < chip->badblockbits;
+               if (likely(chip->badblockbits == 8))
+                       res = bad != 0xFF;
+               else
+                       res = hweight8(bad) < chip->badblockbits;
+               ofs += mtd->writesize;
+               page = (int)(ofs >> chip->page_shift) & chip->pagemask;
+               i++;
+       } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));
 
        if (getchip)
                nand_release_device(mtd);
@@ -387,57 +386,83 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 
 /**
  * nand_default_block_markbad - [DEFAULT] mark a block bad
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
+ * @mtd: MTD device structure
+ * @ofs: offset from device start
  *
- * This is the default implementation, which can be overridden by
- * a hardware specific driver.
+ * This is the default implementation, which can be overridden by a hardware
+ * specific driver. We try operations in the following order, according to our
+ * bbt_options (NAND_BBT_NO_OOB_BBM and NAND_BBT_USE_FLASH):
+ *  (1) erase the affected block, to allow OOB marker to be written cleanly
+ *  (2) update in-memory BBT
+ *  (3) write bad block marker to OOB area of affected block
+ *  (4) update flash-based BBT
+ * Note that we retain the first error encountered in (3) or (4), finish the
+ * procedures, and dump the error in the end.
 */
 static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
        struct nand_chip *chip = mtd->priv;
        uint8_t buf[2] = { 0, 0 };
-       int block, ret, i = 0;
+       int block, res, ret = 0, i = 0;
+       int write_oob = !(chip->bbt_options & NAND_BBT_NO_OOB_BBM);
 
-       if (chip->options & NAND_BBT_SCANLASTPAGE)
-               ofs += mtd->erasesize - mtd->writesize;
+       if (write_oob) {
+               struct erase_info einfo;
+
+               /* Attempt erase before marking OOB */
+               memset(&einfo, 0, sizeof(einfo));
+               einfo.mtd = mtd;
+               einfo.addr = ofs;
+               einfo.len = 1 << chip->phys_erase_shift;
+               nand_erase_nand(mtd, &einfo, 0);
+       }
 
        /* Get block number */
        block = (int)(ofs >> chip->bbt_erase_shift);
+       /* Mark block bad in memory-based BBT */
        if (chip->bbt)
                chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
 
-       /* Do we have a flash based bad block table ? */
-       if (chip->options & NAND_USE_FLASH_BBT)
-               ret = nand_update_bbt(mtd, ofs);
-       else {
+       /* Write bad block marker to OOB */
+       if (write_oob) {
+               struct mtd_oob_ops ops;
+               loff_t wr_ofs = ofs;
+
                nand_get_device(chip, mtd, FL_WRITING);
 
-               /* Write to first two pages and to byte 1 and 6 if necessary.
-                * If we write to more than one location, the first error
-                * encountered quits the procedure. We write two bytes per
-                * location, so we dont have to mess with 16 bit access.
-                */
-               do {
-                       chip->ops.len = chip->ops.ooblen = 2;
-                       chip->ops.datbuf = NULL;
-                       chip->ops.oobbuf = buf;
-                       chip->ops.ooboffs = chip->badblockpos & ~0x01;
+               ops.datbuf = NULL;
+               ops.oobbuf = buf;
+               ops.ooboffs = chip->badblockpos;
+               if (chip->options & NAND_BUSWIDTH_16) {
+                       ops.ooboffs &= ~0x01;
+                       ops.len = ops.ooblen = 2;
+               } else {
+                       ops.len = ops.ooblen = 1;
+               }
+               ops.mode = MTD_OPS_PLACE_OOB;
 
-                       ret = nand_do_write_oob(mtd, ofs, &chip->ops);
+               /* Write to first/last page(s) if necessary */
+               if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
+                       wr_ofs += mtd->erasesize - mtd->writesize;
+               do {
+                       res = nand_do_write_oob(mtd, wr_ofs, &ops);
+                       if (!ret)
+                               ret = res;
 
-                       if (!ret && (chip->options & NAND_BBT_SCANBYTE1AND6)) {
-                               chip->ops.ooboffs = NAND_SMALL_BADBLOCK_POS
-                                       & ~0x01;
-                               ret = nand_do_write_oob(mtd, ofs, &chip->ops);
-                       }
                        i++;
-                       ofs += mtd->writesize;
-               } while (!ret && (chip->options & NAND_BBT_SCAN2NDPAGE) &&
-                               i < 2);
+                       wr_ofs += mtd->writesize;
+               } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);
 
                nand_release_device(mtd);
        }
+
+       /* Update flash-based bad block table */
+       if (chip->bbt_options & NAND_BBT_USE_FLASH) {
+               res = nand_update_bbt(mtd, ofs);
+               if (!ret)
+                       ret = res;
+       }
+
        if (!ret)
                mtd->ecc_stats.badblocks++;
 
@@ -446,16 +471,16 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
 /**
  * nand_check_wp - [GENERIC] check if the chip is write protected
- * @mtd:       MTD device structure
- * Check, if the device is write protected
+ * @mtd: MTD device structure
  *
- * The function expects, that the device is already selected
+ * Check, if the device is write protected. The function expects, that the
+ * device is already selected.
  */
 static int nand_check_wp(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
 
-       /* broken xD cards report WP despite being writable */
+       /* Broken xD cards report WP despite being writable */
        if (chip->options & NAND_BROKEN_XD)
                return 0;
 
@@ -466,10 +491,10 @@ static int nand_check_wp(struct mtd_info *mtd)
 
 /**
  * nand_block_checkbad - [GENERIC] Check if a block is marked bad
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
- * @getchip:   0, if the chip is already selected
- * @allowbbt:  1, if its allowed to access the bbt area
+ * @mtd: MTD device structure
+ * @ofs: offset from device start
+ * @getchip: 0, if the chip is already selected
+ * @allowbbt: 1, if its allowed to access the bbt area
  *
  * Check, if the block is bad. Either by reading the bad block table or
  * calling of the scan function.
@@ -491,10 +516,7 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
        return nand_isbad_bbt(mtd, ofs, allowbbt);
 }
 
-/*
- * Wait for the ready pin, after a command
- * The timeout is catched later.
- */
+/* Wait for the ready pin, after a command. The timeout is caught later. */
 void nand_wait_ready(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
@@ -503,7 +525,7 @@ void nand_wait_ready(struct mtd_info *mtd)
 
        time_start = get_timer(0);
 
-       /* wait until command is processed or timeout occures */
+       /* Wait until command is processed or timeout occurs */
        while (get_timer(time_start) < timeo) {
                if (chip->dev_ready)
                        if (chip->dev_ready(mtd))
@@ -513,13 +535,13 @@ void nand_wait_ready(struct mtd_info *mtd)
 
 /**
  * nand_command - [DEFAULT] Send command to NAND device
- * @mtd:       MTD device structure
- * @command:   the command to be sent
- * @column:    the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
+ * @mtd: MTD device structure
+ * @command: the command to be sent
+ * @column: the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
  *
- * Send command to NAND device. This function is used for small page
- * devices (256/512 Bytes per page)
+ * Send command to NAND device. This function is used for small page devices
+ * (256/512 Bytes per page).
  */
 static void nand_command(struct mtd_info *mtd, unsigned int command,
                         int column, int page_addr)
@@ -528,9 +550,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
        uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT;
 
-       /*
-        * Write out the command to the device.
-        */
+       /* Write out the command to the device */
        if (command == NAND_CMD_SEQIN) {
                int readcmd;
 
@@ -550,9 +570,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        }
        chip->cmd_ctrl(mtd, command, ctrl);
 
-       /*
-        * Address cycle, when necessary
-        */
+       /* Address cycle, when necessary */
        ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
        /* Serially input address */
        if (column != -1) {
@@ -573,8 +591,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
 
        /*
-        * program and erase have their own busy handlers
-        * status and sequential in needs no delay
+        * Program and erase have their own busy handlers status and sequential
+        * in needs no delay
         */
        switch (command) {
 
@@ -608,8 +626,10 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
                        return;
                }
        }
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
+       /*
+        * Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine.
+        */
        ndelay(100);
 
        nand_wait_ready(mtd);
@@ -617,14 +637,14 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
 
 /**
  * nand_command_lp - [DEFAULT] Send command to NAND large page device
- * @mtd:       MTD device structure
- * @command:   the command to be sent
- * @column:    the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
+ * @mtd: MTD device structure
+ * @command: the command to be sent
+ * @column: the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
  *
  * Send command to NAND device. This is the version for the new large page
- * devices We dont have the separate regions as we have in the small page
- * devices.  We must emulate NAND_CMD_READOOB to keep the code compatible.
+ * devices. We don't have the separate regions as we have in the small page
+ * devices. We must emulate NAND_CMD_READOOB to keep the code compatible.
  */
 static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                            int column, int page_addr)
@@ -667,8 +687,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
 
        /*
-        * program and erase have their own busy handlers
-        * status, sequential in, and deplete1 need no delay
+        * Program and erase have their own busy handlers status, sequential
+        * in, and deplete1 need no delay.
         */
        switch (command) {
 
@@ -682,14 +702,12 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        case NAND_CMD_DEPLETE1:
                return;
 
-               /*
-                * read error status commands require only a short delay
-                */
        case NAND_CMD_STATUS_ERROR:
        case NAND_CMD_STATUS_ERROR0:
        case NAND_CMD_STATUS_ERROR1:
        case NAND_CMD_STATUS_ERROR2:
        case NAND_CMD_STATUS_ERROR3:
+               /* Read error status commands require only a short delay */
                udelay(chip->chip_delay);
                return;
 
@@ -723,7 +741,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        default:
                /*
                 * If we don't have access to the busy pin, we apply the given
-                * command delay
+                * command delay.
                 */
                if (!chip->dev_ready) {
                        udelay(chip->chip_delay);
@@ -731,8 +749,10 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                }
        }
 
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
+       /*
+        * Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine.
+        */
        ndelay(100);
 
        nand_wait_ready(mtd);
@@ -740,9 +760,9 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
 
 /**
  * nand_get_device - [GENERIC] Get chip for selected access
- * @chip:      the nand chip descriptor
- * @mtd:       MTD device structure
- * @new_state: the state which is requested
+ * @chip: the nand chip descriptor
+ * @mtd: MTD device structure
+ * @new_state: the state which is requested
  *
  * Get the device and lock it for exclusive access
  */
@@ -754,13 +774,13 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
 }
 
 /**
- * nand_wait - [DEFAULT]  wait until the command is done
- * @mtd:       MTD device structure
- * @chip:      NAND chip structure
+ * nand_wait - [DEFAULT] wait until the command is done
+ * @mtd: MTD device structure
+ * @chip: NAND chip structure
  *
- * Wait for command done. This applies to erase and program only
- * Erase can take up to 400ms and program up to 20ms according to
- * general NAND and SmartMedia specs
+ * Wait for command done. This applies to erase and program only. Erase can
+ * take up to 400ms and program up to 20ms according to general NAND and
+ * SmartMedia specs.
  */
 static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 {
@@ -804,34 +824,37 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 }
 
 /**
- * nand_read_page_raw - [Intern] read raw page data without ecc
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_raw - [INTERN] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
  *
- * Not for syndrome calculating ecc controllers, which use a special oob layout
+ * Not for syndrome calculating ECC controllers, which use a special oob layout.
  */
 static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
-                             uint8_t *buf, int page)
+                             uint8_t *buf, int oob_required, int page)
 {
        chip->read_buf(mtd, buf, mtd->writesize);
-       chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+       if (oob_required)
+               chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
        return 0;
 }
 
 /**
- * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
  *
  * We need a special oob layout and handling even when OOB isn't used.
  */
 static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
-                                       struct nand_chip *chip,
-                                       uint8_t *buf, int page)
+                                      struct nand_chip *chip, uint8_t *buf,
+                                      int oob_required, int page)
 {
        int eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -864,14 +887,15 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
 }
 
 /**
- * nand_read_page_swecc - [REPLACABLE] software ecc based page read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_swecc - [REPLACEABLE] software ECC based page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
  */
 static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
-                               uint8_t *buf, int page)
+                               uint8_t *buf, int oob_required, int page)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -881,7 +905,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
        uint8_t *ecc_code = chip->buffers->ecccode;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
 
-       chip->ecc.read_page_raw(mtd, chip, buf, page);
+       chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
 
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
                chip->ecc.calculate(mtd, p, &ecc_calc[i]);
@@ -905,12 +929,12 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @data_offs: offset of requested data within the page
- * @readlen:   data length
- * @bufpoi:    buffer to store read data
+ * nand_read_subpage - [REPLACEABLE] software ECC based sub-page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @data_offs: offset of requested data within the page
+ * @readlen: data length
+ * @bufpoi: buffer to store read data
  */
 static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
                        uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
@@ -923,12 +947,12 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
        int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
        int index = 0;
 
-       /* Column address wihin the page aligned to ECC size (256bytes). */
+       /* Column address within the page aligned to ECC size (256bytes) */
        start_step = data_offs / chip->ecc.size;
        end_step = (data_offs + readlen - 1) / chip->ecc.size;
        num_steps = end_step - start_step + 1;
 
-       /* Data size aligned to ECC ecc.size*/
+       /* Data size aligned to ECC ecc.size */
        datafrag_len = num_steps * chip->ecc.size;
        eccfrag_len = num_steps * chip->ecc.bytes;
 
@@ -940,13 +964,14 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
        p = bufpoi + data_col_addr;
        chip->read_buf(mtd, p, datafrag_len);
 
-       /* Calculate  ECC */
+       /* Calculate ECC */
        for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
                chip->ecc.calculate(mtd, p, &chip->buffers->ecccalc[i]);
 
-       /* The performance is faster if to position offsets
-          according to ecc.pos. Let make sure here that
-          there are no gaps in ecc positions */
+       /*
+        * The performance is faster if we position offsets according to
+        * ecc.pos. Let's make sure that there are no gaps in ECC positions.
+        */
        for (i = 0; i < eccfrag_len - 1; i++) {
                if (eccpos[i + start_step * chip->ecc.bytes] + 1 !=
                        eccpos[i + start_step * chip->ecc.bytes + 1]) {
@@ -958,8 +983,10 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
                chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
                chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
        } else {
-               /* send the command to read the particular ecc bytes */
-               /* take care about buswidth alignment in read_buf */
+               /*
+                * Send the command to read the particular ECC bytes take care
+                * about buswidth alignment in read_buf.
+                */
                index = start_step * chip->ecc.bytes;
 
                aligned_pos = eccpos[index] & ~(busw - 1);
@@ -992,16 +1019,17 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_page_hwecc - [REPLACABLE] hardware ecc based page read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_hwecc - [REPLACEABLE] hardware ECC based page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
  *
- * Not for syndrome calculating ecc controllers which need a special oob layout
+ * Not for syndrome calculating ECC controllers which need a special oob layout.
  */
 static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
-                               uint8_t *buf, int page)
+                               uint8_t *buf, int oob_required, int page)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1037,21 +1065,21 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_page_hwecc_oob_first - [REPLACABLE] hw ecc, read oob first
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_hwecc_oob_first - [REPLACEABLE] hw ecc, read oob first
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
  *
- * Hardware ECC for large page chips, require OOB to be read first.
- * For this ECC mode, the write_page method is re-used from ECC_HW.
- * These methods read/write ECC from the OOB area, unlike the
- * ECC_HW_SYNDROME support with multiple ECC steps, follows the
- * "infix ECC" scheme and reads/writes ECC from the data area, by
- * overwriting the NAND manufacturer bad block markings.
+ * Hardware ECC for large page chips, require OOB to be read first. For this
+ * ECC mode, the write_page method is re-used from ECC_HW. These methods
+ * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with
+ * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from
+ * the data area, by overwriting the NAND manufacturer bad block markings.
  */
 static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
-       struct nand_chip *chip, uint8_t *buf, int page)
+       struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1086,17 +1114,18 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 }
 
 /**
- * nand_read_page_syndrome - [REPLACABLE] hardware ecc syndrom based page read
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
  *
- * The hw generator calculates the error syndrome automatically. Therefor
- * we need a special oob layout and handling.
+ * The hw generator calculates the error syndrome automatically. Therefore we
+ * need a special oob layout and handling.
  */
 static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
-                                  uint8_t *buf, int page)
+                                  uint8_t *buf, int oob_required, int page)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1141,29 +1170,29 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_transfer_oob - [Internal] Transfer oob to client buffer
- * @chip:      nand chip structure
- * @oob:       oob destination address
- * @ops:       oob ops structure
- * @len:       size of oob to transfer
+ * nand_transfer_oob - [INTERN] Transfer oob to client buffer
+ * @chip: nand chip structure
+ * @oob: oob destination address
+ * @ops: oob ops structure
+ * @len: size of oob to transfer
  */
 static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
                                  struct mtd_oob_ops *ops, size_t len)
 {
        switch (ops->mode) {
 
-       case MTD_OOB_PLACE:
-       case MTD_OOB_RAW:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_RAW:
                memcpy(oob, chip->oob_poi + ops->ooboffs, len);
                return oob + len;
 
-       case MTD_OOB_AUTO: {
+       case MTD_OPS_AUTO_OOB: {
                struct nand_oobfree *free = chip->ecc.layout->oobfree;
                uint32_t boffs = 0, roffs = ops->ooboffs;
                size_t bytes = 0;
 
                for (; free->length && len; free++, len -= bytes) {
-                       /* Read request not from offset 0 ? */
+                       /* Read request not from offset 0? */
                        if (unlikely(roffs)) {
                                if (roffs >= free->length) {
                                        roffs -= free->length;
@@ -1189,26 +1218,23 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
 }
 
 /**
- * nand_do_read_ops - [Internal] Read data with ECC
- *
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob ops structure
+ * nand_do_read_ops - [INTERN] Read data with ECC
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @ops: oob ops structure
  *
  * Internal function. Called with chip held.
  */
 static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                            struct mtd_oob_ops *ops)
 {
-       int chipnr, page, realpage, col, bytes, aligned;
+       int chipnr, page, realpage, col, bytes, aligned, oob_required;
        struct nand_chip *chip = mtd->priv;
        struct mtd_ecc_stats stats;
-       int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
-       int sndcmd = 1;
        int ret = 0;
        uint32_t readlen = ops->len;
        uint32_t oobreadlen = ops->ooblen;
-       uint32_t max_oobsize = ops->mode == MTD_OOB_AUTO ?
+       uint32_t max_oobsize = ops->mode == MTD_OPS_AUTO_OOB ?
                mtd->oobavail : mtd->oobsize;
 
        uint8_t *bufpoi, *oob, *buf;
@@ -1225,6 +1251,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 
        buf = ops->datbuf;
        oob = ops->oobbuf;
+       oob_required = oob ? 1 : 0;
 
        while (1) {
                WATCHDOG_RESET();
@@ -1232,41 +1259,46 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                bytes = min(mtd->writesize - col, readlen);
                aligned = (bytes == mtd->writesize);
 
-               /* Is the current page in the buffer ? */
+               /* Is the current page in the buffer? */
                if (realpage != chip->pagebuf || oob) {
                        bufpoi = aligned ? buf : chip->buffers->databuf;
 
-                       if (likely(sndcmd)) {
-                               chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
-                               sndcmd = 0;
-                       }
+                       chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
 
                        /* Now read the page into the buffer */
-                       if (unlikely(ops->mode == MTD_OOB_RAW))
-                               ret = chip->ecc.read_page_raw(mtd, chip,
-                                                             bufpoi, page);
+                       if (unlikely(ops->mode == MTD_OPS_RAW))
+                               ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
+                                                             oob_required,
+                                                             page);
                        else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
                            !oob)
                                ret = chip->ecc.read_subpage(mtd, chip,
                                                        col, bytes, bufpoi);
                        else
                                ret = chip->ecc.read_page(mtd, chip, bufpoi,
-                                                         page);
-                       if (ret < 0)
+                                                         oob_required, page);
+                       if (ret < 0) {
+                               if (!aligned)
+                                       /* Invalidate page cache */
+                                       chip->pagebuf = -1;
                                break;
+                       }
 
                        /* Transfer not aligned data */
                        if (!aligned) {
                                if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
-                                   !(mtd->ecc_stats.failed - stats.failed))
+                                   !(mtd->ecc_stats.failed - stats.failed) &&
+                                   (ops->mode != MTD_OPS_RAW))
                                        chip->pagebuf = realpage;
+                               else
+                                       /* Invalidate page cache */
+                                       chip->pagebuf = -1;
                                memcpy(buf, chip->buffers->databuf + col, bytes);
                        }
 
                        buf += bytes;
 
                        if (unlikely(oob)) {
-
                                int toread = min(oobreadlen, max_oobsize);
 
                                if (toread) {
@@ -1275,20 +1307,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                                        oobreadlen -= toread;
                                }
                        }
-
-                       if (!(chip->options & NAND_NO_READRDY)) {
-                               /*
-                                * Apply delay or wait for ready/busy pin. Do
-                                * this before the AUTOINCR check, so no
-                                * problems arise if a chip which does auto
-                                * increment is marked as NOAUTOINCR by the
-                                * board driver.
-                                */
-                               if (!chip->dev_ready)
-                                       udelay(chip->chip_delay);
-                               else
-                                       nand_wait_ready(mtd);
-                       }
                } else {
                        memcpy(buf, chip->buffers->databuf + col, bytes);
                        buf += bytes;
@@ -1299,7 +1317,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                if (!readlen)
                        break;
 
-               /* For subsequent reads align to page boundary. */
+               /* For subsequent reads align to page boundary */
                col = 0;
                /* Increment page address */
                realpage++;
@@ -1311,12 +1329,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                        chip->select_chip(mtd, -1);
                        chip->select_chip(mtd, chipnr);
                }
-
-               /* Check, if the chip supports auto page increment
-                * or if we have hit a block boundary.
-                */
-               if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
-                       sndcmd = 1;
        }
 
        ops->retlen = ops->len - (size_t) readlen;
@@ -1334,69 +1346,55 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 
 /**
  * nand_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @len:       number of bytes to read
- * @retlen:    pointer to variable to store the number of read bytes
- * @buf:       the databuffer to put data
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @len: number of bytes to read
+ * @retlen: pointer to variable to store the number of read bytes
+ * @buf: the databuffer to put data
  *
- * Get hold of the chip and call nand_do_read
+ * Get hold of the chip and call nand_do_read.
  */
 static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
                     size_t *retlen, uint8_t *buf)
 {
        struct nand_chip *chip = mtd->priv;
+       struct mtd_oob_ops ops;
        int ret;
 
-       /* Do not allow reads past end of device */
-       if ((from + len) > mtd->size)
-               return -EINVAL;
-       if (!len)
-               return 0;
-
        nand_get_device(chip, mtd, FL_READING);
-
-       chip->ops.len = len;
-       chip->ops.datbuf = buf;
-       chip->ops.oobbuf = NULL;
-
-       ret = nand_do_read_ops(mtd, from, &chip->ops);
-
-       *retlen = chip->ops.retlen;
-
+       ops.len = len;
+       ops.datbuf = buf;
+       ops.oobbuf = NULL;
+       ops.mode = MTD_OPS_PLACE_OOB;
+       ret = nand_do_read_ops(mtd, from, &ops);
+       *retlen = ops.retlen;
        nand_release_device(mtd);
-
        return ret;
 }
 
 /**
- * nand_read_oob_std - [REPLACABLE] the most common OOB data read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to read
- * @sndcmd:    flag whether to issue read command or not
+ * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to read
  */
 static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
-                            int page, int sndcmd)
+                            int page)
 {
-       if (sndcmd) {
-               chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
-               sndcmd = 0;
-       }
+       chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
        chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-       return sndcmd;
+       return 0;
 }
 
 /**
- * nand_read_oob_syndrome - [REPLACABLE] OOB data read function for HW ECC
+ * nand_read_oob_syndrome - [REPLACEABLE] OOB data read function for HW ECC
  *                         with syndromes
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to read
- * @sndcmd:    flag whether to issue read command or not
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to read
  */
 static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
-                                 int page, int sndcmd)
+                                 int page)
 {
        uint8_t *buf = chip->oob_poi;
        int length = mtd->oobsize;
@@ -1423,14 +1421,14 @@ static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
        if (length > 0)
                chip->read_buf(mtd, bufpoi, length);
 
-       return 1;
+       return 0;
 }
 
 /**
- * nand_write_oob_std - [REPLACABLE] the most common OOB data write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to write
+ * nand_write_oob_std - [REPLACEABLE] the most common OOB data write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to write
  */
 static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
                              int page)
@@ -1450,11 +1448,11 @@ static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_oob_syndrome - [REPLACABLE] OOB data write function for HW ECC
- *                          with syndrome - only for large page flash !
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to write
+ * nand_write_oob_syndrome - [REPLACEABLE] OOB data write function for HW ECC
+ *                          with syndrome - only for large page flash
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to write
  */
 static int nand_write_oob_syndrome(struct mtd_info *mtd,
                                   struct nand_chip *chip, int page)
@@ -1509,27 +1507,30 @@ static int nand_write_oob_syndrome(struct mtd_info *mtd,
 }
 
 /**
- * nand_do_read_oob - [Intern] NAND read out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operations description structure
+ * nand_do_read_oob - [INTERN] NAND read out-of-band
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @ops: oob operations description structure
  *
- * NAND read out-of-band data from the spare area
+ * NAND read out-of-band data from the spare area.
  */
 static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
                            struct mtd_oob_ops *ops)
 {
-       int page, realpage, chipnr, sndcmd = 1;
+       int page, realpage, chipnr;
        struct nand_chip *chip = mtd->priv;
-       int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
+       struct mtd_ecc_stats stats;
        int readlen = ops->ooblen;
        int len;
        uint8_t *buf = ops->oobbuf;
+       int ret = 0;
 
        MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08Lx, len = %i\n",
                        __func__, (unsigned long long)from, readlen);
 
-       if (ops->mode == MTD_OOB_AUTO)
+       stats = mtd->ecc_stats;
+
+       if (ops->mode == MTD_OPS_AUTO_OOB)
                len = chip->ecc.layout->oobavail;
        else
                len = mtd->oobsize;
@@ -1558,24 +1559,17 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 
        while (1) {
                WATCHDOG_RESET();
-               sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
+               if (ops->mode == MTD_OPS_RAW)
+                       ret = chip->ecc.read_oob_raw(mtd, chip, page);
+               else
+                       ret = chip->ecc.read_oob(mtd, chip, page);
+
+               if (ret < 0)
+                       break;
 
                len = min(len, readlen);
                buf = nand_transfer_oob(chip, buf, ops, len);
 
-               if (!(chip->options & NAND_NO_READRDY)) {
-                       /*
-                        * Apply delay or wait for ready/busy pin. Do this
-                        * before the AUTOINCR check, so no problems arise if a
-                        * chip which does auto increment is marked as
-                        * NOAUTOINCR by the board driver.
-                        */
-                       if (!chip->dev_ready)
-                               udelay(chip->chip_delay);
-                       else
-                               nand_wait_ready(mtd);
-               }
-
                readlen -= len;
                if (!readlen)
                        break;
@@ -1590,25 +1584,26 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
                        chip->select_chip(mtd, -1);
                        chip->select_chip(mtd, chipnr);
                }
-
-               /* Check, if the chip supports auto page increment
-                * or if we have hit a block boundary.
-                */
-               if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
-                       sndcmd = 1;
        }
 
-       ops->oobretlen = ops->ooblen;
-       return 0;
+       ops->oobretlen = ops->ooblen - readlen;
+
+       if (ret < 0)
+               return ret;
+
+       if (mtd->ecc_stats.failed - stats.failed)
+               return -EBADMSG;
+
+       return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
 }
 
 /**
  * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operation description structure
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @ops: oob operation description structure
  *
- * NAND read data and/or out-of-band data
+ * NAND read data and/or out-of-band data.
  */
 static int nand_read_oob(struct mtd_info *mtd, loff_t from,
                         struct mtd_oob_ops *ops)
@@ -1628,9 +1623,9 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
        nand_get_device(chip, mtd, FL_READING);
 
        switch (ops->mode) {
-       case MTD_OOB_PLACE:
-       case MTD_OOB_AUTO:
-       case MTD_OOB_RAW:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_AUTO_OOB:
+       case MTD_OPS_RAW:
                break;
 
        default:
@@ -1649,31 +1644,36 @@ out:
 
 
 /**
- * nand_write_page_raw - [Intern] raw page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_raw - [INTERN] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
  *
- * Not for syndrome calculating ecc controllers, which use a special oob layout
+ * Not for syndrome calculating ECC controllers, which use a special oob layout.
  */
-static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
-                               const uint8_t *buf)
+static int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+                               const uint8_t *buf, int oob_required)
 {
        chip->write_buf(mtd, buf, mtd->writesize);
-       chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+       if (oob_required)
+               chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       return 0;
 }
 
 /**
- * nand_write_page_raw_syndrome - [Intern] raw page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_raw_syndrome - [INTERN] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
  *
  * We need a special oob layout and handling even when ECC isn't checked.
  */
-static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
+static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
                                        struct nand_chip *chip,
-                                       const uint8_t *buf)
+                                       const uint8_t *buf, int oob_required)
 {
        int eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1701,15 +1701,18 @@ static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
        size = mtd->oobsize - (oob - chip->oob_poi);
        if (size)
                chip->write_buf(mtd, oob, size);
+
+       return 0;
 }
 /**
- * nand_write_page_swecc - [REPLACABLE] software ecc based page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
  */
-static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
-                                 const uint8_t *buf)
+static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+                                 const uint8_t *buf, int oob_required)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1718,24 +1721,25 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
        const uint8_t *p = buf;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
 
-       /* Software ecc calculation */
+       /* Software ECC calculation */
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
                chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
        for (i = 0; i < chip->ecc.total; i++)
                chip->oob_poi[eccpos[i]] = ecc_calc[i];
 
-       chip->ecc.write_page_raw(mtd, chip, buf);
+       return chip->ecc.write_page_raw(mtd, chip, buf, 1);
 }
 
 /**
- * nand_write_page_hwecc - [REPLACABLE] hardware ecc based page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_hwecc - [REPLACEABLE] hardware ECC based page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
  */
-static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
-                                 const uint8_t *buf)
+static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+                                 const uint8_t *buf, int oob_required)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1754,19 +1758,23 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
                chip->oob_poi[eccpos[i]] = ecc_calc[i];
 
        chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       return 0;
 }
 
 /**
- * nand_write_page_syndrome - [REPLACABLE] hardware ecc syndrom based page write
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
  *
- * The hw generator calculates the error syndrome automatically. Therefor
- * we need a special oob layout and handling.
+ * The hw generator calculates the error syndrome automatically. Therefore we
+ * need a special oob layout and handling.
  */
-static void nand_write_page_syndrome(struct mtd_info *mtd,
-                                   struct nand_chip *chip, const uint8_t *buf)
+static int nand_write_page_syndrome(struct mtd_info *mtd,
+                                   struct nand_chip *chip,
+                                   const uint8_t *buf, int oob_required)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1798,32 +1806,39 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
        i = mtd->oobsize - (oob - chip->oob_poi);
        if (i)
                chip->write_buf(mtd, oob, i);
+
+       return 0;
 }
 
 /**
  * nand_write_page - [REPLACEABLE] write one page
- * @mtd:       MTD device structure
- * @chip:      NAND chip descriptor
- * @buf:       the data to write
- * @page:      page number to write
- * @cached:    cached programming
- * @raw:       use _raw version of write_page
+ * @mtd: MTD device structure
+ * @chip: NAND chip descriptor
+ * @buf: the data to write
+ * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
+ * @cached: cached programming
+ * @raw: use _raw version of write_page
  */
 static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-                          const uint8_t *buf, int page, int cached, int raw)
+                          const uint8_t *buf, int oob_required, int page,
+                          int cached, int raw)
 {
        int status;
 
        chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 
        if (unlikely(raw))
-               chip->ecc.write_page_raw(mtd, chip, buf);
+               status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
        else
-               chip->ecc.write_page(mtd, chip, buf);
+               status = chip->ecc.write_page(mtd, chip, buf, oob_required);
+
+       if (status < 0)
+               return status;
 
        /*
-        * Cached progamming disabled for now, Not sure if its worth the
-        * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s)
+        * Cached progamming disabled for now. Not sure if it's worth the
+        * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s).
         */
        cached = 0;
 
@@ -1833,7 +1848,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                status = chip->waitfunc(mtd, chip);
                /*
                 * See if operation failed and additional status checks are
-                * available
+                * available.
                 */
                if ((status & NAND_STATUS_FAIL) && (chip->errstat))
                        status = chip->errstat(mtd, chip, FL_WRITING, status,
@@ -1852,34 +1867,45 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 
        if (chip->verify_buf(mtd, buf, mtd->writesize))
                return -EIO;
+
+       /* Make sure the next page prog is preceded by a status read */
+       chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
 #endif
        return 0;
 }
 
 /**
- * nand_fill_oob - [Internal] Transfer client buffer to oob
- * @chip:      nand chip structure
- * @oob:       oob data buffer
- * @len:       oob data write length
- * @ops:       oob ops structure
+ * nand_fill_oob - [INTERN] Transfer client buffer to oob
+ * @mtd: MTD device structure
+ * @oob: oob data buffer
+ * @len: oob data write length
+ * @ops: oob ops structure
  */
-static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
-                                               struct mtd_oob_ops *ops)
+static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
+                             struct mtd_oob_ops *ops)
 {
+       struct nand_chip *chip = mtd->priv;
+
+       /*
+        * Initialise to all 0xFF, to avoid the possibility of left over OOB
+        * data from a previous OOB read.
+        */
+       memset(chip->oob_poi, 0xff, mtd->oobsize);
+
        switch (ops->mode) {
 
-       case MTD_OOB_PLACE:
-       case MTD_OOB_RAW:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_RAW:
                memcpy(chip->oob_poi + ops->ooboffs, oob, len);
                return oob + len;
 
-       case MTD_OOB_AUTO: {
+       case MTD_OPS_AUTO_OOB: {
                struct nand_oobfree *free = chip->ecc.layout->oobfree;
                uint32_t boffs = 0, woffs = ops->ooboffs;
                size_t bytes = 0;
 
                for (; free->length && len; free++, len -= bytes) {
-                       /* Write request not from offset 0 ? */
+                       /* Write request not from offset 0? */
                        if (unlikely(woffs)) {
                                if (woffs >= free->length) {
                                        woffs -= free->length;
@@ -1907,12 +1933,12 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
 #define NOTALIGNED(x)  ((x & (chip->subpagesize - 1)) != 0)
 
 /**
- * nand_do_write_ops - [Internal] NAND write with ECC
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @ops:       oob operations description structure
+ * nand_do_write_ops - [INTERN] NAND write with ECC
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @ops: oob operations description structure
  *
- * NAND write with ECC
+ * NAND write with ECC.
  */
 static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
@@ -1922,12 +1948,13 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
        uint32_t writelen = ops->len;
 
        uint32_t oobwritelen = ops->ooblen;
-       uint32_t oobmaxlen = ops->mode == MTD_OOB_AUTO ?
+       uint32_t oobmaxlen = ops->mode == MTD_OPS_AUTO_OOB ?
                                mtd->oobavail : mtd->oobsize;
 
        uint8_t *oob = ops->oobbuf;
        uint8_t *buf = ops->datbuf;
        int ret, subpage;
+       int oob_required = oob ? 1 : 0;
 
        ops->retlen = 0;
        if (!writelen)
@@ -1957,10 +1984,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
            (chip->pagebuf << chip->page_shift) < (to + ops->len))
                chip->pagebuf = -1;
 
-       /* If we're not given explicit OOB data, let it be 0xFF */
-       if (likely(!oob))
-               memset(chip->oob_poi, 0xff, mtd->oobsize);
-
        /* Don't allow multipage oob writes with offset */
        if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
                return -EINVAL;
@@ -1972,8 +1995,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                int cached = writelen > bytes && page != blockmask;
                uint8_t *wbuf = buf;
 
-               /* Partial page write ? */
-               if (unlikely(column || writelen < (mtd->writesize - 1))) {
+               /* Partial page write? */
+               if (unlikely(column || writelen < mtd->writesize)) {
                        cached = 0;
                        bytes = min_t(int, bytes - column, (int) writelen);
                        chip->pagebuf = -1;
@@ -1984,12 +2007,15 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 
                if (unlikely(oob)) {
                        size_t len = min(oobwritelen, oobmaxlen);
-                       oob = nand_fill_oob(chip, oob, len, ops);
+                       oob = nand_fill_oob(mtd, oob, len, ops);
                        oobwritelen -= len;
+               } else {
+                       /* We still need to erase leftover OOB data */
+                       memset(chip->oob_poi, 0xff, mtd->oobsize);
                }
 
-               ret = chip->write_page(mtd, chip, wbuf, page, cached,
-                                      (ops->mode == MTD_OOB_RAW));
+               ret = chip->write_page(mtd, chip, wbuf, oob_required, page,
+                                      cached, (ops->mode == MTD_OPS_RAW));
                if (ret)
                        break;
 
@@ -2018,48 +2044,39 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 
 /**
  * nand_write - [MTD Interface] NAND write with ECC
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @len:       number of bytes to write
- * @retlen:    pointer to variable to store the number of written bytes
- * @buf:       the data to write
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @len: number of bytes to write
+ * @retlen: pointer to variable to store the number of written bytes
+ * @buf: the data to write
  *
- * NAND write with ECC
+ * NAND write with ECC.
  */
 static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
                          size_t *retlen, const uint8_t *buf)
 {
        struct nand_chip *chip = mtd->priv;
+       struct mtd_oob_ops ops;
        int ret;
 
-       /* Do not allow writes past end of device */
-       if ((to + len) > mtd->size)
-               return -EINVAL;
-       if (!len)
-               return 0;
-
        nand_get_device(chip, mtd, FL_WRITING);
-
-       chip->ops.len = len;
-       chip->ops.datbuf = (uint8_t *)buf;
-       chip->ops.oobbuf = NULL;
-
-       ret = nand_do_write_ops(mtd, to, &chip->ops);
-
-       *retlen = chip->ops.retlen;
-
+       ops.len = len;
+       ops.datbuf = (uint8_t *)buf;
+       ops.oobbuf = NULL;
+       ops.mode = MTD_OPS_PLACE_OOB;
+       ret = nand_do_write_ops(mtd, to, &ops);
+       *retlen = ops.retlen;
        nand_release_device(mtd);
-
        return ret;
 }
 
 /**
  * nand_do_write_oob - [MTD Interface] NAND write out-of-band
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @ops:       oob operation description structure
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @ops: oob operation description structure
  *
- * NAND write out-of-band
+ * NAND write out-of-band.
  */
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
@@ -2070,7 +2087,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
                         __func__, (unsigned int)to, (int)ops->ooblen);
 
-       if (ops->mode == MTD_OOB_AUTO)
+       if (ops->mode == MTD_OPS_AUTO_OOB)
                len = chip->ecc.layout->oobavail;
        else
                len = mtd->oobsize;
@@ -2120,10 +2137,12 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        if (page == chip->pagebuf)
                chip->pagebuf = -1;
 
-       memset(chip->oob_poi, 0xff, mtd->oobsize);
-       nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
-       status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
-       memset(chip->oob_poi, 0xff, mtd->oobsize);
+       nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops);
+
+       if (ops->mode == MTD_OPS_RAW)
+               status = chip->ecc.write_oob_raw(mtd, chip, page & chip->pagemask);
+       else
+               status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
 
        if (status)
                return status;
@@ -2135,9 +2154,9 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 
 /**
  * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @ops:       oob operation description structure
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @ops: oob operation description structure
  */
 static int nand_write_oob(struct mtd_info *mtd, loff_t to,
                          struct mtd_oob_ops *ops)
@@ -2157,9 +2176,9 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
        nand_get_device(chip, mtd, FL_WRITING);
 
        switch (ops->mode) {
-       case MTD_OOB_PLACE:
-       case MTD_OOB_AUTO:
-       case MTD_OOB_RAW:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_AUTO_OOB:
+       case MTD_OPS_RAW:
                break;
 
        default:
@@ -2177,11 +2196,11 @@ out:
 }
 
 /**
- * single_erease_cmd - [GENERIC] NAND standard block erase command function
- * @mtd:       MTD device structure
- * @page:      the page address of the block which will be erased
+ * single_erase_cmd - [GENERIC] NAND standard block erase command function
+ * @mtd: MTD device structure
+ * @page: the page address of the block which will be erased
  *
- * Standard erase command for NAND chips
+ * Standard erase command for NAND chips.
  */
 static void single_erase_cmd(struct mtd_info *mtd, int page)
 {
@@ -2192,12 +2211,11 @@ static void single_erase_cmd(struct mtd_info *mtd, int page)
 }
 
 /**
- * multi_erease_cmd - [GENERIC] AND specific block erase command function
- * @mtd:       MTD device structure
- * @page:      the page address of the block which will be erased
+ * multi_erase_cmd - [GENERIC] AND specific block erase command function
+ * @mtd: MTD device structure
+ * @page: the page address of the block which will be erased
  *
- * AND multi block erase command function
- * Erase 4 consecutive blocks
+ * AND multi block erase command function. Erase 4 consecutive blocks.
  */
 static void multi_erase_cmd(struct mtd_info *mtd, int page)
 {
@@ -2212,10 +2230,10 @@ static void multi_erase_cmd(struct mtd_info *mtd, int page)
 
 /**
  * nand_erase - [MTD Interface] erase block(s)
- * @mtd:       MTD device structure
- * @instr:     erase instruction
+ * @mtd: MTD device structure
+ * @instr: erase instruction
  *
- * Erase one ore more blocks
+ * Erase one ore more blocks.
  */
 static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
@@ -2224,12 +2242,12 @@ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 #define BBT_PAGE_MASK  0xffffff3f
 /**
- * nand_erase_nand - [Internal] erase block(s)
- * @mtd:       MTD device structure
- * @instr:     erase instruction
- * @allowbbt:  allow erasing the bbt area
+ * nand_erase_nand - [INTERN] erase block(s)
+ * @mtd: MTD device structure
+ * @instr: erase instruction
+ * @allowbbt: allow erasing the bbt area
  *
- * Erase one ore more blocks
+ * Erase one ore more blocks.
  */
 int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
                    int allowbbt)
@@ -2247,8 +2265,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
        if (check_offs_len(mtd, instr->addr, instr->len))
                return -EINVAL;
 
-       instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
-
        /* Grab the lock and see if the device is available */
        nand_get_device(chip, mtd, FL_ERASING);
 
@@ -2274,7 +2290,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
         * If BBT requires refresh, set the BBT page mask to see if the BBT
         * should be rewritten. Otherwise the mask is set to 0xffffffff which
         * can not be matched. This is also done when the bbt is actually
-        * erased to avoid recusrsive updates
+        * erased to avoid recursive updates.
         */
        if (chip->options & BBT_AUTO_REFRESH && !allowbbt)
                bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
@@ -2286,20 +2302,18 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
        while (len) {
                WATCHDOG_RESET();
-               /*
-                * heck if we have a bad block, we do not erase bad blocks !
-                */
+               /* Check if we have a bad block, we do not erase bad blocks! */
                if (!instr->scrub && nand_block_checkbad(mtd, ((loff_t) page) <<
                                        chip->page_shift, 0, allowbbt)) {
-                       printk(KERN_WARNING "%s: attempt to erase a bad block "
-                                       "at page 0x%08x\n", __func__, page);
+                       pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
+                                  __func__, page);
                        instr->state = MTD_ERASE_FAILED;
                        goto erase_exit;
                }
 
                /*
                 * Invalidate the page cache, if we erase the block which
-                * contains the current cached page
+                * contains the current cached page.
                 */
                if (page <= chip->pagebuf && chip->pagebuf <
                    (page + pages_per_block))
@@ -2329,7 +2343,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
                /*
                 * If BBT requires refresh, set the BBT rewrite flag to the
-                * page being erased
+                * page being erased.
                 */
                if (bbt_masked_page != 0xffffffff &&
                    (page & BBT_PAGE_MASK) == bbt_masked_page)
@@ -2348,7 +2362,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
                        /*
                         * If BBT requires refresh and BBT-PERCHIP, set the BBT
-                        * page mask to see if this BBT should be rewritten
+                        * page mask to see if this BBT should be rewritten.
                         */
                        if (bbt_masked_page != 0xffffffff &&
                            (chip->bbt_td->options & NAND_BBT_PERCHIP))
@@ -2371,7 +2385,7 @@ erase_exit:
 
        /*
         * If BBT requires refresh and erase was successful, rewrite any
-        * selected bad block tables
+        * selected bad block tables.
         */
        if (bbt_masked_page == 0xffffffff || ret)
                return ret;
@@ -2379,7 +2393,7 @@ erase_exit:
        for (chipnr = 0; chipnr < chip->numchips; chipnr++) {
                if (!rewrite_bbt[chipnr])
                        continue;
-               /* update the BBT for chip */
+               /* Update the BBT for chip */
                MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: nand_update_bbt "
                        "(%d:0x%0llx 0x%0x)\n", __func__, chipnr,
                        rewrite_bbt[chipnr], chip->bbt_td->pages[chipnr]);
@@ -2392,9 +2406,9 @@ erase_exit:
 
 /**
  * nand_sync - [MTD Interface] sync
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Sync is actually a wait for chip ready function
+ * Sync is actually a wait for chip ready function.
  */
 static void nand_sync(struct mtd_info *mtd)
 {
@@ -2410,22 +2424,18 @@ static void nand_sync(struct mtd_info *mtd)
 
 /**
  * nand_block_isbad - [MTD Interface] Check if block at offset is bad
- * @mtd:       MTD device structure
- * @offs:      offset relative to mtd start
+ * @mtd: MTD device structure
+ * @offs: offset relative to mtd start
  */
 static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
 {
-       /* Check for invalid offset */
-       if (offs > mtd->size)
-               return -EINVAL;
-
        return nand_block_checkbad(mtd, offs, 1, 0);
 }
 
 /**
  * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad
- * @mtd:       MTD device structure
- * @ofs:       offset relative to mtd start
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
  */
 static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
@@ -2434,7 +2444,7 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
        ret = nand_block_isbad(mtd, ofs);
        if (ret) {
-               /* If it was bad already, return success and do nothing. */
+               /* If it was bad already, return success and do nothing */
                if (ret > 0)
                        return 0;
                return ret;
@@ -2443,9 +2453,51 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
        return chip->block_markbad(mtd, ofs);
 }
 
-/*
- * Set default functions
+ /**
+ * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
+ * @mtd: MTD device structure
+ * @chip: nand chip info structure
+ * @addr: feature address.
+ * @subfeature_param: the subfeature parameters, a four bytes array.
  */
+static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
+                       int addr, uint8_t *subfeature_param)
+{
+       int status;
+
+       if (!chip->onfi_version)
+               return -EINVAL;
+
+       chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1);
+       chip->write_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
+       status = chip->waitfunc(mtd, chip);
+       if (status & NAND_STATUS_FAIL)
+               return -EIO;
+       return 0;
+}
+
+/**
+ * nand_onfi_get_features- [REPLACEABLE] get features for ONFI nand
+ * @mtd: MTD device structure
+ * @chip: nand chip info structure
+ * @addr: feature address.
+ * @subfeature_param: the subfeature parameters, a four bytes array.
+ */
+static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
+                       int addr, uint8_t *subfeature_param)
+{
+       if (!chip->onfi_version)
+               return -EINVAL;
+
+       /* clear the sub feature parameters */
+       memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
+
+       chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1);
+       chip->read_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
+       return 0;
+}
+
+/* Set default functions */
 static void nand_set_defaults(struct nand_chip *chip, int busw)
 {
        /* check for proper chip_delay setup, set 20us if not */
@@ -2483,23 +2535,21 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
 }
 
 #ifdef CONFIG_SYS_NAND_ONFI_DETECTION
-/*
- * sanitize ONFI strings so we can safely print them
- */
+/* Sanitize ONFI strings so we can safely print them */
 static void sanitize_string(char *s, size_t len)
 {
        ssize_t i;
 
-       /* null terminate */
+       /* Null terminate */
        s[len - 1] = 0;
 
-       /* remove non printable chars */
+       /* Remove non printable chars */
        for (i = 0; i < len - 1; i++) {
                if (s[i] < ' ' || s[i] > 127)
                        s[i] = '?';
        }
 
-       /* remove trailing spaces */
+       /* Remove trailing spaces */
        strim(s);
 }
 
@@ -2516,7 +2566,7 @@ static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
 }
 
 /*
- * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise
+ * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise.
  */
 static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
                                        int *busw)
@@ -2525,20 +2575,18 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        int i;
        int val;
 
-       /* try ONFI for unknow chip or LP */
+       /* Try ONFI for unknown chip or LP */
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
        if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
                chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
                return 0;
 
-       MTDDEBUG(MTD_DEBUG_LEVEL0, "ONFI flash detected\n");
        chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
        for (i = 0; i < 3; i++) {
                chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
                if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
                                le16_to_cpu(p->crc)) {
-                       MTDDEBUG(MTD_DEBUG_LEVEL0,
-                                "ONFI param page %d valid\n", i);
+                       pr_info("ONFI param page %d valid\n", i);
                        break;
                }
        }
@@ -2546,7 +2594,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        if (i == 3)
                return 0;
 
-       /* check version */
+       /* Check version */
        val = le16_to_cpu(p->revision);
        if (val & (1 << 5))
                chip->onfi_version = 23;
@@ -2562,8 +2610,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
                chip->onfi_version = 0;
 
        if (!chip->onfi_version) {
-               printk(KERN_INFO "%s: unsupported ONFI version: %d\n",
-                                                               __func__, val);
+               pr_info("%s: unsupported ONFI version: %d\n", __func__, val);
                return 0;
        }
 
@@ -2580,8 +2627,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        if (le16_to_cpu(p->features) & 1)
                *busw = NAND_BUSWIDTH_16;
 
-       chip->options |= NAND_NO_READRDY | NAND_NO_AUTOINCR;
-
+       pr_info("ONFI flash detected\n");
        return 1;
 }
 #else
@@ -2594,7 +2640,248 @@ static inline int nand_flash_detect_onfi(struct mtd_info *mtd,
 #endif
 
 /*
- * Get the flash and manufacturer id and lookup if the type is supported
+ * nand_id_has_period - Check if an ID string has a given wraparound period
+ * @id_data: the ID string
+ * @arrlen: the length of the @id_data array
+ * @period: the period of repitition
+ *
+ * Check if an ID string is repeated within a given sequence of bytes at
+ * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a
+ * period of 2). This is a helper function for nand_id_len(). Returns non-zero
+ * if the repetition has a period of @period; otherwise, returns zero.
+ */
+static int nand_id_has_period(u8 *id_data, int arrlen, int period)
+{
+       int i, j;
+       for (i = 0; i < period; i++)
+               for (j = i + period; j < arrlen; j += period)
+                       if (id_data[i] != id_data[j])
+                               return 0;
+       return 1;
+}
+
+/*
+ * nand_id_len - Get the length of an ID string returned by CMD_READID
+ * @id_data: the ID string
+ * @arrlen: the length of the @id_data array
+
+ * Returns the length of the ID string, according to known wraparound/trailing
+ * zero patterns. If no pattern exists, returns the length of the array.
+ */
+static int nand_id_len(u8 *id_data, int arrlen)
+{
+       int last_nonzero, period;
+
+       /* Find last non-zero byte */
+       for (last_nonzero = arrlen - 1; last_nonzero >= 0; last_nonzero--)
+               if (id_data[last_nonzero])
+                       break;
+
+       /* All zeros */
+       if (last_nonzero < 0)
+               return 0;
+
+       /* Calculate wraparound period */
+       for (period = 1; period < arrlen; period++)
+               if (nand_id_has_period(id_data, arrlen, period))
+                       break;
+
+       /* There's a repeated pattern */
+       if (period < arrlen)
+               return period;
+
+       /* There are trailing zeros */
+       if (last_nonzero < arrlen - 1)
+               return last_nonzero + 1;
+
+       /* No pattern detected */
+       return arrlen;
+}
+
+/*
+ * Many new NAND share similar device ID codes, which represent the size of the
+ * chip. The rest of the parameters must be decoded according to generic or
+ * manufacturer-specific "extended ID" decoding patterns.
+ */
+static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
+                               u8 id_data[8], int *busw)
+{
+       int extid, id_len;
+       /* The 3rd id byte holds MLC / multichip data */
+       chip->cellinfo = id_data[2];
+       /* The 4th id byte is the important one */
+       extid = id_data[3];
+
+       id_len = nand_id_len(id_data, 8);
+
+       /*
+        * Field definitions are in the following datasheets:
+        * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
+        * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
+        * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
+        *
+        * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
+        * ID to decide what to do.
+        */
+       if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
+                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+                       id_data[5] != 0x00) {
+               /* Calc pagesize */
+               mtd->writesize = 2048 << (extid & 0x03);
+               extid >>= 2;
+               /* Calc oobsize */
+               switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
+               case 1:
+                       mtd->oobsize = 128;
+                       break;
+               case 2:
+                       mtd->oobsize = 218;
+                       break;
+               case 3:
+                       mtd->oobsize = 400;
+                       break;
+               case 4:
+                       mtd->oobsize = 436;
+                       break;
+               case 5:
+                       mtd->oobsize = 512;
+                       break;
+               case 6:
+               default: /* Other cases are "reserved" (unknown) */
+                       mtd->oobsize = 640;
+                       break;
+               }
+               extid >>= 2;
+               /* Calc blocksize */
+               mtd->erasesize = (128 * 1024) <<
+                       (((extid >> 1) & 0x04) | (extid & 0x03));
+               *busw = 0;
+       } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
+                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+               unsigned int tmp;
+
+               /* Calc pagesize */
+               mtd->writesize = 2048 << (extid & 0x03);
+               extid >>= 2;
+               /* Calc oobsize */
+               switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
+               case 0:
+                       mtd->oobsize = 128;
+                       break;
+               case 1:
+                       mtd->oobsize = 224;
+                       break;
+               case 2:
+                       mtd->oobsize = 448;
+                       break;
+               case 3:
+                       mtd->oobsize = 64;
+                       break;
+               case 4:
+                       mtd->oobsize = 32;
+                       break;
+               case 5:
+                       mtd->oobsize = 16;
+                       break;
+               default:
+                       mtd->oobsize = 640;
+                       break;
+               }
+               extid >>= 2;
+               /* Calc blocksize */
+               tmp = ((extid >> 1) & 0x04) | (extid & 0x03);
+               if (tmp < 0x03)
+                       mtd->erasesize = (128 * 1024) << tmp;
+               else if (tmp == 0x03)
+                       mtd->erasesize = 768 * 1024;
+               else
+                       mtd->erasesize = (64 * 1024) << tmp;
+               *busw = 0;
+       } else {
+               /* Calc pagesize */
+               mtd->writesize = 1024 << (extid & 0x03);
+               extid >>= 2;
+               /* Calc oobsize */
+               mtd->oobsize = (8 << (extid & 0x01)) *
+                       (mtd->writesize >> 9);
+               extid >>= 2;
+               /* Calc blocksize. Blocksize is multiples of 64KiB */
+               mtd->erasesize = (64 * 1024) << (extid & 0x03);
+               extid >>= 2;
+               /* Get buswidth information */
+               *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+       }
+}
+
+ /*
+ * Old devices have chip data hardcoded in the device ID table. nand_decode_id
+ * decodes a matching ID table entry and assigns the MTD size parameters for
+ * the chip.
+ */
+static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
+                               const struct nand_flash_dev *type, u8 id_data[8],
+                               int *busw)
+{
+       int maf_id = id_data[0];
+
+       mtd->erasesize = type->erasesize;
+       mtd->writesize = type->pagesize;
+       mtd->oobsize = mtd->writesize / 32;
+       *busw = type->options & NAND_BUSWIDTH_16;
+
+       /*
+        * Check for Spansion/AMD ID + repeating 5th, 6th byte since
+        * some Spansion chips have erasesize that conflicts with size
+        * listed in nand_ids table.
+        * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
+        */
+       if (maf_id == NAND_MFR_AMD && id_data[4] != 0x00 && id_data[5] == 0x00
+                       && id_data[6] == 0x00 && id_data[7] == 0x00
+                       && mtd->writesize == 512) {
+               mtd->erasesize = 128 * 1024;
+               mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
+       }
+}
+
+ /*
+ * Set the bad block marker/indicator (BBM/BBI) patterns according to some
+ * heuristic patterns using various detected parameters (e.g., manufacturer,
+ * page size, cell-type information).
+ */
+static void nand_decode_bbm_options(struct mtd_info *mtd,
+                                   struct nand_chip *chip, u8 id_data[8])
+{
+       int maf_id = id_data[0];
+
+       /* Set the bad block position */
+       if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16))
+               chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
+       else
+               chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
+
+       /*
+        * Bad block marker is stored in the last page of each block on Samsung
+        * and Hynix MLC devices; stored in first two pages of each block on
+        * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,
+        * AMD/Spansion, and Macronix.  All others scan only the first page.
+        */
+       if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+                       (maf_id == NAND_MFR_SAMSUNG ||
+                        maf_id == NAND_MFR_HYNIX))
+               chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
+       else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+                               (maf_id == NAND_MFR_SAMSUNG ||
+                                maf_id == NAND_MFR_HYNIX ||
+                                maf_id == NAND_MFR_TOSHIBA ||
+                                maf_id == NAND_MFR_AMD ||
+                                maf_id == NAND_MFR_MACRONIX)) ||
+                       (mtd->writesize == 2048 &&
+                        maf_id == NAND_MFR_MICRON))
+               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+}
+
+/*
+ * Get the flash and manufacturer id and lookup if the type is supported.
  */
 static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                                                  struct nand_chip *chip,
@@ -2605,14 +2892,13 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        const char *name;
        int i, maf_idx;
        u8 id_data[8];
-       int ret;
 
        /* Select the device */
        chip->select_chip(mtd, 0);
 
        /*
         * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
-        * after power-up
+        * after power-up.
         */
        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
 
@@ -2623,7 +2909,8 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        *maf_id = chip->read_byte(mtd);
        *dev_id = chip->read_byte(mtd);
 
-       /* Try again to make sure, as some systems the bus-hold or other
+       /*
+        * Try again to make sure, as some systems the bus-hold or other
         * interface concerns can cause random data which looks like a
         * possibly credible NAND flash to appear. If the two results do
         * not match, ignore the device completely.
@@ -2631,13 +2918,14 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
 
-       for (i = 0; i < 2; i++)
+       /* Read entire ID string */
+       for (i = 0; i < 8; i++)
                id_data[i] = chip->read_byte(mtd);
 
        if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
-               printk(KERN_INFO "%s: second ID read did not match "
-                      "%02x,%02x against %02x,%02x\n", __func__,
-                      *maf_id, *dev_id, id_data[0], id_data[1]);
+               pr_info("%s: second ID read did not match "
+                       "%02x,%02x against %02x,%02x\n", __func__,
+                       *maf_id, *dev_id, id_data[0], id_data[1]);
                return ERR_PTR(-ENODEV);
        }
 
@@ -2651,18 +2939,10 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        chip->onfi_version = 0;
        if (!type->name || !type->pagesize) {
                /* Check is chip is ONFI compliant */
-               ret = nand_flash_detect_onfi(mtd, chip, &busw);
-               if (ret)
+               if (nand_flash_detect_onfi(mtd, chip, &busw))
                        goto ident_done;
        }
 
-       chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
-
-       /* Read entire ID string */
-
-       for (i = 0; i < 8; i++)
-               id_data[i] = chip->read_byte(mtd);
-
        if (!type->name)
                return ERR_PTR(-ENODEV);
 
@@ -2672,101 +2952,25 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        chip->chipsize = (uint64_t)type->chipsize << 20;
 
        if (!type->pagesize && chip->init_size) {
-               /* set the pagesize, oobsize, erasesize by the driver*/
+               /* Set the pagesize, oobsize, erasesize by the driver */
                busw = chip->init_size(mtd, chip, id_data);
        } else if (!type->pagesize) {
-               int extid;
-               /* The 3rd id byte holds MLC / multichip data */
-               chip->cellinfo = id_data[2];
-               /* The 4th id byte is the important one */
-               extid = id_data[3];
-
-               /*
-                * Field definitions are in the following datasheets:
-                * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
-                * New style   (6 byte ID): Samsung K9GBG08U0M (p.40)
-                *
-                * Check for wraparound + Samsung ID + nonzero 6th byte
-                * to decide what to do.
-                */
-               if (id_data[0] == id_data[6] && id_data[1] == id_data[7] &&
-                               id_data[0] == NAND_MFR_SAMSUNG &&
-                               (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
-                               id_data[5] != 0x00) {
-                       /* Calc pagesize */
-                       mtd->writesize = 2048 << (extid & 0x03);
-                       extid >>= 2;
-                       /* Calc oobsize */
-                       switch (extid & 0x03) {
-                       case 1:
-                               mtd->oobsize = 128;
-                               break;
-                       case 2:
-                               mtd->oobsize = 218;
-                               break;
-                       case 3:
-                               mtd->oobsize = 400;
-                               break;
-                       default:
-                               mtd->oobsize = 436;
-                               break;
-                       }
-                       extid >>= 2;
-                       /* Calc blocksize */
-                       mtd->erasesize = (128 * 1024) <<
-                               (((extid >> 1) & 0x04) | (extid & 0x03));
-                       busw = 0;
-               } else {
-                       /* Calc pagesize */
-                       mtd->writesize = 1024 << (extid & 0x03);
-                       extid >>= 2;
-                       /* Calc oobsize */
-                       mtd->oobsize = (8 << (extid & 0x01)) *
-                               (mtd->writesize >> 9);
-                       extid >>= 2;
-                       /* Calc blocksize. Blocksize is multiples of 64KiB */
-                       mtd->erasesize = (64 * 1024) << (extid & 0x03);
-                       extid >>= 2;
-                       /* Get buswidth information */
-                       busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
-               }
+               /* Decode parameters from extended ID */
+               nand_decode_ext_id(mtd, chip, id_data, &busw);
        } else {
-               /*
-                * Old devices have chip data hardcoded in the device id table
-                */
-               mtd->erasesize = type->erasesize;
-               mtd->writesize = type->pagesize;
-               mtd->oobsize = mtd->writesize / 32;
-               busw = type->options & NAND_BUSWIDTH_16;
-
-               /*
-                * Check for Spansion/AMD ID + repeating 5th, 6th byte since
-                * some Spansion chips have erasesize that conflicts with size
-                * listed in nand_ids table
-                * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
-                */
-               if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 &&
-                               id_data[5] == 0x00 && id_data[6] == 0x00 &&
-                               id_data[7] == 0x00 && mtd->writesize == 512) {
-                       mtd->erasesize = 128 * 1024;
-                       mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
-               }
+               nand_decode_id(mtd, chip, type, id_data, &busw);
        }
        /* Get chip options, preserve non chip based options */
        chip->options |= type->options;
 
-       /* Check if chip is a not a samsung device. Do not clear the
-        * options for chips which are not having an extended id.
+       /*
+        * Check if chip is not a Samsung device. Do not clear the
+        * options for chips which do not have an extended id.
         */
        if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
                chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
 ident_done:
 
-       /*
-        * Set chip as a default. Board drivers can override it, if necessary
-        */
-       chip->options |= NAND_NO_AUTOINCR;
-
        /* Try to identify manufacturer */
        for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
                if (nand_manuf_ids[maf_idx].id == *maf_id)
@@ -2775,21 +2979,23 @@ ident_done:
 
        /*
         * Check, if buswidth is correct. Hardware drivers should set
-        * chip correct !
+        * chip correct!
         */
        if (busw != (chip->options & NAND_BUSWIDTH_16)) {
-               printk(KERN_INFO "NAND device: Manufacturer ID:"
-                      " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
-                      *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
-               printk(KERN_WARNING "NAND bus width %d instead %d bit\n",
-                      (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
-                      busw ? 16 : 8);
+               pr_info("NAND device: Manufacturer ID:"
+                       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
+                       *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
+               pr_warn("NAND bus width %d instead %d bit\n",
+                          (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
+                          busw ? 16 : 8);
                return ERR_PTR(-EINVAL);
        }
 
+       nand_decode_bbm_options(mtd, chip, id_data);
+
        /* Calculate the address shift from the page size */
        chip->page_shift = ffs(mtd->writesize) - 1;
-       /* Convert chipsize to number of pages per chip -1. */
+       /* Convert chipsize to number of pages per chip -1 */
        chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
 
        chip->bbt_erase_shift = chip->phys_erase_shift =
@@ -2803,73 +3009,38 @@ ident_done:
 
        chip->badblockbits = 8;
 
-       /* Set the bad block position */
-       if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
-               chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
-       else
-               chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
-
-       /*
-        * Bad block marker is stored in the last page of each block
-        * on Samsung and Hynix MLC devices; stored in first two pages
-        * of each block on Micron devices with 2KiB pages and on
-        * SLC Samsung, Hynix, Toshiba and AMD/Spansion. All others scan
-        * only the first page.
-        */
-       if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
-                       (*maf_id == NAND_MFR_SAMSUNG ||
-                        *maf_id == NAND_MFR_HYNIX))
-               chip->options |= NAND_BBT_SCANLASTPAGE;
-       else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
-                               (*maf_id == NAND_MFR_SAMSUNG ||
-                                *maf_id == NAND_MFR_HYNIX ||
-                                *maf_id == NAND_MFR_TOSHIBA ||
-                                *maf_id == NAND_MFR_AMD)) ||
-                       (mtd->writesize == 2048 &&
-                        *maf_id == NAND_MFR_MICRON))
-               chip->options |= NAND_BBT_SCAN2NDPAGE;
-
-       /*
-        * Numonyx/ST 2K pages, x8 bus use BOTH byte 1 and 6
-        */
-       if (!(busw & NAND_BUSWIDTH_16) &&
-                       *maf_id == NAND_MFR_STMICRO &&
-                       mtd->writesize == 2048) {
-               chip->options |= NAND_BBT_SCANBYTE1AND6;
-               chip->badblockpos = 0;
-       }
-
        /* Check for AND chips with 4 page planes */
        if (chip->options & NAND_4PAGE_ARRAY)
                chip->erase_cmd = multi_erase_cmd;
        else
                chip->erase_cmd = single_erase_cmd;
 
-       /* Do not replace user supplied command function ! */
+       /* Do not replace user supplied command function! */
        if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
                chip->cmdfunc = nand_command_lp;
 
-       /* TODO onfi flash name */
        name = type->name;
 #ifdef CONFIG_SYS_NAND_ONFI_DETECTION
        if (chip->onfi_version)
                name = chip->onfi_params.model;
 #endif
-       MTDDEBUG(MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:"
-                " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,
-                nand_manuf_ids[maf_idx].name, name);
+       pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
+               " page size: %d, OOB size: %d\n",
+               *maf_id, *dev_id, nand_manuf_ids[maf_idx].name,
+               name,
+               mtd->writesize, mtd->oobsize);
 
        return type;
 }
 
 /**
  * nand_scan_ident - [NAND Interface] Scan for the NAND device
- * @mtd:            MTD device structure
- * @maxchips:       Number of chips to scan for
- * @table:          Alternative NAND ID table
+ * @mtd: MTD device structure
+ * @maxchips: number of chips to scan for
+ * @table: alternative NAND ID table
  *
- * This is the first phase of the normal nand_scan() function. It
- * reads the flash ID and sets up MTD fields accordingly.
+ * This is the first phase of the normal nand_scan() function. It reads the
+ * flash ID and sets up MTD fields accordingly.
  *
  * The mtd->owner field must be set to the module of the caller.
  */
@@ -2891,7 +3062,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
 
        if (IS_ERR(type)) {
 #ifndef CONFIG_SYS_NAND_QUIET_TEST
-               printk(KERN_WARNING "No NAND device found!!!\n");
+               pr_warn("No NAND device found\n");
 #endif
                chip->select_chip(mtd, -1);
                return PTR_ERR(type);
@@ -2911,7 +3082,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
        }
 #ifdef DEBUG
        if (i > 1)
-               printk(KERN_INFO "%d NAND chips detected\n", i);
+               pr_info("%d NAND chips detected\n", i);
 #endif
 
        /* Store the number of chips and calc total size for mtd */
@@ -2924,17 +3095,21 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
 
 /**
  * nand_scan_tail - [NAND Interface] Scan for the NAND device
- * @mtd:           MTD device structure
+ * @mtd: MTD device structure
  *
- * This is the second phase of the normal nand_scan() function. It
- * fills out all the uninitialized function pointers with the defaults
- * and scans for a bad block table if appropriate.
+ * This is the second phase of the normal nand_scan() function. It fills out
+ * all the uninitialized function pointers with the defaults and scans for a
+ * bad block table if appropriate.
  */
 int nand_scan_tail(struct mtd_info *mtd)
 {
        int i;
        struct nand_chip *chip = mtd->priv;
 
+       /* New bad blocks should be marked in OOB, flash-based BBT, or both */
+       BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
+                       !(chip->bbt_options & NAND_BBT_USE_FLASH));
+
        if (!(chip->options & NAND_OWN_BUFFERS))
                chip->buffers = memalign(ARCH_DMA_MINALIGN,
                                         sizeof(*chip->buffers));
@@ -2945,7 +3120,7 @@ int nand_scan_tail(struct mtd_info *mtd)
        chip->oob_poi = chip->buffers->databuf + mtd->writesize;
 
        /*
-        * If no default placement scheme is given, select an appropriate one
+        * If no default placement scheme is given, select an appropriate one.
         */
        if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) {
                switch (mtd->oobsize) {
@@ -2962,16 +3137,22 @@ int nand_scan_tail(struct mtd_info *mtd)
                        chip->ecc.layout = &nand_oob_128;
                        break;
                default:
-                       printk(KERN_WARNING "No oob scheme defined for "
-                              "oobsize %d\n", mtd->oobsize);
+                       pr_warn("No oob scheme defined for oobsize %d\n",
+                                  mtd->oobsize);
                }
        }
 
        if (!chip->write_page)
                chip->write_page = nand_write_page;
 
+       /* set for ONFI nand */
+       if (!chip->onfi_set_features)
+               chip->onfi_set_features = nand_onfi_set_features;
+       if (!chip->onfi_get_features)
+               chip->onfi_get_features = nand_onfi_get_features;
+
        /*
-        * check ECC mode, default to software if 3byte/512byte hardware ECC is
+        * Check ECC mode, default to software if 3byte/512byte hardware ECC is
         * selected and we have 256 byte pagesize fallback to software ECC
         */
 
@@ -2980,15 +3161,15 @@ int nand_scan_tail(struct mtd_info *mtd)
                /* Similar to NAND_ECC_HW, but a separate read_page handle */
                if (!chip->ecc.calculate || !chip->ecc.correct ||
                     !chip->ecc.hwctl) {
-                       printk(KERN_WARNING "No ECC functions supplied; "
-                              "Hardware ECC not possible\n");
+                       pr_warn("No ECC functions supplied; "
+                                  "hardware ECC not possible\n");
                        BUG();
                }
                if (!chip->ecc.read_page)
                        chip->ecc.read_page = nand_read_page_hwecc_oob_first;
 
        case NAND_ECC_HW:
-               /* Use standard hwecc read page function ? */
+               /* Use standard hwecc read page function? */
                if (!chip->ecc.read_page)
                        chip->ecc.read_page = nand_read_page_hwecc;
                if (!chip->ecc.write_page)
@@ -3009,11 +3190,11 @@ int nand_scan_tail(struct mtd_info *mtd)
                     chip->ecc.read_page == nand_read_page_hwecc ||
                     !chip->ecc.write_page ||
                     chip->ecc.write_page == nand_write_page_hwecc)) {
-                       printk(KERN_WARNING "No ECC functions supplied; "
-                              "Hardware ECC not possible\n");
+                       pr_warn("No ECC functions supplied; "
+                                  "hardware ECC not possible\n");
                        BUG();
                }
-               /* Use standard syndrome read/write page function ? */
+               /* Use standard syndrome read/write page function? */
                if (!chip->ecc.read_page)
                        chip->ecc.read_page = nand_read_page_syndrome;
                if (!chip->ecc.write_page)
@@ -3027,11 +3208,16 @@ int nand_scan_tail(struct mtd_info *mtd)
                if (!chip->ecc.write_oob)
                        chip->ecc.write_oob = nand_write_oob_syndrome;
 
-               if (mtd->writesize >= chip->ecc.size)
+               if (mtd->writesize >= chip->ecc.size) {
+                       if (!chip->ecc.strength) {
+                               pr_warn("Driver must set ecc.strength when using hardware ECC\n");
+                               BUG();
+                       }
                        break;
-               printk(KERN_WARNING "%d byte HW ECC not possible on "
-                      "%d byte page size, fallback to SW ECC\n",
-                      chip->ecc.size, mtd->writesize);
+               }
+               pr_warn("%d byte HW ECC not possible on "
+                          "%d byte page size, fallback to SW ECC\n",
+                          chip->ecc.size, mtd->writesize);
                chip->ecc.mode = NAND_ECC_SOFT;
 
        case NAND_ECC_SOFT:
@@ -3047,11 +3233,12 @@ int nand_scan_tail(struct mtd_info *mtd)
                if (!chip->ecc.size)
                        chip->ecc.size = 256;
                chip->ecc.bytes = 3;
+               chip->ecc.strength = 1;
                break;
 
        case NAND_ECC_SOFT_BCH:
                if (!mtd_nand_has_bch()) {
-                       printk(KERN_WARNING "CONFIG_MTD_ECC_BCH not enabled\n");
+                       pr_warn("CONFIG_MTD_ECC_BCH not enabled\n");
                        return -EINVAL;
                }
                chip->ecc.calculate = nand_bch_calculate_ecc;
@@ -3066,8 +3253,8 @@ int nand_scan_tail(struct mtd_info *mtd)
                /*
                 * Board driver should supply ecc.size and ecc.bytes values to
                 * select how many bits are correctable; see nand_bch_init()
-                * for details.
-                * Otherwise, default to 4 bits for large page devices
+                * for details. Otherwise, default to 4 bits for large page
+                * devices.
                 */
                if (!chip->ecc.size && (mtd->oobsize >= 64)) {
                        chip->ecc.size = 512;
@@ -3078,13 +3265,14 @@ int nand_scan_tail(struct mtd_info *mtd)
                                               chip->ecc.bytes,
                                               &chip->ecc.layout);
                if (!chip->ecc.priv)
-                       printk(KERN_WARNING "BCH ECC initialization failed!\n");
-
+                       pr_warn("BCH ECC initialization failed!\n");
+               chip->ecc.strength =
+                       chip->ecc.bytes * 8 / fls(8 * chip->ecc.size);
                break;
 
        case NAND_ECC_NONE:
-               printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
-                      "This is not recommended !!\n");
+               pr_warn("NAND_ECC_NONE selected by board driver. "
+                       "This is not recommended !!\n");
                chip->ecc.read_page = nand_read_page_raw;
                chip->ecc.write_page = nand_write_page_raw;
                chip->ecc.read_oob = nand_read_oob_std;
@@ -3096,14 +3284,19 @@ int nand_scan_tail(struct mtd_info *mtd)
                break;
 
        default:
-               printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
-                      chip->ecc.mode);
+               pr_warn("Invalid NAND_ECC_MODE %d\n", chip->ecc.mode);
                BUG();
        }
 
+       /* For many systems, the standard OOB write also works for raw */
+       if (!chip->ecc.read_oob_raw)
+               chip->ecc.read_oob_raw = chip->ecc.read_oob;
+       if (!chip->ecc.write_oob_raw)
+               chip->ecc.write_oob_raw = chip->ecc.write_oob;
+
        /*
         * The number of bytes available for a client to place data into
-        * the out of band area
+        * the out of band area.
         */
        chip->ecc.layout->oobavail = 0;
        for (i = 0; chip->ecc.layout->oobfree[i].length
@@ -3114,19 +3307,16 @@ int nand_scan_tail(struct mtd_info *mtd)
 
        /*
         * Set the number of read / write steps for one page depending on ECC
-        * mode
+        * mode.
         */
        chip->ecc.steps = mtd->writesize / chip->ecc.size;
        if (chip->ecc.steps * chip->ecc.size != mtd->writesize) {
-               printk(KERN_WARNING "Invalid ecc parameters\n");
+               pr_warn("Invalid ECC parameters\n");
                BUG();
        }
        chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
 
-       /*
-        * Allow subpage writes up to ecc.steps. Not possible for MLC
-        * FLASH.
-        */
+       /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
        if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
            !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
                switch (chip->ecc.steps) {
@@ -3159,21 +3349,29 @@ int nand_scan_tail(struct mtd_info *mtd)
        mtd->type = MTD_NANDFLASH;
        mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
                                                MTD_CAP_NANDFLASH;
-       mtd->erase = nand_erase;
-       mtd->point = NULL;
-       mtd->unpoint = NULL;
-       mtd->read = nand_read;
-       mtd->write = nand_write;
-       mtd->read_oob = nand_read_oob;
-       mtd->write_oob = nand_write_oob;
-       mtd->sync = nand_sync;
-       mtd->lock = NULL;
-       mtd->unlock = NULL;
-       mtd->block_isbad = nand_block_isbad;
-       mtd->block_markbad = nand_block_markbad;
-
-       /* propagate ecc.layout to mtd_info */
+       mtd->_erase = nand_erase;
+       mtd->_point = NULL;
+       mtd->_unpoint = NULL;
+       mtd->_read = nand_read;
+       mtd->_write = nand_write;
+       mtd->_read_oob = nand_read_oob;
+       mtd->_write_oob = nand_write_oob;
+       mtd->_sync = nand_sync;
+       mtd->_lock = NULL;
+       mtd->_unlock = NULL;
+       mtd->_block_isbad = nand_block_isbad;
+       mtd->_block_markbad = nand_block_markbad;
+
+       /* propagate ecc info to mtd_info */
        mtd->ecclayout = chip->ecc.layout;
+       mtd->ecc_strength = chip->ecc.strength;
+       /*
+        * Initialize bitflip_threshold to its default prior scan_bbt() call.
+        * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be
+        * properly set.
+        */
+       if (!mtd->bitflip_threshold)
+               mtd->bitflip_threshold = mtd->ecc_strength;
 
        /* Check, if we should skip the bad block table scan */
        if (chip->options & NAND_SKIP_BBTSCAN)
@@ -3184,15 +3382,13 @@ int nand_scan_tail(struct mtd_info *mtd)
 
 /**
  * nand_scan - [NAND Interface] Scan for the NAND device
- * @mtd:       MTD device structure
- * @maxchips:  Number of chips to scan for
- *
- * This fills out all the uninitialized function pointers
- * with the defaults.
- * The flash ID is read and the mtd/chip structures are
- * filled with the appropriate values.
- * The mtd->owner field must be set to the module of the caller
+ * @mtd: MTD device structure
+ * @maxchips: number of chips to scan for
  *
+ * This fills out all the uninitialized function pointers with the defaults.
+ * The flash ID is read and the mtd/chip structures are filled with the
+ * appropriate values. The mtd->owner field must be set to the module of the
+ * caller.
  */
 int nand_scan(struct mtd_info *mtd, int maxchips)
 {
@@ -3206,8 +3402,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
 
 /**
  * nand_release - [NAND Interface] Free resources held by the NAND device
- * @mtd:       MTD device structure
-*/
+ * @mtd: MTD device structure
+ */
 void nand_release(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
index 74a7061b055efe51defdb2a0f2271364d34029bc..8ef58451d522131ba3b9bec3c116531c94217681 100644 (file)
@@ -4,7 +4,7 @@
  *  Overview:
  *   Bad block table support for the NAND driver
  *
- *  Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
+ *  Copyright Â© 2004 Thomas Gleixner (tglx@linutronix.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -14,7 +14,7 @@
  *
  * When nand_scan_bbt is called, then it tries to find the bad block table
  * depending on the options in the BBT descriptor(s). If no flash based BBT
- * (NAND_USE_FLASH_BBT) is specified then the device is scanned for factory
+ * (NAND_BBT_USE_FLASH) is specified then the device is scanned for factory
  * marked good / bad blocks. This information is used to create a memory BBT.
  * Once a new bad block is discovered then the "factory" information is updated
  * on the device.
@@ -22,7 +22,7 @@
  * BBT on flash. If a BBT is found then the contents are read and the memory
  * based BBT is created. If a mirrored BBT is selected then the mirror is
  * searched too and the versions are compared. If the mirror has a greater
- * version number than the mirror BBT is used to build the memory based BBT.
+ * version number, then the mirror BBT is used to build the memory based BBT.
  * If the tables are not versioned, then we "or" the bad block information.
  * If one of the BBTs is out of date or does not exist it is (re)created.
  * If no BBT exists at all then the device is scanned for factory marked
@@ -36,9 +36,9 @@
  * The table is marked in the OOB area with an ident pattern and a version
  * number which indicates which of both tables is more up to date. If the NAND
  * controller needs the complete OOB area for the ECC information then the
- * option NAND_USE_FLASH_BBT_NO_OOB should be used: it moves the ident pattern
- * and the version byte into the data area and the OOB area will remain
- * untouched.
+ * option NAND_BBT_NO_OOB should be used (along with NAND_BBT_USE_FLASH, of
+ * course): it moves the ident pattern and the version byte into the data area
+ * and the OOB area will remain untouched.
  *
  * The table uses 2 bits per block
  * 11b:                block is good
 #include <malloc.h>
 #include <linux/compat.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/bbm.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/bitops.h>
+#include <linux/string.h>
 
 #include <asm/errno.h>
 
 static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
 {
-       int ret;
-
-       ret = memcmp(buf, td->pattern, td->len);
-       if (!ret)
-               return ret;
-       return -1;
+       if (memcmp(buf, td->pattern, td->len))
+               return -1;
+       return 0;
 }
 
 /**
  * check_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf:       the buffer to search
- * @len:       the length of buffer to search
- * @paglen:    the pagelength
- * @td:                search pattern descriptor
- *
- * Check for a pattern at the given place. Used to search bad block
- * tables and good / bad block identifiers.
- * If the SCAN_EMPTY option is set then check, if all bytes except the
- * pattern area contain 0xff
+ * @buf: the buffer to search
+ * @len: the length of buffer to search
+ * @paglen: the pagelength
+ * @td: search pattern descriptor
  *
-*/
+ * Check for a pattern at the given place. Used to search bad block tables and
+ * good / bad block identifiers. If the SCAN_EMPTY option is set then check, if
+ * all bytes except the pattern area contain 0xff.
+ */
 static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
 {
-       int i, end = 0;
+       int end = 0;
        uint8_t *p = buf;
 
        if (td->options & NAND_BBT_NO_OOB)
                return check_pattern_no_oob(buf, td);
 
        end = paglen + td->offs;
-       if (td->options & NAND_BBT_SCANEMPTY) {
-               for (i = 0; i < end; i++) {
-                       if (p[i] != 0xff)
-                               return -1;
-               }
-       }
+       if (td->options & NAND_BBT_SCANEMPTY)
+               if (memchr_inv(p, 0xff, end))
+                       return -1;
        p += end;
 
        /* Compare the pattern */
-       for (i = 0; i < td->len; i++) {
-               if (p[i] != td->pattern[i])
-                       return -1;
-       }
-
-       /* Check both positions 1 and 6 for pattern? */
-       if (td->options & NAND_BBT_SCANBYTE1AND6) {
-               if (td->options & NAND_BBT_SCANEMPTY) {
-                       p += td->len;
-                       end += NAND_SMALL_BADBLOCK_POS - td->offs;
-                       /* Check region between positions 1 and 6 */
-                       for (i = 0; i < NAND_SMALL_BADBLOCK_POS - td->offs - td->len;
-                                       i++) {
-                               if (*p++ != 0xff)
-                                       return -1;
-                       }
-               }
-               else {
-                       p += NAND_SMALL_BADBLOCK_POS - td->offs;
-               }
-               /* Compare the pattern */
-               for (i = 0; i < td->len; i++) {
-                       if (p[i] != td->pattern[i])
-                               return -1;
-               }
-       }
+       if (memcmp(p, td->pattern, td->len))
+               return -1;
 
        if (td->options & NAND_BBT_SCANEMPTY) {
                p += td->len;
                end += td->len;
-               for (i = end; i < len; i++) {
-                       if (*p++ != 0xff)
-                               return -1;
-               }
+               if (memchr_inv(p, 0xff, len - end))
+                       return -1;
        }
        return 0;
 }
 
 /**
  * check_short_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf:       the buffer to search
- * @td:                search pattern descriptor
+ * @buf: the buffer to search
+ * @td:        search pattern descriptor
  *
- * Check for a pattern at the given place. Used to search bad block
- * tables and good / bad block identifiers. Same as check_pattern, but
- * no optional empty check
- *
-*/
+ * Check for a pattern at the given place. Used to search bad block tables and
+ * good / bad block identifiers. Same as check_pattern, but no optional empty
+ * check.
+ */
 static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
 {
-       int i;
-       uint8_t *p = buf;
-
        /* Compare the pattern */
-       for (i = 0; i < td->len; i++) {
-               if (p[td->offs + i] != td->pattern[i])
-                       return -1;
-       }
-       /* Need to check location 1 AND 6? */
-       if (td->options & NAND_BBT_SCANBYTE1AND6) {
-               for (i = 0; i < td->len; i++) {
-                       if (p[NAND_SMALL_BADBLOCK_POS + i] != td->pattern[i])
-                               return -1;
-               }
-       }
+       if (memcmp(buf + td->offs, td->pattern, td->len))
+               return -1;
        return 0;
 }
 
 /**
  * add_marker_len - compute the length of the marker in data area
- * @td:                BBT descriptor used for computation
+ * @td: BBT descriptor used for computation
  *
- * The length will be 0 if the markeris located in OOB area.
+ * The length will be 0 if the marker is located in OOB area.
  */
 static u32 add_marker_len(struct nand_bbt_descr *td)
 {
@@ -199,34 +154,33 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
 
 /**
  * read_bbt - [GENERIC] Read the bad block table starting from page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @page:      the starting page
- * @num:       the number of bbt descriptors to read
- * @td:                the bbt describtion table
- * @offs:      offset in the memory table
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @page: the starting page
+ * @num: the number of bbt descriptors to read
+ * @td: the bbt describtion table
+ * @offs: offset in the memory table
  *
  * Read the bad block table starting from page.
- *
  */
 static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                struct nand_bbt_descr *td, int offs)
 {
-       int res, i, j, act = 0;
+       int res, ret = 0, i, j, act = 0;
        struct nand_chip *this = mtd->priv;
        size_t retlen, len, totlen;
        loff_t from;
        int bits = td->options & NAND_BBT_NRBITS_MSK;
-       uint8_t msk = (uint8_t) ((1 << bits) - 1);
+       uint8_t msk = (uint8_t)((1 << bits) - 1);
        u32 marker_len;
        int reserved_block_code = td->reserved_block_code;
 
        totlen = (num * bits) >> 3;
        marker_len = add_marker_len(td);
-       from = ((loff_t) page) << this->page_shift;
+       from = ((loff_t)page) << this->page_shift;
 
        while (totlen) {
-               len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
+               len = min(totlen, (size_t)(1 << this->bbt_erase_shift));
                if (marker_len) {
                        /*
                         * In case the BBT marker is not in the OOB area it
@@ -236,13 +190,20 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                        from += marker_len;
                        marker_len = 0;
                }
-               res = mtd->read(mtd, from, len, &retlen, buf);
+               res = mtd_read(mtd, from, len, &retlen, buf);
                if (res < 0) {
-                       if (retlen != len) {
-                               printk(KERN_INFO "nand_bbt: Error reading bad block table\n");
+                       if (mtd_is_eccerr(res)) {
+                               pr_info("nand_bbt: ECC error in BBT at "
+                                       "0x%012llx\n", from & ~mtd->writesize);
+                               return res;
+                       } else if (mtd_is_bitflip(res)) {
+                               pr_info("nand_bbt: corrected error in BBT at "
+                                       "0x%012llx\n", from & ~mtd->writesize);
+                               ret = res;
+                       } else {
+                               pr_info("nand_bbt: error reading BBT\n");
                                return res;
                        }
-                       printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
                }
 
                /* Analyse data */
@@ -253,17 +214,16 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                                if (tmp == msk)
                                        continue;
                                if (reserved_block_code && (tmp == reserved_block_code)) {
-                                       printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%012llx\n",
-                                              (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                                       pr_info("nand_read_bbt: reserved block at 0x%012llx\n",
+                                                (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
                                        this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
                                        mtd->ecc_stats.bbtblocks++;
                                        continue;
                                }
-                               MTDDEBUG(MTD_DEBUG_LEVEL0, "nand_read_bbt: " \
-                                       "Bad block at 0x%012llx\n",
+                               pr_info("nand_read_bbt: Bad block at 0x%012llx\n",
                                        (loff_t)((offs << 2) + (act >> 1))
                                        << this->bbt_erase_shift);
-                               /* Factory marked bad or worn out ? */
+                               /* Factory marked bad or worn out? */
                                if (tmp == 0)
                                        this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
                                else
@@ -274,20 +234,20 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                totlen -= len;
                from += len;
        }
-       return 0;
+       return ret;
 }
 
 /**
  * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @chip:      read the table for a specific chip, -1 read all chips.
- *             Applies only if NAND_BBT_PERCHIP option is set
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @chip: read the table for a specific chip, -1 read all chips; applies only if
+ *        NAND_BBT_PERCHIP option is set
  *
- * Read the bad block table for all chips starting at a given page
- * We assume that the bbt bits are in consecutive order.
-*/
+ * Read the bad block table for all chips starting at a given page. We assume
+ * that the bbt bits are in consecutive order.
+ */
 static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
 {
        struct nand_chip *this = mtd->priv;
@@ -313,10 +273,8 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
        return 0;
 }
 
-/*
- * BBT marker is in the first page, no OOB.
- */
-static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+/* BBT marker is in the first page, no OOB */
+static int scan_read_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                         struct nand_bbt_descr *td)
 {
        size_t retlen;
@@ -326,70 +284,73 @@ static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
        if (td->options & NAND_BBT_VERSION)
                len++;
 
-       return mtd->read(mtd, offs, len, &retlen, buf);
+       return mtd_read(mtd, offs, len, &retlen, buf);
 }
 
-/*
- * Scan read raw data from flash
+/**
+ * scan_read_oob - [GENERIC] Scan data+OOB region to buffer
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @offs: offset at which to scan
+ * @len: length of data region to read
+ *
+ * Scan read data from data+OOB. May traverse multiple pages, interleaving
+ * page,OOB,page,OOB,... in buf. Completes transfer and returns the "strongest"
+ * ECC condition (error or bitflip). May quit on the first (non-ECC) error.
  */
-static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                         size_t len)
 {
        struct mtd_oob_ops ops;
-       int res;
+       int res, ret = 0;
 
-       ops.mode = MTD_OOB_RAW;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = 0;
        ops.ooblen = mtd->oobsize;
 
-
        while (len > 0) {
-               if (len <= mtd->writesize) {
-                       ops.oobbuf = buf + len;
-                       ops.datbuf = buf;
-                       ops.len = len;
-                       return mtd->read_oob(mtd, offs, &ops);
-               } else {
-                       ops.oobbuf = buf + mtd->writesize;
-                       ops.datbuf = buf;
-                       ops.len = mtd->writesize;
-                       res = mtd->read_oob(mtd, offs, &ops);
+               ops.datbuf = buf;
+               ops.len = min(len, (size_t)mtd->writesize);
+               ops.oobbuf = buf + ops.len;
 
-                       if (res)
+               res = mtd_read_oob(mtd, offs, &ops);
+               if (res) {
+                       if (!mtd_is_bitflip_or_eccerr(res))
                                return res;
+                       else if (mtd_is_eccerr(res) || !ret)
+                               ret = res;
                }
 
                buf += mtd->oobsize + mtd->writesize;
                len -= mtd->writesize;
+               offs += mtd->writesize;
        }
-       return 0;
+       return ret;
 }
 
-static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                         size_t len, struct nand_bbt_descr *td)
 {
        if (td->options & NAND_BBT_NO_OOB)
-               return scan_read_raw_data(mtd, buf, offs, td);
+               return scan_read_data(mtd, buf, offs, td);
        else
-               return scan_read_raw_oob(mtd, buf, offs, len);
+               return scan_read_oob(mtd, buf, offs, len);
 }
 
-/*
- * Scan write data with oob to flash
- */
+/* Scan write data with oob to flash */
 static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
                          uint8_t *buf, uint8_t *oob)
 {
        struct mtd_oob_ops ops;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = 0;
        ops.ooblen = mtd->oobsize;
        ops.datbuf = buf;
        ops.oobbuf = oob;
        ops.len = len;
 
-       return mtd->write_oob(mtd, offs, &ops);
+       return mtd_write_oob(mtd, offs, &ops);
 }
 
 static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
@@ -403,65 +364,60 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
 
 /**
  * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
- *
- * Read the bad block table(s) for all chips starting at a given page
- * We assume that the bbt bits are in consecutive order.
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @md:        descriptor for the bad block table mirror
  *
-*/
-static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
-                        struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+ * Read the bad block table(s) for all chips starting at a given page. We
+ * assume that the bbt bits are in consecutive order.
+ */
+static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
+                         struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
        struct nand_chip *this = mtd->priv;
 
        /* Read the primary version, if available */
        if (td->options & NAND_BBT_VERSION) {
-               scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
+               scan_read(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
                              mtd->writesize, td);
                td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
-               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
-                      td->pages[0], td->version[0]);
+               pr_info("Bad block table at page %d, version 0x%02X\n",
+                        td->pages[0], td->version[0]);
        }
 
        /* Read the mirror version, if available */
        if (md && (md->options & NAND_BBT_VERSION)) {
-               scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
-                             mtd->writesize, td);
+               scan_read(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
+                             mtd->writesize, md);
                md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
-               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
-                      md->pages[0], md->version[0]);
+               pr_info("Bad block table at page %d, version 0x%02X\n",
+                        md->pages[0], md->version[0]);
        }
-       return 1;
 }
 
-/*
- * Scan a given block full
- */
+/* Scan a given block full */
 static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
                           loff_t offs, uint8_t *buf, size_t readlen,
-                          int scanlen, int len)
+                          int scanlen, int numpages)
 {
        int ret, j;
 
-       ret = scan_read_raw_oob(mtd, buf, offs, readlen);
-       if (ret)
+       ret = scan_read_oob(mtd, buf, offs, readlen);
+       /* Ignore ECC errors when checking for BBM */
+       if (ret && !mtd_is_bitflip_or_eccerr(ret))
                return ret;
 
-       for (j = 0; j < len; j++, buf += scanlen) {
+       for (j = 0; j < numpages; j++, buf += scanlen) {
                if (check_pattern(buf, scanlen, mtd->writesize, bd))
                        return 1;
        }
        return 0;
 }
 
-/*
- * Scan a given block partially
- */
+/* Scan a given block partially */
 static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
-                          loff_t offs, uint8_t *buf, int len)
+                          loff_t offs, uint8_t *buf, int numpages)
 {
        struct mtd_oob_ops ops;
        int j, ret;
@@ -470,16 +426,16 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
        ops.oobbuf = buf;
        ops.ooboffs = 0;
        ops.datbuf = NULL;
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
 
-       for (j = 0; j < len; j++) {
+       for (j = 0; j < numpages; j++) {
                /*
-                * Read the full oob until read_oob is fixed to
-                * handle single byte reads for 16 bit
-                * buswidth
+                * Read the full oob until read_oob is fixed to handle single
+                * byte reads for 16 bit buswidth.
                 */
-               ret = mtd->read_oob(mtd, offs, &ops);
-               if (ret)
+               ret = mtd_read_oob(mtd, offs, &ops);
+               /* Ignore ECC errors when checking for BBM */
+               if (ret && !mtd_is_bitflip_or_eccerr(ret))
                        return ret;
 
                if (check_short_pattern(buf, bd))
@@ -492,32 +448,32 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
 
 /**
  * create_bbt - [GENERIC] Create a bad block table by scanning the device
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @bd:                descriptor for the good/bad block search pattern
- * @chip:      create the table for a specific chip, -1 read all chips.
- *             Applies only if NAND_BBT_PERCHIP option is set
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @bd: descriptor for the good/bad block search pattern
+ * @chip: create the table for a specific chip, -1 read all chips; applies only
+ *        if NAND_BBT_PERCHIP option is set
  *
- * Create a bad block table by scanning the device
- * for the given good/bad block identify pattern
+ * Create a bad block table by scanning the device for the given good/bad block
+ * identify pattern.
  */
 static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        struct nand_bbt_descr *bd, int chip)
 {
        struct nand_chip *this = mtd->priv;
-       int i, numblocks, len, scanlen;
+       int i, numblocks, numpages, scanlen;
        int startblock;
        loff_t from;
        size_t readlen;
 
-       MTDDEBUG(MTD_DEBUG_LEVEL0, "Scanning device for bad blocks\n");
+       pr_info("Scanning device for bad blocks\n");
 
        if (bd->options & NAND_BBT_SCANALLPAGES)
-               len = 1 << (this->bbt_erase_shift - this->page_shift);
+               numpages = 1 << (this->bbt_erase_shift - this->page_shift);
        else if (bd->options & NAND_BBT_SCAN2NDPAGE)
-               len = 2;
+               numpages = 2;
        else
-               len = 1;
+               numpages = 1;
 
        if (!(bd->options & NAND_BBT_SCANEMPTY)) {
                /* We need only read few bytes from the OOB area */
@@ -526,18 +482,20 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        } else {
                /* Full page content should be read */
                scanlen = mtd->writesize + mtd->oobsize;
-               readlen = len * mtd->writesize;
+               readlen = numpages * mtd->writesize;
        }
 
        if (chip == -1) {
-               /* Note that numblocks is 2 * (real numblocks) here, see i+=2
-                * below as it makes shifting and masking less painful */
+               /*
+                * Note that numblocks is 2 * (real numblocks) here, see i+=2
+                * below as it makes shifting and masking less painful
+                */
                numblocks = mtd->size >> (this->bbt_erase_shift - 1);
                startblock = 0;
                from = 0;
        } else {
                if (chip >= this->numchips) {
-                       printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
+                       pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n",
                               chip + 1, this->numchips);
                        return -EINVAL;
                }
@@ -547,8 +505,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
                from = (loff_t)startblock << (this->bbt_erase_shift - 1);
        }
 
-       if (this->options & NAND_BBT_SCANLASTPAGE)
-               from += mtd->erasesize - (mtd->writesize * len);
+       if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
+               from += mtd->erasesize - (mtd->writesize * numpages);
 
        for (i = startblock; i < numblocks;) {
                int ret;
@@ -557,17 +515,16 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 
                if (bd->options & NAND_BBT_SCANALLPAGES)
                        ret = scan_block_full(mtd, bd, from, buf, readlen,
-                                             scanlen, len);
+                                             scanlen, numpages);
                else
-                       ret = scan_block_fast(mtd, bd, from, buf, len);
+                       ret = scan_block_fast(mtd, bd, from, buf, numpages);
 
                if (ret < 0)
                        return ret;
 
                if (ret) {
                        this->bbt[i >> 3] |= 0x03 << (i & 0x6);
-                       MTDDEBUG(MTD_DEBUG_LEVEL0,
-                                 "Bad eraseblock %d at 0x%012llx\n",
+                       pr_warn("Bad eraseblock %d at 0x%012llx\n",
                                  i >> 1, (unsigned long long)from);
                        mtd->ecc_stats.badblocks++;
                }
@@ -580,20 +537,18 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 
 /**
  * search_bbt - [GENERIC] scan the device for a specific bad block table
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
  *
- * Read the bad block table by searching for a given ident pattern.
- * Search is preformed either from the beginning up or from the end of
- * the device downwards. The search starts always at the start of a
- * block.
- * If the option NAND_BBT_PERCHIP is given, each chip is searched
- * for a bbt, which contains the bad block information of this chip.
- * This is necessary to provide support for certain DOC devices.
+ * Read the bad block table by searching for a given ident pattern. Search is
+ * preformed either from the beginning up or from the end of the device
+ * downwards. The search starts always at the start of a block. If the option
+ * NAND_BBT_PERCHIP is given, each chip is searched for a bbt, which contains
+ * the bad block information of this chip. This is necessary to provide support
+ * for certain DOC devices.
  *
- * The bbt ident pattern resides in the oob area of the first page
- * in a block.
+ * The bbt ident pattern resides in the oob area of the first page in a block.
  */
 static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
 {
@@ -604,7 +559,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
        int bbtblocks;
        int blocktopage = this->bbt_erase_shift - this->page_shift;
 
-       /* Search direction top -> down ? */
+       /* Search direction top -> down? */
        if (td->options & NAND_BBT_LASTBLOCK) {
                startblock = (mtd->size >> this->bbt_erase_shift) - 1;
                dir = -1;
@@ -613,7 +568,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
                dir = 1;
        }
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP) {
                chips = this->numchips;
                bbtblocks = this->chipsize >> this->bbt_erase_shift;
@@ -634,7 +589,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
                        loff_t offs = (loff_t)actblock << this->bbt_erase_shift;
 
                        /* Read first page */
-                       scan_read_raw(mtd, buf, offs, mtd->writesize, td);
+                       scan_read(mtd, buf, offs, mtd->writesize, td);
                        if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
                                td->pages[i] = actblock << blocktopage;
                                if (td->options & NAND_BBT_VERSION) {
@@ -649,10 +604,9 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
        /* Check, if we found a bbt for each requested chip */
        for (i = 0; i < chips; i++) {
                if (td->pages[i] == -1)
-                       printk(KERN_WARNING "Bad block table not found for chip %d\n", i);
+                       pr_warn("Bad block table not found for chip %d\n", i);
                else
-                       MTDDEBUG(MTD_DEBUG_LEVEL0, "Bad block table found " \
-                               "at page %d, version 0x%02X\n", td->pages[i],
+                       pr_info("Bad block table found at page %d, version 0x%02X\n", td->pages[i],
                                td->version[i]);
        }
        return 0;
@@ -660,14 +614,16 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
 
 /**
  * search_read_bbts - [GENERIC] scan the device for bad block table(s)
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @md: descriptor for the bad block table mirror
  *
- * Search and read the bad block table(s)
-*/
-static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+ * Search and read the bad block table(s).
+ */
+static void search_read_bbts(struct mtd_info *mtd, uint8_t *buf,
+                            struct nand_bbt_descr *td,
+                            struct nand_bbt_descr *md)
 {
        /* Search the primary table */
        search_bbt(mtd, buf, td);
@@ -675,23 +631,18 @@ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt
        /* Search the mirror table */
        if (md)
                search_bbt(mtd, buf, md);
-
-       /* Force result check */
-       return 1;
 }
 
 /**
  * write_bbt - [GENERIC] (Re)write the bad block table
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @md: descriptor for the bad block table mirror
+ * @chipsel: selector for a specific chip, -1 for all
  *
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
- * @chipsel:   selector for a specific chip, -1 for all
- *
- * (Re)write the bad block table
- *
-*/
+ * (Re)write the bad block table.
+ */
 static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                     struct nand_bbt_descr *td, struct nand_bbt_descr *md,
                     int chipsel)
@@ -710,14 +661,14 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
        ops.ooblen = mtd->oobsize;
        ops.ooboffs = 0;
        ops.datbuf = NULL;
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
 
        if (!rcode)
                rcode = 0xff;
-       /* Write bad block table per chip rather than per device ? */
+       /* Write bad block table per chip rather than per device? */
        if (td->options & NAND_BBT_PERCHIP) {
                numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
-               /* Full device write or specific chip ? */
+               /* Full device write or specific chip? */
                if (chipsel == -1) {
                        nrchips = this->numchips;
                } else {
@@ -731,8 +682,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 
        /* Loop through the chips */
        for (; chip < nrchips; chip++) {
-
-               /* There was already a version of the table, reuse the page
+               /*
+                * There was already a version of the table, reuse the page
                 * This applies for absolute placement too, as we have the
                 * page nr. in td->pages.
                 */
@@ -741,8 +692,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        goto write;
                }
 
-               /* Automatic placement of the bad block table */
-               /* Search direction top -> down ? */
+               /*
+                * Automatic placement of the bad block table. Search direction
+                * top -> down?
+                */
                if (td->options & NAND_BBT_LASTBLOCK) {
                        startblock = numblocks * (chip + 1) - 1;
                        dir = -1;
@@ -766,7 +719,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        if (!md || md->pages[chip] != page)
                                goto write;
                }
-               printk(KERN_ERR "No space left to write bad block table\n");
+               pr_err("No space left to write bad block table\n");
                return -ENOSPC;
        write:
 
@@ -791,29 +744,27 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 
                bbtoffs = chip * (numblocks >> 2);
 
-               to = ((loff_t) page) << this->page_shift;
+               to = ((loff_t)page) << this->page_shift;
 
-               /* Must we save the block contents ? */
+               /* Must we save the block contents? */
                if (td->options & NAND_BBT_SAVECONTENT) {
                        /* Make it block aligned */
-                       to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
+                       to &= ~((loff_t)((1 << this->bbt_erase_shift) - 1));
                        len = 1 << this->bbt_erase_shift;
-                       res = mtd->read(mtd, to, len, &retlen, buf);
+                       res = mtd_read(mtd, to, len, &retlen, buf);
                        if (res < 0) {
                                if (retlen != len) {
-                                       printk(KERN_INFO "nand_bbt: Error "
-                                              "reading block for writing "
-                                              "the bad block table\n");
+                                       pr_info("nand_bbt: error reading block "
+                                               "for writing the bad block table\n");
                                        return res;
                                }
-                               printk(KERN_WARNING "nand_bbt: ECC error "
-                                      "while reading block for writing "
-                                      "bad block table\n");
+                               pr_warn("nand_bbt: ECC error while reading "
+                                       "block for writing bad block table\n");
                        }
                        /* Read oob data */
                        ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
                        ops.oobbuf = &buf[len];
-                       res = mtd->read_oob(mtd, to + mtd->writesize, &ops);
+                       res = mtd_read_oob(mtd, to + mtd->writesize, &ops);
                        if (res < 0 || ops.oobretlen != ops.ooblen)
                                goto outerr;
 
@@ -821,19 +772,19 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        pageoffs = page - (int)(to >> this->page_shift);
                        offs = pageoffs << this->page_shift;
                        /* Preset the bbt area with 0xff */
-                       memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
+                       memset(&buf[offs], 0xff, (size_t)(numblocks >> sft));
                        ooboffs = len + (pageoffs * mtd->oobsize);
 
                } else if (td->options & NAND_BBT_NO_OOB) {
                        ooboffs = 0;
                        offs = td->len;
-                       /* the version byte */
+                       /* The version byte */
                        if (td->options & NAND_BBT_VERSION)
                                offs++;
                        /* Calc length */
-                       len = (size_t) (numblocks >> sft);
+                       len = (size_t)(numblocks >> sft);
                        len += offs;
-                       /* Make it page aligned ! */
+                       /* Make it page aligned! */
                        len = ALIGN(len, mtd->writesize);
                        /* Preset the buffer with 0xff */
                        memset(buf, 0xff, len);
@@ -841,8 +792,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        memcpy(buf, td->pattern, td->len);
                } else {
                        /* Calc length */
-                       len = (size_t) (numblocks >> sft);
-                       /* Make it page aligned ! */
+                       len = (size_t)(numblocks >> sft);
+                       /* Make it page aligned! */
                        len = ALIGN(len, mtd->writesize);
                        /* Preset the buffer with 0xff */
                        memset(buf, 0xff, len +
@@ -856,13 +807,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                if (td->options & NAND_BBT_VERSION)
                        buf[ooboffs + td->veroffs] = td->version[chip];
 
-               /* walk through the memory table */
+               /* Walk through the memory table */
                for (i = 0; i < numblocks;) {
                        uint8_t dat;
                        dat = this->bbt[bbtoffs + (i >> 2)];
                        for (j = 0; j < 4; j++, i++) {
                                int sftcnt = (i << (3 - sft)) & sftmsk;
-                               /* Do not store the reserved bbt blocks ! */
+                               /* Do not store the reserved bbt blocks! */
                                buf[offs + (i >> sft)] &=
                                        ~(msk[dat & 0x03] << sftcnt);
                                dat >>= 2;
@@ -883,8 +834,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                if (res < 0)
                        goto outerr;
 
-               printk(KERN_DEBUG "Bad block table written to 0x%012llx, version "
-                      "0x%02X\n", (unsigned long long)to, td->version[chip]);
+               pr_info("Bad block table written to 0x%012llx, version 0x%02X\n",
+                        (unsigned long long)to, td->version[chip]);
 
                /* Mark it as used */
                td->pages[chip] = page;
@@ -892,19 +843,18 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
        return 0;
 
  outerr:
-       printk(KERN_WARNING
-              "nand_bbt: Error while writing bad block table %d\n", res);
+       pr_warn("nand_bbt: error while writing bad block table %d\n", res);
        return res;
 }
 
 /**
  * nand_memory_bbt - [GENERIC] create a memory based bad block table
- * @mtd:       MTD device structure
- * @bd:                descriptor for the good/bad block search pattern
+ * @mtd: MTD device structure
+ * @bd: descriptor for the good/bad block search pattern
  *
- * The function creates a memory based bbt by scanning the device
- * for manufacturer / software marked good / bad blocks
-*/
+ * The function creates a memory based bbt by scanning the device for
+ * manufacturer / software marked good / bad blocks.
+ */
 static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
        struct nand_chip *this = mtd->priv;
@@ -915,25 +865,24 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
 
 /**
  * check_create - [GENERIC] create and write bbt(s) if necessary
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @bd:                descriptor for the good/bad block search pattern
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @bd: descriptor for the good/bad block search pattern
  *
- * The function checks the results of the previous call to read_bbt
- * and creates / updates the bbt(s) if necessary
- * Creation is necessary if no bbt was found for the chip/device
- * Update is necessary if one of the tables is missing or the
- * version nr. of one table is less than the other
-*/
+ * The function checks the results of the previous call to read_bbt and creates
+ * / updates the bbt(s) if necessary. Creation is necessary if no bbt was found
+ * for the chip/device. Update is necessary if one of the tables is missing or
+ * the version nr. of one table is less than the other.
+ */
 static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
 {
-       int i, chips, writeops, chipsel, res;
+       int i, chips, writeops, create, chipsel, res, res2;
        struct nand_chip *this = mtd->priv;
        struct nand_bbt_descr *td = this->bbt_td;
        struct nand_bbt_descr *md = this->bbt_md;
        struct nand_bbt_descr *rd, *rd2;
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP)
                chips = this->numchips;
        else
@@ -941,86 +890,98 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 
        for (i = 0; i < chips; i++) {
                writeops = 0;
+               create = 0;
                rd = NULL;
                rd2 = NULL;
-               /* Per chip or per device ? */
+               res = res2 = 0;
+               /* Per chip or per device? */
                chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
-               /* Mirrored table available ? */
+               /* Mirrored table available? */
                if (md) {
                        if (td->pages[i] == -1 && md->pages[i] == -1) {
+                               create = 1;
                                writeops = 0x03;
-                               goto create;
-                       }
-
-                       if (td->pages[i] == -1) {
+                       } else if (td->pages[i] == -1) {
                                rd = md;
-                               td->version[i] = md->version[i];
-                               writeops = 1;
-                               goto writecheck;
-                       }
-
-                       if (md->pages[i] == -1) {
+                               writeops = 0x01;
+                       } else if (md->pages[i] == -1) {
                                rd = td;
-                               md->version[i] = td->version[i];
-                               writeops = 2;
-                               goto writecheck;
-                       }
-
-                       if (td->version[i] == md->version[i]) {
+                               writeops = 0x02;
+                       } else if (td->version[i] == md->version[i]) {
                                rd = td;
                                if (!(td->options & NAND_BBT_VERSION))
                                        rd2 = md;
-                               goto writecheck;
-                       }
-
-                       if (((int8_t) (td->version[i] - md->version[i])) > 0) {
+                       } else if (((int8_t)(td->version[i] - md->version[i])) > 0) {
                                rd = td;
-                               md->version[i] = td->version[i];
-                               writeops = 2;
+                               writeops = 0x02;
                        } else {
                                rd = md;
-                               td->version[i] = md->version[i];
-                               writeops = 1;
+                               writeops = 0x01;
                        }
-
-                       goto writecheck;
-
                } else {
                        if (td->pages[i] == -1) {
+                               create = 1;
                                writeops = 0x01;
-                               goto create;
+                       } else {
+                               rd = td;
                        }
-                       rd = td;
-                       goto writecheck;
                }
-       create:
-               /* Create the bad block table by scanning the device ? */
-               if (!(td->options & NAND_BBT_CREATE))
-                       continue;
 
-               /* Create the table in memory by scanning the chip(s) */
-               if (!(this->options & NAND_CREATE_EMPTY_BBT))
-                       create_bbt(mtd, buf, bd, chipsel);
-
-               td->version[i] = 1;
-               if (md)
-                       md->version[i] = 1;
-       writecheck:
-               /* read back first ? */
-               if (rd)
-                       read_abs_bbt(mtd, buf, rd, chipsel);
-               /* If they weren't versioned, read both. */
-               if (rd2)
-                       read_abs_bbt(mtd, buf, rd2, chipsel);
-
-               /* Write the bad block table to the device ? */
+               if (create) {
+                       /* Create the bad block table by scanning the device? */
+                       if (!(td->options & NAND_BBT_CREATE))
+                               continue;
+
+                       /* Create the table in memory by scanning the chip(s) */
+                       if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY))
+                               create_bbt(mtd, buf, bd, chipsel);
+
+                       td->version[i] = 1;
+                       if (md)
+                               md->version[i] = 1;
+               }
+
+               /* Read back first? */
+               if (rd) {
+                       res = read_abs_bbt(mtd, buf, rd, chipsel);
+                       if (mtd_is_eccerr(res)) {
+                               /* Mark table as invalid */
+                               rd->pages[i] = -1;
+                               rd->version[i] = 0;
+                               i--;
+                               continue;
+                       }
+               }
+               /* If they weren't versioned, read both */
+               if (rd2) {
+                       res2 = read_abs_bbt(mtd, buf, rd2, chipsel);
+                       if (mtd_is_eccerr(res2)) {
+                               /* Mark table as invalid */
+                               rd2->pages[i] = -1;
+                               rd2->version[i] = 0;
+                               i--;
+                               continue;
+                       }
+               }
+
+               /* Scrub the flash table(s)? */
+               if (mtd_is_bitflip(res) || mtd_is_bitflip(res2))
+                       writeops = 0x03;
+
+               /* Update version numbers before writing */
+               if (md) {
+                       td->version[i] = max(td->version[i], md->version[i]);
+                       md->version[i] = td->version[i];
+               }
+
+               /* Write the bad block table to the device? */
                if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
                        res = write_bbt(mtd, buf, td, md, chipsel);
                        if (res < 0)
                                return res;
                }
 
-               /* Write the mirror bad block table to the device ? */
+               /* Write the mirror bad block table to the device? */
                if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
                        res = write_bbt(mtd, buf, md, td, chipsel);
                        if (res < 0)
@@ -1032,20 +993,19 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 
 /**
  * mark_bbt_regions - [GENERIC] mark the bad block table regions
- * @mtd:       MTD device structure
- * @td:                bad block table descriptor
+ * @mtd: MTD device structure
+ * @td: bad block table descriptor
  *
- * The bad block table regions are marked as "bad" to prevent
- * accidental erasures / writes. The regions are identified by
- * the mark 0x02.
-*/
+ * The bad block table regions are marked as "bad" to prevent accidental
+ * erasures / writes. The regions are identified by the mark 0x02.
+ */
 static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 {
        struct nand_chip *this = mtd->priv;
        int i, j, chips, block, nrblocks, update;
        uint8_t oldval, newval;
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP) {
                chips = this->numchips;
                nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
@@ -1082,9 +1042,11 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
                                update = 1;
                        block += 2;
                }
-               /* If we want reserved blocks to be recorded to flash, and some
-                  new ones have been marked, then we need to update the stored
-                  bbts.  This should only happen once. */
+               /*
+                * If we want reserved blocks to be recorded to flash, and some
+                * new ones have been marked, then we need to update the stored
+                * bbts.  This should only happen once.
+                */
                if (update && td->reserved_block_code)
                        nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1));
        }
@@ -1092,8 +1054,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 
 /**
  * verify_bbt_descr - verify the bad block description
- * @mtd:       MTD device structure
- * @bd:                the table to verify
+ * @mtd: MTD device structure
+ * @bd: the table to verify
  *
  * This functions performs a few sanity checks on the bad block description
  * table.
@@ -1111,16 +1073,16 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        pattern_len = bd->len;
        bits = bd->options & NAND_BBT_NRBITS_MSK;
 
-       BUG_ON((this->options & NAND_USE_FLASH_BBT_NO_OOB) &&
-                       !(this->options & NAND_USE_FLASH_BBT));
+       BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) &&
+                       !(this->bbt_options & NAND_BBT_USE_FLASH));
        BUG_ON(!bits);
 
        if (bd->options & NAND_BBT_VERSION)
                pattern_len++;
 
        if (bd->options & NAND_BBT_NO_OOB) {
-               BUG_ON(!(this->options & NAND_USE_FLASH_BBT));
-               BUG_ON(!(this->options & NAND_USE_FLASH_BBT_NO_OOB));
+               BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH));
+               BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB));
                BUG_ON(bd->offs);
                if (bd->options & NAND_BBT_VERSION)
                        BUG_ON(bd->veroffs != bd->len);
@@ -1140,18 +1102,16 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 
 /**
  * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
- * @mtd:       MTD device structure
- * @bd:                descriptor for the good/bad block search pattern
- *
- * The function checks, if a bad block table(s) is/are already
- * available. If not it scans the device for manufacturer
- * marked good / bad blocks and writes the bad block table(s) to
- * the selected place.
+ * @mtd: MTD device structure
+ * @bd: descriptor for the good/bad block search pattern
  *
- * The bad block table memory is allocated here. It must be freed
- * by calling the nand_free_bbt function.
+ * The function checks, if a bad block table(s) is/are already available. If
+ * not it scans the device for manufacturer marked good / bad blocks and writes
+ * the bad block table(s) to the selected place.
  *
-*/
+ * The bad block table memory is allocated here. It must be freed by calling
+ * the nand_free_bbt function.
+ */
 int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
        struct nand_chip *this = mtd->priv;
@@ -1161,19 +1121,21 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        struct nand_bbt_descr *md = this->bbt_md;
 
        len = mtd->size >> (this->bbt_erase_shift + 2);
-       /* Allocate memory (2bit per block) and clear the memory bad block table */
+       /*
+        * Allocate memory (2bit per block) and clear the memory bad block
+        * table.
+        */
        this->bbt = kzalloc(len, GFP_KERNEL);
-       if (!this->bbt) {
-               printk(KERN_ERR "nand_scan_bbt: Out of memory\n");
+       if (!this->bbt)
                return -ENOMEM;
-       }
 
-       /* If no primary table decriptor is given, scan the device
-        * to build a memory based bad block table
+       /*
+        * If no primary table decriptor is given, scan the device to build a
+        * memory based bad block table.
         */
        if (!td) {
                if ((res = nand_memory_bbt(mtd, bd))) {
-                       printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
+                       pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n");
                        kfree(this->bbt);
                        this->bbt = NULL;
                }
@@ -1187,22 +1149,20 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        len += (len >> this->page_shift) * mtd->oobsize;
        buf = vmalloc(len);
        if (!buf) {
-               printk(KERN_ERR "nand_bbt: Out of memory\n");
                kfree(this->bbt);
                this->bbt = NULL;
                return -ENOMEM;
        }
 
-       /* Is the bbt at a given page ? */
+       /* Is the bbt at a given page? */
        if (td->options & NAND_BBT_ABSPAGE) {
-               res = read_abs_bbts(mtd, buf, td, md);
+               read_abs_bbts(mtd, buf, td, md);
        } else {
                /* Search the bad block table using a pattern in oob */
-               res = search_read_bbts(mtd, buf, td, md);
+               search_read_bbts(mtd, buf, td, md);
        }
 
-       if (res)
-               res = check_create(mtd, buf, bd);
+       res = check_create(mtd, buf, bd);
 
        /* Prevent the bbt regions from erasing / writing */
        mark_bbt_region(mtd, td);
@@ -1215,15 +1175,15 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 
 /**
  * nand_update_bbt - [NAND Interface] update bad block table(s)
- * @mtd:       MTD device structure
- * @offs:      the offset of the newly marked block
+ * @mtd: MTD device structure
+ * @offs: the offset of the newly marked block
  *
- * The function updates the bad block table(s)
-*/
+ * The function updates the bad block table(s).
+ */
 int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
 {
        struct nand_chip *this = mtd->priv;
-       int len, res = 0, writeops = 0;
+       int len, res = 0;
        int chip, chipsel;
        uint8_t *buf;
        struct nand_bbt_descr *td = this->bbt_td;
@@ -1236,14 +1196,10 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
        len = (1 << this->bbt_erase_shift);
        len += (len >> this->page_shift) * mtd->oobsize;
        buf = kmalloc(len, GFP_KERNEL);
-       if (!buf) {
-               printk(KERN_ERR "nand_update_bbt: Out of memory\n");
+       if (!buf)
                return -ENOMEM;
-       }
 
-       writeops = md != NULL ? 0x03 : 0x01;
-
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP) {
                chip = (int)(offs >> this->chip_shift);
                chipsel = chip;
@@ -1256,14 +1212,14 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
        if (md)
                md->version[chip]++;
 
-       /* Write the bad block table to the device ? */
-       if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
+       /* Write the bad block table to the device? */
+       if (td->options & NAND_BBT_WRITE) {
                res = write_bbt(mtd, buf, td, md, chipsel);
                if (res < 0)
                        goto out;
        }
-       /* Write the mirror bad block table to the device ? */
-       if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
+       /* Write the mirror bad block table to the device? */
+       if (md && (md->options & NAND_BBT_WRITE)) {
                res = write_bbt(mtd, buf, md, td, chipsel);
        }
 
@@ -1272,8 +1228,10 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
        return res;
 }
 
-/* Define some generic bad / good block scan pattern which are used
- * while scanning a device for factory marked good / bad blocks. */
+/*
+ * Define some generic bad / good block scan pattern which are used
+ * while scanning a device for factory marked good / bad blocks.
+ */
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 
 static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
@@ -1285,8 +1243,7 @@ static struct nand_bbt_descr agand_flashbased = {
        .pattern = scan_agand_pattern
 };
 
-/* Generic flash bbt decriptors
-*/
+/* Generic flash bbt descriptors */
 static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
 static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
 
@@ -1296,7 +1253,7 @@ static struct nand_bbt_descr bbt_main_descr = {
        .offs = 8,
        .len = 4,
        .veroffs = 12,
-       .maxblocks = 4,
+       .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
        .pattern = bbt_pattern
 };
 
@@ -1306,55 +1263,51 @@ static struct nand_bbt_descr bbt_mirror_descr = {
        .offs = 8,
        .len = 4,
        .veroffs = 12,
-       .maxblocks = 4,
+       .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
        .pattern = mirror_pattern
 };
 
-static struct nand_bbt_descr bbt_main_no_bbt_descr = {
+static struct nand_bbt_descr bbt_main_no_oob_descr = {
        .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
                | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
                | NAND_BBT_NO_OOB,
        .len = 4,
        .veroffs = 4,
-       .maxblocks = 4,
+       .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
        .pattern = bbt_pattern
 };
 
-static struct nand_bbt_descr bbt_mirror_no_bbt_descr = {
+static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
        .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
                | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
                | NAND_BBT_NO_OOB,
        .len = 4,
        .veroffs = 4,
-       .maxblocks = 4,
+       .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
        .pattern = mirror_pattern
 };
 
-#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \
-               NAND_BBT_SCANBYTE1AND6)
+#define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB)
 /**
- * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure
- * @this:      NAND chip to create descriptor for
+ * nand_create_badblock_pattern - [INTERN] Creates a BBT descriptor structure
+ * @this: NAND chip to create descriptor for
  *
  * This function allocates and initializes a nand_bbt_descr for BBM detection
- * based on the properties of "this". The new descriptor is stored in
+ * based on the properties of @this. The new descriptor is stored in
  * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
  * passed to this function.
- *
  */
-static int nand_create_default_bbt_descr(struct nand_chip *this)
+static int nand_create_badblock_pattern(struct nand_chip *this)
 {
        struct nand_bbt_descr *bd;
        if (this->badblock_pattern) {
-               printk(KERN_WARNING "BBT descr already allocated; not replacing.\n");
+               pr_warn("Bad block pattern already allocated; not replacing\n");
                return -EINVAL;
        }
        bd = kzalloc(sizeof(*bd), GFP_KERNEL);
-       if (!bd) {
-               printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n");
+       if (!bd)
                return -ENOMEM;
-       }
-       bd->options = this->options & BBT_SCAN_OPTIONS;
+       bd->options = this->bbt_options & BADBLOCK_SCAN_MASK;
        bd->offs = this->badblockpos;
        bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1;
        bd->pattern = scan_ff_pattern;
@@ -1365,22 +1318,20 @@ static int nand_create_default_bbt_descr(struct nand_chip *this)
 
 /**
  * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
- * @mtd:       MTD device structure
- *
- * This function selects the default bad block table
- * support for the device and calls the nand_scan_bbt function
+ * @mtd: MTD device structure
  *
-*/
+ * This function selects the default bad block table support for the device and
+ * calls the nand_scan_bbt function.
+ */
 int nand_default_bbt(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
 
-       /* Default for AG-AND. We must use a flash based
-        * bad block table as the devices have factory marked
-        * _good_ blocks. Erasing those blocks leads to loss
-        * of the good / bad information, so we _must_ store
-        * this information in a good / bad table during
-        * startup
+       /*
+        * Default for AG-AND. We must use a flash based bad block table as the
+        * devices have factory marked _good_ blocks. Erasing those blocks
+        * leads to loss of the good / bad information, so we _must_ store this
+        * information in a good / bad table during startup.
         */
        if (this->options & NAND_IS_AND) {
                /* Use the default pattern descriptors */
@@ -1388,17 +1339,17 @@ int nand_default_bbt(struct mtd_info *mtd)
                        this->bbt_td = &bbt_main_descr;
                        this->bbt_md = &bbt_mirror_descr;
                }
-               this->options |= NAND_USE_FLASH_BBT;
+               this->bbt_options |= NAND_BBT_USE_FLASH;
                return nand_scan_bbt(mtd, &agand_flashbased);
        }
 
-       /* Is a flash based bad block table requested ? */
-       if (this->options & NAND_USE_FLASH_BBT) {
+       /* Is a flash based bad block table requested? */
+       if (this->bbt_options & NAND_BBT_USE_FLASH) {
                /* Use the default pattern descriptors */
                if (!this->bbt_td) {
-                       if (this->options & NAND_USE_FLASH_BBT_NO_OOB) {
-                               this->bbt_td = &bbt_main_no_bbt_descr;
-                               this->bbt_md = &bbt_mirror_no_bbt_descr;
+                       if (this->bbt_options & NAND_BBT_NO_OOB) {
+                               this->bbt_td = &bbt_main_no_oob_descr;
+                               this->bbt_md = &bbt_mirror_no_oob_descr;
                        } else {
                                this->bbt_td = &bbt_main_descr;
                                this->bbt_md = &bbt_mirror_descr;
@@ -1410,18 +1361,17 @@ int nand_default_bbt(struct mtd_info *mtd)
        }
 
        if (!this->badblock_pattern)
-               nand_create_default_bbt_descr(this);
+               nand_create_badblock_pattern(this);
 
        return nand_scan_bbt(mtd, this->badblock_pattern);
 }
 
 /**
  * nand_isbad_bbt - [NAND Interface] Check if a block is bad
- * @mtd:       MTD device structure
- * @offs:      offset in the device
- * @allowbbt:  allow access to bad block table region
- *
-*/
+ * @mtd: MTD device structure
+ * @offs: offset in the device
+ * @allowbbt: allow access to bad block table region
+ */
 int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
 {
        struct nand_chip *this = mtd->priv;
index 39535497f8dfede06d6ca0e7ee009178fc7b8569..f856778b5e1a3209dbd962c7fc88aececb32b9bc 100644 (file)
@@ -71,14 +71,15 @@ const struct nand_flash_dev nand_flash_ids[] = {
         * These are the new chips with large page size. The pagesize and the
         * erasesize is determined from the extended id bytes
         */
-#define LP_OPTIONS (NAND_SAMSUNG_LP_OPTIONS | NAND_NO_READRDY | NAND_NO_AUTOINCR)
+#define LP_OPTIONS NAND_SAMSUNG_LP_OPTIONS
 #define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16)
 
-       /*512 Megabit */
+       /* 512 Megabit */
        {"NAND 64MiB 1,8V 8-bit",       0xA2, 0,  64, 0, LP_OPTIONS},
        {"NAND 64MiB 1,8V 8-bit",       0xA0, 0,  64, 0, LP_OPTIONS},
        {"NAND 64MiB 3,3V 8-bit",       0xF2, 0,  64, 0, LP_OPTIONS},
        {"NAND 64MiB 3,3V 8-bit",       0xD0, 0,  64, 0, LP_OPTIONS},
+       {"NAND 64MiB 3,3V 8-bit",       0xF0, 0,  64, 0, LP_OPTIONS},
        {"NAND 64MiB 1,8V 16-bit",      0xB2, 0,  64, 0, LP_OPTIONS16},
        {"NAND 64MiB 1,8V 16-bit",      0xB0, 0,  64, 0, LP_OPTIONS16},
        {"NAND 64MiB 3,3V 16-bit",      0xC2, 0,  64, 0, LP_OPTIONS16},
@@ -157,9 +158,7 @@ const struct nand_flash_dev nand_flash_ids[] = {
         * writes possible, but not implemented now
         */
        {"AND 128MiB 3,3V 8-bit",       0x01, 2048, 128, 0x4000,
-        NAND_IS_AND | NAND_NO_AUTOINCR |NAND_NO_READRDY | NAND_4PAGE_ARRAY |
-        BBT_AUTO_REFRESH
-       },
+        NAND_IS_AND | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
 
        {NULL,}
 };
@@ -176,6 +175,9 @@ const struct nand_manufacturers nand_manuf_ids[] = {
        {NAND_MFR_STMICRO, "ST Micro"},
        {NAND_MFR_HYNIX, "Hynix"},
        {NAND_MFR_MICRON, "Micron"},
-       {NAND_MFR_AMD, "AMD"},
+       {NAND_MFR_AMD, "AMD/Spansion"},
+       {NAND_MFR_MACRONIX, "Macronix"},
+       {NAND_MFR_EON, "Eon"},
        {0x0, "Unknown"}
 };
+
index 4727f9c9892517df97b5951e88f11b384177ba01..d81972ca27baa9f851af9aa872da262386f31d2c 100644 (file)
@@ -121,7 +121,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
                WATCHDOG_RESET();
 
                if (!opts->scrub && bbtest) {
-                       int ret = meminfo->block_isbad(meminfo, erase.addr);
+                       int ret = mtd_block_isbad(meminfo, erase.addr);
                        if (ret > 0) {
                                if (!opts->quiet)
                                        printf("\rSkipping bad block at  "
@@ -144,7 +144,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
 
                erased_length++;
 
-               result = meminfo->erase(meminfo, &erase);
+               result = mtd_erase(meminfo, &erase);
                if (result != 0) {
                        printf("\n%s: MTD Erase failure: %d\n",
                               mtd_device, result);
@@ -153,15 +153,16 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
 
                /* format for JFFS2 ? */
                if (opts->jffs2 && chip->ecc.layout->oobavail >= 8) {
-                       chip->ops.ooblen = 8;
-                       chip->ops.datbuf = NULL;
-                       chip->ops.oobbuf = (uint8_t *)&cleanmarker;
-                       chip->ops.ooboffs = 0;
-                       chip->ops.mode = MTD_OOB_AUTO;
+                       struct mtd_oob_ops ops;
+                       ops.ooblen = 8;
+                       ops.datbuf = NULL;
+                       ops.oobbuf = (uint8_t *)&cleanmarker;
+                       ops.ooboffs = 0;
+                       ops.mode = MTD_OPS_AUTO_OOB;
 
-                       result = meminfo->write_oob(meminfo,
+                       result = mtd_write_oob(meminfo,
                                                    erase.addr,
-                                                   &chip->ops);
+                                                   &ops);
                        if (result != 0) {
                                printf("\n%s: MTD writeoob failure: %d\n",
                                       mtd_device, result);
@@ -458,7 +459,8 @@ static int check_skip_len(nand_info_t *nand, loff_t offset, size_t length,
 static size_t drop_ffs(const nand_info_t *nand, const u_char *buf,
                        const size_t *len)
 {
-       size_t i, l = *len;
+       size_t l = *len;
+       ssize_t i;
 
        for (i = l - 1; i >= 0; i--)
                if (buf[i] != 0xFF)
@@ -604,7 +606,7 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 
                        ops.len = pagesize;
                        ops.ooblen = nand->oobsize;
-                       ops.mode = MTD_OOB_AUTO;
+                       ops.mode = MTD_OPS_AUTO_OOB;
                        ops.ooboffs = 0;
 
                        pages = write_size / pagesize_oob;
@@ -614,7 +616,7 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
                                ops.datbuf = p_buffer;
                                ops.oobbuf = ops.datbuf + pagesize;
 
-                               rval = nand->write_oob(nand, offset, &ops);
+                               rval = mtd_write_oob(nand, offset, &ops);
                                if (rval != 0)
                                        break;
 
index 213d2c945a9a878d8bcd15ec5f16c219d240ba3d..94b90332d622acb518d3006857ca6e9ecba99dd7 100644 (file)
@@ -216,6 +216,7 @@ int board_nand_init(struct nand_chip *nand)
        nand->ecc.mode = NAND_ECC_HW;
        nand->ecc.size = 256;
        nand->ecc.bytes = 3;
+       nand->ecc.strength = 1;
        nand->select_chip = ndfc_select_chip;
 
 #ifdef CONFIG_SYS_NAND_BUSWIDTH_16BIT
index b76f4cbb5e6d43ab4217ddbdc15e6b735c7893f4..dc8e5137397d6035a024433b9a9c9e76e2d60737 100644 (file)
@@ -212,6 +212,7 @@ int board_nand_init(struct nand_chip *chip)
        chip->ecc.mode = NAND_ECC_HW;
        chip->ecc.bytes = 3;
        chip->ecc.size = 512;
+       chip->ecc.strength = 1;
        chip->ecc.layout = &nomadik_ecc_layout;
        chip->ecc.calculate = nomadik_ecc_calculate;
        chip->ecc.hwctl = nomadik_ecc_hwctl;
index bc1bcad3bad6d66576167dfb26add5651f959c7c..5d088227ea7024423bbabce0d078adc3f6fe6088 100644 (file)
@@ -590,11 +590,12 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
+ * @oob_required: caller expects OOB data read to chip->oob_poi
  * @page:      page number to read
  *
  */
 static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
-                               uint8_t *buf, int page)
+                               uint8_t *buf, int oob_required, int page)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -804,6 +805,7 @@ void omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
        nand->ecc.hwctl = NULL;
        nand->ecc.correct = NULL;
        nand->ecc.calculate = NULL;
+       nand->ecc.strength = eccstrength;
 
        /* Setup the ecc configurations again */
        if (hardware) {
@@ -901,7 +903,7 @@ int board_nand_init(struct nand_chip *nand)
        nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
 
        nand->cmd_ctrl = omap_nand_hwcontrol;
-       nand->options = NAND_NO_PADDING | NAND_CACHEPRG | NAND_NO_AUTOINCR;
+       nand->options = NAND_NO_PADDING | NAND_CACHEPRG;
        /* If we are 16 bit dev, our gpmc config tells us that */
        if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000)
                nand->options |= NAND_BUSWIDTH_16;
@@ -934,6 +936,7 @@ int board_nand_init(struct nand_chip *nand)
        nand->ecc.layout = &hw_bch8_nand_oob;
        nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
        nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
+       nand->ecc.strength = 8;
        nand->ecc.hwctl = omap_enable_ecc_bch;
        nand->ecc.correct = omap_correct_data_bch;
        nand->ecc.calculate = omap_calculate_ecc_bch;
@@ -952,6 +955,7 @@ int board_nand_init(struct nand_chip *nand)
        nand->ecc.hwctl = omap_enable_hwecc;
        nand->ecc.correct = omap_correct_data;
        nand->ecc.calculate = omap_calculate_ecc;
+       nand->ecc.strength = 1;
        omap_hwecc_init(nand);
 #endif
 #endif
index e1a459b009a283d0b287d2131b77753f88725831..43d8213e04a10b7c4add28d1d951fc013cf75ac2 100644 (file)
@@ -173,6 +173,7 @@ int board_nand_init(struct nand_chip *nand)
        nand->ecc.mode = NAND_ECC_HW;
        nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
        nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
+       nand->ecc.strength = 1;
 #else
        nand->ecc.mode = NAND_ECC_SOFT;
 #endif
index 4d94cc6f562819c98b0ca3801f31d5a39cdd6cb1..6afbec61ee2c506904e11421b1ce9176ed9a168f 100644 (file)
@@ -707,7 +707,7 @@ static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip,
  *             -EIO when command timeout
  */
 static int nand_read_page_hwecc(struct mtd_info *mtd,
-       struct nand_chip *chip, uint8_t *buf, int page)
+       struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
 {
        return nand_rw_page(mtd, chip, buf, page, 1, 0);
 }
@@ -719,8 +719,8 @@ static int nand_read_page_hwecc(struct mtd_info *mtd,
  * @param chip nand chip info structure
  * @param buf  data buffer
  */
-static void nand_write_page_hwecc(struct mtd_info *mtd,
-       struct nand_chip *chip, const uint8_t *buf)
+static int nand_write_page_hwecc(struct mtd_info *mtd,
+       struct nand_chip *chip, const uint8_t *buf, int oob_required)
 {
        int page;
        struct nand_drv *info;
@@ -731,6 +731,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd,
                (readl(&info->reg->addr_reg2) << 16);
 
        nand_rw_page(mtd, chip, (uint8_t *)buf, page, 1, 1);
+       return 0;
 }
 
 
@@ -746,7 +747,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd,
  *             -EIO when command timeout
  */
 static int nand_read_page_raw(struct mtd_info *mtd,
-       struct nand_chip *chip, uint8_t *buf, int page)
+       struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
 {
        return nand_rw_page(mtd, chip, buf, page, 0, 0);
 }
@@ -758,8 +759,8 @@ static int nand_read_page_raw(struct mtd_info *mtd,
  * @param chip nand chip info structure
  * @param buf  data buffer
  */
-static void nand_write_page_raw(struct mtd_info *mtd,
-               struct nand_chip *chip, const uint8_t *buf)
+static int nand_write_page_raw(struct mtd_info *mtd,
+               struct nand_chip *chip, const uint8_t *buf, int oob_required)
 {
        int page;
        struct nand_drv *info;
@@ -769,6 +770,7 @@ static void nand_write_page_raw(struct mtd_info *mtd,
                (readl(&info->reg->addr_reg2) << 16);
 
        nand_rw_page(mtd, chip, (uint8_t *)buf, page, 0, 1);
+       return 0;
 }
 
 /**
@@ -873,19 +875,13 @@ static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip,
  * @param mtd          mtd info structure
  * @param chip         nand chip info structure
  * @param page         page number to read
- * @param sndcmd       flag whether to issue read command or not
- * @return     1 - issue read command next time
- *             0 - not to issue
  */
 static int nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
-       int page, int sndcmd)
+       int page)
 {
-       if (sndcmd) {
-               chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
-               sndcmd = 0;
-       }
+       chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
        nand_rw_oob(mtd, chip, page, 0, 0);
-       return sndcmd;
+       return 0;
 }
 
 /**
@@ -1018,6 +1014,7 @@ int tegra_nand_init(struct nand_chip *nand, int devnum)
        nand->ecc.write_page_raw = nand_write_page_raw;
        nand->ecc.read_oob = nand_read_oob;
        nand->ecc.write_oob = nand_write_oob;
+       nand->ecc.strength = 1;
        nand->select_chip = nand_select_chip;
        nand->dev_ready  = nand_dev_ready;
        nand->priv = &nand_ctrl;
index 7e74be75f8195aaeeb4895db4bca6e0bf47b5403..622b8698083a067f60aaa3efd35d337213ecb09d 100644 (file)
@@ -224,7 +224,7 @@ enum {
 #define BCH_DEC_STATUS_MAX_CORR_CNT_MASK       (0x1f << 8)
 #define BCH_DEC_STATUS_PAGE_NUMBER_MASK                0xFF
 
-#define LP_OPTIONS (NAND_NO_READRDY | NAND_NO_AUTOINCR)
+#define LP_OPTIONS     0
 
 struct nand_ctlr {
        u32     command;        /* offset 00h */
index 858e322743b5f6e08677a0488d204024b5cd3e7a..ddfe7e7c756dbff2cb385d88e5bbc27b0a496369 100644 (file)
@@ -743,7 +743,7 @@ static void onenand_release_device(struct mtd_info *mtd)
 }
 
 /**
- * onenand_transfer_auto_oob - [Internal] oob auto-placement transfer
+ * onenand_transfer_auto_oob - [INTERN] oob auto-placement transfer
  * @param mtd          MTD device structure
  * @param buf          destination address
  * @param column       oob offset to read from
@@ -807,7 +807,7 @@ static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status)
                return status;
 
        /* check if we failed due to uncorrectable error */
-       if (status != -EBADMSG && status != ONENAND_BBT_READ_ECC_ERROR)
+       if (!mtd_is_eccerr(status) && status != ONENAND_BBT_READ_ECC_ERROR)
                return status;
 
        /* check if address lies in MLC region */
@@ -847,7 +847,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
 
        MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
 
-       if (ops->mode == MTD_OOB_AUTO)
+       if (ops->mode == MTD_OPS_AUTO_OOB)
                oobsize = this->ecclayout->oobavail;
        else
                oobsize = mtd->oobsize;
@@ -914,7 +914,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                        thisooblen = oobsize - oobcolumn;
                        thisooblen = min_t(int, thisooblen, ooblen - oobread);
 
-                       if (ops->mode == MTD_OOB_AUTO)
+                       if (ops->mode == MTD_OPS_AUTO_OOB)
                                onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
                        else
                                this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
@@ -929,7 +929,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                        if (unlikely(ret))
                                ret = onenand_recover_lsb(mtd, from, ret);
                        onenand_update_bufferram(mtd, from, !ret);
-                       if (ret == -EBADMSG)
+                       if (mtd_is_eccerr(ret))
                                ret = 0;
                }
 
@@ -950,7 +950,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                        /* Now wait for load */
                        ret = this->wait(mtd, FL_READING);
                        onenand_update_bufferram(mtd, from, !ret);
-                       if (ret == -EBADMSG)
+                       if (mtd_is_eccerr(ret))
                                ret = 0;
                }
        }
@@ -987,7 +987,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
        struct mtd_ecc_stats stats;
        int read = 0, thislen, column, oobsize;
        size_t len = ops->ooblen;
-       mtd_oob_mode_t mode = ops->mode;
+       unsigned int mode = ops->mode;
        u_char *buf = ops->oobbuf;
        int ret = 0, readcmd;
 
@@ -998,7 +998,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
        /* Initialize return length value */
        ops->oobretlen = 0;
 
-       if (mode == MTD_OOB_AUTO)
+       if (mode == MTD_OPS_AUTO_OOB)
                oobsize = this->ecclayout->oobavail;
        else
                oobsize = mtd->oobsize;
@@ -1041,7 +1041,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
                        break;
                }
 
-               if (mode == MTD_OOB_AUTO)
+               if (mode == MTD_OPS_AUTO_OOB)
                        onenand_transfer_auto_oob(mtd, buf, column, thislen);
                else
                        this->read_bufferram(mtd, 0, ONENAND_SPARERAM, buf, column, thislen);
@@ -1115,10 +1115,10 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from,
        int ret;
 
        switch (ops->mode) {
-       case MTD_OOB_PLACE:
-       case MTD_OOB_AUTO:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_AUTO_OOB:
                break;
-       case MTD_OOB_RAW:
+       case MTD_OPS_RAW:
                /* Not implemented yet */
        default:
                return -EINVAL;
@@ -1337,7 +1337,7 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr,
 #define NOTALIGNED(x)  ((x & (this->subpagesize - 1)) != 0)
 
 /**
- * onenand_fill_auto_oob - [Internal] oob auto-placement transfer
+ * onenand_fill_auto_oob - [INTERN] oob auto-placement transfer
  * @param mtd           MTD device structure
  * @param oob_buf       oob buffer
  * @param buf           source address
@@ -1404,19 +1404,13 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
        ops->retlen = 0;
        ops->oobretlen = 0;
 
-       /* Do not allow writes past end of device */
-       if (unlikely((to + len) > mtd->size)) {
-               printk(KERN_ERR "onenand_write_ops_nolock: Attempt write to past end of device\n");
-               return -EINVAL;
-       }
-
        /* Reject writes, which are not page aligned */
        if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
                printk(KERN_ERR "onenand_write_ops_nolock: Attempt to write not page aligned data\n");
                return -EINVAL;
        }
 
-       if (ops->mode == MTD_OOB_AUTO)
+       if (ops->mode == MTD_OPS_AUTO_OOB)
                oobsize = this->ecclayout->oobavail;
        else
                oobsize = mtd->oobsize;
@@ -1450,7 +1444,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
                        /* We send data to spare ram with oobsize
                         *                          * to prevent byte access */
                        memset(oobbuf, 0xff, mtd->oobsize);
-                       if (ops->mode == MTD_OOB_AUTO)
+                       if (ops->mode == MTD_OPS_AUTO_OOB)
                                onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
                        else
                                memcpy(oobbuf + oobcolumn, oob, thisooblen);
@@ -1502,7 +1496,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
 }
 
 /**
- * onenand_write_oob_nolock - [Internal] OneNAND write out-of-band
+ * onenand_write_oob_nolock - [INTERN] OneNAND write out-of-band
  * @param mtd           MTD device structure
  * @param to            offset to write to
  * @param len           number of bytes to write
@@ -1521,7 +1515,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
        u_char *oobbuf;
        size_t len = ops->ooblen;
        const u_char *buf = ops->oobbuf;
-       mtd_oob_mode_t mode = ops->mode;
+       unsigned int mode = ops->mode;
 
        to += ops->ooboffs;
 
@@ -1530,7 +1524,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
        /* Initialize retlen, in case of early exit */
        ops->oobretlen = 0;
 
-       if (mode == MTD_OOB_AUTO)
+       if (mode == MTD_OPS_AUTO_OOB)
                oobsize = this->ecclayout->oobavail;
        else
                oobsize = mtd->oobsize;
@@ -1571,7 +1565,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
                /* We send data to spare ram with oobsize
                 * to prevent byte access */
                memset(oobbuf, 0xff, mtd->oobsize);
-               if (mode == MTD_OOB_AUTO)
+               if (mode == MTD_OPS_AUTO_OOB)
                        onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
                else
                        memcpy(oobbuf + column, buf, thislen);
@@ -1661,10 +1655,10 @@ int onenand_write_oob(struct mtd_info *mtd, loff_t to,
        int ret;
 
        switch (ops->mode) {
-       case MTD_OOB_PLACE:
-       case MTD_OOB_AUTO:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_AUTO_OOB:
                break;
-       case MTD_OOB_RAW:
+       case MTD_OPS_RAW:
                /* Not implemented yet */
        default:
                return -EINVAL;
@@ -1720,13 +1714,6 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
        MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n",
                        (unsigned int) addr, len);
 
-       /* Do not allow erase past end of device */
-       if (unlikely((len + addr) > mtd->size)) {
-               MTDDEBUG(MTD_DEBUG_LEVEL0, "onenand_erase:"
-                                       "Erase past end of device\n");
-               return -EINVAL;
-       }
-
        if (FLEXONENAND(this)) {
                /* Find the eraseregion of this address */
                i = flexonenand_region(mtd, addr);
@@ -1762,8 +1749,6 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
                return -EINVAL;
        }
 
-       instr->fail_addr = 0xffffffff;
-
        /* Grab the lock and see if the device is available */
        onenand_get_device(mtd, FL_ERASING);
 
@@ -1889,7 +1874,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
        struct bbm_info *bbm = this->bbm;
        u_char buf[2] = {0, 0};
        struct mtd_oob_ops ops = {
-               .mode = MTD_OOB_PLACE,
+               .mode = MTD_OPS_PLACE_OOB,
                .ooblen = 2,
                .oobbuf = buf,
                .ooboffs = 0,
@@ -1915,7 +1900,6 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
  */
 int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
-       struct onenand_chip *this = mtd->priv;
        int ret;
 
        ret = onenand_block_isbad(mtd, ofs);
@@ -1926,7 +1910,7 @@ int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
                return ret;
        }
 
-       ret = this->block_markbad(mtd, ofs);
+       ret = mtd_block_markbad(mtd, ofs);
        return ret;
 }
 
@@ -2386,7 +2370,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd,
        int i, ret;
        int block;
        struct mtd_oob_ops ops = {
-               .mode = MTD_OOB_PLACE,
+               .mode = MTD_OPS_PLACE_OOB,
                .ooboffs = 0,
                .ooblen = mtd->oobsize,
                .datbuf = NULL,
@@ -2645,14 +2629,14 @@ int onenand_probe(struct mtd_info *mtd)
                mtd->size = this->chipsize;
 
        mtd->flags = MTD_CAP_NANDFLASH;
-       mtd->erase = onenand_erase;
-       mtd->read = onenand_read;
-       mtd->write = onenand_write;
-       mtd->read_oob = onenand_read_oob;
-       mtd->write_oob = onenand_write_oob;
-       mtd->sync = onenand_sync;
-       mtd->block_isbad = onenand_block_isbad;
-       mtd->block_markbad = onenand_block_markbad;
+       mtd->_erase = onenand_erase;
+       mtd->_read = onenand_read;
+       mtd->_write = onenand_write;
+       mtd->_read_oob = onenand_read_oob;
+       mtd->_write_oob = onenand_write_oob;
+       mtd->_sync = onenand_sync;
+       mtd->_block_isbad = onenand_block_isbad;
+       mtd->_block_markbad = onenand_block_markbad;
 
        return 0;
 }
index 9d5da54708ec9ed9db9c83eff0b9939adb6d90bd..0267c2c5c90a8b7f8b0bba69422638e625c22c0c 100644 (file)
@@ -87,7 +87,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
        startblock = 0;
        from = 0;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooblen = readlen;
        ops.oobbuf = buf;
        ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
@@ -200,10 +200,8 @@ int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        len = this->chipsize >> (this->erase_shift + 2);
        /* Allocate memory (2bit per block) */
        bbm->bbt = malloc(len);
-       if (!bbm->bbt) {
-               printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
+       if (!bbm->bbt)
                return -ENOMEM;
-       }
        /* Clear the memory bad block table */
        memset(bbm->bbt, 0x00, len);
 
index dad30b54c54e97547f13c14039483da30e1eb409..b3ef90f136367e954aaf08a2477f9c17810fd620 100644 (file)
@@ -89,6 +89,13 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = {
                .nr_sectors = 64,
                .name = "S25FL032P",
        },
+       {
+               .idcode1 = 0x0216,
+               .idcode2 = 0x4d00,
+               .pages_per_sector = 256,
+               .nr_sectors = 128,
+               .name = "S25FL064P",
+       },
        {
                .idcode1 = 0x2018,
                .idcode2 = 0x4d01,
@@ -101,7 +108,7 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = {
                .idcode2 = 0x4d01,
                .pages_per_sector = 256,
                .nr_sectors = 512,
-               .name = "S25FL256S",
+               .name = "S25FL256S_64K",
        },
 };
 
index 6507aa34bb4e82de466fa04eca7e6e303b22fedd..9991d47a468e0a07f323213de933c793f5257632 100644 (file)
@@ -124,9 +124,6 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
                }
        }
 
-       debug("SF: program %s %zu bytes @ %#x\n",
-             ret ? "failure" : "success", len, offset);
-
        spi_release_bus(flash->spi);
        return ret;
 }
@@ -150,8 +147,10 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
        u8 cmd[5];
 
        /* Handle memory-mapped SPI */
-       if (flash->memory_map)
+       if (flash->memory_map) {
                memcpy(data, flash->memory_map + offset, len);
+               return 0;
+       }
 
        cmd[0] = CMD_READ_ARRAY_FAST;
        spi_flash_addr(offset, cmd);
@@ -205,7 +204,7 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
 
 int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
-       u32 start, end, erase_size;
+       u32 end, erase_size;
        int ret;
        u8 cmd[4];
 
@@ -225,8 +224,7 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
                cmd[0] = CMD_ERASE_4K;
        else
                cmd[0] = CMD_ERASE_64K;
-       start = offset;
-       end = start + len;
+       end = offset + len;
 
        while (offset < end) {
                spi_flash_addr(offset, cmd);
@@ -248,8 +246,6 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
                        goto out;
        }
 
-       debug("SF: Successfully erased %zu bytes @ %#x\n", len, start);
-
  out:
        spi_release_bus(flash->spi);
        return ret;
index 27162091c5ac69e4cfe8af4fc7d4f4944391c0a5..845780849273078251da183bf66e50659a95e42d 100644 (file)
@@ -17,6 +17,21 @@ struct winbond_spi_flash_params {
 };
 
 static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
+       {
+               .id                     = 0x2014,
+               .nr_blocks              = 16,
+               .name                   = "W25P80",
+       },
+       {
+               .id                     = 0x2015,
+               .nr_blocks              = 32,
+               .name                   = "W25P16",
+       },
+       {
+               .id                     = 0x2016,
+               .nr_blocks              = 64,
+               .name                   = "W25P32",
+       },
        {
                .id                     = 0x3013,
                .nr_blocks              = 8,
@@ -62,14 +77,19 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
                .nr_blocks              = 256,
                .name                   = "W25Q128",
        },
+       {
+               .id                     = 0x4019,
+               .nr_blocks              = 512,
+               .name                   = "W25Q256",
+       },
        {
                .id                     = 0x5014,
-               .nr_blocks              = 128,
-               .name                   = "W25Q80",
+               .nr_blocks              = 16,
+               .name                   = "W25Q80BW",
        },
        {
                .id                     = 0x6016,
-               .nr_blocks              = 512,
+               .nr_blocks              = 64,
                .name                   = "W25Q32DW",
        },
        {
@@ -104,7 +124,7 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
        }
 
        flash->page_size = 256;
-       flash->sector_size = 4096;
+       flash->sector_size = (idcode[1] == 0x20) ? 65536 : 4096;
        flash->size = 4096 * 16 * params->nr_blocks;
 
        return flash;
index a708162e43a826846584cf1440a0d783bbd4a53a..25888220df287e99a673a6a95c97de5af76c8b4b 100644 (file)
@@ -539,7 +539,7 @@ static int io_init(struct ubi_device *ubi)
        ubi->peb_count  = mtd_div_by_eb(ubi->mtd->size, ubi->mtd);
        ubi->flash_size = ubi->mtd->size;
 
-       if (ubi->mtd->block_isbad && ubi->mtd->block_markbad)
+       if (mtd_can_have_bb(ubi->mtd))
                ubi->bad_allowed = 1;
 
        ubi->min_io_size = ubi->mtd->writesize;
index d523c94b129df74a30ae32744847540320c83362..d2d3c9c5805d1b21fb5a3c79b183968572ee22e5 100644 (file)
@@ -460,7 +460,7 @@ retry:
                if (err == UBI_IO_BITFLIPS) {
                        scrub = 1;
                        err = 0;
-               } else if (err == -EBADMSG) {
+               } else if (mtd_is_eccerr(err)) {
                        if (vol->vol_type == UBI_DYNAMIC_VOLUME)
                                goto out_unlock;
                        scrub = 1;
index 8423894000bcc41597c47c80992bbe7134164fec..05de9aeb6eea6c25b7001a5b6c783383edf1ca7f 100644 (file)
@@ -154,7 +154,7 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
 
        addr = (loff_t)pnum * ubi->peb_size + offset;
 retry:
-       err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
+       err = mtd_read(ubi->mtd, addr, len, &read, buf);
        if (err) {
                if (err == -EUCLEAN) {
                        /*
@@ -268,7 +268,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
        }
 
        addr = (loff_t)pnum * ubi->peb_size + offset;
-       err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf);
+       err = mtd_write(ubi->mtd, addr, len, &written, buf);
        if (err) {
                ubi_err("error %d while writing %d bytes to PEB %d:%d, written"
                        " %zd bytes", err, len, pnum, offset, written);
@@ -318,7 +318,7 @@ retry:
        ei.callback = erase_callback;
        ei.priv     = (unsigned long)&wq;
 
-       err = ubi->mtd->erase(ubi->mtd, &ei);
+       err = mtd_erase(ubi->mtd, &ei);
        if (err) {
                if (retries++ < UBI_IO_RETRIES) {
                        dbg_io("error %d while erasing PEB %d, retry",
@@ -516,7 +516,7 @@ int ubi_io_is_bad(const struct ubi_device *ubi, int pnum)
        if (ubi->bad_allowed) {
                int ret;
 
-               ret = mtd->block_isbad(mtd, (loff_t)pnum * ubi->peb_size);
+               ret = mtd_block_isbad(mtd, (loff_t)pnum * ubi->peb_size);
                if (ret < 0)
                        ubi_err("error %d while checking if PEB %d is bad",
                                ret, pnum);
@@ -551,7 +551,7 @@ int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum)
        if (!ubi->bad_allowed)
                return 0;
 
-       err = mtd->block_markbad(mtd, (loff_t)pnum * ubi->peb_size);
+       err = mtd_block_markbad(mtd, (loff_t)pnum * ubi->peb_size);
        if (err)
                ubi_err("cannot mark PEB %d bad, error %d", pnum, err);
        return err;
@@ -1242,7 +1242,7 @@ static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
        loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
 
        mutex_lock(&ubi->dbg_buf_mutex);
-       err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf);
+       err = mtd_read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf);
        if (err && err != -EUCLEAN) {
                ubi_err("error %d while reading %d bytes from PEB %d:%d, "
                        "read %zd bytes", err, len, pnum, offset, read);
index 423d479152f367fdb25d7fec024fe23421d1dd53..e553188797cd8a41a924cf05484b32fd060e734a 100644 (file)
@@ -349,7 +349,7 @@ int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
                return 0;
 
        err = ubi_eba_read_leb(ubi, vol, lnum, buf, offset, len, check);
-       if (err && err == -EBADMSG && vol->vol_type == UBI_STATIC_VOLUME) {
+       if (err && mtd_is_eccerr(err) && vol->vol_type == UBI_STATIC_VOLUME) {
                ubi_warn("mark volume %d as corrupted", vol_id);
                vol->corrupted = 1;
        }
index a6410bfb6bce4f82211cbdd8ee54401dadedbc77..e8660d997037e995bd5cfa9a4f14b4d3b6f4b5d3 100644 (file)
@@ -82,7 +82,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id)
 
                err = ubi_eba_read_leb(ubi, vol, i, buf, 0, size, 1);
                if (err) {
-                       if (err == -EBADMSG)
+                       if (mtd_is_eccerr(err))
                                err = 1;
                        break;
                }
index f679f06494b6c79f355976826695693aead1efd0..29d23200104a26e0a4ea552750e0890e6e2fe03d 100644 (file)
@@ -388,7 +388,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
 
                err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0,
                                       ubi->vtbl_size);
-               if (err == UBI_IO_BITFLIPS || err == -EBADMSG)
+               if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err))
                        /*
                         * Scrub the PEB later. Note, -EBADMSG indicates an
                         * uncorrectable ECC error, but we have our own CRC and
index 1ae35d360bab7250854658ca77efbdec68fca86e..14999447b17d9a8515ecb766c971fc024f33a8c3 100644 (file)
@@ -26,7 +26,8 @@ include $(TOPDIR)/config.mk
 LIB    := $(obj)libpci.o
 
 COBJS-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o
-COBJS-$(CONFIG_PCI) += pci.o pci_auto.o pci_indirect.o
+COBJS-$(CONFIG_PCI) += pci.o pci_auto.o
+COBJS-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o
 COBJS-$(CONFIG_FTPCI100) += pci_ftpci100.o
 COBJS-$(CONFIG_IXP_PCI) += pci_ixp.o
 COBJS-$(CONFIG_SH4_PCI) += pci_sh4.o
index 77ac1f7c7b9a1a8452c064dc6abfd39fb3785ec8..621c899120af29bb4a77adbbc75423075d70f9b9 100644 (file)
@@ -211,7 +211,7 @@ static int fsl_pci_setup_inbound_windows(struct pci_controller *hose,
        return 1;
 }
 
-#ifdef CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
+#ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
 static void fsl_pcie_boot_master(pit_t *pi)
 {
        /* configure inbound window for slave's u-boot image */
@@ -388,7 +388,7 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info)
        /* see if we are a PCIe or PCI controller */
        pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
 
-#ifdef CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
+#ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
        /* boot from PCIE --master */
        char *s = getenv("bootmaster");
        char pcie[6];
@@ -624,7 +624,7 @@ int fsl_pci_init_port(struct fsl_pci_info *pci_info,
        if (fsl_is_pci_agent(hose)) {
                fsl_pci_config_unlock(hose);
                hose->last_busno = hose->first_busno;
-#ifdef CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
+#ifdef CONFIG_SRIO_PCIE_BOOT_MASTER
        } else {
                /* boot from PCIE --master releases slave's core 0 */
                char *s = getenv("bootmaster");
index afdbe0508ca1c0db7cc88237e45288c626f8e304..b237c7c0feac747eeaf8649e65ab8fba3407bdbb 100644 (file)
@@ -182,15 +182,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
                goto done;
        }
 
-       if (dout)
-               pss->tx = dout;
-       else
-               pss->tx = NULL;
-
-       if (din)
-               pss->rx = din;
-       else
-               pss->rx = NULL;
+       pss->tx = dout;
+       pss->rx = din;
 
        if (flags & SPI_XFER_BEGIN) {
                spi_cs_activate(slave);
index 607e1cdec2f9dc774693b6a23ecfe05f14aef06d..01378d098e53cf7065425bd4d83a5a38415ba4d5 100644 (file)
@@ -51,6 +51,7 @@ struct exynos_spi_slave {
        unsigned int mode;
        enum periph_id periph_id;       /* Peripheral ID for this device */
        unsigned int fifo_size;
+       int skip_preamble;
 };
 
 static struct spi_bus *spi_get_bus(unsigned dev_index)
@@ -105,6 +106,8 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
        else
                spi_slave->fifo_size = 256;
 
+       spi_slave->skip_preamble = 0;
+
        spi_slave->freq = bus->frequency;
        if (max_hz)
                spi_slave->freq = min(max_hz, spi_slave->freq);
@@ -217,17 +220,23 @@ static void spi_request_bytes(struct exynos_spi *regs, int count)
        writel(count | SPI_PACKET_CNT_EN, &regs->pkt_cnt);
 }
 
-static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
-                       void **dinp, void const **doutp)
+static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
+                       void **dinp, void const **doutp, unsigned long flags)
 {
        struct exynos_spi *regs = spi_slave->regs;
        uchar *rxp = *dinp;
        const uchar *txp = *doutp;
        int rx_lvl, tx_lvl;
        uint out_bytes, in_bytes;
+       int toread;
+       unsigned start = get_timer(0);
+       int stopping;
 
        out_bytes = in_bytes = todo;
 
+       stopping = spi_slave->skip_preamble && (flags & SPI_XFER_END) &&
+                                       !(spi_slave->mode & SPI_SLAVE);
+
        /*
         * If there's something to send, do a software reset and set a
         * transaction size.
@@ -238,6 +247,8 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
         * Bytes are transmitted/received in pairs. Wait to receive all the
         * data because then transmission will be done as well.
         */
+       toread = in_bytes;
+
        while (in_bytes) {
                int temp;
 
@@ -248,15 +259,43 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
                        writel(temp, &regs->tx_data);
                        out_bytes--;
                }
-               if (rx_lvl > 0 && in_bytes) {
+               if (rx_lvl > 0) {
                        temp = readl(&regs->rx_data);
-                       if (rxp)
-                               *rxp++ = temp;
-                       in_bytes--;
+                       if (spi_slave->skip_preamble) {
+                               if (temp == SPI_PREAMBLE_END_BYTE) {
+                                       spi_slave->skip_preamble = 0;
+                                       stopping = 0;
+                               }
+                       } else {
+                               if (rxp || stopping)
+                                       *rxp++ = temp;
+                               in_bytes--;
+                       }
+                       toread--;
+               } else if (!toread) {
+                       /*
+                        * We have run out of input data, but haven't read
+                        * enough bytes after the preamble yet. Read some more,
+                        * and make sure that we transmit dummy bytes too, to
+                        * keep things going.
+                        */
+                       assert(!out_bytes);
+                       out_bytes = in_bytes;
+                       toread = in_bytes;
+                       txp = NULL;
+                       spi_request_bytes(regs, toread);
+               }
+               if (spi_slave->skip_preamble && get_timer(start) > 100) {
+                       printf("SPI timeout: in_bytes=%d, out_bytes=%d, ",
+                              in_bytes, out_bytes);
+                       return -1;
                }
        }
+
        *dinp = rxp;
        *doutp = txp;
+
+       return 0;
 }
 
 /**
@@ -276,6 +315,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
        struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
        int upto, todo;
        int bytelen;
+       int ret = 0;
 
        /* spi core configured to do 8 bit transfers */
        if (bitlen % 8) {
@@ -289,16 +329,24 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
 
        /* Exynos SPI limits each transfer to 65535 bytes */
        bytelen =  bitlen / 8;
-       for (upto = 0; upto < bytelen; upto += todo) {
+       for (upto = 0; !ret && upto < bytelen; upto += todo) {
                todo = min(bytelen - upto, (1 << 16) - 1);
-               spi_rx_tx(spi_slave, todo, &din, &dout);
+               ret = spi_rx_tx(spi_slave, todo, &din, &dout, flags);
+               if (ret)
+                       break;
        }
 
        /* Stop the transaction, if necessary. */
-       if ((flags & SPI_XFER_END))
+       if ((flags & SPI_XFER_END) && !(spi_slave->mode & SPI_SLAVE)) {
                spi_cs_deactivate(slave);
+               if (spi_slave->skip_preamble) {
+                       assert(!spi_slave->skip_preamble);
+                       debug("Failed to complete premable transaction\n");
+                       ret = -1;
+               }
+       }
 
-       return 0;
+       return ret;
 }
 
 /**
@@ -325,6 +373,7 @@ void spi_cs_activate(struct spi_slave *slave)
 
        clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
        debug("Activate CS, bus %d\n", spi_slave->slave.bus);
+       spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE;
 }
 
 /**
index b11a0a1ff7c8a190e22e543c041d04b0556a14d7..4d2af483d77f07688e6a4297a1ad952ea0d9a99a 100644 (file)
@@ -152,13 +152,11 @@ struct spi_slave *tegra114_spi_setup_slave(unsigned int bus, unsigned int cs,
                return NULL;
        }
 
-       spi = malloc(sizeof(struct tegra_spi_slave));
+       spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs);
        if (!spi) {
                printf("SPI error: malloc of SPI structure failed\n");
                return NULL;
        }
-       spi->slave.bus = bus;
-       spi->slave.cs = cs;
        spi->ctrl = &spi_ctrls[bus];
        if (!spi->ctrl) {
                printf("SPI error: could not find controller for bus %d\n",
index 9322ce7f64102b61100039feb071716f243ab65e..7c3a3fc35b1aec9ae445af9e9cbe40c20c102e89 100644 (file)
@@ -132,8 +132,6 @@ struct spi_slave *tegra20_spi_setup_slave(unsigned int bus, unsigned int cs,
                printf("SPI error: malloc of SPI structure failed\n");
                return NULL;
        }
-       spi->slave.bus = bus;
-       spi->slave.cs = cs;
        spi->ctrl = &spi_ctrls[bus];
        if (!spi->ctrl) {
                printf("SPI error: could not find controller for bus %d\n",
index e8c159c0f3fee868c68c42a34e35799e87ce7c25..913dd9c8620199e7a9fa6b3464258022446c7f41 100644 (file)
@@ -25,9 +25,10 @@ LIB := $(obj)libtpm.o
 
 $(shell mkdir -p $(obj)slb9635_i2c)
 
-COBJS-$(CONFIG_GENERIC_LPC_TPM) = generic_lpc_tpm.o
-COBJS-$(CONFIG_INFINEON_TPM_I2C) += tis_i2c.o slb9635_i2c/tpm.o
-COBJS-$(CONFIG_INFINEON_TPM_I2C) += slb9635_i2c/tpm_tis_i2c.o
+# TODO: Merge tpm_tis_lpc.c with tpm.c
+COBJS-$(CONFIG_TPM_TIS_I2C) += tpm.o
+COBJS-$(CONFIG_TPM_TIS_I2C) += tpm_tis_i2c.o
+COBJS-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
 
 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
index e818fbaf541808953c60c62e7b348b7f002b055e..22554e1456b345fa5511131616dec7469d86caa3 100644 (file)
@@ -67,6 +67,10 @@ static int tpm_decode_config(struct tpm *dev)
        int i2c_bus;
 
        node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
+       if (node < 0) {
+               node = fdtdec_next_compatible(blob, 0,
+                                             COMPAT_INFINEON_SLB9645_TPM);
+       }
        if (node < 0) {
                debug("%s: Node not found\n", __func__);
                return -1;
similarity index 63%
rename from drivers/tpm/slb9635_i2c/tpm.c
rename to drivers/tpm/tpm.c
index 496c48e8cf9bed01843fcce41868e32df2dd5f6f..b6573341956d6d0d4ffc76239b1bf71da550a8f9 100644 (file)
  * MA 02111-1307 USA
  */
 
-#include <malloc.h>
-#include "tpm.h"
+#include <config.h>
+#include <common.h>
+#include <compiler.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <tpm.h>
+#include <asm-generic/errno.h>
+#include <linux/types.h>
+#include <linux/unaligned/be_byteshift.h>
 
-/* global structure for tpm chip data */
-struct tpm_chip g_chip;
+#include "tpm_private.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* TPM configuration */
+struct tpm {
+       int i2c_bus;
+       int slave_addr;
+       char inited;
+       int old_bus;
+} tpm;
+
+/* Global structure for tpm chip data */
+static struct tpm_chip g_chip;
 
 enum tpm_duration {
        TPM_SHORT = 0,
@@ -45,9 +64,18 @@ enum tpm_duration {
        TPM_UNDEFINED,
 };
 
-#define TPM_MAX_ORDINAL 243
-#define TPM_MAX_PROTECTED_ORDINAL 12
-#define TPM_PROTECTED_ORDINAL_MASK 0xFF
+/* Extended error numbers from linux (see errno.h) */
+#define ECANCELED      125     /* Operation Canceled */
+
+/* Timer frequency. Corresponds to msec timer resolution*/
+#define HZ             1000
+
+#define TPM_MAX_ORDINAL                        243
+#define TPM_MAX_PROTECTED_ORDINAL      12
+#define TPM_PROTECTED_ORDINAL_MASK     0xFF
+
+#define TPM_CMD_COUNT_BYTE     2
+#define TPM_CMD_ORDINAL_BYTE   6
 
 /*
  * Array with one entry per ordinal defining the maximum amount
@@ -318,34 +346,31 @@ static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
        TPM_MEDIUM,
 };
 
-/*
- * Returns max number of milliseconds to wait
- */
-unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
+/* Returns max number of milliseconds to wait */
+static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
+               u32 ordinal)
 {
        int duration_idx = TPM_UNDEFINED;
        int duration = 0;
 
-       if (ordinal < TPM_MAX_ORDINAL)
+       if (ordinal < TPM_MAX_ORDINAL) {
                duration_idx = tpm_ordinal_duration[ordinal];
-       else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
-                TPM_MAX_PROTECTED_ORDINAL)
-               duration_idx =
-                   tpm_protected_ordinal_duration[ordinal &
-                                                  TPM_PROTECTED_ORDINAL_MASK];
+       else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
+                       TPM_MAX_PROTECTED_ORDINAL) {
+               duration_idx = tpm_protected_ordinal_duration[
+                               ordinal & TPM_PROTECTED_ORDINAL_MASK];
+       }
 
        if (duration_idx != TPM_UNDEFINED)
                duration = chip->vendor.duration[duration_idx];
+
        if (duration <= 0)
-               return 2 * 60 * HZ; /*two minutes timeout*/
+               return 2 * 60 * HZ; /* Two minutes timeout */
        else
                return duration;
 }
 
-#define TPM_CMD_COUNT_BYTE 2
-#define TPM_CMD_ORDINAL_BYTE 6
-
-ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
+static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 {
        ssize_t rc;
        u32 count, ordinal;
@@ -358,18 +383,17 @@ ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
        ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
 
        if (count == 0) {
-               dev_err(chip->dev, "no data\n");
+               error("no data\n");
                return -ENODATA;
        }
        if (count > bufsiz) {
-               dev_err(chip->dev,
-                       "invalid count value %x %zx\n", count, bufsiz);
+               error("invalid count value %x %zx\n", count, bufsiz);
                return -E2BIG;
        }
 
        rc = chip->vendor.send(chip, (u8 *)buf, count);
        if (rc < 0) {
-               dev_err(chip->dev, "tpm_transmit: tpm_send: error %zd\n", rc);
+               error("tpm_transmit: tpm_send: error %zd\n", rc);
                goto out;
        }
 
@@ -379,47 +403,126 @@ ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
        start = get_timer(0);
        stop = tpm_calc_ordinal_duration(chip, ordinal);
        do {
-               dbg_printf("waiting for status...\n");
+               debug("waiting for status...\n");
                u8 status = chip->vendor.status(chip);
                if ((status & chip->vendor.req_complete_mask) ==
                    chip->vendor.req_complete_val) {
-                       dbg_printf("...got it;\n");
+                       debug("...got it;\n");
                        goto out_recv;
                }
 
                if ((status == chip->vendor.req_canceled)) {
-                       dev_err(chip->dev, "Operation Canceled\n");
+                       error("Operation Canceled\n");
                        rc = -ECANCELED;
                        goto out;
                }
-               msleep(TPM_TIMEOUT);
+               udelay(TPM_TIMEOUT * 1000);
        } while (get_timer(start) < stop);
 
        chip->vendor.cancel(chip);
-       dev_err(chip->dev, "Operation Timed out\n");
+       error("Operation Timed out\n");
        rc = -ETIME;
        goto out;
 
 out_recv:
-
-       dbg_printf("out_recv: reading response...\n");
+       debug("out_recv: reading response...\n");
        rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
        if (rc < 0)
-               dev_err(chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc);
+               error("tpm_transmit: tpm_recv: error %zd\n", rc);
+
 out:
        return rc;
 }
 
-#define TPM_ERROR_SIZE 10
+static int tpm_open(uint32_t dev_addr)
+{
+       int rc;
+       if (g_chip.is_open)
+               return -EBUSY;
+       rc = tpm_vendor_init(dev_addr);
+       if (rc < 0)
+               g_chip.is_open = 0;
+       return rc;
+}
 
-enum tpm_capabilities {
-       TPM_CAP_PROP = cpu_to_be32(5),
-};
+static void tpm_close(void)
+{
+       if (g_chip.is_open) {
+               tpm_vendor_cleanup(&g_chip);
+               g_chip.is_open = 0;
+       }
+}
 
-enum tpm_sub_capabilities {
-       TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
-       TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
-};
+static int tpm_select(void)
+{
+       int ret;
+
+       tpm.old_bus = i2c_get_bus_num();
+       if (tpm.old_bus != tpm.i2c_bus) {
+               ret = i2c_set_bus_num(tpm.i2c_bus);
+               if (ret) {
+                       debug("%s: Fail to set i2c bus %d\n", __func__,
+                             tpm.i2c_bus);
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+static int tpm_deselect(void)
+{
+       int ret;
+
+       if (tpm.old_bus != i2c_get_bus_num()) {
+               ret = i2c_set_bus_num(tpm.old_bus);
+               if (ret) {
+                       debug("%s: Fail to restore i2c bus %d\n",
+                             __func__, tpm.old_bus);
+                       return -1;
+               }
+       }
+       tpm.old_bus = -1;
+       return 0;
+}
+
+/**
+ * Decode TPM configuration.
+ *
+ * @param dev  Returns a configuration of TPM device
+ * @return 0 if ok, -1 on error
+ */
+static int tpm_decode_config(struct tpm *dev)
+{
+#ifdef CONFIG_OF_CONTROL
+       const void *blob = gd->fdt_blob;
+       int node, parent;
+       int i2c_bus;
+
+       node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
+       if (node < 0) {
+               node = fdtdec_next_compatible(blob, 0,
+                               COMPAT_INFINEON_SLB9645_TPM);
+       }
+       if (node < 0) {
+               debug("%s: Node not found\n", __func__);
+               return -1;
+       }
+       parent = fdt_parent_offset(blob, node);
+       if (parent < 0) {
+               debug("%s: Cannot find node parent\n", __func__);
+               return -1;
+       }
+       i2c_bus = i2c_get_bus_num_fdt(parent);
+       if (i2c_bus < 0)
+               return -1;
+       dev->i2c_bus = i2c_bus;
+       dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
+#else
+       dev->i2c_bus = CONFIG_TPM_TIS_I2C_BUS_NUMBER;
+       dev->slave_addr = CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS;
+#endif
+       return 0;
+}
 
 struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
 {
@@ -433,21 +536,94 @@ struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
        return chip;
 }
 
-int tpm_open(uint32_t dev_addr)
+int tis_init(void)
+{
+       if (tpm.inited)
+               return 0;
+
+       if (tpm_decode_config(&tpm))
+               return -1;
+
+       if (tpm_select())
+               return -1;
+
+       /*
+        * Probe TPM twice; the first probing might fail because TPM is asleep,
+        * and the probing can wake up TPM.
+        */
+       if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) {
+               debug("%s: fail to probe i2c addr 0x%x\n", __func__,
+                     tpm.slave_addr);
+               return -1;
+       }
+
+       tpm_deselect();
+
+       tpm.inited = 1;
+
+       return 0;
+}
+
+int tis_open(void)
 {
        int rc;
-       if (g_chip.is_open)
-               return -EBUSY;
-       rc = tpm_vendor_init(dev_addr);
-       if (rc < 0)
-               g_chip.is_open = 0;
+
+       if (!tpm.inited)
+               return -1;
+
+       if (tpm_select())
+               return -1;
+
+       rc = tpm_open(tpm.slave_addr);
+
+       tpm_deselect();
+
        return rc;
 }
 
-void tpm_close(void)
+int tis_close(void)
 {
-       if (g_chip.is_open) {
-               tpm_vendor_cleanup(&g_chip);
-               g_chip.is_open = 0;
+       if (!tpm.inited)
+               return -1;
+
+       if (tpm_select())
+               return -1;
+
+       tpm_close();
+
+       tpm_deselect();
+
+       return 0;
+}
+
+int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
+               uint8_t *recvbuf, size_t *rbuf_len)
+{
+       int len;
+       uint8_t buf[4096];
+
+       if (!tpm.inited)
+               return -1;
+
+       if (sizeof(buf) < sbuf_size)
+               return -1;
+
+       memcpy(buf, sendbuf, sbuf_size);
+
+       if (tpm_select())
+               return -1;
+
+       len = tpm_transmit(buf, sbuf_size);
+
+       tpm_deselect();
+
+       if (len < 10) {
+               *rbuf_len = 0;
+               return -1;
        }
+
+       memcpy(recvbuf, buf, len);
+       *rbuf_len = len;
+
+       return 0;
 }
similarity index 71%
rename from drivers/tpm/slb9635_i2c/tpm.h
rename to drivers/tpm/tpm_private.h
index 9ddee865df605cd6444a730201a89c61068cc160..888a074d35ab78a55e6667cf8e131372ed267038 100644 (file)
  * MA 02111-1307 USA
  */
 
-#ifndef _TPM_H_
-#define _TPM_H_
+#ifndef _TPM_PRIVATE_H_
+#define _TPM_PRIVATE_H_
 
 #include <linux/compiler.h>
-
-#include "compatibility.h"
+#include <linux/types.h>
 
 enum tpm_timeout {
        TPM_TIMEOUT = 5,        /* msecs */
@@ -47,13 +46,9 @@ enum tpm_timeout {
 /* Size of external transmit buffer (used in tpm_transmit)*/
 #define TPM_BUFSIZE 4096
 
-/* Index of fields in TPM command buffer */
-#define TPM_CMD_SIZE_BYTE 2
-#define TPM_CMD_ORDINAL_BYTE 6
-
 /* Index of Count field in TPM response buffer */
-#define TPM_RSP_SIZE_BYTE 2
-#define TPM_RSP_RC_BYTE 6
+#define TPM_RSP_SIZE_BYTE      2
+#define TPM_RSP_RC_BYTE                6
 
 struct tpm_chip;
 
@@ -65,10 +60,10 @@ struct tpm_vendor_specific {
        int (*recv) (struct tpm_chip *, u8 *, size_t);
        int (*send) (struct tpm_chip *, u8 *, size_t);
        void (*cancel) (struct tpm_chip *);
-        u8(*status) (struct tpm_chip *);
+       u8(*status) (struct tpm_chip *);
        int locality;
-       unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
-       unsigned long duration[3];      /* msec */
+       unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
+       unsigned long duration[3];  /* msec */
 };
 
 struct tpm_chip {
@@ -132,30 +127,11 @@ struct tpm_cmd_t {
        union tpm_cmd_params params;
 } __packed;
 
+struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
 
-/* ---------- Interface for TPM vendor ------------ */
-
-extern struct tpm_chip *tpm_register_hardware(
-       const struct tpm_vendor_specific *);
+int tpm_vendor_init(uint32_t dev_addr);
 
-extern int tpm_vendor_init(uint32_t dev_addr);
+void tpm_vendor_cleanup(struct tpm_chip *chip);
 
-extern void tpm_vendor_cleanup(struct tpm_chip *chip);
-
-/* ---------- Interface for TDDL ------------------- */
-
-/*
- * if dev_addr != 0 - redefines TPM device address
- * Returns < 0 on error, 0 on success.
- */
-extern int tpm_open(uint32_t dev_addr);
-
-extern void tpm_close(void);
-
-/*
- * Transmit bufsiz bytes out of buf to TPM and get results back in buf, too.
- * Returns < 0 on error, 0 on success.
- */
-extern ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz);
 
 #endif
similarity index 59%
rename from drivers/tpm/slb9635_i2c/tpm_tis_i2c.c
rename to drivers/tpm/tpm_tis_i2c.c
index 82a41bf5b272ce2b3f99791c0174a977089f304a..2dd8501f92d127125dec36d09f9af25a2ecac87b 100644 (file)
  */
 
 #include <common.h>
+#include <fdtdec.h>
+#include <compiler.h>
 #include <i2c.h>
+#include <tpm.h>
+#include <asm-generic/errno.h>
 #include <linux/types.h>
+#include <linux/unaligned/be_byteshift.h>
 
-#include "compatibility.h"
-#include "tpm.h"
+#include "tpm_private.h"
+
+DECLARE_GLOBAL_DATA_PTR;
 
-/* max. buffer size supported by our tpm */
-#ifdef TPM_BUFSIZE
-#undef TPM_BUFSIZE
-#endif
-#define TPM_BUFSIZE 1260
 /* Address of the TPM on the I2C bus */
-#define TPM_I2C_ADDR 0x20
-/* max. number of iterations after i2c NAK */
-#define MAX_COUNT 3
+#define TPM_I2C_ADDR           0x20
+
+/* Max buffer size supported by our tpm */
+#define TPM_DEV_BUFSIZE                1260
 
-#define SLEEP_DURATION 60 /*in usec*/
+/* Max number of iterations after i2c NAK */
+#define MAX_COUNT              3
 
-/* max. number of iterations after i2c NAK for 'long' commands
- * we need this especially for sending TPM_READY, since the cleanup after the
+/*
+ * Max number of iterations after i2c NAK for 'long' commands
+ *
+ * We need this especially for sending TPM_READY, since the cleanup after the
  * transtion to the ready state may take some time, but it is unpredictable
  * how long it will take.
  */
-#define MAX_COUNT_LONG 50
+#define MAX_COUNT_LONG         50
+
+#define SLEEP_DURATION         60      /* in usec */
+#define SLEEP_DURATION_LONG    210     /* in usec */
 
-#define SLEEP_DURATION_LONG 210 /* in usec */
+#define TPM_HEADER_SIZE                10
+
+/*
+ * Expected value for DIDVID register
+ *
+ * The only device the system knows about at this moment is Infineon slb9635.
+ */
+#define TPM_TIS_I2C_DID_VID    0x000b15d1L
+
+enum tis_access {
+       TPM_ACCESS_VALID                = 0x80,
+       TPM_ACCESS_ACTIVE_LOCALITY      = 0x20,
+       TPM_ACCESS_REQUEST_PENDING      = 0x04,
+       TPM_ACCESS_REQUEST_USE          = 0x02,
+};
+
+enum tis_status {
+       TPM_STS_VALID                   = 0x80,
+       TPM_STS_COMMAND_READY           = 0x40,
+       TPM_STS_GO                      = 0x20,
+       TPM_STS_DATA_AVAIL              = 0x10,
+       TPM_STS_DATA_EXPECT             = 0x08,
+};
+
+enum tis_defaults {
+       TIS_SHORT_TIMEOUT               = 750,  /* ms */
+       TIS_LONG_TIMEOUT                = 2000, /* ms */
+};
 
 /* expected value for DIDVID register */
-#define TPM_TIS_I2C_DID_VID 0x000b15d1L
+#define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
+#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
+
+enum i2c_chip_type {
+       SLB9635,
+       SLB9645,
+       UNKNOWN,
+};
+
+static const char * const chip_name[] = {
+       [SLB9635] = "slb9635tt",
+       [SLB9645] = "slb9645tt",
+       [UNKNOWN] = "unknown/fallback to slb9635",
+};
+
+#define        TPM_ACCESS(l)                   (0x0000 | ((l) << 4))
+#define        TPM_STS(l)                      (0x0001 | ((l) << 4))
+#define        TPM_DATA_FIFO(l)                (0x0005 | ((l) << 4))
+#define        TPM_DID_VID(l)                  (0x0006 | ((l) << 4))
 
 /* Structure to store I2C TPM specific stuff */
-struct tpm_inf_dev {
+struct tpm_dev {
        uint addr;
-       u8 buf[TPM_BUFSIZE + sizeof(u8)];       /* max. buffer size + addr */
+       u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
+       enum i2c_chip_type chip_type;
 };
 
-static struct tpm_inf_dev tpm_dev = {
+static struct tpm_dev tpm_dev = {
        .addr = TPM_I2C_ADDR
 };
 
+static struct tpm_dev tpm_dev;
+
 /*
  * iic_tpm_read() - read from TPM register
  * @addr: register address to read from
@@ -91,34 +147,52 @@ static struct tpm_inf_dev tpm_dev = {
  *
  * Return -EIO on error, 0 on success.
  */
-int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
+static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 {
        int rc;
        int count;
-       uint myaddr = addr;
-       /* we have to use uint here, uchar hangs the board */
-
-       for (count = 0; count < MAX_COUNT; count++) {
-               rc = i2c_write(tpm_dev.addr, 0, 0, (uchar *)&myaddr, 1);
-               if (rc == 0)
-                       break; /*success, break to skip sleep*/
-
-               udelay(SLEEP_DURATION);
-       }
-
-       if (rc)
-               return -rc;
-
-       /* After the TPM has successfully received the register address it needs
-        * some time, thus we're sleeping here again, before retrieving the data
-        */
-       for (count = 0; count < MAX_COUNT; count++) {
-               udelay(SLEEP_DURATION);
-               rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len);
-               if (rc == 0)
-                       break; /*success, break to skip sleep*/
+       uint32_t addrbuf = addr;
+
+       if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
+               /* slb9635 protocol should work in both cases */
+               for (count = 0; count < MAX_COUNT; count++) {
+                       rc = i2c_write(tpm_dev.addr, 0, 0,
+                                      (uchar *)&addrbuf, 1);
+                       if (rc == 0)
+                               break;  /* Success, break to skip sleep */
+                       udelay(SLEEP_DURATION);
+               }
+               if (rc)
+                       return -rc;
+
+               /* After the TPM has successfully received the register address
+                * it needs some time, thus we're sleeping here again, before
+                * retrieving the data
+                */
+               for (count = 0; count < MAX_COUNT; count++) {
+                       udelay(SLEEP_DURATION);
+                       rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len);
+                       if (rc == 0)
+                               break;  /* success, break to skip sleep */
+               }
+       } else {
+               /*
+                * Use a combined read for newer chips.
+                * Unfortunately the smbus functions are not suitable due to
+                * the 32 byte limit of the smbus.
+                * Retries should usually not be needed, but are kept just to
+                * be safe on the safe side.
+                */
+               for (count = 0; count < MAX_COUNT; count++) {
+                       rc = i2c_read(tpm_dev.addr, addr, 1, buffer, len);
+                       if (rc == 0)
+                               break;  /* break here to skip sleep */
+                       udelay(SLEEP_DURATION);
+               }
        }
 
+       /* Take care of 'guard time' */
+       udelay(SLEEP_DURATION);
        if (rc)
                return -rc;
 
@@ -126,24 +200,24 @@ int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 }
 
 static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
-                               unsigned int sleep_time,
-                               u8 max_count)
+               unsigned int sleep_time, u8 max_count)
 {
        int rc = 0;
        int count;
 
-       /* prepare send buffer */
+       /* Prepare send buffer */
        tpm_dev.buf[0] = addr;
        memcpy(&(tpm_dev.buf[1]), buffer, len);
 
        for (count = 0; count < max_count; count++) {
                rc = i2c_write(tpm_dev.addr, 0, 0, tpm_dev.buf, len + 1);
                if (rc == 0)
-                       break; /*success, break to skip sleep*/
-
+                       break;  /* Success, break to skip sleep */
                udelay(sleep_time);
        }
 
+       /* take care of 'guard time' */
+       udelay(SLEEP_DURATION);
        if (rc)
                return -rc;
 
@@ -175,42 +249,16 @@ static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
 /*
  * This function is needed especially for the cleanup situation after
  * sending TPM_READY
- * */
+ */
 static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
 {
        return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
                        MAX_COUNT_LONG);
 }
 
-#define TPM_HEADER_SIZE 10
-
-enum tis_access {
-       TPM_ACCESS_VALID = 0x80,
-       TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
-       TPM_ACCESS_REQUEST_PENDING = 0x04,
-       TPM_ACCESS_REQUEST_USE = 0x02,
-};
-
-enum tis_status {
-       TPM_STS_VALID = 0x80,
-       TPM_STS_COMMAND_READY = 0x40,
-       TPM_STS_GO = 0x20,
-       TPM_STS_DATA_AVAIL = 0x10,
-       TPM_STS_DATA_EXPECT = 0x08,
-};
-
-enum tis_defaults {
-       TIS_SHORT_TIMEOUT = 750,        /* ms */
-       TIS_LONG_TIMEOUT = 2000,        /* 2 sec */
-};
-
-#define        TPM_ACCESS(l)                   (0x0000 | ((l) << 4))
-#define        TPM_STS(l)                      (0x0001 | ((l) << 4))
-#define        TPM_DATA_FIFO(l)                (0x0005 | ((l) << 4))
-#define        TPM_DID_VID(l)                  (0x0006 | ((l) << 4))
-
 static int check_locality(struct tpm_chip *chip, int loc)
 {
+       const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID;
        u8 buf;
        int rc;
 
@@ -218,8 +266,7 @@ static int check_locality(struct tpm_chip *chip, int loc)
        if (rc < 0)
                return rc;
 
-       if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
-               (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
+       if ((buf & mask) == mask) {
                chip->vendor.locality = loc;
                return loc;
        }
@@ -229,12 +276,13 @@ static int check_locality(struct tpm_chip *chip, int loc)
 
 static void release_locality(struct tpm_chip *chip, int loc, int force)
 {
+       const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID;
        u8 buf;
+
        if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
                return;
 
-       if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
-                       (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
+       if (force || (buf & mask) == mask) {
                buf = TPM_ACCESS_ACTIVE_LOCALITY;
                iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
        }
@@ -246,17 +294,17 @@ static int request_locality(struct tpm_chip *chip, int loc)
        u8 buf = TPM_ACCESS_REQUEST_USE;
 
        if (check_locality(chip, loc) >= 0)
-               return loc; /* we already have the locality */
+               return loc;  /* We already have the locality */
 
        iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
 
-       /* wait for burstcount */
+       /* Wait for burstcount */
        start = get_timer(0);
        stop = chip->vendor.timeout_a;
        do {
                if (check_locality(chip, loc) >= 0)
                        return loc;
-               msleep(TPM_TIMEOUT);
+               udelay(TPM_TIMEOUT * 1000);
        } while (get_timer(start) < stop);
 
        return -1;
@@ -264,8 +312,9 @@ static int request_locality(struct tpm_chip *chip, int loc)
 
 static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
 {
-       /* NOTE: since i2c read may fail, return 0 in this case --> time-out */
+       /* NOTE: Since i2c read may fail, return 0 in this case --> time-out */
        u8 buf;
+
        if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
                return 0;
        else
@@ -274,8 +323,9 @@ static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
 
 static void tpm_tis_i2c_ready(struct tpm_chip *chip)
 {
-       /* this causes the current command to be aborted */
+       /* This causes the current command to be aborted */
        u8 buf = TPM_STS_COMMAND_READY;
+
        iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
 }
 
@@ -283,34 +333,34 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
 {
        unsigned long start, stop;
        ssize_t burstcnt;
-       u8 buf[3];
+       u8 addr, buf[3];
 
-       /* wait for burstcount */
-       /* which timeout value, spec has 2 answers (c & d) */
+       /* Wait for burstcount */
+       /* XXX: Which timeout value? Spec has 2 answers (c & d) */
        start = get_timer(0);
        stop = chip->vendor.timeout_d;
        do {
                /* Note: STS is little endian */
-               if (iic_tpm_read(TPM_STS(chip->vendor.locality) + 1, buf, 3)
-                               < 0)
+               addr = TPM_STS(chip->vendor.locality) + 1;
+               if (iic_tpm_read(addr, buf, 3) < 0)
                        burstcnt = 0;
                else
                        burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
 
                if (burstcnt)
                        return burstcnt;
-               msleep(TPM_TIMEOUT);
+               udelay(TPM_TIMEOUT * 1000);
        } while (get_timer(start) < stop);
 
        return -EBUSY;
 }
 
 static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
-                       int *status)
+               int *status)
 {
        unsigned long start, stop;
 
-       /* check current status */
+       /* Check current status */
        *status = tpm_tis_i2c_status(chip);
        if ((*status & mask) == mask)
                return 0;
@@ -318,11 +368,10 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
        start = get_timer(0);
        stop = timeout;
        do {
-               msleep(TPM_TIMEOUT);
+               udelay(TPM_TIMEOUT * 1000);
                *status = tpm_tis_i2c_status(chip);
                if ((*status & mask) == mask)
                        return 0;
-
        } while (get_timer(start) < stop);
 
        return -ETIME;
@@ -337,17 +386,16 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
        while (size < count) {
                burstcnt = get_burstcount(chip);
 
-               /* burstcount < 0 = tpm is busy */
+               /* burstcount < 0 -> tpm is busy */
                if (burstcnt < 0)
                        return burstcnt;
 
-               /* limit received data to max. left */
+               /* Limit received data to max left */
                if (burstcnt > (count - size))
                        burstcnt = count - size;
 
                rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
-                                 &(buf[size]),
-                                 burstcnt);
+                               &(buf[size]), burstcnt);
                if (rc == 0)
                        size += burstcnt;
        }
@@ -365,10 +413,10 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
                goto out;
        }
 
-       /* read first 10 bytes, including tag, paramsize, and result */
+       /* Read first 10 bytes, including tag, paramsize, and result */
        size = recv_data(chip, buf, TPM_HEADER_SIZE);
        if (size < TPM_HEADER_SIZE) {
-               dev_err(chip->dev, "Unable to read header\n");
+               error("Unable to read header\n");
                goto out;
        }
 
@@ -379,23 +427,24 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
        }
 
        size += recv_data(chip, &buf[TPM_HEADER_SIZE],
-                               expected - TPM_HEADER_SIZE);
+                       expected - TPM_HEADER_SIZE);
        if (size < expected) {
-               dev_err(chip->dev, "Unable to read remainder of result\n");
+               error("Unable to read remainder of result\n");
                size = -ETIME;
                goto out;
        }
 
        wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
-       if (status & TPM_STS_DATA_AVAIL) {      /* retry? */
-               dev_err(chip->dev, "Error left over data\n");
+       if (status & TPM_STS_DATA_AVAIL) {  /* Retry? */
+               error("Error left over data\n");
                size = -EIO;
                goto out;
        }
 
 out:
        tpm_tis_i2c_ready(chip);
-       /* The TPM needs some time to clean up here,
+       /*
+        * The TPM needs some time to clean up here,
         * so we sleep rather than keeping the bus busy
         */
        udelay(2000);
@@ -409,10 +458,11 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
        int rc, status;
        ssize_t burstcnt;
        size_t count = 0;
+       int retry = 0;
        u8 sts = TPM_STS_GO;
 
-       if (len > TPM_BUFSIZE)
-               return -E2BIG; /* command is too long for our tpm, sorry */
+       if (len > TPM_DEV_BUFSIZE)
+               return -E2BIG;  /* Command is too long for our tpm, sorry */
 
        if (request_locality(chip, 0) < 0)
                return -EBUSY;
@@ -420,44 +470,45 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
        status = tpm_tis_i2c_status(chip);
        if ((status & TPM_STS_COMMAND_READY) == 0) {
                tpm_tis_i2c_ready(chip);
-               if (wait_for_stat
-                   (chip, TPM_STS_COMMAND_READY,
-                    chip->vendor.timeout_b, &status) < 0) {
+               if (wait_for_stat(chip, TPM_STS_COMMAND_READY,
+                                 chip->vendor.timeout_b, &status) < 0) {
                        rc = -ETIME;
                        goto out_err;
                }
        }
 
-       while (count < len - 1) {
-               burstcnt = get_burstcount(chip);
+       burstcnt = get_burstcount(chip);
 
-               /* burstcount < 0 = tpm is busy */
-               if (burstcnt < 0)
-                       return burstcnt;
+       /* burstcount < 0 -> tpm is busy */
+       if (burstcnt < 0)
+               return burstcnt;
 
-               if (burstcnt > (len-1-count))
-                       burstcnt = len-1-count;
+       while (count < len - 1) {
+               if (burstcnt > len - 1 - count)
+                       burstcnt = len - 1 - count;
 
-#ifdef CONFIG_TPM_I2C_BURST_LIMITATION
-               if (burstcnt > CONFIG_TPM_I2C_BURST_LIMITATION)
-                       burstcnt = CONFIG_TPM_I2C_BURST_LIMITATION;
-#endif /* CONFIG_TPM_I2C_BURST_LIMITATION */
+#ifdef CONFIG_TPM_TIS_I2C_BURST_LIMITATION
+               if (retry && burstcnt > CONFIG_TPM_TIS_I2C_BURST_LIMITATION)
+                       burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION;
+#endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */
 
                rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
-                                  &(buf[count]), burstcnt);
+                               &(buf[count]), burstcnt);
                if (rc == 0)
                        count += burstcnt;
-
-               wait_for_stat(chip, TPM_STS_VALID,
-                             chip->vendor.timeout_c, &status);
-
-               if ((status & TPM_STS_DATA_EXPECT) == 0) {
-                       rc = -EIO;
-                       goto out_err;
+               else {
+                       retry++;
+                       wait_for_stat(chip, TPM_STS_VALID,
+                                     chip->vendor.timeout_c, &status);
+
+                       if ((status & TPM_STS_DATA_EXPECT) == 0) {
+                               rc = -EIO;
+                               goto out_err;
+                       }
                }
        }
 
-       /* write last byte */
+       /* Write last byte */
        iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
        wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
        if ((status & TPM_STS_DATA_EXPECT) != 0) {
@@ -465,13 +516,15 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
                goto out_err;
        }
 
-       /* go and do it */
+       /* Go and do it */
        iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
 
        return len;
+
 out_err:
        tpm_tis_i2c_ready(chip);
-       /* The TPM needs some time to clean up here,
+       /*
+        * The TPM needs some time to clean up here,
         * so we sleep rather than keeping the bus busy
         */
        udelay(2000);
@@ -490,12 +543,26 @@ static struct tpm_vendor_specific tpm_tis_i2c = {
        .req_canceled = TPM_STS_COMMAND_READY,
 };
 
-/* initialisation of i2c tpm */
 
+static enum i2c_chip_type tpm_vendor_chip_type(void)
+{
+#ifdef CONFIG_OF_CONTROL
+       const void *blob = gd->fdt_blob;
+
+       if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9645_TPM) >= 0)
+               return SLB9645;
+
+       if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM) >= 0)
+               return SLB9635;
+#endif
+       return UNKNOWN;
+}
 
+/* Initialisation of i2c tpm */
 int tpm_vendor_init(uint32_t dev_addr)
 {
        u32 vendor;
+       u32 expected_did_vid;
        uint old_addr;
        int rc = 0;
        struct tpm_chip *chip;
@@ -504,6 +571,8 @@ int tpm_vendor_init(uint32_t dev_addr)
        if (dev_addr != 0)
                tpm_dev.addr = dev_addr;
 
+       tpm_dev.chip_type = tpm_vendor_chip_type();
+
        chip = tpm_register_hardware(&tpm_tis_i2c);
        if (chip < 0) {
                rc = -ENODEV;
@@ -519,26 +588,33 @@ int tpm_vendor_init(uint32_t dev_addr)
        chip->vendor.timeout_c = TIS_SHORT_TIMEOUT;
        chip->vendor.timeout_d = TIS_SHORT_TIMEOUT;
 
-       if (request_locality(chip, 0) != 0) {
+       if (request_locality(chip, 0) < 0) {
                rc = -ENODEV;
                goto out_err;
        }
 
-       /* read four bytes from DID_VID register */
+       /* Read four bytes from DID_VID register */
        if (iic_tpm_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
                rc = -EIO;
                goto out_release;
        }
 
-       /* create DID_VID register value, after swapping to little-endian */
-       vendor = be32_to_cpu(vendor);
+       if (tpm_dev.chip_type == SLB9635) {
+               vendor = be32_to_cpu(vendor);
+               expected_did_vid = TPM_TIS_I2C_DID_VID_9635;
+       } else {
+               /* device id and byte order has changed for newer i2c tpms */
+               expected_did_vid = TPM_TIS_I2C_DID_VID_9645;
+       }
 
-       if (vendor != TPM_TIS_I2C_DID_VID) {
+       if (tpm_dev.chip_type != UNKNOWN && vendor != expected_did_vid) {
+               error("Vendor id did not match! ID was %08x\n", vendor);
                rc = -ENODEV;
                goto out_release;
        }
 
-       dev_info(dev, "1.2 TPM (device-id 0x%X)\n", vendor >> 16);
+       debug("1.2 TPM (chip type %s device-id 0x%X)\n",
+             chip_name[tpm_dev.chip_type], vendor >> 16);
 
        /*
         * A timeout query to TPM can be placed here.
index 75ec8f78815b39810a68b3448193bc0bc7f19494..76624b92564b7dca9b6de50b9f90977bee70c84f 100644 (file)
@@ -407,46 +407,40 @@ static int asix_basic_reset(struct ueth_data *dev)
        rx_ctl = asix_read_rx_ctl(dev);
        debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl);
 
-       return 0;
-}
-
-/*
- * Asix callbacks
- */
-static int asix_init(struct eth_device *eth, bd_t *bd)
-{
-       struct ueth_data        *dev = (struct ueth_data *)eth->priv;
-       int timeout = 0;
-#define TIMEOUT_RESOLUTION 50  /* ms */
-       int link_detected;
-
-       debug("** %s()\n", __func__);
-
        dev->phy_id = asix_get_phy_addr(dev);
        if (dev->phy_id < 0)
                debug("Failed to read phy id\n");
 
-       if (asix_sw_reset(dev, AX_SWRESET_PRL) < 0)
-               goto out_err;
-
-       if (asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL) < 0)
-               goto out_err;
-
        asix_mdio_write(dev, dev->phy_id, MII_BMCR, BMCR_RESET);
        asix_mdio_write(dev, dev->phy_id, MII_ADVERTISE,
                        ADVERTISE_ALL | ADVERTISE_CSMA);
        mii_nway_restart(dev);
 
        if (asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT) < 0)
-               goto out_err;
+               return -1;
 
        if (asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
                                AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
                                AX88772_IPG2_DEFAULT, 0, NULL) < 0) {
                debug("Write IPG,IPG1,IPG2 failed\n");
-               goto out_err;
+               return -1;
        }
 
+       return 0;
+}
+
+/*
+ * Asix callbacks
+ */
+static int asix_init(struct eth_device *eth, bd_t *bd)
+{
+       struct ueth_data        *dev = (struct ueth_data *)eth->priv;
+       int timeout = 0;
+#define TIMEOUT_RESOLUTION 50  /* ms */
+       int link_detected;
+
+       debug("** %s()\n", __func__);
+
        if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0)
                goto out_err;
 
index e545b6be6b33030bd42cf27d9a8a2cdde8027bb1..432cf178cf4a056cd9decd44da0defc93e844fc2 100644 (file)
@@ -35,6 +35,7 @@ endif
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
index 2c5600ed5210c9da2e2450132d11d1c65a41578e..f30778a163b2950b2681a5ea9b610a7d74d10fb3 100644 (file)
@@ -1098,4 +1098,5 @@ void usb_composite_unregister(struct usb_composite_driver *driver)
        if (composite != driver)
                return;
        usb_gadget_unregister_driver(&composite_driver);
+       composite = NULL;
 }
index c28866f7d3c2e5dbcae7766d4d9b0958113c2ec2..45bc132aef6729827594dcf1a373c7e49510114f 100644 (file)
@@ -2261,7 +2261,8 @@ reset:
        if (rc)
                goto reset;
        fsg->bulk_out_enabled = 1;
-       common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
+       common->bulk_out_maxpacket =
+                               le16_to_cpu(get_unaligned(&d->wMaxPacketSize));
        clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
 
        /* Allocate the requests */
diff --git a/drivers/usb/gadget/fotg210.c b/drivers/usb/gadget/fotg210.c
new file mode 100644 (file)
index 0000000..d003331
--- /dev/null
@@ -0,0 +1,948 @@
+/*
+ * Faraday USB 2.0 OTG Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <net.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <linux/types.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#include <usb/fotg210.h>
+
+#define CFG_NUM_ENDPOINTS              4
+#define CFG_EP0_MAX_PACKET_SIZE        64
+#define CFG_EPX_MAX_PACKET_SIZE        512
+
+#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 2) /* 250 ms */
+
+struct fotg210_chip;
+
+struct fotg210_ep {
+       struct usb_ep ep;
+
+       uint maxpacket;
+       uint id;
+       uint stopped;
+
+       struct list_head                      queue;
+       struct fotg210_chip                  *chip;
+       const struct usb_endpoint_descriptor *desc;
+};
+
+struct fotg210_request {
+       struct usb_request req;
+       struct list_head   queue;
+       struct fotg210_ep *ep;
+};
+
+struct fotg210_chip {
+       struct usb_gadget         gadget;
+       struct usb_gadget_driver *driver;
+       struct fotg210_regs      *regs;
+       uint8_t                   irq;
+       uint16_t                  addr;
+       int                       pullup;
+       enum usb_device_state     state;
+       struct fotg210_ep         ep[1 + CFG_NUM_ENDPOINTS];
+};
+
+static struct usb_endpoint_descriptor ep0_desc = {
+       .bLength = sizeof(struct usb_endpoint_descriptor),
+       .bDescriptorType = USB_DT_ENDPOINT,
+       .bEndpointAddress = USB_DIR_IN,
+       .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
+};
+
+static inline int fifo_to_ep(struct fotg210_chip *chip, int id, int in)
+{
+       return (id < 0) ? 0 : ((id & 0x03) + 1);
+}
+
+static inline int ep_to_fifo(struct fotg210_chip *chip, int id)
+{
+       return (id <= 0) ? -1 : ((id - 1) & 0x03);
+}
+
+static inline int ep_reset(struct fotg210_chip *chip, uint8_t ep_addr)
+{
+       int ep = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+       struct fotg210_regs *regs = chip->regs;
+
+       if (ep_addr & USB_DIR_IN) {
+               /* reset endpoint */
+               setbits_le32(&regs->iep[ep - 1], IEP_RESET);
+               mdelay(1);
+               clrbits_le32(&regs->iep[ep - 1], IEP_RESET);
+               /* clear endpoint stall */
+               clrbits_le32(&regs->iep[ep - 1], IEP_STALL);
+       } else {
+               /* reset endpoint */
+               setbits_le32(&regs->oep[ep - 1], OEP_RESET);
+               mdelay(1);
+               clrbits_le32(&regs->oep[ep - 1], OEP_RESET);
+               /* clear endpoint stall */
+               clrbits_le32(&regs->oep[ep - 1], OEP_STALL);
+       }
+
+       return 0;
+}
+
+static int fotg210_reset(struct fotg210_chip *chip)
+{
+       struct fotg210_regs *regs = chip->regs;
+       uint32_t i;
+
+       chip->state = USB_STATE_POWERED;
+
+       /* chip enable */
+       writel(DEVCTRL_EN, &regs->dev_ctrl);
+
+       /* device address reset */
+       chip->addr = 0;
+       writel(0, &regs->dev_addr);
+
+       /* set idle counter to 7ms */
+       writel(7, &regs->idle);
+
+       /* disable all interrupts */
+       writel(IMR_MASK, &regs->imr);
+       writel(GIMR_MASK, &regs->gimr);
+       writel(GIMR0_MASK, &regs->gimr0);
+       writel(GIMR1_MASK, &regs->gimr1);
+       writel(GIMR2_MASK, &regs->gimr2);
+
+       /* clear interrupts */
+       writel(ISR_MASK, &regs->isr);
+       writel(0, &regs->gisr);
+       writel(0, &regs->gisr0);
+       writel(0, &regs->gisr1);
+       writel(0, &regs->gisr2);
+
+       /* chip reset */
+       setbits_le32(&regs->dev_ctrl, DEVCTRL_RESET);
+       mdelay(10);
+       if (readl(&regs->dev_ctrl) & DEVCTRL_RESET) {
+               printf("fotg210: chip reset failed\n");
+               return -1;
+       }
+
+       /* CX FIFO reset */
+       setbits_le32(&regs->cxfifo, CXFIFO_CXFIFOCLR);
+       mdelay(10);
+       if (readl(&regs->cxfifo) & CXFIFO_CXFIFOCLR) {
+               printf("fotg210: ep0 fifo reset failed\n");
+               return -1;
+       }
+
+       /* create static ep-fifo map (EP1 <-> FIFO0, EP2 <-> FIFO1 ...) */
+       writel(EPMAP14_DEFAULT, &regs->epmap14);
+       writel(EPMAP58_DEFAULT, &regs->epmap58);
+       writel(FIFOMAP_DEFAULT, &regs->fifomap);
+       writel(0, &regs->fifocfg);
+       for (i = 0; i < 8; ++i) {
+               writel(CFG_EPX_MAX_PACKET_SIZE, &regs->iep[i]);
+               writel(CFG_EPX_MAX_PACKET_SIZE, &regs->oep[i]);
+       }
+
+       /* FIFO reset */
+       for (i = 0; i < 4; ++i) {
+               writel(FIFOCSR_RESET, &regs->fifocsr[i]);
+               mdelay(10);
+               if (readl(&regs->fifocsr[i]) & FIFOCSR_RESET) {
+                       printf("fotg210: fifo%d reset failed\n", i);
+                       return -1;
+               }
+       }
+
+       /* enable only device interrupt and triggered at level-high */
+       writel(IMR_IRQLH | IMR_HOST | IMR_OTG, &regs->imr);
+       writel(ISR_MASK, &regs->isr);
+       /* disable EP0 IN/OUT interrupt */
+       writel(GIMR0_CXOUT | GIMR0_CXIN, &regs->gimr0);
+       /* disable EPX IN+SPK+OUT interrupts */
+       writel(GIMR1_MASK, &regs->gimr1);
+       /* disable wakeup+idle+dma+zlp interrupts */
+       writel(GIMR2_WAKEUP | GIMR2_IDLE | GIMR2_DMAERR | GIMR2_DMAFIN
+               | GIMR2_ZLPRX | GIMR2_ZLPTX, &regs->gimr2);
+       /* enable all group interrupt */
+       writel(0, &regs->gimr);
+
+       /* suspend delay = 3 ms */
+       writel(3, &regs->idle);
+
+       /* turn-on device interrupts */
+       setbits_le32(&regs->dev_ctrl, DEVCTRL_GIRQ_EN);
+
+       return 0;
+}
+
+static inline int fotg210_cxwait(struct fotg210_chip *chip, uint32_t mask)
+{
+       struct fotg210_regs *regs = chip->regs;
+       int ret = -1;
+       ulong ts;
+
+       for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
+               if ((readl(&regs->cxfifo) & mask) != mask)
+                       continue;
+               ret = 0;
+               break;
+       }
+
+       if (ret)
+               printf("fotg210: cx/ep0 timeout\n");
+
+       return ret;
+}
+
+static int fotg210_dma(struct fotg210_ep *ep, struct fotg210_request *req)
+{
+       struct fotg210_chip *chip = ep->chip;
+       struct fotg210_regs *regs = chip->regs;
+       uint32_t tmp, ts;
+       uint8_t *buf  = req->req.buf + req->req.actual;
+       uint32_t len  = req->req.length - req->req.actual;
+       int fifo = ep_to_fifo(chip, ep->id);
+       int ret = -EBUSY;
+
+       /* 1. init dma buffer */
+       if (len > ep->maxpacket)
+               len = ep->maxpacket;
+
+       /* 2. wait for dma ready (hardware) */
+       for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
+               if (!(readl(&regs->dma_ctrl) & DMACTRL_START)) {
+                       ret = 0;
+                       break;
+               }
+       }
+       if (ret) {
+               printf("fotg210: dma busy\n");
+               req->req.status = ret;
+               return ret;
+       }
+
+       /* 3. DMA target setup */
+       if (ep->desc->bEndpointAddress & USB_DIR_IN)
+               flush_dcache_range((ulong)buf, (ulong)buf + len);
+       else
+               invalidate_dcache_range((ulong)buf, (ulong)buf + len);
+
+       writel(virt_to_phys(buf), &regs->dma_addr);
+
+       if (ep->desc->bEndpointAddress & USB_DIR_IN) {
+               if (ep->id == 0) {
+                       /* Wait until cx/ep0 fifo empty */
+                       fotg210_cxwait(chip, CXFIFO_CXFIFOE);
+                       writel(DMAFIFO_CX, &regs->dma_fifo);
+               } else {
+                       /* Wait until epx fifo empty */
+                       fotg210_cxwait(chip, CXFIFO_FIFOE(fifo));
+                       writel(DMAFIFO_FIFO(fifo), &regs->dma_fifo);
+               }
+               writel(DMACTRL_LEN(len) | DMACTRL_MEM2FIFO, &regs->dma_ctrl);
+       } else {
+               uint32_t blen;
+
+               if (ep->id == 0) {
+                       writel(DMAFIFO_CX, &regs->dma_fifo);
+                       do {
+                               blen = CXFIFO_BYTES(readl(&regs->cxfifo));
+                       } while (blen < len);
+               } else {
+                       writel(DMAFIFO_FIFO(fifo), &regs->dma_fifo);
+                       blen = FIFOCSR_BYTES(readl(&regs->fifocsr[fifo]));
+               }
+               len  = (len < blen) ? len : blen;
+               writel(DMACTRL_LEN(len) | DMACTRL_FIFO2MEM, &regs->dma_ctrl);
+       }
+
+       /* 4. DMA start */
+       setbits_le32(&regs->dma_ctrl, DMACTRL_START);
+
+       /* 5. DMA wait */
+       ret = -EBUSY;
+       for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
+               tmp = readl(&regs->gisr2);
+               /* DMA complete */
+               if (tmp & GISR2_DMAFIN) {
+                       ret = 0;
+                       break;
+               }
+               /* DMA error */
+               if (tmp & GISR2_DMAERR) {
+                       printf("fotg210: dma error\n");
+                       break;
+               }
+               /* resume, suspend, reset */
+               if (tmp & (GISR2_RESUME | GISR2_SUSPEND | GISR2_RESET)) {
+                       printf("fotg210: dma reset by host\n");
+                       break;
+               }
+       }
+
+       /* 7. DMA target reset */
+       if (ret)
+               writel(DMACTRL_ABORT | DMACTRL_CLRFF, &regs->dma_ctrl);
+
+       writel(0, &regs->gisr2);
+       writel(0, &regs->dma_fifo);
+
+       req->req.status = ret;
+       if (!ret)
+               req->req.actual += len;
+       else
+               printf("fotg210: ep%d dma error(code=%d)\n", ep->id, ret);
+
+       return len;
+}
+
+/*
+ * result of setup packet
+ */
+#define CX_IDLE                0
+#define CX_FINISH      1
+#define CX_STALL       2
+
+static void fotg210_setup(struct fotg210_chip *chip)
+{
+       int id, ret = CX_IDLE;
+       uint32_t tmp[2];
+       struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)tmp;
+       struct fotg210_regs *regs = chip->regs;
+
+       /*
+        * If this is the first Cx 8 byte command,
+        * we can now query USB mode (high/full speed; USB 2.0/USB 1.0)
+        */
+       if (chip->state == USB_STATE_POWERED) {
+               chip->state = USB_STATE_DEFAULT;
+               if (readl(&regs->otgcsr) & OTGCSR_DEV_B) {
+                       /* Mini-B */
+                       if (readl(&regs->dev_ctrl) & DEVCTRL_HS) {
+                               puts("fotg210: HS\n");
+                               chip->gadget.speed = USB_SPEED_HIGH;
+                               /* SOF mask timer = 1100 ticks */
+                               writel(SOFMTR_TMR(1100), &regs->sof_mtr);
+                       } else {
+                               puts("fotg210: FS\n");
+                               chip->gadget.speed = USB_SPEED_FULL;
+                               /* SOF mask timer = 10000 ticks */
+                               writel(SOFMTR_TMR(10000), &regs->sof_mtr);
+                       }
+               } else {
+                       printf("fotg210: mini-A?\n");
+               }
+       }
+
+       /* switch data port to ep0 */
+       writel(DMAFIFO_CX, &regs->dma_fifo);
+       /* fetch 8 bytes setup packet */
+       tmp[0] = readl(&regs->ep0_data);
+       tmp[1] = readl(&regs->ep0_data);
+       /* release data port */
+       writel(0, &regs->dma_fifo);
+
+       if (req->bRequestType & USB_DIR_IN)
+               ep0_desc.bEndpointAddress = USB_DIR_IN;
+       else
+               ep0_desc.bEndpointAddress = USB_DIR_OUT;
+
+       ret = CX_IDLE;
+
+       if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
+               switch (req->bRequest) {
+               case USB_REQ_SET_CONFIGURATION:
+                       debug("fotg210: set_cfg(%d)\n", req->wValue & 0x00FF);
+                       if (!(req->wValue & 0x00FF)) {
+                               chip->state = USB_STATE_ADDRESS;
+                               writel(chip->addr, &regs->dev_addr);
+                       } else {
+                               chip->state = USB_STATE_CONFIGURED;
+                               writel(chip->addr | DEVADDR_CONF,
+                                       &regs->dev_addr);
+                       }
+                       ret = CX_IDLE;
+                       break;
+
+               case USB_REQ_SET_ADDRESS:
+                       debug("fotg210: set_addr(0x%04X)\n", req->wValue);
+                       chip->state = USB_STATE_ADDRESS;
+                       chip->addr  = req->wValue & DEVADDR_ADDR_MASK;
+                       ret = CX_FINISH;
+                       writel(chip->addr, &regs->dev_addr);
+                       break;
+
+               case USB_REQ_CLEAR_FEATURE:
+                       debug("fotg210: clr_feature(%d, %d)\n",
+                               req->bRequestType & 0x03, req->wValue);
+                       switch (req->wValue) {
+                       case 0:    /* [Endpoint] halt */
+                               ep_reset(chip, req->wIndex);
+                               ret = CX_FINISH;
+                               break;
+                       case 1:    /* [Device] remote wake-up */
+                       case 2:    /* [Device] test mode */
+                       default:
+                               ret = CX_STALL;
+                               break;
+                       }
+                       break;
+
+               case USB_REQ_SET_FEATURE:
+                       debug("fotg210: set_feature(%d, %d)\n",
+                               req->wValue, req->wIndex & 0xf);
+                       switch (req->wValue) {
+                       case 0:    /* Endpoint Halt */
+                               id = req->wIndex & 0xf;
+                               setbits_le32(&regs->iep[id - 1], IEP_STALL);
+                               setbits_le32(&regs->oep[id - 1], OEP_STALL);
+                               ret = CX_FINISH;
+                               break;
+                       case 1:    /* Remote Wakeup */
+                       case 2:    /* Test Mode */
+                       default:
+                               ret = CX_STALL;
+                               break;
+                       }
+                       break;
+
+               case USB_REQ_GET_STATUS:
+                       debug("fotg210: get_status\n");
+                       ret = CX_STALL;
+                       break;
+
+               case USB_REQ_SET_DESCRIPTOR:
+                       debug("fotg210: set_descriptor\n");
+                       ret = CX_STALL;
+                       break;
+
+               case USB_REQ_SYNCH_FRAME:
+                       debug("fotg210: sync frame\n");
+                       ret = CX_STALL;
+                       break;
+               }
+       } /* if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) */
+
+       if (ret == CX_IDLE && chip->driver->setup) {
+               if (chip->driver->setup(&chip->gadget, req) < 0)
+                       ret = CX_STALL;
+               else
+                       ret = CX_FINISH;
+       }
+
+       switch (ret) {
+       case CX_FINISH:
+               setbits_le32(&regs->cxfifo, CXFIFO_CXFIN);
+               break;
+
+       case CX_STALL:
+               setbits_le32(&regs->cxfifo, CXFIFO_CXSTALL | CXFIFO_CXFIN);
+               printf("fotg210: cx_stall!\n");
+               break;
+
+       case CX_IDLE:
+               debug("fotg210: cx_idle?\n");
+       default:
+               break;
+       }
+}
+
+/*
+ * fifo - FIFO id
+ * zlp  - zero length packet
+ */
+static void fotg210_recv(struct fotg210_chip *chip, int ep_id)
+{
+       struct fotg210_regs *regs = chip->regs;
+       struct fotg210_ep *ep = chip->ep + ep_id;
+       struct fotg210_request *req;
+       int len;
+
+       if (ep->stopped || (ep->desc->bEndpointAddress & USB_DIR_IN)) {
+               printf("fotg210: ep%d recv, invalid!\n", ep->id);
+               return;
+       }
+
+       if (list_empty(&ep->queue)) {
+               printf("fotg210: ep%d recv, drop!\n", ep->id);
+               return;
+       }
+
+       req = list_first_entry(&ep->queue, struct fotg210_request, queue);
+       len = fotg210_dma(ep, req);
+       if (len < ep->ep.maxpacket || req->req.length <= req->req.actual) {
+               list_del_init(&req->queue);
+               if (req->req.complete)
+                       req->req.complete(&ep->ep, &req->req);
+       }
+
+       if (ep->id > 0 && list_empty(&ep->queue)) {
+               setbits_le32(&regs->gimr1,
+                       GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id)));
+       }
+}
+
+/*
+ * USB Gadget Layer
+ */
+static int fotg210_ep_enable(
+       struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
+{
+       struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
+       struct fotg210_chip *chip = ep->chip;
+       struct fotg210_regs *regs = chip->regs;
+       int id = ep_to_fifo(chip, ep->id);
+       int in = (desc->bEndpointAddress & USB_DIR_IN) ? 1 : 0;
+
+       if (!_ep || !desc
+               || desc->bDescriptorType != USB_DT_ENDPOINT
+               || le16_to_cpu(desc->wMaxPacketSize) == 0) {
+               printf("fotg210: bad ep or descriptor\n");
+               return -EINVAL;
+       }
+
+       ep->desc = desc;
+       ep->stopped = 0;
+
+       if (in)
+               setbits_le32(&regs->fifomap, FIFOMAP(id, FIFOMAP_IN));
+
+       switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+       case USB_ENDPOINT_XFER_CONTROL:
+               return -EINVAL;
+
+       case USB_ENDPOINT_XFER_ISOC:
+               setbits_le32(&regs->fifocfg,
+                       FIFOCFG(id, FIFOCFG_EN | FIFOCFG_ISOC));
+               break;
+
+       case USB_ENDPOINT_XFER_BULK:
+               setbits_le32(&regs->fifocfg,
+                       FIFOCFG(id, FIFOCFG_EN | FIFOCFG_BULK));
+               break;
+
+       case USB_ENDPOINT_XFER_INT:
+               setbits_le32(&regs->fifocfg,
+                       FIFOCFG(id, FIFOCFG_EN | FIFOCFG_INTR));
+               break;
+       }
+
+       return 0;
+}
+
+static int fotg210_ep_disable(struct usb_ep *_ep)
+{
+       struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
+       struct fotg210_chip *chip = ep->chip;
+       struct fotg210_regs *regs = chip->regs;
+       int id = ep_to_fifo(chip, ep->id);
+
+       ep->desc = NULL;
+       ep->stopped = 1;
+
+       clrbits_le32(&regs->fifocfg, FIFOCFG(id, FIFOCFG_CFG_MASK));
+       clrbits_le32(&regs->fifomap, FIFOMAP(id, FIFOMAP_DIR_MASK));
+
+       return 0;
+}
+
+static struct usb_request *fotg210_ep_alloc_request(
+       struct usb_ep *_ep, gfp_t gfp_flags)
+{
+       struct fotg210_request *req = malloc(sizeof(*req));
+
+       if (req) {
+               memset(req, 0, sizeof(*req));
+               INIT_LIST_HEAD(&req->queue);
+       }
+       return &req->req;
+}
+
+static void fotg210_ep_free_request(
+       struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct fotg210_request *req;
+
+       req = container_of(_req, struct fotg210_request, req);
+       free(req);
+}
+
+static int fotg210_ep_queue(
+       struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+{
+       struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
+       struct fotg210_chip *chip = ep->chip;
+       struct fotg210_regs *regs = chip->regs;
+       struct fotg210_request *req;
+
+       req = container_of(_req, struct fotg210_request, req);
+       if (!_req || !_req->complete || !_req->buf
+               || !list_empty(&req->queue)) {
+               printf("fotg210: invalid request to ep%d\n", ep->id);
+               return -EINVAL;
+       }
+
+       if (!chip || chip->state == USB_STATE_SUSPENDED) {
+               printf("fotg210: request while chip suspended\n");
+               return -EINVAL;
+       }
+
+       req->req.actual = 0;
+       req->req.status = -EINPROGRESS;
+
+       if (req->req.length == 0) {
+               req->req.status = 0;
+               if (req->req.complete)
+                       req->req.complete(&ep->ep, &req->req);
+               return 0;
+       }
+
+       if (ep->id == 0) {
+               do {
+                       int len = fotg210_dma(ep, req);
+                       if (len < ep->ep.maxpacket)
+                               break;
+                       if (ep->desc->bEndpointAddress & USB_DIR_IN)
+                               udelay(100);
+               } while (req->req.length > req->req.actual);
+       } else {
+               if (ep->desc->bEndpointAddress & USB_DIR_IN) {
+                       do {
+                               int len = fotg210_dma(ep, req);
+                               if (len < ep->ep.maxpacket)
+                                       break;
+                       } while (req->req.length > req->req.actual);
+               } else {
+                       list_add_tail(&req->queue, &ep->queue);
+                       clrbits_le32(&regs->gimr1,
+                               GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id)));
+               }
+       }
+
+       if (ep->id == 0 || (ep->desc->bEndpointAddress & USB_DIR_IN)) {
+               if (req->req.complete)
+                       req->req.complete(&ep->ep, &req->req);
+       }
+
+       return 0;
+}
+
+static int fotg210_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+       struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
+       struct fotg210_request *req;
+
+       /* make sure it's actually queued on this endpoint */
+       list_for_each_entry(req, &ep->queue, queue) {
+               if (&req->req == _req)
+                       break;
+       }
+       if (&req->req != _req)
+               return -EINVAL;
+
+       /* remove the request */
+       list_del_init(&req->queue);
+
+       /* update status & invoke complete callback */
+       if (req->req.status == -EINPROGRESS) {
+               req->req.status = -ECONNRESET;
+               if (req->req.complete)
+                       req->req.complete(_ep, &req->req);
+       }
+
+       return 0;
+}
+
+static int fotg210_ep_halt(struct usb_ep *_ep, int halt)
+{
+       struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
+       struct fotg210_chip *chip = ep->chip;
+       struct fotg210_regs *regs = chip->regs;
+       int ret = -1;
+
+       debug("fotg210: ep%d halt=%d\n", ep->id, halt);
+
+       /* Endpoint STALL */
+       if (ep->id > 0 && ep->id <= CFG_NUM_ENDPOINTS) {
+               if (halt) {
+                       /* wait until all ep fifo empty */
+                       fotg210_cxwait(chip, 0xf00);
+                       /* stall */
+                       if (ep->desc->bEndpointAddress & USB_DIR_IN) {
+                               setbits_le32(&regs->iep[ep->id - 1],
+                                       IEP_STALL);
+                       } else {
+                               setbits_le32(&regs->oep[ep->id - 1],
+                                       OEP_STALL);
+                       }
+               } else {
+                       if (ep->desc->bEndpointAddress & USB_DIR_IN) {
+                               clrbits_le32(&regs->iep[ep->id - 1],
+                                       IEP_STALL);
+                       } else {
+                               clrbits_le32(&regs->oep[ep->id - 1],
+                                       OEP_STALL);
+                       }
+               }
+               ret = 0;
+       }
+
+       return ret;
+}
+
+/*
+ * activate/deactivate link with host.
+ */
+static void pullup(struct fotg210_chip *chip, int is_on)
+{
+       struct fotg210_regs *regs = chip->regs;
+
+       if (is_on) {
+               if (!chip->pullup) {
+                       chip->state = USB_STATE_POWERED;
+                       chip->pullup = 1;
+                       /* enable the chip */
+                       setbits_le32(&regs->dev_ctrl, DEVCTRL_EN);
+                       /* clear unplug bit (BIT0) */
+                       clrbits_le32(&regs->phy_tmsr, PHYTMSR_UNPLUG);
+               }
+       } else {
+               chip->state = USB_STATE_NOTATTACHED;
+               chip->pullup = 0;
+               chip->addr = 0;
+               writel(chip->addr, &regs->dev_addr);
+               /* set unplug bit (BIT0) */
+               setbits_le32(&regs->phy_tmsr, PHYTMSR_UNPLUG);
+               /* disable the chip */
+               clrbits_le32(&regs->dev_ctrl, DEVCTRL_EN);
+       }
+}
+
+static int fotg210_pullup(struct usb_gadget *_gadget, int is_on)
+{
+       struct fotg210_chip *chip;
+
+       chip = container_of(_gadget, struct fotg210_chip, gadget);
+
+       debug("fotg210: pullup=%d\n", is_on);
+
+       pullup(chip, is_on);
+
+       return 0;
+}
+
+static int fotg210_get_frame(struct usb_gadget *_gadget)
+{
+       struct fotg210_chip *chip;
+       struct fotg210_regs *regs;
+
+       chip = container_of(_gadget, struct fotg210_chip, gadget);
+       regs = chip->regs;
+
+       return SOFFNR_FNR(readl(&regs->sof_fnr));
+}
+
+static struct usb_gadget_ops fotg210_gadget_ops = {
+       .get_frame = fotg210_get_frame,
+       .pullup = fotg210_pullup,
+};
+
+static struct usb_ep_ops fotg210_ep_ops = {
+       .enable         = fotg210_ep_enable,
+       .disable        = fotg210_ep_disable,
+       .queue          = fotg210_ep_queue,
+       .dequeue        = fotg210_ep_dequeue,
+       .set_halt       = fotg210_ep_halt,
+       .alloc_request  = fotg210_ep_alloc_request,
+       .free_request   = fotg210_ep_free_request,
+};
+
+static struct fotg210_chip controller = {
+       .regs = (void __iomem *)CONFIG_FOTG210_BASE,
+       .gadget = {
+               .name = "fotg210_udc",
+               .ops = &fotg210_gadget_ops,
+               .ep0 = &controller.ep[0].ep,
+               .speed = USB_SPEED_UNKNOWN,
+               .is_dualspeed = 1,
+               .is_otg = 0,
+               .is_a_peripheral = 0,
+               .b_hnp_enable = 0,
+               .a_hnp_support = 0,
+               .a_alt_hnp_support = 0,
+       },
+       .ep[0] = {
+               .id = 0,
+               .ep = {
+                       .name  = "ep0",
+                       .ops   = &fotg210_ep_ops,
+               },
+               .desc      = &ep0_desc,
+               .chip      = &controller,
+               .maxpacket = CFG_EP0_MAX_PACKET_SIZE,
+       },
+       .ep[1] = {
+               .id = 1,
+               .ep = {
+                       .name  = "ep1",
+                       .ops   = &fotg210_ep_ops,
+               },
+               .chip      = &controller,
+               .maxpacket = CFG_EPX_MAX_PACKET_SIZE,
+       },
+       .ep[2] = {
+               .id = 2,
+               .ep = {
+                       .name  = "ep2",
+                       .ops   = &fotg210_ep_ops,
+               },
+               .chip      = &controller,
+               .maxpacket = CFG_EPX_MAX_PACKET_SIZE,
+       },
+       .ep[3] = {
+               .id = 3,
+               .ep = {
+                       .name  = "ep3",
+                       .ops   = &fotg210_ep_ops,
+               },
+               .chip      = &controller,
+               .maxpacket = CFG_EPX_MAX_PACKET_SIZE,
+       },
+       .ep[4] = {
+               .id = 4,
+               .ep = {
+                       .name  = "ep4",
+                       .ops   = &fotg210_ep_ops,
+               },
+               .chip      = &controller,
+               .maxpacket = CFG_EPX_MAX_PACKET_SIZE,
+       },
+};
+
+int usb_gadget_handle_interrupts(void)
+{
+       struct fotg210_chip *chip = &controller;
+       struct fotg210_regs *regs = chip->regs;
+       uint32_t id, st, isr, gisr;
+
+       isr  = readl(&regs->isr) & (~readl(&regs->imr));
+       gisr = readl(&regs->gisr) & (~readl(&regs->gimr));
+       if (!(isr & ISR_DEV) || !gisr)
+               return 0;
+
+       writel(ISR_DEV, &regs->isr);
+
+       /* CX interrupts */
+       if (gisr & GISR_GRP0) {
+               st = readl(&regs->gisr0);
+               writel(0, &regs->gisr0);
+
+               if (st & GISR0_CXERR)
+                       printf("fotg210: cmd error\n");
+
+               if (st & GISR0_CXABORT)
+                       printf("fotg210: cmd abort\n");
+
+               if (st & GISR0_CXSETUP)    /* setup */
+                       fotg210_setup(chip);
+               else if (st & GISR0_CXEND) /* command finish */
+                       setbits_le32(&regs->cxfifo, CXFIFO_CXFIN);
+       }
+
+       /* FIFO interrupts */
+       if (gisr & GISR_GRP1) {
+               st = readl(&regs->gisr1);
+               for (id = 0; id < 4; ++id) {
+                       if (st & GISR1_RX_FIFO(id))
+                               fotg210_recv(chip, fifo_to_ep(chip, id, 0));
+               }
+       }
+
+       /* Device Status Interrupts */
+       if (gisr & GISR_GRP2) {
+               st = readl(&regs->gisr2);
+               writel(0, &regs->gisr2);
+
+               if (st & GISR2_RESET)
+                       printf("fotg210: reset by host\n");
+               else if (st & GISR2_SUSPEND)
+                       printf("fotg210: suspend/removed\n");
+               else if (st & GISR2_RESUME)
+                       printf("fotg210: resume\n");
+
+               /* Errors */
+               if (st & GISR2_ISOCERR)
+                       printf("fotg210: iso error\n");
+               if (st & GISR2_ISOCABT)
+                       printf("fotg210: iso abort\n");
+               if (st & GISR2_DMAERR)
+                       printf("fotg210: dma error\n");
+       }
+
+       return 0;
+}
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+       int i, ret = 0;
+       struct fotg210_chip *chip = &controller;
+
+       if (!driver    || !driver->bind || !driver->setup) {
+               puts("fotg210: bad parameter.\n");
+               return -EINVAL;
+       }
+
+       INIT_LIST_HEAD(&chip->gadget.ep_list);
+       for (i = 0; i < CFG_NUM_ENDPOINTS + 1; ++i) {
+               struct fotg210_ep *ep = chip->ep + i;
+
+               ep->ep.maxpacket = ep->maxpacket;
+               INIT_LIST_HEAD(&ep->queue);
+
+               if (ep->id == 0) {
+                       ep->stopped = 0;
+               } else {
+                       ep->stopped = 1;
+                       list_add_tail(&ep->ep.ep_list, &chip->gadget.ep_list);
+               }
+       }
+
+       if (fotg210_reset(chip)) {
+               puts("fotg210: reset failed.\n");
+               return -EINVAL;
+       }
+
+       ret = driver->bind(&chip->gadget);
+       if (ret) {
+               debug("fotg210: driver->bind() returned %d\n", ret);
+               return ret;
+       }
+       chip->driver = driver;
+
+       return ret;
+}
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+       struct fotg210_chip *chip = &controller;
+
+       driver->unbind(&chip->gadget);
+       chip->driver = NULL;
+
+       pullup(chip, 0);
+
+       return 0;
+}
index e5701422fa3de2e4cb48244fa65b4e63441356d1..f038747e63e0d5175bb58ee495b7e419140d8c98 100644 (file)
 #define gadget_is_mv(g)        0
 #endif
 
+#ifdef CONFIG_USB_GADGET_FOTG210
+#define gadget_is_fotg210(g)        (!strcmp("fotg210_udc", (g)->name))
+#else
+#define gadget_is_fotg210(g)        0
+#endif
+
 /*
  * CONFIG_USB_GADGET_SX2
  * CONFIG_USB_GADGET_AU1X00
@@ -215,5 +221,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
                return 0x20;
        else if (gadget_is_mv(gadget))
                return 0x21;
+       else if (gadget_is_fotg210(gadget))
+               return 0x22;
        return -ENOENT;
 }
index 9ce98f07684af8873e221babb904d66f03160a72..085503dbe8a15f96fa6a492ab7843d7d781c816b 100644 (file)
@@ -314,7 +314,8 @@ static int pxa25x_ep_enable(struct usb_ep *_ep,
        if (!_ep || !desc || ep->desc || _ep->name == ep0name
                        || desc->bDescriptorType != USB_DT_ENDPOINT
                        || ep->bEndpointAddress != desc->bEndpointAddress
-                       || ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) {
+                       || ep->fifo_size <
+                          le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))) {
                printf("%s, bad ep or descriptor\n", __func__);
                return -EINVAL;
        }
@@ -329,9 +330,9 @@ static int pxa25x_ep_enable(struct usb_ep *_ep,
 
        /* hardware _could_ do smaller, but driver doesn't */
        if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
-                               && le16_to_cpu(desc->wMaxPacketSize)
+                       && le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))
                                                != BULK_FIFO_SIZE)
-                       || !desc->wMaxPacketSize) {
+                       || !get_unaligned(&desc->wMaxPacketSize)) {
                printf("%s, bad %s maxpacket\n", __func__, _ep->name);
                return -ERANGE;
        }
@@ -345,7 +346,7 @@ static int pxa25x_ep_enable(struct usb_ep *_ep,
        ep->desc = desc;
        ep->stopped = 0;
        ep->pio_irqs = 0;
-       ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+       ep->ep.maxpacket = le16_to_cpu(get_unaligned(&desc->wMaxPacketSize));
 
        /* flush fifo (mostly for OUT buffers) */
        pxa25x_ep_fifo_flush(_ep);
@@ -485,7 +486,7 @@ write_fifo(struct pxa25x_ep *ep, struct pxa25x_request *req)
 {
        unsigned max;
 
-       max = le16_to_cpu(ep->desc->wMaxPacketSize);
+       max = le16_to_cpu(get_unaligned(&ep->desc->wMaxPacketSize));
        do {
                unsigned count;
                int is_last, is_short;
@@ -766,7 +767,7 @@ pxa25x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
         */
        if (unlikely(ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
                        && req->req.length >
-                       le16_to_cpu(ep->desc->wMaxPacketSize)))
+                       le16_to_cpu(get_unaligned(&ep->desc->wMaxPacketSize))))
                return -EMSGSIZE;
 
        debug_cond(NOISY, "%s queue req %p, len %d buf %p\n",
index 87a59704db764148d97ca17b4227976fc244ef19..98f2a104b7dc77dda540feebee457473317189a7 100644 (file)
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
 else
 COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 endif
+COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
 COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
 COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
 COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
diff --git a/drivers/usb/host/ehci-faraday.c b/drivers/usb/host/ehci-faraday.c
new file mode 100644 (file)
index 0000000..86add36
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Faraday USB 2.0 EHCI Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <usb.h>
+#include <usb/fusbh200.h>
+#include <usb/fotg210.h>
+
+#include "ehci.h"
+
+#ifndef CONFIG_USB_EHCI_BASE_LIST
+#define CONFIG_USB_EHCI_BASE_LIST      { CONFIG_USB_EHCI_BASE }
+#endif
+
+union ehci_faraday_regs {
+       struct fusbh200_regs usb;
+       struct fotg210_regs  otg;
+};
+
+static inline int ehci_is_fotg2xx(union ehci_faraday_regs *regs)
+{
+       return !readl(&regs->usb.easstr);
+}
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ */
+int ehci_hcd_init(int index, struct ehci_hccr **ret_hccr,
+               struct ehci_hcor **ret_hcor)
+{
+       struct ehci_hccr *hccr;
+       struct ehci_hcor *hcor;
+       union ehci_faraday_regs *regs;
+       uint32_t base_list[] = CONFIG_USB_EHCI_BASE_LIST;
+
+       if (index < 0 || index >= ARRAY_SIZE(base_list))
+               return -1;
+       regs = (void __iomem *)base_list[index];
+       hccr = (struct ehci_hccr *)&regs->usb.hccr;
+       hcor = (struct ehci_hcor *)&regs->usb.hcor;
+
+       if (ehci_is_fotg2xx(regs)) {
+               /* A-device bus reset */
+               /* ... Power off A-device */
+               setbits_le32(&regs->otg.otgcsr, OTGCSR_A_BUSDROP);
+               /* ... Drop vbus and bus traffic */
+               clrbits_le32(&regs->otg.otgcsr, OTGCSR_A_BUSREQ);
+               mdelay(1);
+               /* ... Power on A-device */
+               clrbits_le32(&regs->otg.otgcsr, OTGCSR_A_BUSDROP);
+               /* ... Drive vbus and bus traffic */
+               setbits_le32(&regs->otg.otgcsr, OTGCSR_A_BUSREQ);
+               mdelay(1);
+               /* Disable OTG & DEV interrupts, triggered at level-high */
+               writel(IMR_IRQLH | IMR_OTG | IMR_DEV, &regs->otg.imr);
+               /* Clear all interrupt status */
+               writel(ISR_HOST | ISR_OTG | ISR_DEV, &regs->otg.isr);
+       } else {
+               /* Interrupt=level-high */
+               setbits_le32(&regs->usb.bmcsr, BMCSR_IRQLH);
+               /* VBUS on */
+               clrbits_le32(&regs->usb.bmcsr, BMCSR_VBUS_OFF);
+               /* Disable all interrupts */
+               writel(0x00, &regs->usb.bmier);
+               writel(0x1f, &regs->usb.bmisr);
+       }
+
+       *ret_hccr = hccr;
+       *ret_hcor = hcor;
+
+       return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop(int index)
+{
+       return 0;
+}
+
+/*
+ * This ehci_set_usbmode() overrides the weak function
+ * in "ehci-hcd.c".
+ */
+void ehci_set_usbmode(int index)
+{
+       /* nothing needs to be done */
+}
+
+/*
+ * This ehci_get_port_speed() overrides the weak function
+ * in "ehci-hcd.c".
+ */
+int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
+{
+       int spd, ret = PORTSC_PSPD_HS;
+       union ehci_faraday_regs *regs = (void __iomem *)((ulong)hcor - 0x10);
+
+       if (ehci_is_fotg2xx(regs))
+               spd = OTGCSR_SPD(readl(&regs->otg.otgcsr));
+       else
+               spd = BMCSR_SPD(readl(&regs->usb.bmcsr));
+
+       switch (spd) {
+       case 0:    /* full speed */
+               ret = PORTSC_PSPD_FS;
+               break;
+       case 1:    /* low  speed */
+               ret = PORTSC_PSPD_LS;
+               break;
+       case 2:    /* high speed */
+               ret = PORTSC_PSPD_HS;
+               break;
+       default:
+               printf("ehci-faraday: invalid device speed\n");
+               break;
+       }
+
+       return ret;
+}
+
+/*
+ * This ehci_get_portsc_register() overrides the weak function
+ * in "ehci-hcd.c".
+ */
+uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+       /* Faraday EHCI has one and only one portsc register */
+       if (port) {
+               /* Printing the message would cause a scan failure! */
+               debug("The request port(%d) is not configured\n", port);
+               return NULL;
+       }
+
+       /* Faraday EHCI PORTSC register offset is 0x20 from hcor */
+       return (uint32_t *)((uint8_t *)hcor + 0x20);
+}
index e0f3e4b6c788bf3e3d78dcf929c652f5e971845c..706cf0cb7dba246c2c567b5da4111590bb9679b9 100644 (file)
@@ -589,10 +589,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token);
        } else {
                dev->act_len = 0;
+#ifndef CONFIG_USB_EHCI_FARADAY
                debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
                      dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts),
                      ehci_readl(&ctrl->hcor->or_portsc[0]),
                      ehci_readl(&ctrl->hcor->or_portsc[1]));
+#endif
        }
 
        free(qtd);
@@ -603,6 +605,17 @@ fail:
        return -1;
 }
 
+__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+       if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+               /* Printing the message would cause a scan failure! */
+               debug("The request port(%u) is not configured\n", port);
+               return NULL;
+       }
+
+       return (uint32_t *)&hcor->or_portsc[port];
+}
+
 int
 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
                 int length, struct devrequest *req)
@@ -616,11 +629,6 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
        int port = le16_to_cpu(req->index) & 0xff;
        struct ehci_ctrl *ctrl = dev->controller;
 
-       if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-               printf("The request port(%d) is not configured\n", port - 1);
-               return -1;
-       }
-       status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
        srclen = 0;
 
        debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
@@ -630,6 +638,19 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 
        typeReq = req->request | req->requesttype << 8;
 
+       switch (typeReq) {
+       case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
+       case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
+       case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
+               status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1);
+               if (!status_reg)
+                       return -1;
+               break;
+       default:
+               status_reg = NULL;
+               break;
+       }
+
        switch (typeReq) {
        case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
                switch (le16_to_cpu(req->value) >> 8) {
@@ -809,21 +830,23 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
                break;
        case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
                reg = ehci_readl(status_reg);
+               reg &= ~EHCI_PS_CLEAR;
                switch (le16_to_cpu(req->value)) {
                case USB_PORT_FEAT_ENABLE:
                        reg &= ~EHCI_PS_PE;
                        break;
                case USB_PORT_FEAT_C_ENABLE:
-                       reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_PE;
+                       reg |= EHCI_PS_PE;
                        break;
                case USB_PORT_FEAT_POWER:
                        if (HCS_PPC(ehci_readl(&ctrl->hccr->cr_hcsparams)))
-                               reg = reg & ~(EHCI_PS_CLEAR | EHCI_PS_PP);
+                               reg &= ~EHCI_PS_PP;
+                       break;
                case USB_PORT_FEAT_C_CONNECTION:
-                       reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_CSC;
+                       reg |= EHCI_PS_CSC;
                        break;
                case USB_PORT_FEAT_OVER_CURRENT:
-                       reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_OCC;
+                       reg |= EHCI_PS_OCC;
                        break;
                case USB_PORT_FEAT_C_RESET:
                        ctrl->portreset &= ~(1 << port);
@@ -903,6 +926,9 @@ int usb_lowlevel_init(int index, void **controller)
        qh_list->qh_overlay.qt_token =
                        cpu_to_hc32(QT_TOKEN_STATUS(QT_TOKEN_STATUS_HALTED));
 
+       flush_dcache_range((uint32_t)qh_list,
+                          ALIGN_END_ADDR(struct QH, qh_list, 1));
+
        /* Set async. queue head pointer. */
        ehci_writel(&ehcic[index].hcor->or_asynclistaddr, (uint32_t)qh_list);
 
@@ -916,6 +942,9 @@ int usb_lowlevel_init(int index, void **controller)
        periodic->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
        periodic->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
 
+       flush_dcache_range((uint32_t)periodic,
+                          ALIGN_END_ADDR(struct QH, periodic, 1));
+
        /*
         * Step 2: Setup frame-list: Every microframe, USB tries the same list.
         *         In particular, device specifications on polling frequency
@@ -933,6 +962,10 @@ int usb_lowlevel_init(int index, void **controller)
                                                | QH_LINK_TYPE_QH;
        }
 
+       flush_dcache_range((uint32_t)ehcic[index].periodic_list,
+                          ALIGN_END_ADDR(uint32_t, ehcic[index].periodic_list,
+                                         1024));
+
        /* Set periodic list base address */
        ehci_writel(&ehcic[index].hcor->or_periodiclistbase,
                (uint32_t)ehcic[index].periodic_list);
@@ -959,10 +992,13 @@ int usb_lowlevel_init(int index, void **controller)
        cmd |= CMD_RUN;
        ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
 
+#ifndef CONFIG_USB_EHCI_FARADAY
        /* take control over the ports */
        cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
        cmd |= FLAG_CF;
        ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
+#endif
+
        /* unblock posted write */
        cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
        mdelay(5);
@@ -1144,6 +1180,16 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
                *buf = buffer + i * elementsize;
        }
 
+       flush_dcache_range((uint32_t)buffer,
+                          ALIGN_END_ADDR(char, buffer,
+                                         queuesize * elementsize));
+       flush_dcache_range((uint32_t)result->first,
+                          ALIGN_END_ADDR(struct QH, result->first,
+                                         queuesize));
+       flush_dcache_range((uint32_t)result->tds,
+                          ALIGN_END_ADDR(struct qTD, result->tds,
+                                         queuesize));
+
        if (disable_periodic(ctrl) < 0) {
                debug("FATAL: periodic should never fail, but did");
                goto fail3;
@@ -1154,6 +1200,11 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
        result->last->qh_link = list->qh_link;
        list->qh_link = (uint32_t)result->first | QH_LINK_TYPE_QH;
 
+       flush_dcache_range((uint32_t)result->last,
+                          ALIGN_END_ADDR(struct QH, result->last, 1));
+       flush_dcache_range((uint32_t)list,
+                          ALIGN_END_ADDR(struct QH, list, 1));
+
        if (enable_periodic(ctrl) < 0) {
                debug("FATAL: periodic should never fail, but did");
                goto fail3;
@@ -1184,6 +1235,8 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
                return NULL;
        }
        /* still active */
+       invalidate_dcache_range((uint32_t)cur,
+                               ALIGN_END_ADDR(struct QH, cur, 1));
        if (cur->qh_overlay.qt_token & 0x80) {
                debug("Exit poll_int_queue with no completed intr transfer. "
                      "token is %x\n", cur->qh_overlay.qt_token);
@@ -1290,6 +1343,9 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
                return -EINVAL;
        }
 
+       invalidate_dcache_range((uint32_t)buffer,
+                               ALIGN_END_ADDR(char, buffer, length));
+
        ret = destroy_int_queue(dev, queue);
        if (ret < 0)
                return ret;
index 0793f07f242fe4ca02e1a0c43ac63fed68a847e2..b10f1590ba00ee9505bd09fcbc03d1871d7d2fdb 100644 (file)
@@ -572,8 +572,6 @@ static void video_drawchars(int xx, int yy, unsigned char *s, int count)
                                        SWAP32((video_font_draw_table32
                                                [bits & 15][3] & eorx) ^ bgx);
                        }
-                       if (cfb_do_flush_cache)
-                               flush_cache((ulong)dest0, 32);
                        dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
                        s++;
                }
@@ -642,8 +640,6 @@ static void video_invertchar(int xx, int yy)
                for (x = firstx; x < lastx; x++) {
                        u8 *dest = (u8 *)(video_fb_address) + x + y;
                        *dest = ~*dest;
-                       if (cfb_do_flush_cache)
-                               flush_cache((ulong)dest, 4);
                }
        }
 }
@@ -687,6 +683,8 @@ void console_cursor(int state)
                }
                cursor_state = state;
        }
+       if (cfb_do_flush_cache)
+               flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
 }
 #endif
 
@@ -739,8 +737,6 @@ static void console_clear_line(int line, int begin, int end)
                        memsetl(offset + i * VIDEO_LINE_LEN, size, bgx);
        }
 #endif
-       if (cfb_do_flush_cache)
-               flush_cache((ulong)CONSOLE_ROW_FIRST, CONSOLE_SIZE);
 }
 
 static void console_scrollup(void)
@@ -1146,6 +1142,8 @@ void video_putc(const char c)
 #else
        parse_putc(c);
 #endif
+       if (cfb_do_flush_cache)
+               flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
 }
 
 void video_puts(const char *s)
@@ -1799,6 +1797,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y)
        }
 #endif
 
+       if (cfb_do_flush_cache)
+               flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
        return (0);
 }
 #endif
@@ -2209,6 +2209,9 @@ static int video_init(void)
        console_col = 0;
        console_row = 0;
 
+       if (cfb_do_flush_cache)
+               flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
+
        return 0;
 }
 
index e466c904a7866235dae68f5e5c780085501b4e15..215dc220336add24fd14a4cfc7106c81da58a720 100644 (file)
@@ -309,7 +309,8 @@ int idma_init (void)
 
        memaddr = dpalloc (sizeof (pram_idma_t), 64);
 
-       *(volatile ushort *) &immap->im_dprambase[PROFF_IDMA2_BASE] = memaddr;
+       *(volatile u16 *)&immap->im_dprambase16
+               [PROFF_IDMA2_BASE / sizeof(u16)] = memaddr;
        piptr = (volatile pram_idma_t *) ((uint) (immap) + memaddr);
 
        piptr->pi_resv1 = 0;            /* manual says: clear it */
index db49052b385ea0d9c46de954fc3d648869f3f526..6fcba047f968cc7b249cb6ada5eca1c89133696b 100644 (file)
@@ -70,22 +70,22 @@ int nandmtd_WriteChunkToNAND(struct yaffs_dev *dev, int chunkInNAND,
        u8 spareAsBytes[8]; /* OOB */
 
        if (data && !spare)
-               retval = mtd->write(mtd, addr, dev->data_bytes_per_chunk,
+               retval = mtd_write(mtd, addr, dev->data_bytes_per_chunk,
                                &dummy, data);
        else if (spare) {
                if (dev->param.use_nand_ecc) {
                        translate_spare2oob(spare, spareAsBytes);
-                       ops.mode = MTD_OOB_AUTO;
+                       ops.mode = MTD_OPS_AUTO_OOB;
                        ops.ooblen = 8; /* temp hack */
                } else {
-                       ops.mode = MTD_OOB_RAW;
+                       ops.mode = MTD_OPS_RAW;
                        ops.ooblen = YAFFS_BYTES_PER_SPARE;
                }
                ops.len = data ? dev->data_bytes_per_chunk : ops.ooblen;
                ops.datbuf = (u8 *)data;
                ops.ooboffs = 0;
                ops.oobbuf = spareAsBytes;
-               retval = mtd->write_oob(mtd, addr, &ops);
+               retval = mtd_write_oob(mtd, addr, &ops);
        }
 
        if (retval == 0)
@@ -106,21 +106,21 @@ int nandmtd_ReadChunkFromNAND(struct yaffs_dev *dev, int chunkInNAND, u8 *data,
        u8 spareAsBytes[8]; /* OOB */
 
        if (data && !spare)
-               retval = mtd->read(mtd, addr, dev->data_bytes_per_chunk,
+               retval = mtd_read(mtd, addr, dev->data_bytes_per_chunk,
                                &dummy, data);
        else if (spare) {
                if (dev->param.use_nand_ecc) {
-                       ops.mode = MTD_OOB_AUTO;
+                       ops.mode = MTD_OPS_AUTO_OOB;
                        ops.ooblen = 8; /* temp hack */
                } else {
-                       ops.mode = MTD_OOB_RAW;
+                       ops.mode = MTD_OPS_RAW;
                        ops.ooblen = YAFFS_BYTES_PER_SPARE;
                }
                ops.len = data ? dev->data_bytes_per_chunk : ops.ooblen;
                ops.datbuf = data;
                ops.ooboffs = 0;
                ops.oobbuf = spareAsBytes;
-               retval = mtd->read_oob(mtd, addr, &ops);
+               retval = mtd_read_oob(mtd, addr, &ops);
                if (dev->param.use_nand_ecc)
                        translate_oob2spare(spare, spareAsBytes);
        }
@@ -151,7 +151,7 @@ int nandmtd_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber)
        /* Todo finish off the ei if required */
 
 
-       retval = mtd->erase(mtd, &ei);
+       retval = mtd_erase(mtd, &ei);
 
        if (retval == 0)
                return YAFFS_OK;
index 8135bcc0fe1152a20dd8aa55e08d7154a12e5621..234cb706dfb413a1d213879e006c3ecad23b93ac 100644 (file)
@@ -77,13 +77,13 @@ int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
                yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
        }
 
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
        ops.len = dev->param.total_bytes_per_chunk;
        ops.ooboffs = 0;
        ops.datbuf = (u8 *) data;
        ops.oobbuf = (dev->param.inband_tags) ? NULL : packed_tags_ptr;
-       retval = mtd->write_oob(mtd, addr, &ops);
+       retval = mtd_write_oob(mtd, addr, &ops);
 
        if (retval == 0)
                return YAFFS_OK;
@@ -121,16 +121,16 @@ int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
        }
 
        if (dev->param.inband_tags || (data && !tags))
-               retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
+               retval = mtd_read(mtd, addr, dev->param.total_bytes_per_chunk,
                                   &dummy, data);
        else if (tags) {
-               ops.mode = MTD_OOB_AUTO;
+               ops.mode = MTD_OPS_AUTO_OOB;
                ops.ooblen = packed_tags_size;
                ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
                ops.ooboffs = 0;
                ops.datbuf = data;
                ops.oobbuf = local_spare;
-               retval = mtd->read_oob(mtd, addr, &ops);
+               retval = mtd_read_oob(mtd, addr, &ops);
        }
 
        if (dev->param.inband_tags) {
@@ -179,7 +179,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaffs_dev *dev, int blockNo)
                "nandmtd2_MarkNANDBlockBad %d", blockNo);
 
        retval =
-           mtd->block_markbad(mtd,
+           mtd_block_markbad(mtd,
                               blockNo * dev->param.chunks_per_block *
                               dev->data_bytes_per_chunk);
 
@@ -198,7 +198,7 @@ int nandmtd2_QueryNANDBlock(struct yaffs_dev *dev, int blockNo,
 
        yaffs_trace(YAFFS_TRACE_MTD, "nandmtd2_QueryNANDBlock %d", blockNo);
        retval =
-           mtd->block_isbad(mtd,
+           mtd_block_isbad(mtd,
                             blockNo * dev->param.chunks_per_block *
                             dev->data_bytes_per_chunk);
 
index 5416f468b06c6bb4becd6a1fc1f926df2280bd08..3e9ca1182d7e48e2a6cd63d17f5da44da7b027e7 100644 (file)
@@ -68,9 +68,6 @@ typedef struct global_data {
        unsigned long env_addr; /* Address  of Environment struct */
        unsigned long env_valid;        /* Checksum of Environment valid? */
 
-       /* TODO: is this the same as relocaddr, or something else? */
-       unsigned long dest_addr;        /* Post-relocation address of U-Boot */
-       unsigned long dest_addr_sp;
        unsigned long ram_top;  /* Top address of RAM used by U-Boot */
 
        unsigned long relocaddr;        /* Start address of U-Boot in RAM */
index 6dc0422bac42e5960e434559c6bd1b0587be8687..ef07a87e8db33b0f9b7cca0657f0319e415b41f6 100644 (file)
@@ -37,6 +37,24 @@ enum bootstage_flags {
        BOOTSTAGEF_ALLOC        = 1 << 1,       /* Allocate an id */
 };
 
+/* bootstate sub-IDs used for kernel and ramdisk ranges */
+enum {
+       BOOTSTAGE_SUB_FORMAT,
+       BOOTSTAGE_SUB_FORMAT_OK,
+       BOOTSTAGE_SUB_NO_UNIT_NAME,
+       BOOTSTAGE_SUB_UNIT_NAME,
+       BOOTSTAGE_SUB_SUBNODE,
+
+       BOOTSTAGE_SUB_CHECK,
+       BOOTSTAGE_SUB_HASH = 5,
+       BOOTSTAGE_SUB_CHECK_ARCH = 5,
+       BOOTSTAGE_SUB_CHECK_ALL,
+       BOOTSTAGE_SUB_GET_DATA,
+       BOOTSTAGE_SUB_CHECK_ALL_OK = 7,
+       BOOTSTAGE_SUB_GET_DATA_OK,
+       BOOTSTAGE_SUB_LOAD,
+};
+
 /*
  * A list of boot stages that we know about. Each of these indicates the
  * state that we are at, and the action that we are about to perform. For
@@ -137,43 +155,24 @@ enum bootstage_id {
        BOOTSTAGE_ID_NET_DONE_ERR,
        BOOTSTAGE_ID_NET_DONE,
 
+       BOOTSTAGE_ID_FIT_FDT_START = 90,
        /*
         * Boot stages related to loading a FIT image. Some of these are a
         * bit wonky.
         */
-       BOOTSTAGE_ID_FIT_FORMAT = 100,
-       BOOTSTAGE_ID_FIT_NO_UNIT_NAME,
-       BOOTSTAGE_ID_FIT_UNIT_NAME,
-       BOOTSTAGE_ID_FIT_CONFIG,
-       BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE,
-       BOOTSTAGE_ID_FIT_CHECK_HASH = 104,
-
-       BOOTSTAGE_ID_FIT_CHECK_ARCH,
-       BOOTSTAGE_ID_FIT_CHECK_KERNEL,
-       BOOTSTAGE_ID_FIT_CHECKED,
-
-       BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR = 107,
-       BOOTSTAGE_ID_FIT_KERNEL_INFO,
+       BOOTSTAGE_ID_FIT_KERNEL_START = 100,
+
+       BOOTSTAGE_ID_FIT_CONFIG = 110,
        BOOTSTAGE_ID_FIT_TYPE,
+       BOOTSTAGE_ID_FIT_KERNEL_INFO,
 
        BOOTSTAGE_ID_FIT_COMPRESSION,
        BOOTSTAGE_ID_FIT_OS,
        BOOTSTAGE_ID_FIT_LOADADDR,
        BOOTSTAGE_ID_OVERWRITTEN,
 
-       BOOTSTAGE_ID_FIT_RD_FORMAT = 120,
-       BOOTSTAGE_ID_FIT_RD_FORMAT_OK,
-       BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME,
-       BOOTSTAGE_ID_FIT_RD_UNIT_NAME,
-       BOOTSTAGE_ID_FIT_RD_SUBNODE,
-
-       BOOTSTAGE_ID_FIT_RD_CHECK,
-       BOOTSTAGE_ID_FIT_RD_HASH = 125,
-       BOOTSTAGE_ID_FIT_RD_CHECK_ALL,
-       BOOTSTAGE_ID_FIT_RD_GET_DATA,
-       BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK = 127,
-       BOOTSTAGE_ID_FIT_RD_GET_DATA_OK,
-       BOOTSTAGE_ID_FIT_RD_LOAD,
+       /* Next 10 IDs used by BOOTSTAGE_SUB_... */
+       BOOTSTAGE_ID_FIT_RD_START = 120,        /* Ramdisk stages */
 
        BOOTSTAGE_ID_IDE_FIT_READ = 140,
        BOOTSTAGE_ID_IDE_FIT_READ_OK,
index e682bd8237773ccfb9ac939e530c350ca9b8c402..126891d6587ae9060e506f5992a13029e0233baa 100644 (file)
@@ -310,9 +310,6 @@ int readline_into_buffer(const char *const prompt, char *buffer,
 int    parse_line (char *, char *[]);
 void   init_cmd_timeout(void);
 void   reset_cmd_timeout(void);
-#ifdef CONFIG_MENU
-int    abortboot(int bootdelay);
-#endif
 extern char console_buffer[];
 
 /* arch/$(ARCH)/lib/board.c */
index 7ca28c83694ebf23a6c8b5e735e5031c2340d7c6..6959905efe8f1665561f699b6cd71b925577ab58 100644 (file)
@@ -127,6 +127,7 @@ typedef struct cpm_buf_desc {
 */
 #define PROFF_SCC1     ((uint)0x0000)
 #define PROFF_IIC      ((uint)0x0080)
+#define PROFF_REVNUM   ((uint)0x00b0)
 #define PROFF_SCC2     ((uint)0x0100)
 #define PROFF_SPI      ((uint)0x0180)
 #define PROFF_SCC3     ((uint)0x0200)
index b85244a89ad9cfeaaf7456f8679118b09b9acc06..d506a558c0339b0c391000093fe014caaf95f7a5 100644 (file)
@@ -96,6 +96,7 @@
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef CONFIG_PCI_PNP
 #define CONFIG_PCI_SCAN_SHOW           /* print pci devices @ startup  */
 
index 9a65cbced094cf9cd8a9da7af0767caef90668d1..1e392290d70623d3727275303fb024aa94296abf 100644 (file)
 #define PCI_HOST_AUTO          2       /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 99944766ddedc0f19accd4916c7b8f370ea43820..7337f5374ba2f257aede2d19e50c4bf36b8feaf0 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 09aa763c11227c545ce653aed2df1419d14d4ca7..35c37731cbc669d12f456c7882f8fc2ec6831a3f 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_HOST  /* select pci host function     */
 #undef CONFIG_PCI_PNP                  /* do pci plug-and-play         */
                                        /* resource configuration       */
index 1c9d08e256420c8fe008a10deccdbace2de857e2..a823f9f3a77c5ae686b0e9abf663e9e5ed6dd697 100644 (file)
 #define CONFIG_RESET_VECTOR_ADDRESS    0xfffffffc
 #endif
 
+#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
+/* Set 1M boot space */
+#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000)
+#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS \
+               (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR)
+#define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc
+#define CONFIG_SYS_NO_FLASH
+#endif
+
 /* High Level Configuration Options */
 #define CONFIG_BOOKE
 #define CONFIG_E500                    /* BOOKE e500 family */
@@ -63,6 +72,7 @@
 #define CONFIG_SYS_SRIO
 #define CONFIG_SRIO1                   /* SRIO port 1 */
 #define CONFIG_SRIO2                   /* SRIO port 2 */
+#define CONFIG_SRIO_PCIE_BOOT_MASTER
 #endif
 
 #define CONFIG_FSL_LAW                 /* Use common FSL init code */
 #define CONFIG_ENV_OVERWRITE
 
 #ifdef CONFIG_SYS_NO_FLASH
+#if !defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) && !defined(CONFIG_RAMBOOT_PBL)
 #define CONFIG_ENV_IS_NOWHERE
+#endif
 #else
 #define CONFIG_FLASH_CFI_DRIVER
 #define CONFIG_SYS_FLASH_CFI
 #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
 #endif
 
-#ifndef CONFIG_SYS_NO_FLASH
 #if defined(CONFIG_SPIFLASH)
 #define CONFIG_SYS_EXTRA_ENV_RELOC
 #define CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_ENV_IS_IN_NAND
 #define CONFIG_ENV_SIZE                        CONFIG_SYS_NAND_BLOCK_SIZE
 #define CONFIG_ENV_OFFSET              (5 * CONFIG_SYS_NAND_BLOCK_SIZE)
+#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
+#define CONFIG_ENV_IS_IN_REMOTE
+#define CONFIG_ENV_ADDR                0xffe20000
+#define CONFIG_ENV_SIZE                0x2000
+#elif defined(CONFIG_ENV_IS_NOWHERE)
+#define CONFIG_ENV_SIZE                0x2000
 #else
 #define CONFIG_ENV_IS_IN_FLASH
 #define CONFIG_ENV_ADDR                (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SECT_SIZE)
 #define CONFIG_ENV_SIZE                0x2000
 #define CONFIG_ENV_SECT_SIZE   0x20000 /* 128K (one sector) */
 #endif
-#else /* CONFIG_SYS_NO_FLASH */
-#define CONFIG_ENV_SIZE                0x2000
-#define CONFIG_ENV_SECT_SIZE   0x20000 /* 128K (one sector) */
-#endif
 
 #ifndef __ASSEMBLY__
 unsigned long get_board_sys_clk(void);
@@ -223,7 +236,7 @@ unsigned long get_board_ddr_clk(void);
 /* NOR Flash Timing Params */
 #define CONFIG_SYS_NOR_CSOR    CSOR_NOR_ADM_SHIFT(4)
 #define CONFIG_SYS_NOR_FTIM0   (FTIM0_NOR_TACSE(0x01) | \
-                               FTIM0_NOR_TEADC(0x01) | \
+                               FTIM0_NOR_TEADC(0x04) | \
                                FTIM0_NOR_TEAHC(0x20))
 #define CONFIG_SYS_NOR_FTIM1   (FTIM1_NOR_TACO(0x35) | \
                                FTIM1_NOR_TRAD_NOR(0x1A) |\
@@ -600,6 +613,16 @@ unsigned long get_board_ddr_clk(void);
 #elif defined(CONFIG_NAND)
 #define CONFIG_SYS_QE_FMAN_FW_IN_NAND
 #define CONFIG_SYS_QE_FMAN_FW_ADDR     (6 * CONFIG_SYS_NAND_BLOCK_SIZE)
+#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
+/*
+ * Slave has no ucode locally, it can fetch this from remote. When implementing
+ * in two corenet boards, slave's ucode could be stored in master's memory
+ * space, the address can be mapped from slave TLB->slave LAW->
+ * slave SRIO or PCIE outbound window->master inbound window->
+ * master LAW->the ucode address in master's memory space.
+ */
+#define CONFIG_SYS_QE_FMAN_FW_IN_REMOTE
+#define CONFIG_SYS_QE_FMAN_FW_ADDR     0xFFE00000
 #else
 #define CONFIG_SYS_QE_FMAN_FW_IN_NOR
 #define CONFIG_SYS_QE_FMAN_FW_ADDR             0xEFF40000
@@ -620,6 +643,7 @@ unsigned long get_board_ddr_clk(void);
 #endif
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_NET_MULTI
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play */
 #define CONFIG_E1000
index fd076e09a277eeb2d8d1d6383ab76bd739a94242..b5911c69450be70c082f88ccb2d1dff65bbd39f7 100644 (file)
 #define CONFIG_RESET_VECTOR_ADDRESS    0x1107fffc
 #endif
 
-#ifndef CONFIG_SYS_MONITOR_BASE
-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE    /* start of monitor */
+#ifdef CONFIG_NAND
+#define CONFIG_SPL
+#define CONFIG_SPL_INIT_MINIMAL
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_MINIMAL
+#define CONFIG_SPL_FLUSH_IMAGE
+#define CONFIG_SPL_TARGET              "u-boot-with-spl.bin"
+
+#define CONFIG_SYS_TEXT_BASE           0x00201000
+#define CONFIG_SPL_TEXT_BASE           0xFFFFE000
+#define CONFIG_SPL_MAX_SIZE            8192
+#define CONFIG_SPL_RELOC_TEXT_BASE     0x00100000
+#define CONFIG_SPL_RELOC_STACK         0x00100000
+#define CONFIG_SYS_NAND_U_BOOT_SIZE    ((512 << 10) - 0x2000)
+#define CONFIG_SYS_NAND_U_BOOT_DST     (0x00200000 - CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SYS_NAND_U_BOOT_START   0x00200000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS    0
+#define CONFIG_SYS_LDSCRIPT    "arch/powerpc/cpu/mpc85xx/u-boot-nand.lds"
 #endif
 
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_MONITOR_BASE        CONFIG_SPL_TEXT_BASE
+#else
+#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_ENV_OVERWRITE
 
 #define CONFIG_DDR_CLK_FREQ    66666666 /* DDRCLK on 9131 RDB */
+#if defined(CONFIG_SYS_CLK_100)
+#define CONFIG_SYS_CLK_FREQ    100000000 /* SYSCLK for 9131 RDB */
+#else
 #define CONFIG_SYS_CLK_FREQ    66666666 /* SYSCLK for 9131 RDB */
+#endif
 
 #define CONFIG_HWCONFIG
 /*
@@ -125,16 +153,21 @@ extern unsigned long get_sdram_size(void);
 
 #define CONFIG_SYS_IMMR                CONFIG_SYS_CCSRBAR      /* PQII uses */
                                                        /* CONFIG_SYS_IMMR */
+/* DSP CCSRBAR */
+#define CONFIG_SYS_FSL_DSP_CCSRBAR     CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT
+#define CONFIG_SYS_FSL_DSP_CCSRBAR_PHYS        CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT
 
 /*
  * Memory map
  *
  * 0x0000_0000 0x3FFF_FFFF     DDR                     1G cacheable
  * 0x8800_0000 0x8810_0000     IFC internal SRAM               1M
+ * 0xB000_0000 0xB0FF_FFFF     DSP core M2 memory      16M
  * 0xC100_0000 0xC13F_FFFF     MAPLE-2F                4M
  * 0xC1F0_0000 0xC1F3_FFFF     PA L2 SRAM Region 0     256K
  * 0xC1F8_0000 0xC1F9_FFFF     PA L2 SRAM Region 1     128K
  * 0xFED0_0000 0xFED0_3FFF     SEC Secured RAM         16K
+ * 0xFF60_0000 0xFF6F_FFFF     DSP CCSR                1M
  * 0xFF70_0000 0xFF7F_FFFF     PA CCSR                 1M
  * 0xFF80_0000 0xFFFF_FFFF     Boot Page & NAND flash buffer   8M
  *
@@ -214,6 +247,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_SPL_BUILD
+#define CONFIG_NS16550_MIN_FUNCTIONS
+#endif
 
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV   /* determine from environment */
 
@@ -295,7 +331,6 @@ extern unsigned long get_sdram_size(void);
 /*
  * Environment
  */
-#if defined(CONFIG_SYS_RAMBOOT)
 #if defined(CONFIG_RAMBOOT_SPIFLASH)
 #define CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_ENV_SPI_BUS     0
@@ -305,15 +340,16 @@ extern unsigned long get_sdram_size(void);
 #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_NOWHERE  1       /* Store ENV in memory only */
+#elif defined(CONFIG_NAND)
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_SYS_EXTRA_ENV_RELOC
+#define CONFIG_ENV_SIZE                CONFIG_SYS_NAND_BLOCK_SIZE
+#define CONFIG_ENV_OFFSET      ((512 * 1024) + CONFIG_SYS_NAND_BLOCK_SIZE)
+#define CONFIG_ENV_RANGE       (3 * CONFIG_ENV_SIZE)
+#elif defined(CONFIG_SYS_RAMBOOT)
+#define CONFIG_ENV_IS_NOWHERE  /* Store ENV in memory only */
 #define CONFIG_ENV_ADDR                (CONFIG_SYS_MONITOR_BASE - 0x1000)
-#define CONFIG_ENV_SIZE                0x400
+#define CONFIG_ENV_SIZE                0x2000
 #endif
 
 #define CONFIG_LOADS_ECHO              /* echo on for serial download */
@@ -406,7 +442,9 @@ extern unsigned long get_sdram_size(void);
        "fdtfile=bsc9131rdb.dtb\0"              \
        "bdev=sda1\0"   \
        "hwconfig=usb1:dr_mode=host,phy_type=ulpi\0"    \
-       "othbootargs=ramdisk_size=600000 \0" \
+       "bootm_size=0x37000000\0"       \
+       "othbootargs=ramdisk_size=600000 " \
+       "default_hugepagesz=256m hugepagesz=256m hugepages=1\0" \
        "usbext2boot=setenv bootargs root=/dev/ram rw " \
        "console=$consoledev,$baudrate $othbootargs; "  \
        "usb start;"                    \
index 431c6869678194aafb5b2fb91678c197339823ad..3aa44435a204f3a499bc638e4ec95348f0b51015 100644 (file)
 #define CONFIG_RESET_VECTOR_ADDRESS    0x1107fffc
 #endif
 
+#ifdef CONFIG_NAND
+#define CONFIG_SPL
+#define CONFIG_SPL_INIT_MINIMAL
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_MINIMAL
+#define CONFIG_SPL_FLUSH_IMAGE
+#define CONFIG_SPL_TARGET              "u-boot-with-spl.bin"
+
+#define CONFIG_SYS_TEXT_BASE           0x00201000
+#define CONFIG_SPL_TEXT_BASE           0xFFFFE000
+#define CONFIG_SPL_MAX_SIZE            8192
+#define CONFIG_SPL_RELOC_TEXT_BASE     0x00100000
+#define CONFIG_SPL_RELOC_STACK         0x00100000
+#define CONFIG_SYS_NAND_U_BOOT_SIZE    ((512 << 10) - 0x2000)
+#define CONFIG_SYS_NAND_U_BOOT_DST     (0x00200000 - CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SYS_NAND_U_BOOT_START   0x00200000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS    0
+#define CONFIG_SYS_LDSCRIPT    "arch/powerpc/cpu/mpc85xx/u-boot-nand.lds"
+#endif
+
 #ifndef CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_TEXT_BASE           0x8ff80000
 #endif
 #define CONFIG_RESET_VECTOR_ADDRESS    0x8ffffffc
 #endif
 
-#ifndef CONFIG_SYS_MONITOR_BASE
-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE    /* start of monitor */
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_MONITOR_BASE        CONFIG_SPL_TEXT_BASE
+#else
+#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 */
@@ -73,6 +95,7 @@
 #if defined(CONFIG_PCI)
 #define CONFIG_PCIE1                   /* PCIE controler 1 (slot 1) */
 #define CONFIG_FSL_PCI_INIT            /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET          /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT           /* enable 64-bit PCI resources */
 
@@ -221,6 +244,10 @@ combinations. this should be removed later
  * IFC Definitions
  */
 /* NOR Flash on IFC */
+
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_NO_FLASH
+#endif
 #define CONFIG_SYS_FLASH_BASE          0x88000000
 #define CONFIG_SYS_MAX_FLASH_SECT      1024    /* Max number of sector: 32M */
 
@@ -301,7 +328,9 @@ combinations. this should be removed later
 
 #define CONFIG_SYS_NAND_BLOCK_SIZE     (128 * 1024)
 
+#ifndef CONFIG_SPL_BUILD
 #define CONFIG_FSL_QIXIS
+#endif
 #ifdef CONFIG_FSL_QIXIS
 #define CONFIG_SYS_FPGA_BASE   0xffb00000
 #define CONFIG_SYS_I2C_FPGA_ADDR       0x66
@@ -337,6 +366,22 @@ combinations. this should be removed later
 #endif
 
 /* Set up IFC registers for boot location NOR/NAND */
+#if defined(CONFIG_NAND)
+#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
@@ -351,6 +396,7 @@ combinations. this should be removed later
 #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
 
 #define CONFIG_BOARD_EARLY_INIT_F      /* Call board_pre_init */
 #define CONFIG_BOARD_EARLY_INIT_R
@@ -373,6 +419,9 @@ combinations. this should be removed later
 #define CONFIG_SYS_NS16550_SERIAL
 #define CONFIG_SYS_NS16550_REG_SIZE    1
 #define CONFIG_SYS_NS16550_CLK         get_bus_freq(0)
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_NS16550_MIN_FUNCTIONS
+#endif
 
 #define CONFIG_SERIAL_MULTI    1 /* Enable both serial ports */
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV   /* determine from environment */
@@ -502,7 +551,6 @@ combinations. this should be removed later
 /*
  * Environment
  */
-#if defined(CONFIG_SYS_RAMBOOT)
 #if defined(CONFIG_RAMBOOT_SDCARD)
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV         0
@@ -516,11 +564,15 @@ combinations. this should be removed later
 #define CONFIG_ENV_OFFSET      0x100000        /* 1MB */
 #define CONFIG_ENV_SECT_SIZE   0x10000
 #define CONFIG_ENV_SIZE                0x2000
-#else
+#elif defined(CONFIG_NAND)
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_SIZE                CONFIG_SYS_NAND_BLOCK_SIZE
+#define CONFIG_ENV_OFFSET      ((512 * 1024) + CONFIG_SYS_NAND_BLOCK_SIZE)
+#define CONFIG_ENV_RANGE       (3 * CONFIG_ENV_SIZE)
+#elif defined(CONFIG_SYS_RAMBOOT)
 #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
index 1e3a5640eb28c47f3f04ea7a199e099010b569fd..7017f8c19b1438f55cd171ace09648563bf127d5 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_FORCE  /* select pci host function     */
 #undef CONFIG_PCI_PNP                  /* do pci plug-and-play         */
                                        /* resource configuration       */
index e102c365c46d3ab8d308fac60b0e7444f64d9cad..c7904a1880b5d23b4617c7fe961c11b6cc1c2142 100644 (file)
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                     /* include pci support                  */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_SYS_EARLY_PCI_INIT
 #undef CONFIG_PCI_PNP
 #undef CONFIG_PCI_SCAN_SHOW
index 11cf58b1469221d36b2cffde58c94c4cb1a2e52c..bbd93ac502040b1f95e4daec52249e939c22add0 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_AUTO   /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index e3e5ebc53c33b37979ff248ebfd9ac1645359f80..36476e0135b6fe3c5c4ed8020ca9cb7d4fd36017 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_AUTO   /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index c4fff486d88616e88079c6b72af8a195910a29f2..4c12c85c2b2bdb2a026de407dba136aa954099ab 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_AUTO   /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 9122cbd8779ec5a27020b1a44b6c9c3d55d6c193..96b6c0ab669d8320a7237e1225414c4720e3a499 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_AUTO  /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index f778af7e363874e98ad2ba815d163d1ae22e98d1..c4cc5fd7375f92503aea15c7792bb72aec388295 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_AUTO   /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 35daed05efa502117e289a8d30c10cb3692de149..78c66c76a779e38c1a3d2650c38988174a6e55a8 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_AUTO  /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index aa5ce29585469801e51637c8a6cd3c4e829a48d4..3e9c21cc9ddd0d6b646444df2e70ff5ea7968ab0 100644 (file)
 #define CONFIG_CMD_I2C
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
     #define CONFIG_CMD_PCI
 #endif
 
index a3ceed17f1345bc37d3cd16467e57b9365fc0390..6632196ad90c8e8ca03b90314235ea89679ef958 100644 (file)
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                     /* include pci support                  */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef CONFIG_PCI_PNP
 
 
index bbe271303a839f6bc15d6bdaa8c6795f8318cacd..4970ea657b7e73e1322e900e101eeefb3748377b 100644 (file)
@@ -357,6 +357,7 @@ int du440_phy_addr(int devnum);
  * PCI stuff
  */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do (not) pci plug-and-play   */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
 #define CONFIG_SYS_PCI_TARGBASE       0x80000000 /* PCIaddr mapped to CONFIG_SYS_PCI_MEMBASE*/
index 220372ccd8ff4ee72a0d31d5f8b2d54b99bc0e83..d10f4c18a7c636a12f6edb72aa4dbea94a2871e4 100644 (file)
  * PCI stuff
  */
 #define CONFIG_PCI                                /* include pci support */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                            /* pci plug-and-play */
 #define CONFIG_PCI_HOST         PCI_HOST_AUTO
 #undef  CONFIG_PCI_SCAN_SHOW
index 08ba8404bf8c88efc639edec913c83bc669db71b..b6769ae68dc53201832176e695e1c50311478cdf 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_HOST   /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 444413d8d6646545fed0227a42d66cd7d30feba2..d65377f58004aab8e039058a573eee1179bee7cf 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_HOST   /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index a62ef6364b211afc8c6b529e118f083cd1ffa4a4..dbad1fd6afab4edd71491118cf1a3ffa4a2d1083 100644 (file)
@@ -93,6 +93,7 @@
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                             /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef CONFIG_PCI_PNP
 
 
index 791763aaaf4ce9aa45e5342cbe9c527cfcac3092..2b72a33487f391cfed12d8882969e9f3c3e83199 100644 (file)
 #define CONFIG_PCI_PNP         /* Scan PCI busses                      */
 #define CONFIG_CMD_PCI         /* Enable the "pci" command             */
 #define CONFIG_FSL_PCI_INIT    /* Common FreeScale PCI initialization  */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  /* We have PCI-E reset errata           */
 #define CONFIG_SYS_PCI_64BIT   /* PCI resources are 64-bit             */
 #define CONFIG_PCI_SCAN_SHOW   /* Display PCI scan during boot         */
index e0a0d8e46bd54a906df4af8e56f84cdfc680e755..6ce789d7faba2843c74cf6916201ce72d3d40f2b 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function     */
 #undef CONFIG_PCI_PNP                  /* do pci plug-and-play         */
                                        /* resource configuration       */
index 546e28b8fae1f5403f52c4bb59ac399657985158..8d5e8ff653f64f209010f800e6adbbdd00ba7e48 100644 (file)
  *----------------------------------------------------------------------*/
 /* General PCI */
 #define CONFIG_PCI                          /* include pci support     */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                      /* do pci plug-and-play    */
 #define CONFIG_PCI_SCAN_SHOW                /* show pci devices        */
 #define CONFIG_SYS_PCI_TARGBASE      (CONFIG_SYS_PCI_MEMBASE)
index 30fb6c2ffd0aa3aa25f177de7c7087237216f262..2496639512126d0c0329245ba5580a02a5b33e84 100644 (file)
@@ -36,6 +36,7 @@
 #define CONFIG_SYS_TEXT_BASE   0xFC000000
 
 #define CONFIG_PCI     1
+#define CONFIG_PCI_INDIRECT_BRIDGE 1
 
 #define        CONFIG_MASK_AER_AO
 #define CONFIG_DISPLAY_AER_FULL
index 286f8690a82a4f91ae084c151435c48c47a67a67..d1ef559cf4701e1a47448c6c11b092be667242b4 100644 (file)
  *----------------------------------------------------------------------*/
 /* General PCI */
 #define CONFIG_PCI                          /* include pci support     */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                      /* do pci plug-and-play    */
 #define CONFIG_PCI_SCAN_SHOW                /* show pci devices        */
 #define CONFIG_SYS_PCI_TARGBASE      (CONFIG_SYS_PCI_MEMBASE)
index 979495a72c2bfb9a6e66a5c393672daca9539f2e..0d023ab9fbe29d566d1824f16f7dc81ca7871210 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_FORCE /* configure as pci-host        */
 #define CONFIG_PCI_PNP                 /* pci plug-and-play            */
                                        /* resource configuration       */
index 1391ce517dc1a37e332b47e4c1e48aaf37939650..b3dbd6fae5e2a4cfaa30944715d0585ce4d1620a 100644 (file)
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                     /* include pci support                  */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef CONFIG_PCI_PNP
 
 
index c4c41c77deb0d72bc2a052e3eb3c3973cfcdc331..c312b7781dd7ba73196c2e6c309453f74aeb6547 100644 (file)
 /*PCI*/
 #if CONFIG_ADSTYPE >= CONFIG_SYS_PQ2FADS
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_PNP
 #define CONFIG_PCI_BOOTDELAY 0
 #define CONFIG_PCI_SCAN_SHOW
index 0474140fb38b490ad3d3a1d60dac0f71f152203c..c5aa58650ea64f16daf562c4efbe037b5f40213e 100644 (file)
 
 /* PCI */
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_PNP
 #define CONFIG_PCI_BOOTDELAY 0
 #undef CONFIG_PCI_SCAN_SHOW
index 95a1885ace176aab67deaa79d9eea58547ddc3fc..f10555ce01797fa0852c6ab76dfaf236b6303df6 100644 (file)
 #define CONFIG_SYS_SCCR_PCIEXP1CM      1
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCIE
 
 #define CONFIG_PCI_PNP         /* do pci plug-and-play */
index c28dfe0068ebec732937e618886746362292d93a..1d753e76b9a966bef01cf54af070f5e5119456f7 100644 (file)
@@ -76,6 +76,7 @@
 #endif
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_FSL_ELBC 1
 
 #define CONFIG_MISC_INIT_R
index 767b9763e41bc2618c42e98ac09078eccf5b08cf..ee806c4403302ec9ea541565510dd52d73d74e90 100644 (file)
 #define CONFIG_SYS_PCIE2_IO_SIZE       0x00800000
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCIE
 
 #define CONFIG_PCI_PNP         /* do pci plug-and-play */
index 8d5ed0f7aba8bc44d557c309c5071efaddeed63d..ac4c253968d3cc5994324cfcd5798d047acbad66 100644 (file)
 #define CONFIG_SYS_PCI1_IO_SIZE                0x04000000      /* 64M */
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_SKIP_HOST_BRIDGE
 #define CONFIG_PCI_PNP         /* do pci plug-and-play */
 
index f592d3a3a46426b756a9692f44add04ba4f83739..7c31f47953bd0c05497df7f37aa8be65cb6b6db8 100644 (file)
 
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 
 #define CONFIG_PCI_PNP         /* do pci plug-and-play */
 #define CONFIG_83XX_PCI_STREAMING
index e5529c70070b06662185bff8aed20e3479e8e823..212089c238e991e295fcbcc3c9f6b0287c66f1d9 100644 (file)
 
 /* PCI @ 0x80000000 */
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_SYS_IBAT1L      (CONFIG_SYS_PCI1_MEM_BASE \
                                | BATL_PP_RW \
                                | BATL_MEMCOHERENCE)
index 2c3f1f62a64f00bfbbf501e4cbb22defb90602a0..1130b59a217ac2f967bbe84a7d6850add5d21101 100644 (file)
@@ -393,6 +393,7 @@ boards, we say we have two, but don't display a message if we find only one. */
  * PCI
  */
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 
 #define CONFIG_MPC83XX_PCI2
 
index a1fbd5e4a4b4bc8367470b96ddd5e48866c32ac9..a71ac2bd359ee903c51ac6a216e61a314b80e484 100644 (file)
 
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 
 #define CONFIG_PCI_PNP         /* do pci plug-and-play */
 #define CONFIG_83XX_PCI_STREAMING
index fc0095281afecc52d85952525c7174ee8c7ccde4..fcca5424e385a0595a4a332b702f4f9965daafb0 100644 (file)
 #define CONFIG_SYS_PCI1_IO_SIZE                0x100000 /* 1M */
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 
 #define CONFIG_PCI_PNP         /* do pci plug-and-play */
 
index 82436618bea84d741e69765b4cd3cc07a9e1f304..480468f2d7cdb47ed80240e6548b675d9d790e64 100644 (file)
 #define CONFIG_SYS_PCIE2_IO_SIZE       0x00800000
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #ifndef __ASSEMBLY__
 extern int board_pci_host_broken(void);
 #endif
index 9ad7e3a90ff293b8d651c28dacdf0d07aa8124b4..d5c9d059ebdf9b2ec24c322376995cc14aee6e0e 100644 (file)
 #define CONFIG_SYS_PCIE2_IO_SIZE       0x00800000
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_PNP         /* do pci plug-and-play */
 
 #undef CONFIG_PCI_SCAN_SHOW    /* show pci devices on startup */
index bcd77b608f3782f1b013a7865398d9a4b76997b9..cc2b7c332b780849667188c9b9e6b3f3529b7e14 100644 (file)
@@ -84,6 +84,7 @@
 #define CONFIG_PCIE2           1       /* PCIE controler 2 (slot 2) */
 #define CONFIG_PCIE3           1       /* PCIE controler 3 (ULI bridge) */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 
index a0fe15e86e600b1f8f0d796eac23314ebea56589..6cb00ee664689e3b123c289869508e0491acd499 100644 (file)
@@ -52,6 +52,7 @@
 #endif
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_TSEC_ENET               /* tsec ethernet support */
 #define CONFIG_ENV_OVERWRITE
index a6bea153d7ed9ab6656d900ff77a4805d9c9fe09..d0e6ca65bfcd42bffbd1f3c38ea73706cb23c8b6 100644 (file)
@@ -40,6 +40,7 @@
 #define        CONFIG_SYS_TEXT_BASE    0xfff80000
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_TSEC_ENET               /* tsec ethernet support */
 #define CONFIG_ENV_OVERWRITE
index d5f3c5f56f293404b4027dd63b661f142afa5ba3..09d0835c619c2e357c0a2b92550d2d731e82f10d 100644 (file)
@@ -44,6 +44,7 @@
 #define CONFIG_PCIE2           1       /* PCIE controler 2 (slot 2) */
 #define CONFIG_PCIE3           1       /* PCIE controler 3 (ULI bridge) */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 
index 0e22cc7e14df46432e01900d1f64d40089f2f785..d070f6adc3e176844bd2fb292b1ba87df6f86f3b 100644 (file)
@@ -52,6 +52,7 @@
 #define CONFIG_PCIE1           /* PCIE controler 1 (slot 1) */
 #undef CONFIG_PCI2
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 
index 266cb54c923f9cc6d49b16fa553252a3dbfd8ef9..483556b31b1ed448f721fdc7607d48c0b72ec8cb 100644 (file)
@@ -40,6 +40,7 @@
 #define        CONFIG_SYS_TEXT_BASE    0xfff80000
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_TSEC_ENET               /* tsec ethernet support */
 #define CONFIG_ENV_OVERWRITE
index 35d15f4271f62f14ca01ea2173e9fb9caf4427ae..525e88fa1b684a4f9458ccc333865fbe163a63af 100644 (file)
@@ -49,6 +49,7 @@
 #define        CONFIG_SYS_TEXT_BASE    0xfff80000
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_TSEC_ENET               /* tsec ethernet support */
 #undef CONFIG_ETHER_ON_FCC             /* cpm FCC ethernet support */
index 5d69fb66d98016e054e465b5f8424a260b71a7b5..f1bfdcbd2cfbcceb6555fca27f4535074a384378 100644 (file)
@@ -42,6 +42,7 @@
 #define CONFIG_PCI1            1       /* PCI controller */
 #define CONFIG_PCIE1           1       /* PCIE controller */
 #define CONFIG_FSL_PCI_INIT    1       /* use common fsl pci init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_TSEC_ENET               /* tsec ethernet support */
index acd3276e9826e30e14767c9f6b7be0ac7ea20907..c54755fab8da4e6826fc37f46e135d1abb17b1e4 100644 (file)
@@ -41,6 +41,7 @@
 #define CONFIG_PCI             1       /* Disable PCI/PCIE */
 #define CONFIG_PCIE1           1       /* PCIE controller */
 #define CONFIG_FSL_PCI_INIT    1       /* use common fsl pci init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_QE                      /* Enable QE */
index d233365b7d0e5dc9cff1162b11474e84c52b759b..25303c4f65df8fdcbafa7abe35c1f2186499378b 100644 (file)
@@ -71,6 +71,7 @@
 #define CONFIG_PCIE2           1       /* PCIE controler 2 (slot 2) */
 #define CONFIG_PCIE3           1       /* PCIE controler 3 (ULI bridge) */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 
index c61982745fe9d545435d5959d694fa24dbfb4ee9..f791e7682e4a7e9661c70a8dd9267ee210a0afb1 100644 (file)
@@ -51,6 +51,7 @@
 #define CONFIG_PCIE1           1       /* PCIe 1 connected to ULI bridge */
 #define CONFIG_PCIE2           1       /* PCIe 2 connected to slot */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_FSL_LAW         1       /* Use common FSL init code */
 
index 264309772a9b8890ae9fde42b5ba8bea69e0555f..4a3ca017e8377f653e5fa8d7d0b55889257d1017 100644 (file)
@@ -510,6 +510,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
  * BAT2                Rapidio Memory
  */
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_SYS_DBAT2L      (BAT_PHYS_ADDR(CONFIG_SYS_PCIE1_MEM_PHYS_LOW, \
                                               CONFIG_SYS_PCIE1_MEM_PHYS_HIGH) \
                                 | BATL_PP_RW | BATL_CACHEINHIBIT \
index 84a167d2a7196cd08e89af9a0be2b761f41d2346..8b0415158a745f8248f6552bf9c7ebde2cb90c73 100644 (file)
@@ -87,6 +87,7 @@
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef CONFIG_PCI_PNP
 
 
index a9c00acc9ad5d584cffdc920879e379c79690e74..afd4c0356dd6136c3f52ec36b1a93ab636061ccc 100644 (file)
@@ -42,6 +42,7 @@
 #define CONFIG_SYS_IMMR                0xE0000000
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_SKIP_HOST_BRIDGE
 #define CONFIG_HARD_I2C
 #define CONFIG_TSEC_ENET
index 52d172925b5fc88134d561b66b9c2ea48142a080..21f286e0fb5c5e5050ca2ed2fc4f26ea8a375b3f 100644 (file)
  */
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_PNP
 #define CONFIG_PCI_SCAN_SHOW
 
index 47110aff246d63d518d57ae188b83601931469d2..4a934176550fa7b4918ddb8a55713abdfb8d6050 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_AUTO  /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 9f754c2a81e56519a0e9b48c91cd07cd22c0cdbb..cd1f4254ad5936ac828e814b8a0b4bb6138fc7e0 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_ADAPTER /* select pci adapter         */
 #undef CONFIG_PCI_PNP                  /* no pci plug-and-play         */
                                        /* resource configuration       */
index 437ee6ee6b934c10e09e4dfd8c86285eaee23cec..7b28a27bc07619b8b5e4a5b366464ef1c063ad61 100644 (file)
 #define CONFIG_PHYS_64BIT
 #endif
 
-#ifdef CONFIG_P1010RDB
 #define CONFIG_P1010
+#define CONFIG_E500                    /* BOOKE e500 family */
+#include <asm/config_mpc85xx.h>
 #define CONFIG_NAND_FSL_IFC
-#endif
 
 #ifdef CONFIG_SDCARD
 #define CONFIG_RAMBOOT_SDCARD
 #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 */
+#ifdef CONFIG_NAND
+#define CONFIG_SPL
+#define CONFIG_SPL_INIT_MINIMAL
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_MINIMAL
+#define CONFIG_SPL_FLUSH_IMAGE
+#define CONFIG_SPL_TARGET              "u-boot-with-spl.bin"
+
+#define CONFIG_SYS_TEXT_BASE           0x00201000
+#define CONFIG_SPL_TEXT_BASE           0xFFFFE000
+#define CONFIG_SPL_MAX_SIZE            8192
+#define CONFIG_SPL_RELOC_TEXT_BASE     0x00100000
+#define CONFIG_SPL_RELOC_STACK         0x00100000
+#define CONFIG_SYS_NAND_U_BOOT_SIZE    ((512 << 10) - 0x2000)
+#define CONFIG_SYS_NAND_U_BOOT_DST     (0x00200000 - CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SYS_NAND_U_BOOT_START   0x00200000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS    0
+#define CONFIG_SYS_LDSCRIPT    "arch/powerpc/cpu/mpc85xx/u-boot-nand.lds"
 #endif
 
 
 #define CONFIG_RESET_VECTOR_ADDRESS    0xeffffffc
 #endif
 
-#ifndef CONFIG_SYS_MONITOR_BASE
-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE    /* start of monitor */
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_MONITOR_BASE        CONFIG_SPL_TEXT_BASE
+#else
+#define CONFIG_SYS_MONITOR_BASE        CONFIG_SYS_TEXT_BASE    /* start of monitor */
 #endif
 
 /* High Level Configuration Options */
 #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_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET          /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT           /* enable 64-bit PCI resources */
 
@@ -241,7 +254,7 @@ extern unsigned long get_sdram_size(void);
 #define CONFIG_SYS_CCSRBAR_PHYS_LOW            CONFIG_SYS_CCSRBAR
 
 /* Don't relocate CCSRBAR while in NAND_SPL */
-#ifdef CONFIG_NAND_SPL
+#ifdef CONFIG_SPL_BUILD
 #define CONFIG_SYS_CCSR_DO_NOT_RELOCATE
 #endif
 
@@ -267,6 +280,10 @@ extern unsigned long get_sdram_size(void);
  * IFC Definitions
  */
 /* NOR Flash on IFC */
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_NO_FLASH
+#endif
+
 #define CONFIG_SYS_FLASH_BASE          0xee000000
 #define CONFIG_SYS_MAX_FLASH_SECT      256     /* 32M */
 
@@ -352,7 +369,7 @@ extern unsigned long get_sdram_size(void);
 #define CONFIG_SYS_NAND_DDR_LAW                11
 
 /* Set up IFC registers for boot location NOR/NAND */
-#if defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SECBOOT)
+#if defined(CONFIG_NAND) || defined(CONFIG_NAND_SECBOOT)
 #define CONFIG_SYS_CSPR0               CONFIG_SYS_NAND_CSPR
 #define CONFIG_SYS_AMASK0              CONFIG_SYS_NAND_AMASK
 #define CONFIG_SYS_CSOR0               CONFIG_SYS_NAND_CSOR
@@ -384,15 +401,6 @@ extern unsigned long get_sdram_size(void);
 #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
 
@@ -420,14 +428,20 @@ extern unsigned long get_sdram_size(void);
 #define CONFIG_SYS_CS3_FTIM3           0x0
 #endif /* CONFIG_SDCARD */
 
-#if defined(CONFIG_RAMBOOT_SDCARD) || defined(CONFIG_RAMBOOT_SPIFLASH) || \
-    defined(CONFIG_RAMBOOT_NAND)
+#if defined(CONFIG_RAMBOOT_SDCARD) || defined(CONFIG_RAMBOOT_SPIFLASH)
 #define CONFIG_SYS_RAMBOOT
 #define CONFIG_SYS_EXTRA_ENV_RELOC
 #else
 #undef CONFIG_SYS_RAMBOOT
 #endif
 
+#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A003399
+#if !defined(CONFIG_SPL) && !defined(CONFIG_SYS_RAMBOOT)\
+       && !defined(CONFIG_SECURE_BOOT)
+#define CONFIG_A003399_NOR_WORKAROUND
+#endif
+#endif
+
 #define CONFIG_BOARD_EARLY_INIT_F      /* Call board_pre_init */
 #define CONFIG_BOARD_EARLY_INIT_R
 
@@ -449,7 +463,7 @@ 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
+#ifdef CONFIG_SPL_BUILD
 #define CONFIG_NS16550_MIN_FUNCTIONS
 #endif
 
@@ -504,7 +518,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
  */
-#if !defined(CONFIG_NAND_U_BOOT) || !defined(CONFIG_NAND_SECBOOT)
+#if !defined(CONFIG_NAND) || !defined(CONFIG_NAND_SECBOOT)
 /* eSPI - Enhanced SPI */
 #define CONFIG_FSL_ESPI
 #define CONFIG_SPI_FLASH
@@ -599,7 +613,6 @@ extern unsigned long get_sdram_size(void);
 /*
  * Environment
  */
-#if defined(CONFIG_SYS_RAMBOOT)
 #if defined(CONFIG_RAMBOOT_SDCARD)
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_FSL_FIXED_MMC_LOCATION
@@ -614,16 +627,15 @@ 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)
+#elif defined(CONFIG_NAND)
 #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_OFFSET      ((512 * 1024) + CONFIG_SYS_NAND_BLOCK_SIZE)
 #define CONFIG_ENV_RANGE       (3 * CONFIG_ENV_SIZE)
-#else
+#elif defined(CONFIG_SYS_RAMBOOT)
 #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
index 8b13b107e28091ebc1c6230fa8f1695dc44aa6b0..9c27182dc7152b1febb5360e51b70b12849c979b 100644 (file)
 #define CONFIG_SYS_HUSH_PARSER
 
 /* Video */
-#define CONFIG_FSL_DIU_FB
 
 #ifdef CONFIG_FSL_DIU_FB
 #define CONFIG_SYS_DIU_ADDR    (CONFIG_SYS_CCSRBAR + 0x10000)
 #endif
 
 #ifndef CONFIG_FSL_DIU_FB
-#define CONFIG_ATI
 #endif
 
 #ifdef CONFIG_ATI
 #define CONFIG_SYS_PCIE3_IO_SIZE       0x00010000      /* 64k */
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup */
 #define CONFIG_E1000                   /* Define e1000 pci Ethernet card */
diff --git a/include/configs/P1023RDB.h b/include/configs/P1023RDB.h
new file mode 100644 (file)
index 0000000..fee8040
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * Authors:  Roy Zang <tie-fei.zang@freescale.com>
+ *          Chunhe Lan <Chunhe.Lan@freescale.com>
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#ifndef CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_TEXT_BASE   0xeff80000
+#endif
+
+#ifndef CONFIG_SYS_MONITOR_BASE
+#define CONFIG_SYS_MONITOR_BASE        CONFIG_SYS_TEXT_BASE    /* start of monitor */
+#endif
+
+#ifndef CONFIG_RESET_VECTOR_ADDRESS
+#define CONFIG_RESET_VECTOR_ADDRESS    0xeffffffc
+#endif
+
+/* High Level Configuration Options */
+#define CONFIG_BOOKE           /* BOOKE */
+#define CONFIG_E500            /* BOOKE e500 family */
+#define CONFIG_MPC85xx
+#define CONFIG_P1023
+#define CONFIG_MP              /* support multiple processors */
+
+#define CONFIG_FSL_ELBC                /* Has Enhanced localbus controller */
+#define CONFIG_PCI             /* Enable PCI/PCIE */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
+#define CONFIG_PCIE1           /* PCIE controler 1 (slot 1) */
+#define CONFIG_PCIE2           /* PCIE controler 2 (slot 2) */
+#define CONFIG_PCIE3           /* PCIE controler 3 (slot 3) */
+#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_FSL_LAW         /* Use common FSL init code */
+
+#ifndef __ASSEMBLY__
+extern unsigned long get_clock_freq(void);
+#endif
+
+#define CONFIG_SYS_CLK_FREQ    66666666
+#define CONFIG_DDR_CLK_FREQ    CONFIG_SYS_CLK_FREQ
+
+/*
+ * 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_HWCONFIG
+
+#define CONFIG_ENABLE_36BIT_PHYS
+
+#define CONFIG_SYS_MEMTEST_START       0x01000000      /* memtest works on */
+#define CONFIG_SYS_MEMTEST_END         0x02000000
+
+#define CONFIG_PANIC_HANG      /* do not reset board on panic */
+
+/* Implement conversion of addresses in the LBC */
+#define CONFIG_SYS_LBC_LBCR            0x00000000
+#define CONFIG_SYS_LBC_LCRR            LCRR_CLKDIV_8
+
+/* DDR Setup */
+#define CONFIG_VERY_BIG_RAM
+#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
+
+#define CONFIG_DDR_SPD
+#define CONFIG_FSL_DDR3
+#define CONFIG_FSL_DDR_INTERACTIVE
+#define CONFIG_SYS_SDRAM_SIZE          512u    /* DDR is 512M */
+#define CONFIG_SYS_SPD_BUS_NUM          0
+#define SPD_EEPROM_ADDRESS              0x50
+#define CONFIG_SYS_DDR_RAW_TIMING
+
+/*
+ * Memory map
+ *
+ * 0x0000_0000 0x1fff_ffff     DDR                     512M cacheable
+ * 0x8000_0000 0xbfff_ffff     PCI Express Mem         1G non-cacheable
+ * 0xc000_0000 0xdfff_ffff     PCI                     512M non-cacheable
+ * 0xe100_0000 0xe3ff_ffff     PCI IO range            4M non-cacheable
+ * 0xff00_0000 0xff3f_ffff     DPAA_QBMAN              4M cacheable
+ * 0xff60_0000 0xff7f_ffff     CCSR                    2M non-cacheable
+ * 0xffd0_0000 0xffd0_3fff     L1 for stack            16K cacheable TLB0
+ *
+ * Localbus non-cacheable
+ *
+ * 0xec00_0000 0xefff_ffff     NOR flash               64M non-cacheable
+ * 0xffa0_0000 0xffaf_ffff     NAND                    1M non-cacheable
+ */
+
+/*
+ * Local Bus Definitions
+ */
+#define CONFIG_SYS_FLASH_BASE          0xec000000 /* start of FLASH 64M */
+#define CONFIG_SYS_FLASH_BASE_PHYS     CONFIG_SYS_FLASH_BASE
+
+#define CONFIG_FLASH_BR_PRELIM  (BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) \
+                               | BR_PS_16 | BR_V)
+#define CONFIG_FLASH_OR_PRELIM 0xfc000ff7
+
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_SYS_FLASH_EMPTY_INFO
+#define CONFIG_SYS_MAX_FLASH_BANKS     1       /* number of banks */
+#define CONFIG_SYS_MAX_FLASH_SECT      512     /* sectors per device */
+#define CONFIG_SYS_FLASH_ERASE_TOUT    60000   /* Flash Erase Timeout (ms) */
+#define CONFIG_SYS_FLASH_WRITE_TOUT    500     /* Flash Write Timeout (ms) */
+
+#define CONFIG_BOARD_EARLY_INIT_F      /* call board_early_init_f function */
+#define CONFIG_BOARD_EARLY_INIT_R      /* call board_early_init_r function */
+
+#define CONFIG_SYS_INIT_RAM_LOCK
+#define CONFIG_SYS_INIT_RAM_ADDR       0xffd00000      /* Initial L1 address */
+#define CONFIG_SYS_INIT_RAM_SIZE       0x00004000/* Size of used area in RAM */
+#define CONFIG_SYS_GBL_DATA_OFFSET     (CONFIG_SYS_INIT_RAM_SIZE - \
+                                       GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_OFFSET      CONFIG_SYS_GBL_DATA_OFFSET
+
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024)      /* Reserve 512 kB for Mon */
+#define CONFIG_SYS_MALLOC_LEN  (6 * 1024 * 1024) /* Reserved for malloc */
+
+#define CONFIG_SYS_NAND_BASE           0xffa00000
+#define CONFIG_SYS_NAND_BASE_PHYS      CONFIG_SYS_NAND_BASE
+
+#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_NAND_FSL_ELBC
+#define CONFIG_SYS_NAND_BLOCK_SIZE     (128 * 1024)
+
+/* NAND flash config */
+#define CONFIG_SYS_NAND_BR_PRELIM  (BR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \
+                               | (2<<BR_DECC_SHIFT)    /* Use HW ECC */ \
+                               | BR_PS_8               /* Port Size = 8bit */ \
+                               | BR_MS_FCM             /* MSEL = FCM */ \
+                               | BR_V)                 /* valid */
+#define CONFIG_SYS_NAND_OR_PRELIM  (OR_AM_256KB                /* length 256K */ \
+                               | OR_FCM_PGS \
+                               | OR_FCM_CSCT \
+                               | OR_FCM_CST \
+                               | OR_FCM_CHT \
+                               | OR_FCM_SCY_1 \
+                               | OR_FCM_TRLX \
+                               | OR_FCM_EHTR)
+
+#define CONFIG_SYS_BR0_PRELIM  CONFIG_FLASH_BR_PRELIM  /* NOR Base Address */
+#define CONFIG_SYS_OR0_PRELIM  CONFIG_FLASH_OR_PRELIM  /* NOR Options */
+#define CONFIG_SYS_BR1_PRELIM  CONFIG_SYS_NAND_BR_PRELIM
+#define CONFIG_SYS_OR1_PRELIM  CONFIG_SYS_NAND_OR_PRELIM /* NAND Options */
+
+/* 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_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
+
+/*
+ * 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}() */
+
+/* I2C */
+#define CONFIG_FSL_I2C         /* Use FSL common I2C driver */
+#define CONFIG_HARD_I2C                /* I2C with hardware support */
+#define CONFIG_I2C_MULTI_BUS
+#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
+
+/*
+ * I2C2 EEPROM
+ */
+#define CONFIG_ID_EEPROM
+#ifdef CONFIG_ID_EEPROM
+#define CONFIG_SYS_I2C_EEPROM_NXID
+#endif
+#define CONFIG_SYS_I2C_EEPROM_ADDR             0x50
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_BUS_NUM              0
+
+#define CONFIG_CMD_I2C
+
+/*
+ * General PCI
+ * Memory space is mapped 1-1, but I/O space must start from 0.
+ */
+
+/* controller 3, Slot 1, tgtid 3, Base address b000 */
+#define CONFIG_SYS_PCIE3_NAME          "Slot 3"
+#define CONFIG_SYS_PCIE3_MEM_VIRT      0x80000000
+#define CONFIG_SYS_PCIE3_MEM_BUS       0x80000000
+#define CONFIG_SYS_PCIE3_MEM_PHYS      0x80000000
+#define CONFIG_SYS_PCIE3_MEM_SIZE      0x20000000      /* 512M */
+#define CONFIG_SYS_PCIE3_IO_VIRT       0xffc00000
+#define CONFIG_SYS_PCIE3_IO_BUS                0x00000000
+#define CONFIG_SYS_PCIE3_IO_PHYS       0xffc00000
+#define CONFIG_SYS_PCIE3_IO_SIZE       0x00010000      /* 64k */
+
+/* controller 2, direct to uli, tgtid 2, Base address 9000 */
+#define CONFIG_SYS_PCIE2_NAME          "Slot 2"
+#define CONFIG_SYS_PCIE2_MEM_VIRT      0xa0000000
+#define CONFIG_SYS_PCIE2_MEM_BUS       0xa0000000
+#define CONFIG_SYS_PCIE2_MEM_PHYS      0xa0000000
+#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_PHYS       0xffc10000
+#define CONFIG_SYS_PCIE2_IO_SIZE       0x00010000      /* 64k */
+
+/* controller 1, Slot 2, tgtid 1, Base address a000 */
+#define CONFIG_SYS_PCIE1_NAME          "Slot 1"
+#define CONFIG_SYS_PCIE1_MEM_VIRT      0xc0000000
+#define CONFIG_SYS_PCIE1_MEM_BUS       0xc0000000
+#define CONFIG_SYS_PCIE1_MEM_PHYS      0xc0000000
+#define CONFIG_SYS_PCIE1_MEM_SIZE      0x20000000      /* 512M */
+#define CONFIG_SYS_PCIE1_IO_VIRT       0xffc20000
+#define CONFIG_SYS_PCIE1_IO_BUS                0x00000000
+#define CONFIG_SYS_PCIE1_IO_PHYS       0xffc20000
+#define CONFIG_SYS_PCIE1_IO_SIZE       0x00010000      /* 64k */
+
+#if defined(CONFIG_PCI)
+#define CONFIG_E1000           /* Defind e1000 pci Ethernet card */
+#define CONFIG_PCI_PNP         /* do pci plug-and-play */
+#define CONFIG_PCI_SCAN_SHOW   /* show pci devices on startup */
+#endif /* CONFIG_PCI */
+
+/*
+ * Environment
+ */
+#define CONFIG_ENV_OVERWRITE
+
+#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) */
+
+#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_IRQ
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_SETEXPR
+#define CONFIG_CMD_REGINFO
+
+#if defined(CONFIG_PCI)
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_NET
+#endif
+
+/*
+ * USB
+ */
+#define CONFIG_HAS_FSL_DR_USB
+#ifdef CONFIG_HAS_FSL_DR_USB
+#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_CMD_FAT
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+#define CONFIG_DOS_PARTITION
+#endif
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP                    /* undef to save memory */
+#define CONFIG_CMDLINE_EDITING         /* Command-line editing */
+#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
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT)+16)
+#define CONFIG_SYS_MAXARGS     16              /* max number of command args */
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_HZ  1000            /* decrementer freq: 1ms ticks */
+
+/*
+ * 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 */
+
+/*
+ * Environment Configuration
+ */
+#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 -1    /* -1 disables auto-boot */
+
+#define CONFIG_BAUDRATE        115200
+
+/* Qman/Bman */
+#define CONFIG_SYS_DPAA_QBMAN          /* support Q/Bman */
+#define CONFIG_SYS_QMAN_MEM_BASE       0xff000000
+#define CONFIG_SYS_QMAN_MEM_PHYS       CONFIG_SYS_QMAN_MEM_BASE
+#define CONFIG_SYS_QMAN_MEM_SIZE       0x00200000
+#define CONFIG_SYS_BMAN_MEM_BASE       0xff200000
+#define CONFIG_SYS_BMAN_MEM_PHYS       CONFIG_SYS_BMAN_MEM_BASE
+#define CONFIG_SYS_BMAN_MEM_SIZE       0x00200000
+
+/* For FM */
+#define CONFIG_SYS_DPAA_FMAN
+#define CONFIG_PHY_GIGE                /* Include GbE speed/duplex detection */
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+#define CONFIG_FMAN_ENET
+#define CONFIG_PHY_ATHEROS
+#endif
+
+/* Default address of microcode for the Linux Fman driver */
+/* QE microcode/firmware address */
+#define CONFIG_SYS_QE_FMAN_FW_IN_NOR
+#define CONFIG_SYS_QE_FMAN_FW_ADDR     0xeff40000
+#define CONFIG_SYS_QE_FMAN_FW_LENGTH   0x10000
+#define CONFIG_SYS_FDT_PAD             (0x3000 + CONFIG_SYS_QE_FMAN_FW_LENGTH)
+
+#ifdef CONFIG_FMAN_ENET
+#define CONFIG_SYS_FM1_DTSEC1_PHY_ADDR 0x1
+#define CONFIG_SYS_FM1_DTSEC2_PHY_ADDR 0x2
+
+#define CONFIG_SYS_TBIPA_VALUE 8
+#define CONFIG_MII             /* MII PHY management */
+#define CONFIG_ETHPRIME                "FM1@DTSEC1"
+#endif
+
+#define CONFIG_EXTRA_ENV_SETTINGS      \
+       "hwconfig=usb1:dr_mode=host,phy_type=ulpi\0"
+
+#endif /* __CONFIG_H */
index 878bd5fa5e6e9b7627be2466fefd8b1e560b491b..4943d7c8fe95e8d372c0a3cf06d17d86bc906b8e 100644 (file)
@@ -73,6 +73,7 @@
 #define CONFIG_PCIE2           /* PCIE controler 2 (slot 2) */
 #define CONFIG_PCIE3           /* PCIE controler 3 (slot 3) */
 #define CONFIG_FSL_PCI_INIT    /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   /* enable 64-bit PCI resources */
 #define CONFIG_FSL_LAW         /* Use common FSL init code */
index a57d9dd26ec37124a652d4d8133dd07d400e3488..6ce4cbef9c5b4631b14224c8e3272fd51e769bd8 100644 (file)
@@ -94,6 +94,7 @@
 #define CONFIG_PCIE1           1       /* PCIE controler 1 (slot 1) */
 #define CONFIG_PCIE2           1       /* PCIE controler 2 (slot 2) */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #endif /* #if defined(CONFIG_PCI) */
index c75f86cb8445dd76af3a5b0d5779ac84544cb36d..05a75d8a7633841b2a876c7c7f5e50e2a4e0acac 100644 (file)
@@ -58,6 +58,7 @@
 #define CONFIG_PCIE3           1       /* PCIE controller 3 (slot 3) */
 
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #endif /* #if defined(CONFIG_PCI) */
index a975ee10edb30cd6ac4788953532a8d8aa7a3f22..229117c18d58298bc7db48d38b1e5f645c4fed03 100644 (file)
@@ -73,6 +73,7 @@
 #define CONFIG_PCIE2           1       /* PCIE controler 2 (slot 2) */
 #define CONFIG_PCIE3           1       /* PCIE controler 3 (ULI bridge) */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 
index bbc53ceafd22ff5093dd5b52089eba5f3f237e4c..4ea87173682f1aa9b9b9147917be2d76e254b2e4 100644 (file)
@@ -77,6 +77,7 @@
 #define CONFIG_SYS_SRIO
 #define CONFIG_SRIO1                   /* SRIO port 1 */
 #define CONFIG_SRIO2                   /* SRIO port 2 */
+#define CONFIG_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_DPAA_RMAN           /* RMan */
 
 #define CONFIG_FSL_LAW                 /* Use common FSL init code */
@@ -560,6 +561,7 @@ unsigned long get_board_sys_clk(unsigned long dummy);
 #endif
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play */
 #define CONFIG_E1000
 
index ce8f9b0b2eba190c0e11a41bed6a4c054945fc89..dd2b9c34e4f3152d75f8fd396cca086f36cb4656 100644 (file)
@@ -40,7 +40,7 @@
 #define CONFIG_SYS_SRIO
 #define CONFIG_SRIO1                   /* SRIO port 1 */
 #define CONFIG_SRIO2                   /* SRIO port 2 */
-
+#define CONFIG_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_ICS307_REFCLK_HZ                25000000  /* ICS307 ref clk freq */
 
 #include "corenet_ds.h"
index 53979dddf26d10c7e69da2e4418f873dfc6bb29f..48acee4993f1f55fbf6049d9db01dd7038bbb71c 100644 (file)
@@ -36,7 +36,7 @@
 #define CONFIG_SYS_SRIO
 #define CONFIG_SRIO1                   /* SRIO port 1 */
 #define CONFIG_SRIO2                   /* SRIO port 2 */
-
+#define CONFIG_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_ICS307_REFCLK_HZ                33333000  /* ICS307 ref clk freq */
 
 #include "corenet_ds.h"
index 778230d3356c13ced57cc25bde618650f6c9c190..d1e27c42d4c9667b268a4f36b140dada5ed5f8f4 100644 (file)
@@ -41,7 +41,7 @@
 #define CONFIG_SYS_SRIO
 #define CONFIG_SRIO1                   /* SRIO port 1 */
 #define CONFIG_SRIO2                   /* SRIO port 2 */
-
+#define CONFIG_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_ICS307_REFCLK_HZ                25000000  /* ICS307 ref clk freq */
 
 #include "corenet_ds.h"
index 119819e3716f48a3bf32d0427e61f32b841822f5..c3cacefed8cf7dc7e4829dd68d42dcf9d3822542 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_ADAPTER /* select pci host function   */
 #undef CONFIG_PCI_PNP                  /* no pci plug-and-play         */
                                        /* resource configuration       */
index 713ea12ee56deeed42442020a21e372cb5b4245a..3757af07a003a4862d1f3d9f1202377b236d93d8 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_FORCE /* configure as pci-host        */
 #define CONFIG_PCI_PNP                 /* pci plug-and-play            */
                                        /* resource configuration       */
index 1ee0c48fa198848edbbb8e141ddd26e7434956f9..1745eb39fc89c92bce69c6dde3a7be17ecf960f6 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_FORCE  /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index fbcf8e5e227af8bb2b9151a1ea833ca4719bd43a..faadfe43c155d2d98fe0fe7cba915886b77c3ae7 100644 (file)
 #define CONFIG_CMD_SNTP
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_CMD_PCI
 #endif
 
index c37aafdd47a2c3e19126272965ce2deca8a72c09..f563fbe3357c09b0595556d977d438ae10cbb284 100644 (file)
 #define CONFIG_CMD_SNTP
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_CMD_PCI
 #endif
 
index 8235b857d39f648c3ad2d5cebf6e273ae83864ee..d97acecc441a4777dc0ff9b40fe04a496f7f94f1 100644 (file)
 #define PCI_HOST_AUTO          2       /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_AUTO   /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 992443a8e2f6b104e5fb70ae4bf477c98a9ca495..a4275512816b5aeaf89bf297da46712f4623cfc2 100644 (file)
 #define PCI_HOST_AUTO          2       /* detected via arbiter enable  */
 
 #define CONFIG_PCI             /* include pci support                  */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_AUTO  /* select pci host function      */
 #define CONFIG_PCI_PNP         /* do (not) pci plug-and-play           */
 
index 3837b8f1391a232ba222eaec02e76bf4ebe224e3..40c18274f9d61e6a45c9c9c29879794a06750384 100644 (file)
  *----------------------------------------------------------------------*/
 /* General PCI */
 #define CONFIG_PCI             /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP         /* do (not) pci plug-and-play   */
 #define CONFIG_SYS_PCI_CACHE_LINE_SIZE 0       /* to avoid problems with PNP   */
 #define CONFIG_PCI_SCAN_SHOW   /* show pci devices on startup  */
index 93876b13173fd8b3928ec9124ae2029728465d27..e2f96aa4ac018072edf7556ef0cbe29064c88f7d 100644 (file)
  * PCI stuff
  */
 #define CONFIG_PCI                             /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                         /* we need Plug 'n Play         */
 #if 0
 #define CONFIG_PCI_SCAN_SHOW                   /* show PCI auto-scan at boot   */
index 27a12b310be991aa189d057d247b7f39ee7eda89..210bc30ca893580080b38794904f7e171076bdd3 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_FORCE  /* select pci host function     */
 #undef CONFIG_PCI_PNP                  /* do pci plug-and-play         */
                                        /* resource configuration       */
index c0ffb33129d6bad831b6cb6a7297e709765f129e..318c4c5d51cf65ff6c5ca8ed88d37c400aa35106 100644 (file)
@@ -52,6 +52,7 @@
 #endif
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_FSL_ELBC                        1
 
 #define CONFIG_MISC_INIT_R
index f54fcb33e57f0aacb490b966f14fc82ce6018163..fa456ed79f98693d75f33d8a6f733970888c946d 100644 (file)
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                             /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef CONFIG_PCI_PNP
 
 
index 84e4891dc9ac19c226d5cf61138975c2a8f8c7e2..cdc51a501669fc33ad35d6af47fc2dd0ad062552 100644 (file)
@@ -95,6 +95,7 @@
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                             /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef CONFIG_PCI_PNP
 
 
index be977f1d76ea64946c0c294f4bc1c64b33c34bdd..3b3f9e63026ac355984a989d8fe1ff5d62e1fdfe 100644 (file)
 
 #define        CONFIG_PCI
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_BOARD_EARLY_INIT_F 1    /* Call board_early_init_f      */
 #define CONFIG_PCI_PNP
 #define CONFIG_EEPRO100
index 07384234c95deb2428bd6498927bf1a76b5c1a32..966a6e3da9970b863574f2041748959992ea3bb4 100644 (file)
 
 /* PCI */
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_SYS_IBAT3L      (CONFIG_SYS_PCI1_MEM_BASE \
                                | BATL_PP_RW \
                                | BATL_MEMCOHERENCE)
index f1032f0f3ffc26387f5fac36b94e27562438823d..8f0c4b624170659cbb192bbc219d39421ed69ee9 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_HOST   /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 462b155a301131193eddbbf85d8dcd41631d7008..710812fc9f3313f9b9dd6a7f655095021b01a447 100644 (file)
 
 
 #define CONFIG_PCI                             /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST                PCI_HOST_AUTO   /* select pci host function     */
 #define CONFIG_PCI_PNP                         /* pci plug-and-play            */
 /* resource configuration      */
index f28f3e4f9a2aa32351037f7484ef88742a44befa..f88dfe4cde68319f5eef5728fb3a135b4a1e675b 100644 (file)
 #define PCI_HOST_AUTO          2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                             /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST                PCI_HOST_AUTO   /* select pci host function     */
 #define CONFIG_PCI_PNP                         /* pci plug-and-play            */
 /* resource configuration      */
index 5def36ad0c50d17b5024d89a5d7d472a7fd80203..0c78acac80666d7f5fc7f79cc340f2e2c3c5b0ad 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_HOST  /* select pci host function     */
 #undef CONFIG_PCI_PNP                  /* do pci plug-and-play         */
                                        /* resource configuration       */
index e9af8256631c301da586d48a02a4103320092760..8f29229cdca31e67123fb6794e6f480598df0f54 100644 (file)
 #define CONFIG_SPL_BSS_MAX_SIZE                (64 << 10)
 
 #define CONFIG_SPL_OS_BOOT
+#define CONFIG_SPL_ENV_SUPPORT
 /* Place patched DT blob (fdt) at this address */
 #define CONFIG_SYS_SPL_ARGS_ADDR       0x01800000
 
index eea44db356045ef6835c4e22db36978dacf0036c..a6e184961fcc953887184c994fd76fb23c48f043 100644 (file)
  */
 #define CONFIG_PCI
 #define CONFIG_FTPCI100
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_FTPCI100_MEM_BASE        0xa0000000
 #define CONFIG_FTPCI100_IO_SIZE         FTPCI100_BASE_IO_SIZE(256) /* 256M */
 #define CONFIG_FTPCI100_MEM_SIZE        FTPCI100_MEM_SIZE(128)  /* 128M */
index 0d53e51b9d5568471eeba37779ede66258e03ce7..d93d5e204f1155aa9b53824e88f74c794c945c1a 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
 #define CONFIG_SYS_PCI_TARGBASE    0x80000000  /* PCIaddr mapped to CONFIG_SYS_PCI_MEMBASE */
index 7cc3ef24acc30717e2252cb442dd5bd3e755ccb1..9c3c2cd56717d3c3b463892d344800ee03e8cf1c 100644 (file)
 #define CONFIG_SPL
 #define CONFIG_SPL_FRAMEWORK
 /*
- * Place the image at the start of the ROM defined image space and leave
- * space for SRAM scratch entries (see arch/arm/include/omap_common.h).
+ * Place the image at the start of the ROM defined image space.
  * We limit our size to the ROM-defined downloaded image area, and use the
  * rest of the space for stack.
  */
-#define CONFIG_SPL_TEXT_BASE           0x402F0500
+#define CONFIG_SPL_TEXT_BASE           0x402F0400
 #define CONFIG_SPL_MAX_SIZE            (0x4030C000 - CONFIG_SPL_TEXT_BASE)
 #define CONFIG_SPL_STACK               CONFIG_SYS_INIT_SP_ADDR
 
-#define CONFIG_SPL_BSS_START_ADDR      0x80000000
+#define CONFIG_SPL_OS_BOOT
+
+#define CONFIG_SPL_BSS_START_ADDR      0x80a00000
 #define CONFIG_SPL_BSS_MAX_SIZE                0x80000         /* 512 KB */
 
 #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR        0x300 /* address 0x60000 */
 #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS     0x200 /* 256 KB */
 #define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION   1
 #define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME       "u-boot.img"
+
+#ifdef CONFIG_SPL_OS_BOOT
+/* fat */
+#define CONFIG_SPL_FAT_LOAD_KERNEL_NAME                "uImage"
+#define CONFIG_SPL_FAT_LOAD_ARGS_NAME          "args"
+#define CONFIG_SYS_SPL_ARGS_ADDR               (PHYS_DRAM_1 + 0x100)
+
+/* raw mmc */
+#define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR        0x500 /* address 0xa0000 */
+#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR  0x8   /* address 0x1000 */
+#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS 8     /* 4KB */
+
+/* nand */
+#define CONFIG_CMD_SPL_NAND_OFS                        0x240000 /* end of u-boot */
+#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS                0x280000
+#define CONFIG_CMD_SPL_WRITE_SIZE              0x1000
+
+/* spl export command */
+#define CONFIG_CMD_SPL
+#endif
+
 #define CONFIG_SPL_MMC_SUPPORT
 #define CONFIG_SPL_FAT_SUPPORT
 #define CONFIG_SPL_I2C_SUPPORT
 #define CONFIG_SPL_GPIO_SUPPORT
 #define CONFIG_SPL_YMODEM_SUPPORT
 #define CONFIG_SPL_NET_SUPPORT
+#define CONFIG_SPL_ENV_SUPPORT
 #define CONFIG_SPL_NET_VCI_STRING      "AM335x U-Boot SPL"
 #define CONFIG_SPL_ETH_SUPPORT
 #define CONFIG_SPL_SPI_SUPPORT
  * other needs.
  */
 #define CONFIG_SYS_TEXT_BASE           0x80800000
-#define CONFIG_SYS_SPL_MALLOC_START    0x80208000
+#define CONFIG_SYS_SPL_MALLOC_START    0x80a08000
 #define CONFIG_SYS_SPL_MALLOC_SIZE     0x100000
 
 /* Since SPL did pll and ddr initialization for us,
 #define MTDPARTS_DEFAULT               "mtdparts=omap2-nand.0:128k(SPL)," \
                                        "128k(SPL.backup1)," \
                                        "128k(SPL.backup2)," \
-                                       "128k(SPL.backup3),1920k(u-boot)," \
+                                       "128k(SPL.backup3),1792k(u-boot)," \
+                                       "128k(u-boot-spl-os)," \
                                        "128k(u-boot-env),5m(kernel),-(rootfs)"
 #define CONFIG_NAND_OMAP_GPMC
 #define GPMC_NAND_ECC_LP_x16_LAYOUT    1
index 5318aaf99ccd9870b95b695f1630109b85c8a279..bd810538750b03df7524f76bcb0c1763e8798689 100644 (file)
  * PCI
  */
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 
 #define CONFIG_SYS_PCI_MEM_BASE                0xA0000000
 #define CONFIG_SYS_PCI_MEM_PHYS                CONFIG_SYS_PCI_MEM_BASE
index 538a1675286505a4d7844cfb3906fed36f3d525e..57c4b33f1cb09d36ef3857b1b545599d1dd2f587 100644 (file)
 #endif
 
 #define        CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define        CONFIG_PCI_PNP
 #define        CONFIG_SYS_PCI_MSTR_IO_BUS      0x00000000      /* PCI base   */
 
index 506a558f14e5bf0262bb50818837072304d00799..d36984df2d64b4cd0d6372a2e6a0242d9cb6c5ca 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef  CONFIG_PCI_PNP                 /* do (not) pci plug-and-play   */
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
 #define CONFIG_SYS_PCI_TARGBASE        0x80000000 /* PCIaddr mapped to CONFIG_SYS_PCI_MEMBASE*/
index 058da4fa13b60169baa5f3fca3d8707f667591fc..d51f5f885f0f9c1d880f4f58acf0dc2a159d7bd9 100644 (file)
@@ -56,7 +56,7 @@
 
 /* Environment in eMMC, at the end of 2nd "boot sector" */
 #define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OFFSET              ((1024 * 1024) - CONFIG_ENV_SIZE)
+#define CONFIG_ENV_OFFSET              (-CONFIG_ENV_SIZE)
 #define CONFIG_SYS_MMC_ENV_DEV         0
 #define CONFIG_SYS_MMC_ENV_PART                2
 
index da67ae3b5a2be7a9f89a64e34b2e77b9b2d4a299..35a473a429d363489302fdd7886b2996fd04b2cb 100644 (file)
 #define PCI_HOST_AUTO   2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_FORCE  /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index acb127c1d1227a166da8a01d0d45d922ec7ceabe..92106d762de550a7ef7ab17dbce5e42d31f2f400 100644 (file)
  *----------------------------------------------------------------------*/
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play   */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
 #define CONFIG_PCI_CONFIG_HOST_BRIDGE
index 6a991752114ae70ecba7c5829dec2eebf35ae533..f3916de55d61fb0426e3000340dc27d067753cbf 100644 (file)
@@ -55,7 +55,7 @@
 
 /* Environment in eMMC, at the end of 2nd "boot sector" */
 #define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OFFSET              ((512 * 1024) - CONFIG_ENV_SIZE)
+#define CONFIG_ENV_OFFSET              (-CONFIG_ENV_SIZE)
 #define CONFIG_SYS_MMC_ENV_DEV         0
 #define CONFIG_SYS_MMC_ENV_PART                2
 
index be04a7548a7971fa40a11fbc95ff0d6f908babf5..2fefdc80db68e7ea5b72d6493c32ef8add701c44 100644 (file)
@@ -90,7 +90,8 @@
 #endif
 
 /* Generic TPM interfaced through LPC bus */
-#define CONFIG_GENERIC_LPC_TPM
+#define CONFIG_TPM
+#define CONFIG_TPM_TIS_LPC
 #define CONFIG_TPM_TIS_BASE_ADDRESS        0xfed40000
 
 /*-----------------------------------------------------------------------
index 2e2d439678c5fb860290b0f690ddce91a2991f04..66c7b4f95fb3d4a45215cb3e372be630dde5a0e4 100644 (file)
 #endif
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play */
 #define CONFIG_E1000
 
index f21fa648b10ffc02895cc9d4bff6793c3e87021d..eec087c0dc3f5ad0f0e980ea3de8a4f4ace2e728 100644 (file)
  *
  */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define PCI_HOST_ADAPTER       0       /* configure ar pci adapter     */
 #define PCI_HOST_FORCE         1       /* configure as pci host        */
 #define PCI_HOST_AUTO          2       /* detected via arbiter enable  */
index aed5fa6a453e806759cfdf933c9fc525bd5f5bd7..f6a456c18f11f06fcb80864e0bfcafd9d74ab62d 100644 (file)
  *
  */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define PCI_HOST_ADAPTER       0       /* configure ar pci adapter     */
 #define PCI_HOST_FORCE         1       /* configure as pci host        */
 #define PCI_HOST_AUTO          2       /* detected via arbiter enable  */
index 7b68f7ca987515d5473a56ebc3637927e348d33f..6d7a187cf1da954cc71753c876ff0522d9b7becb 100644 (file)
@@ -60,7 +60,7 @@
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV         0
 #define CONFIG_SYS_MMC_ENV_PART                2
-#define CONFIG_ENV_OFFSET              ((4096 * 1024) - CONFIG_ENV_SIZE)
+#define CONFIG_ENV_OFFSET              (-CONFIG_ENV_SIZE)
 
 #define MACH_TYPE_DALMORE      4304    /* not yet in mach-types.h */
 
index 32aa4e50650b1495369371a9f380e96d65a1e5de..c40fbd9f8d330ea7bd285cd6d929b4018f1a9cfd 100644 (file)
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                             /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP
 
 #define CONFIG_EEPRO100
index 788227d79d0233f8527b6c245ac92b36e49d8f61..3b74d7c31c118868823bef179c8c94b1532a504e 100644 (file)
 #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\
                                        0x400000)
 #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000
+
+#define CONFIG_SPL_FAT_LOAD_KERNEL_NAME                "uImage"
+#define CONFIG_SPL_FAT_LOAD_ARGS_NAME          "args"
+
+#define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR        0x500 /* address 0xa0000 */
+#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR  0x8   /* address 0x1000 */
+#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS 8     /* 4KB */
+
 #define CONFIG_SYS_SPL_ARGS_ADDR        (PHYS_SDRAM_1 + 0x100)
 
 #endif /* __CONFIG_H */
index 3238ac7327ae12fc8c33cb5237f6a8fcb37c3c4c..a6a0f8bb58053c0244ca028eb92f32d273b65288 100644 (file)
  * PCI stuff
  */
 #define CONFIG_PCI             1       /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #undef CONFIG_PCI_PNP
 
 
index d6b655122a584854913acb79e1683d521c54e06e..b05ba08afdad9a81a879db3c076480a14bec7440 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                                 /* include pci support              */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                         /* do pci plug-and-play         */
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
 #define CONFIG_SYS_PCI_TARGBASE    0x80000000  /* PCIaddr mapped to CONFIG_SYS_PCI_MEMBASE */
index 8d78921f6b560a46c67a348a9b78d8d57df99e6e..7393f289a79b9d0634cdd47a34371f73ceb8fd35 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play   */
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
 #define CONFIG_PCI_BOOTDELAY   0
index 9b97d4fb04b86c7db32a55f8bb37018e15dd4494..163243572f745303b6d2ce9d1729456d975e4b46 100644 (file)
 /* TPM */
 #define CONFIG_TPM
 #define CONFIG_CMD_TPM
-#define CONFIG_INFINEON_TPM_I2C
-#define CONFIG_INFINEON_TPM_I2C_BUS 3
-#define CONFIG_INFINEON_TPM_I2C_ADDR 0x20
+#define CONFIG_TPM_TIS_I2C
+#define CONFIG_TPM_TIS_I2C_BUS_NUMBER  3
+#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR  0x20
 
 /* MMC SPL */
 #define CONFIG_SPL
index 9efbb8e34cc9b252777bdc2529e8a0c51944aa0d..7b8bac48ec7149ea124786d1cc86a1daeaaa6f69 100644 (file)
 
 /* General PCI */
 #define CONFIG_PCI                             /* include pci support        */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef  CONFIG_PCI_PNP                         /* do (not) pci plug-and-play */
 #define CONFIG_PCI_SCAN_SHOW                   /* show pci devices on startup*/
 #define CONFIG_SYS_PCI_TARGBASE                0x80000000      /* PCIaddr mapped to \
index 2fac0efe13051902c9946497bc4678371b963e5a..c2da4cec9a6e61810e8abf6b77e8fbdb7a190ac8 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
 #define CONFIG_PCI_CONFIG_HOST_BRIDGE
index afbd54999748cc10ed5a47177907ce872f9b32e9..12f28f82a8f7718ba0cdc9a223171f25942800d1 100644 (file)
 #define CONFIG_SPL
 #define CONFIG_SPL_FRAMEWORK
 /*
- * Place the image at the start of the ROM defined image space and leave
- * space for SRAM scratch entries (see arch/arm/include/omap_common.h).
+ * Place the image at the start of the ROM defined image space.
  * We limit our size to the ROM-defined downloaded image area, and use the
  * rest of the space for stack.
  */
-#define CONFIG_SPL_TEXT_BASE           0x402F0500
+#define CONFIG_SPL_TEXT_BASE           0x402F0400
 #define CONFIG_SPL_MAX_SIZE            (0x4030C000 - CONFIG_SPL_TEXT_BASE)
 #define CONFIG_SPL_STACK               CONFIG_SYS_INIT_SP_ADDR
 
index 33364a843e3e1437e92a2c61af0d273981a8a491..ed96b1b3c44da058d386ec83b1b99cfdf94bed62 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play   */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
 #define CONFIG_PCI_CONFIG_HOST_BRIDGE
index 3ed8dc7f3ea2a8ce251006ef500b10db9497ef27..c6f712c93786f00bbd3ecf9dd17745ab4c15f7bc 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP         1       /* do pci plug-and-play         */
 #define CONFIG_PCI_SCAN_SHOW   1       /* show pci devices on startup  */
 #define CONFIG_PCI_CONFIG_HOST_BRIDGE
index d505a41de4510596c8e5c1c13df4d4bcc0f9610a..aec4a584efbc7b18b83019c7978f9dc045ff92b6 100644 (file)
  * PCI stuff
  *----------------------------------------------------------------------*/
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP         1       /* do pci plug-and-play         */
 #define CONFIG_PCI_SCAN_SHOW   1       /* show pci devices on startup  */
 #define CONFIG_PCI_CONFIG_HOST_BRIDGE
index b919aec359fad9b51618ff5eef4a50ee24612f27..d7c1f8508b0b4b17a1924e4c7f5935f9c3f76c01 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
 #define CONFIG_SYS_PCI_CACHE_LINE_SIZE 0       /* to avoid problems with PNP   */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
index e49dc28776124ffeab53f688c93265ca50dc557c..87a5056afd977ff9fe20962e01226ed6ed21f683 100644 (file)
 #define CONFIG_SYS_NS16550_CLK         14745600
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI_PNP
 
 #define CONFIG_EEPRO100
index eec79619c10a2ba2ee68711974995e8652fa9900..20f0a18f86fe0fde7cd7454b9cea072fd7671622 100644 (file)
  * PCI stuff
  */
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 /* Verified: CONFIG_PCI_PNP doesn't work */
 #undef CONFIG_PCI_PNP
 #define CONFIG_PCI_SCAN_SHOW
index 3b4761bd08719919657851195e4067026446446a..f0e568af83457dd43c638fbceb49df554a47cf3c 100644 (file)
 
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do (not) pci plug-and-play   */
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
 
index 6c1b136659abae34d237de17600e1aac3f95cf4c..f71f28bb873a22da2b0d9f23d67e05f758aa9309 100644 (file)
  * PCI stuff
  *----------------------------------------------------------------------*/
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP         1       /* do pci plug-and-play         */
 #define CONFIG_PCI_SCAN_SHOW   1       /* show pci devices on startup  */
 #define CONFIG_PCI_CONFIG_HOST_BRIDGE
index 64ce52dee7f003cbbde0564cf883abaf738f4871..6f003aa03f9eb5777542398abafa5aa803d77e70 100644 (file)
  * PCI
  */
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 
 /*
  * General PCI
index aa681f0628d55129f890e4fbb2f9d8d394f34083..3c7a85e359df106f9148e85a52953226d747194a 100644 (file)
 #define CONFIG_SYS_SCCR_PCIEXP1CM      1
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCIE
 
 #define CONFIG_PCI_PNP         /* do pci plug-and-play */
index d0fe9dadfbe47c06ab50a92033f3b34238145d89..3e64c7405bfda9c096fd2c96eab9131d9ad4d8ac 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
 #define CONFIG_SYS_PCI_TARGBASE    0x80000000  /* PCIaddr mapped to CONFIG_SYS_PCI_MEMBASE */
index 7ed634b701f29541e860ba8459c70b69d418fca9..2fa537291b2bb0aceb3032f30740215e211df0b0 100644 (file)
 #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_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_FSL_PCIE_RESET  /* need PCIe reset errata */
 #define CONFIG_SYS_PCI_64BIT   /* enable 64-bit PCI resources */
 
index d7b1ca203a693445970217ee41656e557f3e220e..a19de079b6e2c6d439ee363914b96006695af15b 100644 (file)
  *----------------------------------------------------------------------*/
 /* General PCI */
 #define CONFIG_PCI                                 /* include pci support              */
+#define        CONFIG_PCI_INDIRECT_BRIDGE 1    /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                         /* do pci plug-and-play         */
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
 #define CONFIG_SYS_PCI_TARGBASE    0x80000000  /* PCIaddr mapped to CONFIG_SYS_PCI_MEMBASE */
index eac1ef9e0217098e8c0892111d770fedae0e1f87..9e2686ac449e8625094bafe5e66653fe3fcd1712 100644 (file)
@@ -46,7 +46,7 @@
 
 /* Environment in eMMC, at the end of 2nd "boot sector" */
 #define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OFFSET ((1024 * 1024) - CONFIG_ENV_SIZE)
+#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE)
 #define CONFIG_SYS_MMC_ENV_DEV 0
 #define CONFIG_SYS_MMC_ENV_PART 2
 
index 348030227db318aa05da1082692e075f5d9bcf1f..9b16c47820fb1bf24caacb06a25e776e4a67deea 100644 (file)
 #define CONFIG_SPL
 #define CONFIG_SPL_FRAMEWORK
 /*
- * Place the image at the start of the ROM defined image space and leave
- * space for SRAM scratch entries (see arch/arm/include/omap_common.h).
+ * Place the image at the start of the ROM defined image space.
  * We limit our size to the ROM-defined downloaded image area, and use the
  * rest of the space for stack.
  */
-#define CONFIG_SPL_TEXT_BASE           0x402F0500
+#define CONFIG_SPL_TEXT_BASE           0x402F0400
 #define CONFIG_SPL_MAX_SIZE            (0x4030C000 - CONFIG_SPL_TEXT_BASE)
 #define CONFIG_SPL_STACK               CONFIG_SYS_INIT_SP_ADDR
 
 #define CONFIG_SPL_GPIO_SUPPORT
 #define CONFIG_SPL_YMODEM_SUPPORT
 #define CONFIG_SPL_NET_SUPPORT
+#define CONFIG_SPL_ENV_SUPPORT
 #define CONFIG_SPL_NET_VCI_STRING      "pcm051 U-Boot SPL"
 #define CONFIG_SPL_ETH_SUPPORT
 #define CONFIG_SPL_SPI_SUPPORT
index 351ff5a22bf0d137f2e0e85500476feef452f949..1897619058ecb8106655154c5a9ae9ad1bb4a40a 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef  CONFIG_PCI_PNP                 /* do (not) pci plug-and-play   */
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
 #define CONFIG_SYS_PCI_TARGBASE        0x80000000 /* PCIaddr mapped to CONFIG_SYS_PCI_MEMBASE*/
index b60a9ade15a130e9975cb1b957327a358779fbac..6f6ddfa20e0f03b81c70aad143b7542be6f92771 100644 (file)
 
 #define CONFIG_BOOTCOMMAND             "run flashboot"
 #define CONFIG_ROOTPATH                        "/ronetix/rootfs"
-#define CONFIG_AUTOBOOT_PROMPT         "autoboot in %d seconds\n"
+#define CONFIG_AUTOBOOT_PROMPT         "autoboot in %d seconds\n", bootdelay
 
 #define CONFIG_CON_ROT                 "fbcon=rotate:3 "
 #define CONFIG_BOOTARGS                        "root=/dev/mtdblock4 rootfstype=jffs2 "\
index 5cd660927a81626919fe19cf86a8d9f6fac48003..3f9fdd444dcbb88f8b7816729645072085fa5027 100644 (file)
  */
 
 #define        CONFIG_PCI
+#define        CONFIG_PCI_INDIRECT_BRIDGE
 #define        CONFIG_PCI_PNP
 #undef CONFIG_PCI_SCAN_SHOW
 
 #define CONFIG_SYS_FLASH_ERASE_TOUT    250000
 #define CONFIG_SYS_FLASH_WRITE_TOUT    5000
 #define CONFIG_SYS_MAX_FLASH_BANKS     1
-#define CONFIG_SYS_MAX_FLASH_SECT      19
+#define CONFIG_SYS_MAX_FLASH_SECT      128
 
 
 /*
index c18b35b0578a64e09aa43a66d86371d84779b18b..216c6cb70b92d1496f582baba0521e90c3709076 100644 (file)
@@ -61,6 +61,7 @@
 #define CONFIG_BCM2835_GPIO
 /* LCD */
 #define CONFIG_LCD
+#define CONFIG_LCD_DT_SIMPLEFB
 #define LCD_BPP                                LCD_COLOR16
 /*
  * Prevent allocation of RAM for FB; the real FB address is queried
 
 /* Device tree support for bootm/bootz */
 #define CONFIG_OF_LIBFDT
+#define CONFIG_OF_BOARD_SETUP
 /* ATAGs support for bootm/bootz */
 #define CONFIG_SETUP_MEMORY_TAGS
 #define CONFIG_CMDLINE_TAG
index 5abcda3c36550323ce13854317170ab26cd013a1..6e53bc2ee2eb420d8ee6b5793ad8efb843842d8a 100644 (file)
 #define PCI_HOST_AUTO          2       /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_FORCE  /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 478d0d8f9d300e0950a0656e7d5242e75bc12213..fdc1b95e230034d6c680b101c2cbcf77a6b10717 100644 (file)
 
 /* PCI @ 0x80000000 */
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_SYS_IBAT1L      (CONFIG_SYS_PCI1_MEM_BASE \
                                | BATL_PP_RW \
                                | BATL_MEMCOHERENCE)
index 2209ddf8238db9010cc54111d2e9da177e8c6246..148ade35685934e108c9506e85eecc69a04de246 100644 (file)
@@ -33,6 +33,7 @@
  * Top level Makefile configuration choices
  */
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCI1
 #endif
 
index 9040ec609587674ebbccc4748087d5bdbfff9d2b..0e2d17deb508b21b19c6ff875e1b144a1421d5af 100644 (file)
@@ -64,6 +64,7 @@
 #define CONFIG_PCIE1           1       /* PCIE controler 1 (slot 1) */
 #define CONFIG_PCIE2           1       /* PCIE controler 2 (slot 2) */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_FSL_LAW         1       /* Use common FSL init code */
 
 #define CONFIG_TSEC_ENET               /* tsec ethernet support */
index fb74608bb9ce89ac26cf2b434b53ef98a94f426d..9dec21de6ea136b56d0d93250a34b9995f28365f 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_FORCE  /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index f66173e0f23bffac173e45e5dec7a53a8cdc55a7..f0da1fcf1f69dc1fed0227fac19d53e95cad1c42 100644 (file)
@@ -72,7 +72,7 @@
 
 /* Environment in eMMC, at the end of 2nd "boot sector" */
 #define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE)
+#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE)
 #define CONFIG_SYS_MMC_ENV_DEV 0
 #define CONFIG_SYS_MMC_ENV_PART 2
 
index dd5d7cd260222d8f6c6428b2822f2e82f98c085b..11fce53c025977ee060c2d8d35115e4165395f16 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
 #define CONFIG_SYS_PCI_CACHE_LINE_SIZE 0       /* to avoid problems with PNP   */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
index 25f15f2c3543b256a4ed1c831e29ffac1744614e..7a0b4819316d4668d48921acdf3577237296c3ae 100644 (file)
@@ -48,6 +48,7 @@
 #define        CONFIG_SYS_TEXT_BASE    0xfff80000
 
 #define CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 
 #define CONFIG_TSEC_ENET               /* tsec ethernet support        */
 
index c1a90a70471edf90cd82fd52451f97ba2074e98c..96d7128d0afe68ef0e56df31be243b56f7839402 100644 (file)
@@ -46,6 +46,7 @@
 #define        CONFIG_SYS_TEXT_BASE    0xFFF80000
 
 #define CONFIG_PCI                     /* PCI ethernet support */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_TSEC_ENET               /* tsec ethernet support*/
 #undef CONFIG_ETHER_ON_FCC             /* cpm FCC ethernet support */
 #define CONFIG_ENV_OVERWRITE
index 2a731a637ba6ed32895ecef899abcec80e0e913b..ff2189c2fbc4416a29947a81ffe48ff57e6aac4b 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play   */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
 #define CONFIG_PCI_CONFIG_HOST_BRIDGE
index fa1dcc3528cea33d0d913e9351f51345ac5e6ec2..92b2179ca7f5ad8693dd1df24f3432c9e13c1a3d 100644 (file)
 #define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/t4qds/t4_rcw.cfg
 #endif
 
+#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
+/* Set 1M boot space */
+#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000)
+#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS \
+               (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR)
+#define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc
+#define CONFIG_SYS_NO_FLASH
+#endif
+
 #define CONFIG_CMD_REGINFO
 
 /* High Level Configuration Options */
 #define CONFIG_SYS_SRIO
 #define CONFIG_SRIO1                   /* SRIO port 1 */
 #define CONFIG_SRIO2                   /* SRIO port 2 */
+#define CONFIG_SRIO_PCIE_BOOT_MASTER
 
 #define CONFIG_FSL_LAW                 /* Use common FSL init code */
 
 #define CONFIG_ENV_OVERWRITE
 
 #ifdef CONFIG_SYS_NO_FLASH
+#if !defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) && !defined(CONFIG_RAMBOOT_PBL)
 #define CONFIG_ENV_IS_NOWHERE
+#endif
 #else
 #define CONFIG_FLASH_CFI_DRIVER
 #define CONFIG_SYS_FLASH_CFI
 #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
 #endif
 
-#ifndef CONFIG_SYS_NO_FLASH
 #if defined(CONFIG_SPIFLASH)
 #define CONFIG_SYS_EXTRA_ENV_RELOC
 #define CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_ENV_IS_IN_NAND
 #define CONFIG_ENV_SIZE                        CONFIG_SYS_NAND_BLOCK_SIZE
 #define CONFIG_ENV_OFFSET              (5 * CONFIG_SYS_NAND_BLOCK_SIZE)
+#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
+#define CONFIG_ENV_IS_IN_REMOTE
+#define CONFIG_ENV_ADDR                0xffe20000
+#define CONFIG_ENV_SIZE                0x2000
+#elif defined(CONFIG_ENV_IS_NOWHERE)
+#define CONFIG_ENV_SIZE                0x2000
 #else
 #define CONFIG_ENV_IS_IN_FLASH
 #define CONFIG_ENV_ADDR                (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SECT_SIZE)
 #define CONFIG_ENV_SIZE                0x2000
 #define CONFIG_ENV_SECT_SIZE   0x20000 /* 128K (one sector) */
 #endif
-#else /* CONFIG_SYS_NO_FLASH */
-#define CONFIG_ENV_SIZE                0x2000
-#define CONFIG_ENV_SECT_SIZE   0x20000 /* 128K (one sector) */
-#endif
-
-
 
 #define CONFIG_SYS_CLK_FREQ    get_board_sys_clk()
 #define CONFIG_DDR_CLK_FREQ    get_board_ddr_clk()
@@ -633,6 +644,16 @@ unsigned long get_board_ddr_clk(void);
 #elif defined(CONFIG_NAND)
 #define CONFIG_SYS_QE_FMAN_FW_IN_NAND
 #define CONFIG_SYS_QE_FMAN_FW_ADDR     (6 * CONFIG_SYS_NAND_BLOCK_SIZE)
+#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
+/*
+ * Slave has no ucode locally, it can fetch this from remote. When implementing
+ * in two corenet boards, slave's ucode could be stored in master's memory
+ * space, the address can be mapped from slave TLB->slave LAW->
+ * slave SRIO or PCIE outbound window->master inbound window->
+ * master LAW->the ucode address in master's memory space.
+ */
+#define CONFIG_SYS_QE_FMAN_FW_IN_REMOTE
+#define CONFIG_SYS_QE_FMAN_FW_ADDR     0xFFE00000
 #else
 #define CONFIG_SYS_QE_FMAN_FW_IN_NOR
 #define CONFIG_SYS_QE_FMAN_FW_ADDR             0xEFF40000
@@ -657,6 +678,7 @@ unsigned long get_board_ddr_clk(void);
 #endif
 
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_NET_MULTI
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play */
 #define CONFIG_E1000
index a3738b7b1d2dcafb9db2c96b566eb51ad9abed15..a43c3da4a07af826aa13b3feea256582276ef806 100644 (file)
@@ -171,6 +171,7 @@ unsigned char spi_read(void);
 #define PCI_HOST_AUTO    2             /* detected via arbiter enable */
 
 #define CONFIG_PCI                     /* include pci support         */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST        PCI_HOST_FORCE  /* select pci host function    */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play        */
                                        /* resource configuration      */
index 3046081c52efc5fd5e637f00b4cc1e946028c405..c9f1a9fa24446dc55229c7e98a59153b52129a2d 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
 #define CONFIG_EEPRO100       1                /* include PCI EEPRO100         */
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup  */
index 66568c8d004b63bc52d4df7dadae752184585238..60d1503bc3190bdda62ab8f8a1cccefd270cd9d0 100644 (file)
@@ -139,6 +139,7 @@ protect on ${u-boot_startaddr} ${u-boot_endaddr}"
  *-----------------------------------------------------------------------
  */
 #define CONFIG_PCI                             /* include pci support          */
+#define        CONFIG_PCI_INDIRECT_BRIDGE 1    /* indirect PCI bridge support */
 #undef CONFIG_PCI_PNP
 #define CONFIG_PCI_SCAN_SHOW
 #define CONFIG_EEPRO100
index d3b8379186390058a2a60caddb49ed4d9afda08b..7b1130a48e2d52fb709a3e76a182690f5963dc9b 100644 (file)
@@ -43,6 +43,7 @@
 #endif
 
 #define CONFIG_PCI             1
+#define CONFIG_PCI_INDIRECT_BRIDGE 1
 #define CONFIG_FSL_ELBC                1
 
 #define CONFIG_BOARD_EARLY_INIT_F      1
index 5755f11714f911a01a71cacad86a10d284d9fd26..41a717622d3ccc41258f617b034c9579a46dd2c6 100644 (file)
@@ -52,7 +52,7 @@
 
 /* Environment in eMMC, at the end of 2nd "boot sector" */
 #define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OFFSET ((1024 * 1024) - CONFIG_ENV_SIZE)
+#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE)
 #define CONFIG_SYS_MMC_ENV_DEV 0
 #define CONFIG_SYS_MMC_ENV_PART 2
 
index 61e02e6077aaee1a67ba3ca626848f4ebf366801..f97de5490bb6b4e74d0e089b210d5144aa413e96 100644 (file)
 
 /* PCI @ 0x80000000 */
 #ifdef CONFIG_PCI
+#define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_SYS_IBAT1L      (CONFIG_SYS_PCI1_MEM_BASE | BATL_PP_RW | \
                                 BATL_MEMCOHERENCE)
 #define CONFIG_SYS_IBAT1U      (CONFIG_SYS_PCI1_MEM_BASE | BATU_BL_256M | \
index d10f74843d26c01665a7f19a84a8e4628d94e1e0..219f276a4c57e37d2b874b56072f46ed0edc186e 100644 (file)
 #define PCI_HOST_AUTO  2               /* detected via arbiter enable  */
 
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function     */
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play         */
                                        /* resource configuration       */
index 9542c7e213141fe07c5667e33be4997e3cdf6135..994edecaab3aa53bc807a31b5f4addc096053eb1 100644 (file)
 
 /*
  * Environment in eMMC, at the end of 2nd "boot sector". Note: This assumes
- * the user plugged the standard 8MB MoviNAND card into J29/HSMMC/POP. If
+ * the user plugged the standard 8GB MoviNAND card into J29/HSMMC/POP. If
  * they didn't, the boot sector layout may be different. However, use of that
  * particular card is standard practice as far as I know.
  */
 #define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE)
+#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE)
 #define CONFIG_SYS_MMC_ENV_DEV 0
 #define CONFIG_SYS_MMC_ENV_PART 2
 
index 506d646fec98696e4665bdf59439be87b22e793a..1f48cc57724ef71822bee78103b76627de98037c 100644 (file)
@@ -167,6 +167,7 @@ extern void out32(unsigned int, unsigned long);
  */
 /* General PCI */
 #define CONFIG_PCI                             /* include pci support */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP                         /* do pci plug-and-play */
 #define CONFIG_PCI_SCAN_SHOW                   /* show pci devices on startup */
 #define CONFIG_SYS_PCI_TARGBASE        0x80000000      /* PCIaddr mapped to CONFIG_SYS_PCI_MEMBASE */
index 1851a00c16202485c01c972213267851493d5da7..f28f443fe926d4afa34d31c143ac96b8ad76b84a 100644 (file)
@@ -49,6 +49,7 @@
 #define CONFIG_PCIE1           1       /* PCIE controler 1 */
 #define CONFIG_PCIE2           1       /* PCIE controler 2 */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_FSL_LAW         1       /* Use common FSL init code */
 
index ff99481b2f8d8c48ff562c66da67b2c1acc985f3..3034a3c9a9f1c72d06695c7174ba3019a50bb8fe 100644 (file)
@@ -48,6 +48,7 @@
 #define CONFIG_PCI_SCAN_SHOW   1       /* show pci devices on startup */
 #define CONFIG_PCI1            1       /* PCI controller 1 */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_FSL_LAW         1       /* Use common FSL init code */
 
index 46f1c903f1356e617ee2572fc219b6d2eb18ba14..43359a2eefc68b95d90ddd1bbda75104c50b142c 100644 (file)
@@ -49,6 +49,7 @@
 #define CONFIG_PCIE1           1       /* PCIE controler 1 */
 #define CONFIG_PCIE2           1       /* PCIE controler 2 */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_FSL_LAW         1       /* Use common FSL init code */
index 2acf6c80a5eee260f9e75691b04e0284d8513c16..a1710853548087913a825982ec2306500ed4d442 100644 (file)
@@ -48,6 +48,7 @@
 #define CONFIG_PCI_SCAN_SHOW   1       /* show pci devices on startup */
 #define CONFIG_PCIE1           1       /* PCIE controler 1 (PEX8112 or XMC) */
 #define CONFIG_FSL_PCI_INIT    1       /* Use common FSL init code */
+#define CONFIG_PCI_INDIRECT_BRIDGE 1   /* indirect PCI bridge support */
 #define CONFIG_SYS_PCI_64BIT   1       /* enable 64-bit PCI resources */
 #define CONFIG_FSL_PCIE_RESET  1       /* need PCIe reset errata */
 #define CONFIG_FSL_LAW         1       /* Use common FSL init code */
index 0cbef6f85f77eb47e8827213076e30ca2ebbb5e5..cde0df1a08f9bab9b560e7ab8fe7358db42c818c 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #undef  CONFIG_PCI_PNP                 /* do (not) pci plug-and-play   */
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
 #define CONFIG_SYS_PCI_TARGBASE        0x80000000 /* PCIaddr mapped to CONFIG_SYS_PCI_MEMBASE*/
index fb684b5e106f039865475937ce1dfd444509af20..3282d378d7de0a837ecfdb0b486455fd4e15dc01 100644 (file)
  */
 /* General PCI */
 #define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_INDIRECT_BRIDGE     /* indirect PCI bridge support */
 #define CONFIG_PCI_PNP         1       /* do pci plug-and-play         */
 #define CONFIG_PCI_SCAN_SHOW   1       /* show pci devices on startup  */
 #define CONFIG_PCI_CONFIG_HOST_BRIDGE
index 4c6a37b112119243a3dff63e2f9288f2ff293e5f..460ccb42affda4d823db40bd7866fa9dff8e399a 100644 (file)
 # endif
 #endif /* CONFIG_ENV_IS_IN_FLASH */
 
+#if defined(CONFIG_ENV_IS_IN_MMC)
+# ifdef CONFIG_ENV_OFFSET_REDUND
+#  define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+# endif
+#endif
+
 #if defined(CONFIG_ENV_IS_IN_NAND)
 # if defined(CONFIG_ENV_OFFSET_OOB)
 #  ifdef CONFIG_ENV_OFFSET_REDUND
index bc3b89bc0fdaa6cd1afc85e1331491f7058aceba..8845e294b91e0e1efdf05cd0b9305d4e019908c6 100644 (file)
@@ -94,6 +94,7 @@ enum fdt_compat_id {
        COMPAT_GENERIC_SPI_FLASH,       /* Generic SPI Flash chip */
        COMPAT_MAXIM_98095_CODEC,       /* MAX98095 Codec */
        COMPAT_INFINEON_SLB9635_TPM,    /* Infineon SLB9635 TPM */
+       COMPAT_INFINEON_SLB9645_TPM,    /* Infineon SLB9645 TPM */
 
        COMPAT_COUNT,
 };
index b8cc5236a819b2ad6b89bab1e16ae7c1b2e6133f..8ccc00b76a13c71a46a380459c9220fc3f9aeb89 100644 (file)
@@ -402,6 +402,13 @@ void genimg_print_size(uint32_t size);
 #endif
 void genimg_print_time(time_t timestamp);
 
+/* What to do with a image load address ('load = <> 'in the FIT) */
+enum fit_load_op {
+       FIT_LOAD_IGNORED,       /* Ignore load address */
+       FIT_LOAD_OPTIONAL,      /* Can be provided, but optional */
+       FIT_LOAD_REQUIRED,      /* Must be provided */
+};
+
 #ifndef USE_HOSTCC
 /* Image format types, returned by _get_format() routine */
 #define IMAGE_FORMAT_INVALID   0x00
@@ -415,8 +422,71 @@ ulong genimg_get_image(ulong img_addr);
 int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
                uint8_t arch, ulong *rd_start, ulong *rd_end);
 
-int boot_get_fdt(int flag, int argc, char * const argv[],
-               bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
+/**
+ * fit_image_load() - load an image from a FIT
+ *
+ * This deals with all aspects of loading an image from a FIT, including
+ * selecting the right image based on configuration, verifying it, printing
+ * out progress messages, checking the type/arch/os and optionally copying it
+ * to the right load address.
+ *
+ * @param images       Boot images structure
+ * @param prop_name    Property name to look up (FIT_..._PROP)
+ * @param addr         Address of FIT in memory
+ * @param fit_unamep   On entry this is the requested image name
+ *                     (e.g. "kernel@1") or NULL to use the default. On exit
+ *                     points to the selected image name
+ * @param fit_uname_config     Requested configuration name, or NULL for the
+ *                     default
+ * @param arch         Expected architecture (IH_ARCH_...)
+ * @param image_type   Required image type (IH_TYPE_...). If this is
+ *                     IH_TYPE_KERNEL then we allow IH_TYPE_KERNEL_NOLOAD
+ *                     also.
+ * @param bootstage_id ID of starting bootstage to use for progress updates.
+ *                     This will be added to the BOOTSTAGE_SUB values when
+ *                     calling bootstage_mark()
+ * @param load_op      Decribes what to do with the load address
+ * @param datap                Returns address of loaded image
+ * @param lenp         Returns length of loaded image
+ */
+int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
+                  const char **fit_unamep, const char *fit_uname_config,
+                  int arch, int image_type, int bootstage_id,
+                  enum fit_load_op load_op, ulong *datap, ulong *lenp);
+
+/**
+ * fit_get_node_from_config() - Look up an image a FIT by type
+ *
+ * This looks in the selected conf@ node (images->fit_uname_cfg) for a
+ * particular image type (e.g. "kernel") and then finds the image that is
+ * referred to.
+ *
+ * For example, for something like:
+ *
+ * images {
+ *     kernel@1 {
+ *             ...
+ *     };
+ * };
+ * configurations {
+ *     conf@1 {
+ *             kernel = "kernel@1";
+ *     };
+ * };
+ *
+ * the function will return the node offset of the kernel@1 node, assuming
+ * that conf@1 is the chosen configuration.
+ *
+ * @param images       Boot images structure
+ * @param prop_name    Property name to look up (FIT_..._PROP)
+ * @param addr         Address of FIT in memory
+ */
+int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
+                       ulong addr);
+
+int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
+                bootm_headers_t *images,
+                char **of_flat_tree, ulong *of_size);
 void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob);
 int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size);
 
@@ -697,6 +767,7 @@ int fit_set_timestamp(void *fit, int noffset, time_t timestamp);
 int fit_add_verification_data(void *fit);
 
 int fit_image_verify(const void *fit, int noffset);
+int fit_config_verify(const void *fit, int conf_noffset);
 int fit_all_image_verify(const void *fit);
 int fit_image_check_os(const void *fit, int noffset, uint8_t os);
 int fit_image_check_arch(const void *fit, int noffset, uint8_t arch);
@@ -706,9 +777,6 @@ int fit_check_format(const void *fit);
 
 int fit_conf_find_compat(const void *fit, const void *fdt);
 int fit_conf_get_node(const void *fit, const char *conf_uname);
-int fit_conf_get_kernel_node(const void *fit, int noffset);
-int fit_conf_get_ramdisk_node(const void *fit, int noffset);
-int fit_conf_get_fdt_node(const void *fit, int noffset);
 
 /**
  * fit_conf_get_prop_node() - Get node refered to by a configuration
@@ -732,12 +800,35 @@ int fit_check_ramdisk(const void *fit, int os_noffset,
 int calculate_hash(const void *data, int data_len, const char *algo,
                        uint8_t *value, int *value_len);
 
-#ifndef USE_HOSTCC
+/*
+ * At present we only support verification on the device
+ */
+#if defined(CONFIG_FIT_SIGNATURE)
+# ifdef USE_HOSTCC
+#  define IMAGE_ENABLE_VERIFY  0
+#else
+#  define IMAGE_ENABLE_VERIFY  1
+# endif
+#else
+# define IMAGE_ENABLE_VERIFY   0
+#endif
+
+#ifdef USE_HOSTCC
+# define gd_fdt_blob()         NULL
+#else
+# define gd_fdt_blob()         (gd->fdt_blob)
+#endif
+
+#ifdef CONFIG_FIT_BEST_MATCH
+#define IMAGE_ENABLE_BEST_MATCH        1
+#else
+#define IMAGE_ENABLE_BEST_MATCH        0
+#endif
+
 static inline int fit_image_check_target_arch(const void *fdt, int node)
 {
        return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT);
 }
-#endif /* USE_HOSTCC */
 
 #ifdef CONFIG_FIT_VERBOSE
 #define fit_unsupported(msg)   printf("! %s:%d " \
index c6e7fc5216330c6797e7c28a640a67322766a446..30225edf563fb1212db8e3868e4ef626921affaf 100644 (file)
@@ -324,6 +324,9 @@ void lcd_show_board_info(void);
 /* Return the size of the LCD frame buffer, and the line length */
 int lcd_get_size(int *line_length);
 
+int lcd_dt_simplefb_add_node(void *blob);
+int lcd_dt_simplefb_enable_existing_node(void *blob);
+
 /************************************************************************/
 /* ** BITMAP DISPLAY SUPPORT                                           */
 /************************************************************************/
index 8cbcdae1143fa28ef406ce7dc795c8c0b6f8f7b8..71292b1a86bc91629acd1c61bf9e4d83e97a65a3 100644 (file)
@@ -81,32 +81,53 @@ struct nand_bbt_descr {
 #define NAND_BBT_LASTBLOCK     0x00000010
 /* The bbt is at the given page, else we must scan for the bbt */
 #define NAND_BBT_ABSPAGE       0x00000020
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_SEARCH                0x00000040
 /* bbt is stored per chip on multichip devices */
 #define NAND_BBT_PERCHIP       0x00000080
 /* bbt has a version counter at offset veroffs */
 #define NAND_BBT_VERSION       0x00000100
 /* Create a bbt if none exists */
 #define NAND_BBT_CREATE                0x00000200
+/*
+ * Create an empty BBT with no vendor information. Vendor's information may be
+ * unavailable, for example, if the NAND controller has a different data and OOB
+ * layout or if this information is already purged. Must be used in conjunction
+ * with NAND_BBT_CREATE.
+ */
+#define NAND_BBT_CREATE_EMPTY  0x00000400
 /* Search good / bad pattern through all pages of a block */
-#define NAND_BBT_SCANALLPAGES  0x00000400
+#define NAND_BBT_SCANALLPAGES  0x00000800
 /* Scan block empty during good / bad block scan */
-#define NAND_BBT_SCANEMPTY     0x00000800
+#define NAND_BBT_SCANEMPTY     0x00001000
 /* Write bbt if neccecary */
-#define NAND_BBT_WRITE         0x00001000
+#define NAND_BBT_WRITE         0x00002000
 /* Read and write back block contents when writing bbt */
-#define NAND_BBT_SAVECONTENT   0x00002000
+#define NAND_BBT_SAVECONTENT   0x00004000
 /* Search good / bad pattern on the first and the second page */
-#define NAND_BBT_SCAN2NDPAGE   0x00004000
+#define NAND_BBT_SCAN2NDPAGE   0x00008000
 /* Search good / bad pattern on the last page of the eraseblock */
-#define NAND_BBT_SCANLASTPAGE  0x00008000
-/* Chip stores bad block marker on BOTH 1st and 6th bytes of OOB */
-#define NAND_BBT_SCANBYTE1AND6 0x00100000
-/* The nand_bbt_descr was created dynamicaly and must be freed */
-#define NAND_BBT_DYNAMICSTRUCT 0x00200000
-/* The bad block table does not OOB for marker */
-#define NAND_BBT_NO_OOB                0x00400000
+#define NAND_BBT_SCANLASTPAGE  0x00010000
+/*
+ * Use a flash based bad block table. By default, OOB identifier is saved in
+ * OOB area. This option is passed to the default bad block table function.
+ */
+#define NAND_BBT_USE_FLASH     0x00020000
+/*
+ * Do not store flash based bad block table marker in the OOB area; store it
+ * in-band.
+ */
+#define NAND_BBT_NO_OOB                0x00040000
+/*
+ * Do not write new bad block markers to OOB; useful, e.g., when ECC covers
+ * entire spare area. Must be used with NAND_BBT_USE_FLASH.
+ */
+#define NAND_BBT_NO_OOB_BBM    0x00080000
+
+/*
+ * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
+ * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
+ * in nand_chip.bbt_options.
+ */
+#define NAND_BBT_DYNAMICSTRUCT 0x80000000
 
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS        4
index 141c96024c57c5246f967f8e045c2a6abab6c3f9..6f44abdc16102d345e97845f17bc624e5c37eb44 100644 (file)
@@ -9,7 +9,8 @@
 
 #include <linux/types.h>
 #include <div64.h>
-#include <linux/mtd/mtd-abi.h>
+#include <mtd/mtd-abi.h>
+#include <asm/errno.h>
 
 #define MTD_CHAR_MAJOR 90
 #define MTD_BLOCK_MAJOR 31
@@ -65,22 +66,6 @@ struct mtd_erase_region_info {
        unsigned long *lockmap;         /* If keeping bitmap of locks */
 };
 
-/*
- * oob operation modes
- *
- * MTD_OOB_PLACE:      oob data are placed at the given offset
- * MTD_OOB_AUTO:       oob data are automatically placed at the free areas
- *                     which are defined by the ecclayout
- * MTD_OOB_RAW:                mode to read raw data+oob in one chunk. The oob data
- *                     is inserted into the data. Thats a raw image of the
- *                     flash contents.
- */
-typedef enum {
-       MTD_OOB_PLACE,
-       MTD_OOB_AUTO,
-       MTD_OOB_RAW,
-} mtd_oob_mode_t;
-
 /**
  * struct mtd_oob_ops - oob operation operands
  * @mode:      operation mode
@@ -92,7 +77,7 @@ typedef enum {
  * @ooblen:    number of oob bytes to write/read
  * @oobretlen: number of oob bytes written/read
  * @ooboffs:   offset of oob data in the oob area (only relevant when
- *             mode = MTD_OOB_PLACE)
+ *             mode = MTD_OPS_PLACE_OOB or MTD_OPS_RAW)
  * @datbuf:    data buffer - if NULL only oob data are read/written
  * @oobbuf:    oob data buffer
  *
@@ -101,7 +86,7 @@ typedef enum {
  * OOB area.
  */
 struct mtd_oob_ops {
-       mtd_oob_mode_t  mode;
+       unsigned int    mode;
        size_t          len;
        size_t          retlen;
        size_t          ooblen;
@@ -133,13 +118,25 @@ struct mtd_info {
        u_int32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */
        u_int32_t oobavail;  /* Available OOB bytes per block */
 
+       /*
+        * read ops return -EUCLEAN if max number of bitflips corrected on any
+        * one region comprising an ecc step equals or exceeds this value.
+        * Settable by driver, else defaults to ecc_strength.  User can override
+        * in sysfs.  N.B. The meaning of the -EUCLEAN return code has changed;
+        * see Documentation/ABI/testing/sysfs-class-mtd for more detail.
+        */
+       unsigned int bitflip_threshold;
+
        /* Kernel-only stuff starts here. */
        const char *name;
        int index;
 
-       /* ecc layout structure pointer - read only ! */
+       /* ECC layout structure pointer - read only! */
        struct nand_ecclayout *ecclayout;
 
+       /* max number of correctible bit errors per ecc step */
+       unsigned int ecc_strength;
+
        /* Data for variable erase regions. If numeraseregions is zero,
         * it means that the whole device has erasesize as given above.
         */
@@ -147,25 +144,17 @@ struct mtd_info {
        struct mtd_erase_region_info *eraseregions;
 
        /*
-        * Erase is an asynchronous operation.  Device drivers are supposed
-        * to call instr->callback() whenever the operation completes, even
-        * if it completes with a failure.
-        * Callers are supposed to pass a callback function and wait for it
-        * to be called before writing to the block.
+        * Do not call via these pointers, use corresponding mtd_*()
+        * wrappers instead.
         */
-       int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
-
-       /* This stuff for eXecute-In-Place */
-       /* phys is optional and may be set to NULL */
-       int (*point) (struct mtd_info *mtd, loff_t from, size_t len,
+       int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
+       int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
                        size_t *retlen, void **virt, phys_addr_t *phys);
-
-       /* We probably shouldn't allow XIP if the unpoint isn't a NULL */
-       void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
-
-
-       int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-       int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
+       void (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
+       int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
+                    size_t *retlen, u_char *buf);
+       int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
+                     size_t *retlen, const u_char *buf);
 
        /* In blackbox flight recorder like scenarios we want to make successful
           writes in interrupt context. panic_write() is only intended to be
@@ -174,24 +163,35 @@ struct mtd_info {
           longer, this function can break locks and delay to ensure the write
           succeeds (but not sleep). */
 
-       int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
+       int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
 
-       int (*read_oob) (struct mtd_info *mtd, loff_t from,
+       int (*_read_oob) (struct mtd_info *mtd, loff_t from,
                         struct mtd_oob_ops *ops);
-       int (*write_oob) (struct mtd_info *mtd, loff_t to,
+       int (*_write_oob) (struct mtd_info *mtd, loff_t to,
                         struct mtd_oob_ops *ops);
-
+       int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
+                                  size_t len);
+       int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
+                                  size_t len, size_t *retlen, u_char *buf);
+       int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
+                                  size_t len);
+       int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
+                                  size_t len, size_t *retlen, u_char *buf);
+       int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to, size_t len,
+                                   size_t *retlen, u_char *buf);
+       int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
+                                  size_t len);
+       void (*_sync) (struct mtd_info *mtd);
+       int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
+       int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
+       int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
+       int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
        /*
-        * Methods to access the protection register area, present in some
-        * flash devices. The user data is one time programmable but the
-        * factory data is read only.
+        * If the driver is something smart, like UBI, it may need to maintain
+        * its own reference counting. The below functions are only for driver.
         */
-       int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
-       int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-       int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
-       int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-       int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-       int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
+       int (*_get_device) (struct mtd_info *mtd);
+       void (*_put_device) (struct mtd_info *mtd);
 
 /* XXX U-BOOT XXX */
 #if 0
@@ -201,18 +201,6 @@ struct mtd_info {
        */
        int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
 #endif
-
-       /* Sync */
-       void (*sync) (struct mtd_info *mtd);
-
-       /* Chip-supported device locking */
-       int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
-       int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
-
-       /* Bad block management functions */
-       int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
-       int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
-
 /* XXX U-BOOT XXX */
 #if 0
        struct notifier_block reboot_notifier;  /* default mode before reboot */
@@ -227,15 +215,59 @@ struct mtd_info {
 
        struct module *owner;
        int usecount;
-
-       /* If the driver is something smart, like UBI, it may need to maintain
-        * its own reference counting. The below functions are only for driver.
-        * The driver may register its callbacks. These callbacks are not
-        * supposed to be called by MTD users */
-       int (*get_device) (struct mtd_info *mtd);
-       void (*put_device) (struct mtd_info *mtd);
 };
 
+int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
+int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
+            u_char *buf);
+int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+             const u_char *buf);
+int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+                   const u_char *buf);
+
+int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
+
+static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
+                               struct mtd_oob_ops *ops)
+{
+       ops->retlen = ops->oobretlen = 0;
+       if (!mtd->_write_oob)
+               return -EOPNOTSUPP;
+       if (!(mtd->flags & MTD_WRITEABLE))
+               return -EROFS;
+       return mtd->_write_oob(mtd, to, ops);
+}
+
+int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
+                          size_t len);
+int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
+                          size_t *retlen, u_char *buf);
+int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
+                          size_t len);
+int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
+                          size_t *retlen, u_char *buf);
+int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
+                           size_t *retlen, u_char *buf);
+int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len);
+
+/* XXX U-BOOT XXX */
+#if 0
+int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
+              unsigned long count, loff_t to, size_t *retlen);
+#endif
+
+static inline void mtd_sync(struct mtd_info *mtd)
+{
+       if (mtd->_sync)
+               mtd->_sync(mtd);
+}
+
+int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
+int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
+
 static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
 {
        do_div(sz, mtd->erasesize);
@@ -247,6 +279,16 @@ static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
        return do_div(sz, mtd->erasesize);
 }
 
+static inline int mtd_has_oob(const struct mtd_info *mtd)
+{
+       return mtd->_read_oob && mtd->_write_oob;
+}
+
+static inline int mtd_can_have_bb(const struct mtd_info *mtd)
+{
+       return !!mtd->_block_isbad;
+}
+
        /* Kernel-side ioctl definitions */
 
 extern int add_mtd_device(struct mtd_info *mtd);
@@ -269,12 +311,6 @@ struct mtd_notifier {
 
 extern void register_mtd_user (struct mtd_notifier *new);
 extern int unregister_mtd_user (struct mtd_notifier *old);
-
-int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
-                      unsigned long count, loff_t to, size_t *retlen);
-
-int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
-                     unsigned long count, loff_t from, size_t *retlen);
 #endif
 
 #ifdef CONFIG_MTD_PARTITIONS
@@ -296,17 +332,34 @@ static inline void mtd_erase_callback(struct erase_info *instr)
 #define MTD_DEBUG_LEVEL3       (3)     /* Noisy   */
 
 #ifdef CONFIG_MTD_DEBUG
+#define pr_debug(args...)      MTDDEBUG(MTD_DEBUG_LEVEL0, args)
 #define MTDDEBUG(n, args...)                           \
        do {                                            \
                if (n <= CONFIG_MTD_DEBUG_VERBOSE)      \
                        printk(KERN_INFO args);         \
        } while(0)
 #else /* CONFIG_MTD_DEBUG */
+#define pr_debug(args...)
 #define MTDDEBUG(n, args...)                           \
        do {                                            \
                if (0)                                  \
                        printk(KERN_INFO args);         \
        } while(0)
 #endif /* CONFIG_MTD_DEBUG */
+#define pr_info(args...)       MTDDEBUG(MTD_DEBUG_LEVEL0, args)
+#define pr_warn(args...)       MTDDEBUG(MTD_DEBUG_LEVEL0, args)
+#define pr_err(args...)                MTDDEBUG(MTD_DEBUG_LEVEL0, args)
+
+static inline int mtd_is_bitflip(int err) {
+       return err == -EUCLEAN;
+}
+
+static inline int mtd_is_eccerr(int err) {
+       return err == -EBADMSG;
+}
+
+static inline int mtd_is_bitflip_or_eccerr(int err) {
+       return mtd_is_bitflip(err) || mtd_is_eccerr(err);
+}
 
 #endif /* __MTD_MTD_H__ */
index 98bf255bb28526f5703f55fd9615e1ab9c595144..2055584374d6277629ee3ec16b8c9a812af65483 100644 (file)
@@ -46,7 +46,7 @@ extern void nand_wait_ready(struct mtd_info *mtd);
  * is supported now. If you add a chip with bigger oobsize/page
  * adjust this accordingly.
  */
-#define NAND_MAX_OOBSIZE       576
+#define NAND_MAX_OOBSIZE       640
 #define NAND_MAX_PAGESIZE      8192
 
 /*
@@ -82,6 +82,8 @@ extern void nand_wait_ready(struct mtd_info *mtd);
 #define NAND_CMD_READID                0x90
 #define NAND_CMD_ERASE2                0xd0
 #define NAND_CMD_PARAM         0xec
+#define NAND_CMD_GET_FEATURES  0xee
+#define NAND_CMD_SET_FEATURES  0xef
 #define NAND_CMD_RESET         0xff
 
 #define NAND_CMD_LOCK          0x2a
@@ -142,7 +144,7 @@ typedef enum {
 #define NAND_ECC_READ          0
 /* Reset Hardware ECC for write */
 #define NAND_ECC_WRITE         1
-/* Enable Hardware ECC before syndrom is read back from flash */
+/* Enable Hardware ECC before syndrome is read back from flash */
 #define NAND_ECC_READSYN       2
 
 /* Bit mask for flags passed to do_nand_read_ecc */
@@ -153,9 +155,7 @@ typedef enum {
  * Option constants for bizarre disfunctionality and real
  * features.
  */
-/* Chip can not auto increment pages */
-#define NAND_NO_AUTOINCR       0x00000001
-/* Buswitdh is 16 bit */
+/* Buswidth is 16 bit */
 #define NAND_BUSWIDTH_16       0x00000002
 /* Device supports partial programming without padding */
 #define NAND_NO_PADDING                0x00000004
@@ -179,12 +179,6 @@ typedef enum {
  * This happens with the Renesas AG-AND chips, possibly others.
  */
 #define BBT_AUTO_REFRESH       0x00000080
-/*
- * Chip does not require ready check on read. true
- * for all large page devices, as they do not support
- * autoincrement.
- */
-#define NAND_NO_READRDY                0x00000100
 /* Chip does not allow subpage writes */
 #define NAND_NO_SUBPAGE_WRITE  0x00000200
 
@@ -202,34 +196,21 @@ typedef enum {
        (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
 
 /* Macros to identify the above */
-#define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR))
 #define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
 #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
 #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
 #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
 
 /* Non chip related options */
-/*
- * Use a flash based bad block table. OOB identifier is saved in OOB area.
- * This option is passed to the default bad block table function.
- */
-#define NAND_USE_FLASH_BBT     0x00010000
 /* This option skips the bbt scan during initialization. */
-#define NAND_SKIP_BBTSCAN      0x00020000
+#define NAND_SKIP_BBTSCAN      0x00010000
 /*
  * This option is defined if the board driver allocates its own buffers
  * (e.g. because it needs them DMA-coherent).
  */
-#define NAND_OWN_BUFFERS       0x00040000
+#define NAND_OWN_BUFFERS       0x00020000
 /* Chip may not exist, so silence any errors in scan */
-#define NAND_SCAN_SILENT_NODEV 0x00080000
-/*
- * If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch
- * the OOB area.
- */
-#define NAND_USE_FLASH_BBT_NO_OOB      0x00800000
-/* Create an empty BBT with no vendor information if the BBT is available */
-#define NAND_CREATE_EMPTY_BBT          0x01000000
+#define NAND_SCAN_SILENT_NODEV 0x00040000
 
 /* Options set by nand scan */
 /* bbt has already been read */
@@ -244,6 +225,21 @@ typedef enum {
 /* Keep gcc happy */
 struct nand_chip;
 
+/* ONFI timing mode, used in both asynchronous and synchronous mode */
+#define ONFI_TIMING_MODE_0             (1 << 0)
+#define ONFI_TIMING_MODE_1             (1 << 1)
+#define ONFI_TIMING_MODE_2             (1 << 2)
+#define ONFI_TIMING_MODE_3             (1 << 3)
+#define ONFI_TIMING_MODE_4             (1 << 4)
+#define ONFI_TIMING_MODE_5             (1 << 5)
+#define ONFI_TIMING_MODE_UNKNOWN       (1 << 6)
+
+/* ONFI feature address */
+#define ONFI_FEATURE_ADDR_TIMING_MODE  0x1
+
+/* ONFI subfeature parameters length */
+#define ONFI_SUBFEATURE_PARAM_LEN      4
+
 struct nand_onfi_params {
        /* rev info and features block */
        /* 'O' 'N' 'F' 'I'  */
@@ -326,27 +322,32 @@ struct nand_hw_control {
 };
 
 /**
- * struct nand_ecc_ctrl - Control structure for ecc
- * @mode:      ecc mode
- * @steps:     number of ecc steps per page
- * @size:      data bytes per ecc step
- * @bytes:     ecc bytes per step
- * @total:     total number of ecc bytes per page
- * @prepad:    padding information for syndrome based ecc generators
- * @postpad:   padding information for syndrome based ecc generators
+ * struct nand_ecc_ctrl - Control structure for ECC
+ * @mode:      ECC mode
+ * @steps:     number of ECC steps per page
+ * @size:      data bytes per ECC step
+ * @bytes:     ECC bytes per step
+ * @strength:  max number of correctible bits per ECC step
+ * @total:     total number of ECC bytes per page
+ * @prepad:    padding information for syndrome based ECC generators
+ * @postpad:   padding information for syndrome based ECC generators
  * @layout:    ECC layout control struct pointer
- * @priv:      pointer to private ecc control data
- * @hwctl:     function to control hardware ecc generator. Must only
+ * @priv:      pointer to private ECC control data
+ * @hwctl:     function to control hardware ECC generator. Must only
  *             be provided if an hardware ECC is available
- * @calculate: function for ecc calculation or readback from ecc hardware
- * @correct:   function for ecc correction, matching to ecc generator (sw/hw)
+ * @calculate: function for ECC calculation or readback from ECC hardware
+ * @correct:   function for ECC correction, matching to ECC generator (sw/hw)
  * @read_page_raw:     function to read a raw page without ECC
  * @write_page_raw:    function to write a raw page without ECC
- * @read_page: function to read a page according to the ecc generator
- *             requirements.
- * @read_subpage:      function to read parts of the page covered by ECC.
- * @write_page:        function to write a page according to the ecc generator
+ * @read_page: function to read a page according to the ECC generator
+ *             requirements; returns maximum number of bitflips corrected in
+ *             any single ECC step, 0 if bitflips uncorrectable, -EIO hw error
+ * @read_subpage:      function to read parts of the page covered by ECC;
+ *                     returns same as read_page()
+ * @write_page:        function to write a page according to the ECC generator
  *             requirements.
+ * @write_oob_raw:     function to write chip OOB data without ECC
+ * @read_oob_raw:      function to read chip OOB data without ECC
  * @read_oob:  function to read chip OOB data
  * @write_oob: function to write chip OOB data
  */
@@ -356,6 +357,7 @@ struct nand_ecc_ctrl {
        int size;
        int bytes;
        int total;
+       int strength;
        int prepad;
        int postpad;
        struct nand_ecclayout   *layout;
@@ -366,25 +368,28 @@ struct nand_ecc_ctrl {
        int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,
                        uint8_t *calc_ecc);
        int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
-                       uint8_t *buf, int page);
-       void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
-                       const uint8_t *buf);
+                       uint8_t *buf, int oob_required, int page);
+       int (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+                       const uint8_t *buf, int oob_required);
        int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
-                       uint8_t *buf, int page);
+                       uint8_t *buf, int oob_required, int page);
        int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
                        uint32_t offs, uint32_t len, uint8_t *buf);
-       void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
-                       const uint8_t *buf);
-       int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page,
-                       int sndcmd);
+       int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+                       const uint8_t *buf, int oob_required);
+       int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+                       int page);
+       int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+                       int page);
+       int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page);
        int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip,
                        int page);
 };
 
 /**
  * struct nand_buffers - buffer structure for read/write
- * @ecccalc:   buffer for calculated ecc
- * @ecccode:   buffer for ecc read from flash
+ * @ecccalc:   buffer for calculated ECC
+ * @ecccode:   buffer for ECC read from flash
  * @databuf:   buffer for data - dynamically sized
  *
  * Do not change the order of buffers. databuf and oobrbuf must be in
@@ -418,7 +423,7 @@ struct nand_buffers {
  *                     mtd->oobsize, mtd->writesize and so on.
  *                     @id_data contains the 8 bytes values of NAND_CMD_READID.
  *                     Return with the bus width.
- * @dev_ready:         [BOARDSPECIFIC] hardwarespecific function for accesing
+ * @dev_ready:         [BOARDSPECIFIC] hardwarespecific function for accessing
  *                     device ready/busy line. If set to NULL no access to
  *                     ready/busy is available and the ready/busy information
  *                     is read from the chip status register.
@@ -426,17 +431,17 @@ struct nand_buffers {
  *                     commands to the chip.
  * @waitfunc:          [REPLACEABLE] hardwarespecific function for wait on
  *                     ready.
- * @ecc:               [BOARDSPECIFIC] ecc control ctructure
+ * @ecc:               [BOARDSPECIFIC] ECC control structure
  * @buffers:           buffer structure for read/write
  * @hwcontrol:         platform-specific hardware control structure
- * @ops:               oob operation operands
  * @erase_cmd:         [INTERN] erase command write function, selectable due
  *                     to AND support.
  * @scan_bbt:          [REPLACEABLE] function to scan bad block table
  * @chip_delay:                [BOARDSPECIFIC] chip dependent delay for transferring
  *                     data from array to read regs (tR).
  * @state:             [INTERN] the current state of the NAND device
- * @oob_poi:           poison value buffer
+ * @oob_poi:           "poison value buffer," used for laying out OOB data
+ *                     before writing
  * @page_shift:                [INTERN] number of address bits in a page (column
  *                     address bits).
  * @phys_erase_shift:  [INTERN] number of address bits in a physical eraseblock
@@ -445,10 +450,14 @@ struct nand_buffers {
  * @options:           [BOARDSPECIFIC] various chip options. They can partly
  *                     be set to inform nand_scan about special functionality.
  *                     See the defines for further explanation.
+ * @bbt_options:       [INTERN] bad block specific options. All options used
+ *                     here must come from bbm.h. By default, these options
+ *                     will be copied to the appropriate nand_bbt_descr's.
  * @badblockpos:       [INTERN] position of the bad block marker in the oob
  *                     area.
- * @badblockbits:      [INTERN] number of bits to left-shift the bad block
- *                     number
+ * @badblockbits:      [INTERN] minimum number of set bits in a good block's
+ *                     bad block marker position; i.e., BBM == 11110111b is
+ *                     not bad when badblockbits == 7
  * @cellinfo:          [INTERN] MLC/multichip data from chip ident
  * @numchips:          [INTERN] number of physical chips
  * @chipsize:          [INTERN] the size of one chip for multichip arrays
@@ -460,7 +469,9 @@ struct nand_buffers {
  *                     non 0 if ONFI supported.
  * @onfi_params:       [INTERN] holds the ONFI page parameter when ONFI is
  *                     supported, 0 otherwise.
- * @ecclayout:         [REPLACEABLE] the default ecc placement scheme
+ * @onfi_set_features  [REPLACEABLE] set the features for ONFI nand
+ * @onfi_get_features  [REPLACEABLE] get the features for ONFI nand
+ * @ecclayout:         [REPLACEABLE] the default ECC placement scheme
  * @bbt:               [INTERN] bad block table pointer
  * @bbt_td:            [REPLACEABLE] bad block table descriptor for flash
  *                     lookup.
@@ -468,9 +479,9 @@ struct nand_buffers {
  * @badblock_pattern:  [REPLACEABLE] bad block scan pattern used for initial
  *                     bad block scan.
  * @controller:                [REPLACEABLE] a pointer to a hardware controller
- *                     structure which is shared among multiple independend
+ *                     structure which is shared among multiple independent
  *                     devices.
- * @priv:              [OPTIONAL] pointer to private chip date
+ * @priv:              [OPTIONAL] pointer to private chip data
  * @errstat:           [OPTIONAL] hardware specific function to perform
  *                     additional error status checks (determine if errors are
  *                     correctable).
@@ -501,10 +512,16 @@ struct nand_chip {
        int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
                        int status, int page);
        int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
-                       const uint8_t *buf, int page, int cached, int raw);
+                       const uint8_t *buf, int oob_required, int page,
+                       int cached, int raw);
+       int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
+                       int feature_addr, uint8_t *subfeature_para);
+       int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
+                       int feature_addr, uint8_t *subfeature_para);
 
        int chip_delay;
        unsigned int options;
+       unsigned int bbt_options;
 
        int page_shift;
        int phys_erase_shift;
@@ -534,8 +551,6 @@ struct nand_chip {
        struct nand_buffers *buffers;
        struct nand_hw_control hwcontrol;
 
-       struct mtd_oob_ops ops;
-
        uint8_t *bbt;
        struct nand_bbt_descr *bbt_td;
        struct nand_bbt_descr *bbt_md;
@@ -557,6 +572,8 @@ struct nand_chip {
 #define NAND_MFR_HYNIX         0xad
 #define NAND_MFR_MICRON                0x2c
 #define NAND_MFR_AMD           0x01
+#define NAND_MFR_MACRONIX      0xc2
+#define NAND_MFR_EON           0x92
 
 /**
  * struct nand_flash_dev - NAND Flash Device ID Structure
@@ -615,9 +632,9 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
  * @partitions:                mtd partition list
  * @chip_delay:                R/B delay value in us
  * @options:           Option flags, e.g. 16bit buswidth
- * @ecclayout:         ecc layout info structure
+ * @bbt_options:       BBT option flags, e.g. NAND_BBT_USE_FLASH
+ * @ecclayout:         ECC layout info structure
  * @part_probe_types:  NULL-terminated array of probe types
- * @priv:              hardware controller specific settings
  */
 struct platform_nand_chip {
        int nr_chips;
@@ -627,8 +644,8 @@ struct platform_nand_chip {
        struct nand_ecclayout *ecclayout;
        int chip_delay;
        unsigned int options;
+       unsigned int bbt_options;
        const char **part_probe_types;
-       void *priv;
 };
 
 /* Keep gcc happy */
@@ -650,6 +667,7 @@ struct platform_nand_ctrl {
        int (*dev_ready)(struct mtd_info *mtd);
        void (*select_chip)(struct mtd_info *mtd, int chip);
        void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
+       unsigned char (*read_byte)(struct mtd_info *mtd);
        void *priv;
 };
 
@@ -679,4 +697,23 @@ void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
 void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
 uint8_t nand_read_byte(struct mtd_info *mtd);
 
+/* return the supported asynchronous timing mode. */
+
+#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
+static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
+{
+       if (!chip->onfi_version)
+               return ONFI_TIMING_MODE_UNKNOWN;
+       return le16_to_cpu(chip->onfi_params.async_timing_mode);
+}
+
+/* return the supported synchronous timing mode. */
+static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
+{
+       if (!chip->onfi_version)
+               return ONFI_TIMING_MODE_UNKNOWN;
+       return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
+}
+#endif
+
 #endif /* __LINUX_MTD_NAND_H */
index e9b134d1428f43786bce85d8f7dc4a6fc72d1907..8e44855712c33be990b02ff0db8f70f67110d08d 100644 (file)
@@ -85,6 +85,9 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
 #ifndef __HAVE_ARCH_MEMCHR
 extern void * memchr(const void *,int,__kernel_size_t);
 #endif
+#ifndef __HAVE_ARCH_MEMCHR_INV
+void *memchr_inv(const void *, int, size_t);
+#endif
 
 #ifdef __cplusplus
 }
index d1d732c2838d3a48788c16fe87bd9552a8558ab8..bd48704c870daee4eb860586bade83995abd720c 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/types.h>       /* __u8 etc */
 #include <asm/byteorder.h>     /* le16_to_cpu */
+#include <asm/unaligned.h>     /* get_unaligned() */
 
 /*-------------------------------------------------------------------------*/
 
@@ -596,7 +597,7 @@ static inline int usb_endpoint_is_isoc_out(
  */
 static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd)
 {
-       return __le16_to_cpu(epd->wMaxPacketSize);
+       return __le16_to_cpu(get_unaligned(&epd->wMaxPacketSize));
 }
 
 static inline int usb_endpoint_interrupt_type(
index f88f672f111fee172e655167b0284e5b7521774d..583c30e270fa1c4af7af70c089143a8494cdbb78 100644 (file)
 /*
  * EXT_CSD fields
  */
+#define EXT_CSD_GP_SIZE_MULT           143     /* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT   160     /* RO */
+#define EXT_CSD_RPMB_MULT              168     /* RO */
 #define EXT_CSD_ERASE_GROUP_DEF                175     /* R/W */
 #define EXT_CSD_BOOT_BUS_WIDTH         177
 #define EXT_CSD_PART_CONF              179     /* R/W */
 #define EXT_CSD_REV                    192     /* RO */
 #define EXT_CSD_CARD_TYPE              196     /* RO */
 #define EXT_CSD_SEC_CNT                        212     /* RO, 4 bytes */
+#define EXT_CSD_HC_WP_GRP_SIZE         221     /* RO */
 #define EXT_CSD_HC_ERASE_GRP_SIZE      224     /* RO */
 #define EXT_CSD_BOOT_MULT              226     /* RO */
 
@@ -284,6 +287,10 @@ struct mmc {
        uint write_bl_len;
        uint erase_grp_size;
        u64 capacity;
+       u64 capacity_user;
+       u64 capacity_boot;
+       u64 capacity_rpmb;
+       u64 capacity_gp[4];
        block_dev_desc_t block_dev;
        int (*send_cmd)(struct mmc *mmc,
                        struct mmc_cmd *cmd, struct mmc_data *data);
similarity index 65%
rename from include/linux/mtd/mtd-abi.h
rename to include/mtd/mtd-abi.h
index 8bdd23112b4f2cfd5c40079e8301c7ba2ba0966e..d51c1abd186328d9f862aba4febeabcc8fdf4eb1 100644 (file)
@@ -24,6 +24,25 @@ struct mtd_oob_buf {
        unsigned char __user *ptr;
 };
 
+/*
+ * MTD operation modes
+ *
+ * @MTD_OPS_PLACE_OOB: OOB data are placed at the given offset (default)
+ * @MTD_OPS_AUTO_OOB:  OOB data are automatically placed at the free areas
+ *                     which are defined by the internal ecclayout
+ * @MTD_OPS_RAW:       data are transferred as-is, with no error correction;
+ *                     this mode implies %MTD_OPS_PLACE_OOB
+ *
+ * These modes can be passed to ioctl(MEMWRITE) and are also used internally.
+ * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs.
+ * %MTD_FILE_MODE_RAW.
+ */
+enum {
+       MTD_OPS_PLACE_OOB = 0,
+       MTD_OPS_AUTO_OOB = 1,
+       MTD_OPS_RAW = 2,
+};
+
 #define MTD_ABSENT             0
 #define MTD_RAM                        1
 #define MTD_ROM                        2
@@ -82,24 +101,42 @@ struct otp_info {
        uint32_t locked;
 };
 
+/* Get basic MTD characteristics info (better to use sysfs) */
 #define MEMGETINFO             _IOR('M', 1, struct mtd_info_user)
+/* Erase segment of MTD */
 #define MEMERASE               _IOW('M', 2, struct erase_info_user)
+/* Write out-of-band data from MTD */
 #define MEMWRITEOOB            _IOWR('M', 3, struct mtd_oob_buf)
+/* Read out-of-band data from MTD */
 #define MEMREADOOB             _IOWR('M', 4, struct mtd_oob_buf)
+/* Lock a chip (for MTD that supports it) */
 #define MEMLOCK                        _IOW('M', 5, struct erase_info_user)
+/* Unlock a chip (for MTD that supports it) */
 #define MEMUNLOCK              _IOW('M', 6, struct erase_info_user)
+/* Get the number of different erase regions */
 #define MEMGETREGIONCOUNT      _IOR('M', 7, int)
+/* Get information about the erase region for a specific index */
 #define MEMGETREGIONINFO       _IOWR('M', 8, struct region_info_user)
+/* Get info about OOB modes (e.g., RAW, PLACE, AUTO) - legacy interface */
 #define MEMSETOOBSEL           _IOW('M', 9, struct nand_oobinfo)
 #define MEMGETOOBSEL           _IOR('M', 10, struct nand_oobinfo)
+/* Check if an eraseblock is bad */
 #define MEMGETBADBLOCK         _IOW('M', 11, loff_t)
+/* Mark an eraseblock as bad */
 #define MEMSETBADBLOCK         _IOW('M', 12, loff_t)
+/* Set OTP (One-Time Programmable) mode (factory vs. user) */
 #define OTPSELECT              _IOR('M', 13, int)
+/* Get number of OTP (One-Time Programmable) regions */
 #define OTPGETREGIONCOUNT      _IOW('M', 14, int)
+/* Get all OTP (One-Time Programmable) info about MTD */
 #define OTPGETREGIONINFO       _IOW('M', 15, struct otp_info)
+/* Lock a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */
 #define OTPLOCK                        _IOR('M', 16, struct otp_info)
+/* Get ECC layout (deprecated) */
 #define ECCGETLAYOUT           _IOR('M', 17, struct nand_ecclayout)
+/* Get statistics about corrected/uncorrected errors */
 #define ECCGETSTATS            _IOR('M', 18, struct mtd_ecc_stats)
+/* Set MTD mode on a per-file-descriptor basis (see "MTD file modes") */
 #define MTDFILEMODE            _IO('M', 19)
 
 /*
@@ -146,7 +183,21 @@ struct mtd_ecc_stats {
 };
 
 /*
- * Read/write file modes for access to MTD
+ * MTD file modes - for read/write access to MTD
+ *
+ * @MTD_FILE_MODE_NORMAL:      OTP disabled, ECC enabled
+ * @MTD_FILE_MODE_OTP_FACTORY: OTP enabled in factory mode
+ * @MTD_FILE_MODE_OTP_USER:    OTP enabled in user mode
+ * @MTD_FILE_MODE_RAW:         OTP disabled, ECC disabled
+ *
+ * These modes can be set via ioctl(MTDFILEMODE). The mode mode will be retained
+ * separately for each open file descriptor.
+ *
+ * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW -
+ * raw access to the flash, without error correction or autoplacement schemes.
+ * Wherever possible, the MTD_OPS_* mode will override the MTD_FILE_MODE_* mode
+ * (e.g., when using ioctl(MEMWRITE)), but in some cases, the MTD_FILE_MODE is
+ * used out of necessity (e.g., `write()', ioctl(MEMWRITEOOB64)).
  */
 enum mtd_file_modes {
        MTD_MODE_NORMAL = MTD_OTP_OFF,
index f0f3bf94b555d4c6055d65cdc81d30c264cdd9a9..26190e4137da9ac05c896506f909d230f5f4537d 100644 (file)
@@ -31,7 +31,8 @@
  * at the same time, so do it here.  When all drivers are
  * converted, this will go away.
  */
-#if defined(CONFIG_NAND_FSL_ELBC) || defined(CONFIG_NAND_ATMEL)
+#if defined(CONFIG_NAND_FSL_ELBC) || defined(CONFIG_NAND_ATMEL)\
+       || defined(CONFIG_NAND_FSL_IFC)
 #define CONFIG_SYS_NAND_SELF_INIT
 #endif
 
@@ -55,17 +56,17 @@ extern nand_info_t nand_info[];
 
 static inline int nand_read(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf)
 {
-       return info->read(info, ofs, *len, (size_t *)len, buf);
+       return mtd_read(info, ofs, *len, (size_t *)len, buf);
 }
 
 static inline int nand_write(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf)
 {
-       return info->write(info, ofs, *len, (size_t *)len, buf);
+       return mtd_write(info, ofs, *len, (size_t *)len, buf);
 }
 
 static inline int nand_block_isbad(nand_info_t *info, loff_t ofs)
 {
-       return info->block_isbad(info, ofs);
+       return mtd_block_isbad(info, ofs);
 }
 
 static inline int nand_erase(nand_info_t *info, loff_t off, size_t size)
@@ -77,7 +78,7 @@ static inline int nand_erase(nand_info_t *info, loff_t off, size_t size)
        instr.len = size;
        instr.callback = 0;
 
-       return info->erase(info, &instr);
+       return mtd_erase(info, &instr);
 }
 
 
index 970d4d1fab13df2c093062e1cf015625bb5db558..23fb947292ccf3e1e1b805e86c11ac75106f3107 100644 (file)
@@ -695,6 +695,9 @@ extern void copy_filename(char *dst, const char *src, int size);
 /* get a random source port */
 extern unsigned int random_port(void);
 
+/* Update U-Boot over TFTP */
+extern int update_tftp(ulong addr);
+
 /**********************************************************************/
 
 #endif /* __NET_H__ */
index 15f583f069d4ca1c45f09893542af487cb37f998..f9c51482550d7cd6980d16d0e2659c287ec799d5 100644 (file)
@@ -569,7 +569,9 @@ extern __inline__ void pci_set_ops(struct pci_controller *hose,
        hose->write_dword = write_dword;
 }
 
+#ifdef CONFIG_PCI_INDIRECT_BRIDGE
 extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
+#endif
 
 extern phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
                                        pci_addr_t addr, unsigned long flags);
index 3fe2e1eab2defc568079cd8a035225bbf682b18d..1638b503945071c9ccbd5486a870ac1814160779 100644 (file)
 #define        SPI_LSB_FIRST   0x08                    /* per-word bits-on-wire */
 #define        SPI_3WIRE       0x10                    /* SI/SO signals shared */
 #define        SPI_LOOP        0x20                    /* loopback mode */
+#define        SPI_SLAVE       0x40                    /* slave mode */
+#define        SPI_PREAMBLE    0x80                    /* Skip preamble bytes */
 
 /* SPI transfer flags */
 #define SPI_XFER_BEGIN 0x01                    /* Assert CS before transfer */
 #define SPI_XFER_END   0x02                    /* Deassert CS after transfer */
 
+/* Header byte that marks the start of the message */
+#define SPI_PREAMBLE_END_BYTE  0xec
+
 /*-----------------------------------------------------------------------
  * Representation of a SPI slave, i.e. what we're communicating with.
  *
diff --git a/include/usb/fotg210.h b/include/usb/fotg210.h
new file mode 100644 (file)
index 0000000..2d2d243
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+ * Faraday USB 2.0 OTG Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef _FOTG210_H
+#define _FOTG210_H
+
+struct fotg210_regs {
+       /* USB Host Controller */
+       struct {
+               uint32_t data[4];
+       } hccr;                 /* 0x00 - 0x0f: hccr */
+       struct {
+               uint32_t data[9];
+       } hcor;                 /* 0x10 - 0x33: hcor */
+       uint32_t rsvd1[3];
+       uint32_t miscr; /* 0x40: Miscellaneous Register */
+       uint32_t rsvd2[15];
+       /* USB OTG Controller */
+       uint32_t otgcsr;/* 0x80: OTG Control Status Register */
+       uint32_t otgisr;/* 0x84: OTG Interrupt Status Register */
+       uint32_t otgier;/* 0x88: OTG Interrupt Enable Register */
+       uint32_t rsvd3[13];
+       uint32_t isr;   /* 0xC0: Global Interrupt Status Register */
+       uint32_t imr;   /* 0xC4: Global Interrupt Mask Register */
+       uint32_t rsvd4[14];
+       /* USB Device Controller */
+       uint32_t dev_ctrl;/* 0x100: Device Control Register */
+       uint32_t dev_addr;/* 0x104: Device Address Register */
+       uint32_t dev_test;/* 0x108: Device Test Register */
+       uint32_t sof_fnr; /* 0x10c: SOF Frame Number Register */
+       uint32_t sof_mtr; /* 0x110: SOF Mask Timer Register */
+       uint32_t phy_tmsr;/* 0x114: PHY Test Mode Selector Register */
+       uint32_t rsvd5[2];
+       uint32_t cxfifo;/* 0x120: CX FIFO Register */
+       uint32_t idle;  /* 0x124: IDLE Counter Register */
+       uint32_t rsvd6[2];
+       uint32_t gimr;  /* 0x130: Group Interrupt Mask Register */
+       uint32_t gimr0; /* 0x134: Group Interrupt Mask Register 0 */
+       uint32_t gimr1; /* 0x138: Group Interrupt Mask Register 1 */
+       uint32_t gimr2; /* 0x13c: Group Interrupt Mask Register 2 */
+       uint32_t gisr;  /* 0x140: Group Interrupt Status Register */
+       uint32_t gisr0; /* 0x144: Group Interrupt Status Register 0 */
+       uint32_t gisr1; /* 0x148: Group Interrupt Status Register 1 */
+       uint32_t gisr2; /* 0x14c: Group Interrupt Status Register 2 */
+       uint32_t rxzlp; /* 0x150: Receive Zero-Length-Packet Register */
+       uint32_t txzlp; /* 0x154: Transfer Zero-Length-Packet Register */
+       uint32_t isoeasr;/* 0x158: ISOC Error/Abort Status Register */
+       uint32_t rsvd7[1];
+       uint32_t iep[8]; /* 0x160 - 0x17f: IN Endpoint Register */
+       uint32_t oep[8]; /* 0x180 - 0x19f: OUT Endpoint Register */
+       uint32_t epmap14;/* 0x1a0: Endpoint Map Register (EP1 ~ 4) */
+       uint32_t epmap58;/* 0x1a4: Endpoint Map Register (EP5 ~ 8) */
+       uint32_t fifomap;/* 0x1a8: FIFO Map Register */
+       uint32_t fifocfg; /* 0x1ac: FIFO Configuration Register */
+       uint32_t fifocsr[4];/* 0x1b0 - 0x1bf: FIFO Control Status Register */
+       uint32_t dma_fifo; /* 0x1c0: DMA Target FIFO Register */
+       uint32_t rsvd8[1];
+       uint32_t dma_ctrl; /* 0x1c8: DMA Control Register */
+       uint32_t dma_addr; /* 0x1cc: DMA Address Register */
+       uint32_t ep0_data; /* 0x1d0: EP0 Setup Packet PIO Register */
+};
+
+/* Miscellaneous Register */
+#define MISCR_SUSPEND  (1 << 6) /* Put transceiver in suspend mode */
+#define MISCR_EOF2(x)  (((x) & 0x3) << 4) /* EOF 2 Timing */
+#define MISCR_EOF1(x)  (((x) & 0x3) << 2) /* EOF 1 Timing */
+#define MISCR_ASST(x)  (((x) & 0x3) << 0) /* Async. Sched. Sleep Timer */
+
+/* OTG Control Status Register */
+#define OTGCSR_SPD_HIGH     (2 << 22) /* Speed of the attached device (host) */
+#define OTGCSR_SPD_LOW      (1 << 22)
+#define OTGCSR_SPD_FULL     (0 << 22)
+#define OTGCSR_SPD_MASK     (3 << 22)
+#define OTGCSR_SPD_SHIFT    22
+#define OTGCSR_SPD(x)       (((x) >> 22) & 0x03)
+#define OTGCSR_DEV_A        (0 << 21) /* Acts as A-device */
+#define OTGCSR_DEV_B        (1 << 21) /* Acts as B-device */
+#define OTGCSR_ROLE_H       (0 << 20) /* Acts as Host */
+#define OTGCSR_ROLE_D       (1 << 20) /* Acts as Device */
+#define OTGCSR_A_VBUS_VLD   (1 << 19) /* A-device VBUS Valid */
+#define OTGCSR_A_SESS_VLD   (1 << 18) /* A-device Session Valid */
+#define OTGCSR_B_SESS_VLD   (1 << 17) /* B-device Session Valid */
+#define OTGCSR_B_SESS_END   (1 << 16) /* B-device Session End */
+#define OTGCSR_HFT_LONG     (1 << 11) /* HDISCON noise filter = 270 us*/
+#define OTGCSR_HFT          (0 << 11) /* HDISCON noise filter = 135 us*/
+#define OTGCSR_VFT_LONG     (1 << 10) /* VBUS noise filter = 472 us*/
+#define OTGCSR_VFT          (0 << 10) /* VBUS noise filter = 135 us*/
+#define OTGCSR_IDFT_LONG    (1 << 9)  /* ID noise filter = 4 ms*/
+#define OTGCSR_IDFT         (0 << 9)  /* ID noise filter = 3 ms*/
+#define OTGCSR_A_SRPR_VBUS  (0 << 8)  /* A-device: SRP responds to VBUS */
+#define OTGCSR_A_SRPR_DATA  (1 << 8)  /* A-device: SRP responds to DATA-LINE */
+#define OTGCSR_A_SRP_EN     (1 << 7)  /* A-device SRP detection enabled */
+#define OTGCSR_A_HNP        (1 << 6)  /* Set role=A-device with HNP enabled */
+#define OTGCSR_A_BUSDROP    (1 << 5)  /* A-device drop bus (power-down) */
+#define OTGCSR_A_BUSREQ     (1 << 4)  /* A-device request bus */
+#define OTGCSR_B_VBUS_DISC  (1 << 2)  /* B-device discharges VBUS */
+#define OTGCSR_B_HNP        (1 << 1)  /* B-device enable HNP */
+#define OTGCSR_B_BUSREQ     (1 << 0)  /* B-device request bus */
+
+/* OTG Interrupt Status Register */
+#define OTGISR_APRM         (1 << 12) /* Mini-A plug removed */
+#define OTGISR_BPRM         (1 << 11) /* Mini-B plug removed */
+#define OTGISR_OVD          (1 << 10) /* over-current detected */
+#define OTGISR_IDCHG        (1 << 9)  /* ID(A/B) changed */
+#define OTGISR_RLCHG        (1 << 8)  /* Role(Host/Device) changed */
+#define OTGISR_BSESSEND     (1 << 6)  /* B-device Session End */
+#define OTGISR_AVBUSERR     (1 << 5)  /* A-device VBUS Error */
+#define OTGISR_ASRP         (1 << 4)  /* A-device SRP detected */
+#define OTGISR_BSRP         (1 << 0)  /* B-device SRP complete */
+
+/* OTG Interrupt Enable Register */
+#define OTGIER_APRM         (1 << 12) /* Mini-A plug removed */
+#define OTGIER_BPRM         (1 << 11) /* Mini-B plug removed */
+#define OTGIER_OVD          (1 << 10) /* over-current detected */
+#define OTGIER_IDCHG        (1 << 9)  /* ID(A/B) changed */
+#define OTGIER_RLCHG        (1 << 8)  /* Role(Host/Device) changed */
+#define OTGIER_BSESSEND     (1 << 6)  /* B-device Session End */
+#define OTGIER_AVBUSERR     (1 << 5)  /* A-device VBUS Error */
+#define OTGIER_ASRP         (1 << 4)  /* A-device SRP detected */
+#define OTGIER_BSRP         (1 << 0)  /* B-device SRP complete */
+
+/* Global Interrupt Status Register (W1C) */
+#define ISR_HOST            (1 << 2)  /* USB Host interrupt */
+#define ISR_OTG             (1 << 1)  /* USB OTG interrupt */
+#define ISR_DEV             (1 << 0)  /* USB Device interrupt */
+#define ISR_MASK            0x07
+
+/* Global Interrupt Mask Register */
+#define IMR_IRQLH           (1 << 3)  /* Interrupt triggered at level-high */
+#define IMR_IRQLL           (0 << 3)  /* Interrupt triggered at level-low */
+#define IMR_HOST            (1 << 2)  /* USB Host interrupt */
+#define IMR_OTG             (1 << 1)  /* USB OTG interrupt */
+#define IMR_DEV             (1 << 0)  /* USB Device interrupt */
+#define IMR_MASK            0x0f
+
+/* Device Control Register */
+#define DEVCTRL_FS_FORCED   (1 << 9)  /* Forced to be Full-Speed Mode */
+#define DEVCTRL_HS          (1 << 6)  /* High Speed Mode */
+#define DEVCTRL_FS          (0 << 6)  /* Full Speed Mode */
+#define DEVCTRL_EN          (1 << 5)  /* Chip Enable */
+#define DEVCTRL_RESET       (1 << 4)  /* Chip Software Reset */
+#define DEVCTRL_SUSPEND     (1 << 3)  /* Enter Suspend Mode */
+#define DEVCTRL_GIRQ_EN     (1 << 2)  /* Global Interrupt Enabled */
+#define DEVCTRL_HALFSPD     (1 << 1)  /* Half speed mode for FPGA test */
+#define DEVCTRL_RWAKEUP     (1 << 0)  /* Enable remote wake-up */
+
+/* Device Address Register */
+#define DEVADDR_CONF        (1 << 7)  /* SET_CONFIGURATION has been executed */
+#define DEVADDR_ADDR(x)     ((x) & 0x7f)
+#define DEVADDR_ADDR_MASK   0x7f
+
+/* Device Test Register */
+#define DEVTEST_NOSOF       (1 << 6)  /* Do not generate SOF */
+#define DEVTEST_TST_MODE    (1 << 5)  /* Enter Test Mode */
+#define DEVTEST_TST_NOTS    (1 << 4)  /* Do not toggle sequence */
+#define DEVTEST_TST_NOCRC   (1 << 3)  /* Do not append CRC */
+#define DEVTEST_TST_CLREA   (1 << 2)  /* Clear External Side Address */
+#define DEVTEST_TST_CXLP    (1 << 1)  /* EP0 loopback test */
+#define DEVTEST_TST_CLRFF   (1 << 0)  /* Clear FIFO */
+
+/* SOF Frame Number Register */
+#define SOFFNR_UFN(x)       (((x) >> 11) & 0x7) /* SOF Micro-Frame Number */
+#define SOFFNR_FNR(x)       ((x) & 0x7ff) /* SOF Frame Number */
+
+/* SOF Mask Timer Register */
+#define SOFMTR_TMR(x)       ((x) & 0xffff)
+
+/* PHY Test Mode Selector Register */
+#define PHYTMSR_TST_PKT     (1 << 4) /* Packet send test */
+#define PHYTMSR_TST_SE0NAK  (1 << 3) /* High-Speed quiescent state */
+#define PHYTMSR_TST_KSTA    (1 << 2) /* High-Speed K state */
+#define PHYTMSR_TST_JSTA    (1 << 1) /* High-Speed J state */
+#define PHYTMSR_UNPLUG      (1 << 0) /* Enable soft-detachment */
+
+/* CX FIFO Register */
+#define CXFIFO_BYTES(x)     (((x) >> 24) & 0x7f) /* CX/EP0 FIFO byte count */
+#define CXFIFO_FIFOE(x)     (1 << (((x) & 0x03) + 8)) /* EPx FIFO empty */
+#define CXFIFO_FIFOE_FIFO0  (1 << 8)
+#define CXFIFO_FIFOE_FIFO1  (1 << 9)
+#define CXFIFO_FIFOE_FIFO2  (1 << 10)
+#define CXFIFO_FIFOE_FIFO3  (1 << 11)
+#define CXFIFO_FIFOE_MASK   (0x0f << 8)
+#define CXFIFO_CXFIFOE      (1 << 5) /* CX FIFO empty */
+#define CXFIFO_CXFIFOF      (1 << 4) /* CX FIFO full */
+#define CXFIFO_CXFIFOCLR    (1 << 3) /* CX FIFO clear */
+#define CXFIFO_CXSTALL      (1 << 2) /* CX Stall */
+#define CXFIFO_TSTPKTFIN    (1 << 1) /* Test packet data transfer finished */
+#define CXFIFO_CXFIN        (1 << 0) /* CX data transfer finished */
+
+/* IDLE Counter Register */
+#define IDLE_MS(x)          ((x) & 0x07) /* PHY suspend delay = x ms */
+
+/* Group Interrupt Mask(Disable) Register */
+#define GIMR_GRP2           (1 << 2) /* Disable interrupt group 2 */
+#define GIMR_GRP1           (1 << 1) /* Disable interrupt group 1 */
+#define GIMR_GRP0           (1 << 0) /* Disable interrupt group 0 */
+#define GIMR_MASK           0x07
+
+/* Group Interrupt Mask(Disable) Register 0 (CX) */
+#define GIMR0_CXABORT       (1 << 5) /* CX command abort interrupt */
+#define GIMR0_CXERR         (1 << 4) /* CX command error interrupt */
+#define GIMR0_CXEND         (1 << 3) /* CX command end interrupt */
+#define GIMR0_CXOUT         (1 << 2) /* EP0-OUT packet interrupt */
+#define GIMR0_CXIN          (1 << 1) /* EP0-IN packet interrupt */
+#define GIMR0_CXSETUP       (1 << 0) /* EP0-SETUP packet interrupt */
+#define GIMR0_MASK          0x3f
+
+/* Group Interrupt Mask(Disable) Register 1 (FIFO) */
+#define GIMR1_FIFO_IN(x)    (1 << (((x) & 3) + 16))    /* FIFOx IN */
+#define GIMR1_FIFO_TX(x)    GIMR1_FIFO_IN(x)
+#define GIMR1_FIFO_OUT(x)   (1 << (((x) & 3) * 2))     /* FIFOx OUT */
+#define GIMR1_FIFO_SPK(x)   (1 << (((x) & 3) * 2 + 1)) /* FIFOx SHORT PACKET */
+#define GIMR1_FIFO_RX(x)    (GIMR1_FIFO_OUT(x) | GIMR1_FIFO_SPK(x))
+#define GIMR1_MASK          0xf00ff
+
+/* Group Interrupt Mask(Disable) Register 2 (Device) */
+#define GIMR2_WAKEUP        (1 << 10) /* Device waked up */
+#define GIMR2_IDLE          (1 << 9)  /* Device idle */
+#define GIMR2_DMAERR        (1 << 8)  /* DMA error */
+#define GIMR2_DMAFIN        (1 << 7)  /* DMA finished */
+#define GIMR2_ZLPRX         (1 << 6)  /* Zero-Length-Packet Rx Interrupt */
+#define GIMR2_ZLPTX         (1 << 5)  /* Zero-Length-Packet Tx Interrupt */
+#define GIMR2_ISOCABT       (1 << 4)  /* ISOC Abort Interrupt */
+#define GIMR2_ISOCERR       (1 << 3)  /* ISOC Error Interrupt */
+#define GIMR2_RESUME        (1 << 2)  /* Resume state change Interrupt */
+#define GIMR2_SUSPEND       (1 << 1)  /* Suspend state change Interrupt */
+#define GIMR2_RESET         (1 << 0)  /* Reset Interrupt */
+#define GIMR2_MASK          0x7ff
+
+/* Group Interrupt Status Register */
+#define GISR_GRP2           (1 << 2) /* Interrupt group 2 */
+#define GISR_GRP1           (1 << 1) /* Interrupt group 1 */
+#define GISR_GRP0           (1 << 0) /* Interrupt group 0 */
+
+/* Group Interrupt Status Register 0 (CX) */
+#define GISR0_CXABORT       (1 << 5) /* CX command abort interrupt */
+#define GISR0_CXERR         (1 << 4) /* CX command error interrupt */
+#define GISR0_CXEND         (1 << 3) /* CX command end interrupt */
+#define GISR0_CXOUT         (1 << 2) /* EP0-OUT packet interrupt */
+#define GISR0_CXIN          (1 << 1) /* EP0-IN packet interrupt */
+#define GISR0_CXSETUP       (1 << 0) /* EP0-SETUP packet interrupt */
+
+/* Group Interrupt Status Register 1 (FIFO) */
+#define GISR1_IN_FIFO(x)    (1 << (((x) & 0x03) + 16))    /* FIFOx IN */
+#define GISR1_OUT_FIFO(x)   (1 << (((x) & 0x03) * 2))     /* FIFOx OUT */
+#define GISR1_SPK_FIFO(x)   (1 << (((x) & 0x03) * 2 + 1)) /* FIFOx SPK */
+#define GISR1_RX_FIFO(x)    (3 << (((x) & 0x03) * 2))     /* FIFOx OUT/SPK */
+
+/* Group Interrupt Status Register 2 (Device) */
+#define GISR2_WAKEUP        (1 << 10) /* Device waked up */
+#define GISR2_IDLE          (1 << 9)  /* Device idle */
+#define GISR2_DMAERR        (1 << 8)  /* DMA error */
+#define GISR2_DMAFIN        (1 << 7)  /* DMA finished */
+#define GISR2_ZLPRX         (1 << 6)  /* Zero-Length-Packet Rx Interrupt */
+#define GISR2_ZLPTX         (1 << 5)  /* Zero-Length-Packet Tx Interrupt */
+#define GISR2_ISOCABT       (1 << 4)  /* ISOC Abort Interrupt */
+#define GISR2_ISOCERR       (1 << 3)  /* ISOC Error Interrupt */
+#define GISR2_RESUME        (1 << 2)  /* Resume state change Interrupt */
+#define GISR2_SUSPEND       (1 << 1)  /* Suspend state change Interrupt */
+#define GISR2_RESET         (1 << 0)  /* Reset Interrupt */
+
+/* Receive Zero-Length-Packet Register */
+#define RXZLP_EP(x)         (1 << ((x) - 1)) /* EPx ZLP rx interrupt */
+
+/* Transfer Zero-Length-Packet Register */
+#define TXZLP_EP(x)         (1 << ((x) - 1)) /* EPx ZLP tx interrupt */
+
+/* ISOC Error/Abort Status Register */
+#define ISOEASR_EP(x)       (0x10001 << ((x) - 1)) /* EPx ISOC Error/Abort */
+
+/* IN Endpoint Register */
+#define IEP_SENDZLP         (1 << 15)     /* Send Zero-Length-Packet */
+#define IEP_TNRHB(x)        (((x) & 0x03) << 13) \
+       /* Transaction Number for High-Bandwidth EP(ISOC) */
+#define IEP_RESET           (1 << 12)     /* Reset Toggle Sequence */
+#define IEP_STALL           (1 << 11)     /* Stall */
+#define IEP_MAXPS(x)        ((x) & 0x7ff) /* Max. packet size */
+
+/* OUT Endpoint Register */
+#define OEP_RESET           (1 << 12)     /* Reset Toggle Sequence */
+#define OEP_STALL           (1 << 11)     /* Stall */
+#define OEP_MAXPS(x)        ((x) & 0x7ff) /* Max. packet size */
+
+/* Endpoint Map Register (EP1 ~ EP4) */
+#define EPMAP14_SET_IN(ep, fifo) \
+       ((fifo) & 3) << (((ep) - 1) << 3 + 0)
+#define EPMAP14_SET_OUT(ep, fifo) \
+       ((fifo) & 3) << (((ep) - 1) << 3 + 4)
+#define EPMAP14_SET(ep, in, out) \
+       do { \
+               EPMAP14_SET_IN(ep, in); \
+               EPMAP14_SET_OUT(ep, out); \
+       } while (0)
+
+#define EPMAP14_DEFAULT     0x33221100 /* EP1->FIFO0, EP2->FIFO1... */
+
+/* Endpoint Map Register (EP5 ~ EP8) */
+#define EPMAP58_SET_IN(ep, fifo) \
+       ((fifo) & 3) << (((ep) - 5) << 3 + 0)
+#define EPMAP58_SET_OUT(ep, fifo) \
+       ((fifo) & 3) << (((ep) - 5) << 3 + 4)
+#define EPMAP58_SET(ep, in, out) \
+       do { \
+               EPMAP58_SET_IN(ep, in); \
+               EPMAP58_SET_OUT(ep, out); \
+       } while (0)
+
+#define EPMAP58_DEFAULT     0x00000000 /* All EPx->FIFO0 */
+
+/* FIFO Map Register */
+#define FIFOMAP_BIDIR       (2 << 4)
+#define FIFOMAP_IN          (1 << 4)
+#define FIFOMAP_OUT         (0 << 4)
+#define FIFOMAP_DIR_MASK    0x30
+#define FIFOMAP_EP(x)       ((x) & 0x0f)
+#define FIFOMAP_EP_MASK     0x0f
+#define FIFOMAP_CFG_MASK    0x3f
+#define FIFOMAP_DEFAULT     0x04030201 /* FIFO0->EP1, FIFO1->EP2... */
+#define FIFOMAP(fifo, cfg)  (((cfg) & 0x3f) << (((fifo) & 3) << 3))
+
+/* FIFO Configuration Register */
+#define FIFOCFG_EN          (1 << 5)
+#define FIFOCFG_BLKSZ_1024  (1 << 4)
+#define FIFOCFG_BLKSZ_512   (0 << 4)
+#define FIFOCFG_3BLK        (2 << 2)
+#define FIFOCFG_2BLK        (1 << 2)
+#define FIFOCFG_1BLK        (0 << 2)
+#define FIFOCFG_NBLK_MASK   3
+#define FIFOCFG_NBLK_SHIFT  2
+#define FIFOCFG_INTR        (3 << 0)
+#define FIFOCFG_BULK        (2 << 0)
+#define FIFOCFG_ISOC        (1 << 0)
+#define FIFOCFG_RSVD        (0 << 0)  /* Reserved */
+#define FIFOCFG_TYPE_MASK   3
+#define FIFOCFG_TYPE_SHIFT  0
+#define FIFOCFG_CFG_MASK    0x3f
+#define FIFOCFG(fifo, cfg)  (((cfg) & 0x3f) << (((fifo) & 3) << 3))
+
+/* FIFO Control Status Register */
+#define FIFOCSR_RESET       (1 << 12) /* FIFO Reset */
+#define FIFOCSR_BYTES(x)    ((x) & 0x7ff) /* Length(bytes) for OUT-EP/FIFO */
+
+/* DMA Target FIFO Register */
+#define DMAFIFO_CX          (1 << 4) /* DMA FIFO = CX FIFO */
+#define DMAFIFO_FIFO(x)     (1 << ((x) & 0x3)) /* DMA FIFO = FIFOx */
+
+/* DMA Control Register */
+#define DMACTRL_LEN(x)      (((x) & 0x1ffff) << 8) /* DMA length (Bytes) */
+#define DMACTRL_LEN_SHIFT   8
+#define DMACTRL_CLRFF       (1 << 4) /* Clear FIFO upon DMA abort */
+#define DMACTRL_ABORT       (1 << 3) /* DMA abort */
+#define DMACTRL_IO2IO       (1 << 2) /* IO to IO */
+#define DMACTRL_FIFO2MEM    (0 << 1) /* FIFO to Memory */
+#define DMACTRL_MEM2FIFO    (1 << 1) /* Memory to FIFO */
+#define DMACTRL_START       (1 << 0) /* DMA start */
+
+#endif
diff --git a/include/usb/fusbh200.h b/include/usb/fusbh200.h
new file mode 100644 (file)
index 0000000..8a9c488
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Faraday USB 2.0 EHCI Controller
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#ifndef _FUSBH200_H
+#define _FUSBH200_H
+
+struct fusbh200_regs {
+       struct {
+               uint32_t data[4];
+       } hccr;                 /* 0x00 - 0x0f: hccr */
+       struct {
+               uint32_t data[9];
+       } hcor;                 /* 0x10 - 0x33: hcor */
+       uint32_t easstr;/* 0x34: EOF&Async. Sched. Sleep Timer Register */
+       uint32_t rsvd[2];
+       uint32_t bmcsr; /* 0x40: Bus Monitor Control Status Register */
+       uint32_t bmisr; /* 0x44: Bus Monitor Interrupt Status Register */
+       uint32_t bmier; /* 0x48: Bus Monitor Interrupt Enable Register */
+};
+
+/* EOF & Async. Schedule Sleep Timer Register */
+#define EASSTR_RUNNING  (1 << 6) /* Put transceiver in running/resume mode */
+#define EASSTR_SUSPEND  (0 << 6) /* Put transceiver in suspend mode */
+#define EASSTR_EOF2(x)  (((x) & 0x3) << 4) /* EOF 2 Timing */
+#define EASSTR_EOF1(x)  (((x) & 0x3) << 2) /* EOF 1 Timing */
+#define EASSTR_ASST(x)  (((x) & 0x3) << 0) /* Async. Sched. Sleep Timer */
+
+/* Bus Monitor Control Status Register */
+#define BMCSR_SPD_HIGH  (2 << 9) /* Speed of the attached device */
+#define BMCSR_SPD_LOW   (1 << 9)
+#define BMCSR_SPD_FULL  (0 << 9)
+#define BMCSR_SPD_MASK  (3 << 9)
+#define BMCSR_SPD_SHIFT 9
+#define BMCSR_SPD(x)    ((x >> 9) & 0x03)
+#define BMCSR_VBUS      (1 << 8) /* VBUS Valid */
+#define BMCSR_VBUS_OFF  (1 << 4) /* VBUS Off */
+#define BMCSR_VBUS_ON   (0 << 4) /* VBUS On */
+#define BMCSR_IRQLH     (1 << 3) /* IRQ triggered at level-high */
+#define BMCSR_IRQLL     (0 << 3) /* IRQ triggered at level-low */
+#define BMCSR_HALFSPD   (1 << 2) /* Half speed mode for FPGA test */
+#define BMCSR_HFT_LONG  (1 << 1) /* HDISCON noise filter = 270 us*/
+#define BMCSR_HFT       (0 << 1) /* HDISCON noise filter = 135 us*/
+#define BMCSR_VFT_LONG  (1 << 1) /* VBUS noise filter = 472 us*/
+#define BMCSR_VFT       (0 << 1) /* VBUS noise filter = 135 us*/
+
+/* Bus Monitor Interrupt Status Register */
+/* Bus Monitor Interrupt Enable Register */
+#define BMISR_DMAERR    (1 << 4) /* DMA error */
+#define BMISR_DMA       (1 << 3) /* DMA complete */
+#define BMISR_DEVRM     (1 << 2) /* device removed */
+#define BMISR_OVD       (1 << 1) /* over-current detected */
+#define BMISR_VBUSERR   (1 << 0) /* VBUS error */
+
+#endif
index 5d586098dd5e850d7a7060d2c61119b42e2ec08e..a94830f51e93730375a70788819c3162e89ca400 100644 (file)
@@ -26,7 +26,6 @@ include $(TOPDIR)/config.mk
 LIB    = $(obj)libgeneric.o
 
 ifndef CONFIG_SPL_BUILD
-COBJS-$(CONFIG_ADDR_MAP) += addr_map.o
 COBJS-$(CONFIG_AES) += aes.o
 COBJS-$(CONFIG_BZIP2) += bzlib.o
 COBJS-$(CONFIG_BZIP2) += bzlib_crctable.o
@@ -36,13 +35,10 @@ COBJS-$(CONFIG_BZIP2) += bzlib_huffman.o
 COBJS-$(CONFIG_USB_TTY) += circbuf.o
 COBJS-y += crc7.o
 COBJS-y += crc16.o
-COBJS-y += display_options.o
-COBJS-y += errno.o
 COBJS-$(CONFIG_OF_CONTROL) += fdtdec.o
 COBJS-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
 COBJS-$(CONFIG_GZIP) += gunzip.o
 COBJS-$(CONFIG_GZIP_COMPRESSED) += gzip.o
-COBJS-y += hashtable.o
 COBJS-y += initcall.o
 COBJS-$(CONFIG_LMB) += lmb.o
 COBJS-y += ldiv.o
@@ -60,14 +56,12 @@ endif
 
 ifdef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
-COBJS-$(CONFIG_SPL_NET_SUPPORT) += crc32.o
-ifneq ($(CONFIG_SPL_SPI_FLASH_SUPPORT)$(CONFIG_SPL_NET_SUPPORT),)
-COBJS-y += display_options.o
-endif
-COBJS-$(CONFIG_SPL_NET_SUPPORT) += errno.o
-COBJS-$(CONFIG_SPL_NET_SUPPORT) += hashtable.o
 COBJS-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
 endif
+COBJS-$(CONFIG_ADDR_MAP) += addr_map.o
+COBJS-y += hashtable.o
+COBJS-y += errno.o
+COBJS-y += display_options.o
 COBJS-$(CONFIG_BCH) += bch.o
 COBJS-y += crc32.o
 COBJS-y += ctype.o
index e3142cbdfe55a8950889b77d2a2f857d20203a1b..ad25a0c9c929627b43e10761d42d679e07e05b77 100644 (file)
@@ -67,6 +67,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
        COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
        COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"),
+       COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645-tpm"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
index 09dfae03c247554deb48c29ce98693ffd9c25f9d..3a82efab6194ce394ebc57e225a17062f7e17757 100644 (file)
@@ -617,3 +617,62 @@ void *memchr(const void *s, int c, size_t n)
 }
 
 #endif
+#ifndef __HAVE_ARCH_MEMCHR_INV
+static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
+{
+       while (bytes) {
+               if (*start != value)
+                       return (void *)start;
+               start++;
+               bytes--;
+       }
+       return NULL;
+}
+/**
+ * memchr_inv - Find an unmatching character in an area of memory.
+ * @start: The memory area
+ * @c: Find a character other than c
+ * @bytes: The size of the area.
+ *
+ * returns the address of the first character other than @c, or %NULL
+ * if the whole buffer contains just @c.
+ */
+void *memchr_inv(const void *start, int c, size_t bytes)
+{
+       u8 value = c;
+       u64 value64;
+       unsigned int words, prefix;
+
+       if (bytes <= 16)
+               return check_bytes8(start, value, bytes);
+
+       value64 = value;
+       value64 |= value64 << 8;
+       value64 |= value64 << 16;
+       value64 |= value64 << 32;
+
+       prefix = (unsigned long)start % 8;
+       if (prefix) {
+               u8 *r;
+
+               prefix = 8 - prefix;
+               r = check_bytes8(start, value, prefix);
+               if (r)
+                       return r;
+               start += prefix;
+               bytes -= prefix;
+       }
+
+       words = bytes / 8;
+
+       while (words) {
+               if (*(u64 *)start != value64)
+                       return check_bytes8(start, value, 8);
+               start += 8;
+               words--;
+       }
+
+       return check_bytes8(start, value, bytes % 8);
+}
+#endif
+
diff --git a/nand_spl/board/freescale/p1010rdb/Makefile b/nand_spl/board/freescale/p1010rdb/Makefile
deleted file mode 100644 (file)
index f7bdf92..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#
-# (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 spl_minimal.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) -I$(nandobj)board/$(BOARDDIR) \
-                -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)spl_minimal.c:
-       @rm -f $(obj)spl_minimal.c
-       ln -sf $(SRCTREE)/$(CPUDIR)/spl_minimal.c $(obj)spl_minimal.c
-
-$(obj)fsl_law.c:
-       @rm -f $(obj)fsl_law.c
-       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc8xxx/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
-
-#########################################################################
index df94789de95f603000d91b2e14d0fec16b544e31..7663b9cd6c92541b657fb3eebcbd72ba98b9a6df 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -271,7 +271,8 @@ static void NetInitLoop(void)
 #endif
                env_changed_id = env_id;
        }
-       memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);
+       if (eth_get_dev())
+               memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);
 
        return;
 }
diff --git a/test/image/test-fit.py b/test/image/test-fit.py
new file mode 100755 (executable)
index 0000000..c4e8211
--- /dev/null
@@ -0,0 +1,422 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013, Google Inc.
+#
+# Sanity check of the FIT handling in U-Boot
+#
+# 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
+#
+# To run this:
+#
+# make O=sandbox sandbox_config
+# make O=sandbox
+# ./test/image/test-fit.py -u sandbox/u-boot
+
+import doctest
+from optparse import OptionParser
+import os
+import shutil
+import struct
+import sys
+import tempfile
+
+# The 'command' library in patman is convenient for running commands
+base_path = os.path.dirname(sys.argv[0])
+patman = os.path.join(base_path, '../../tools/patman')
+sys.path.append(patman)
+
+import command
+
+# Define a base ITS which we can adjust using % and a dictionary
+base_its = '''
+/dts-v1/;
+
+/ {
+        description = "Chrome OS kernel image with one or more FDT blobs";
+        #address-cells = <1>;
+
+        images {
+                kernel@1 {
+                        data = /incbin/("%(kernel)s");
+                        type = "kernel";
+                        arch = "sandbox";
+                        os = "linux";
+                        compression = "none";
+                        load = <0x40000>;
+                        entry = <0x8>;
+                };
+                fdt@1 {
+                        description = "snow";
+                        data = /incbin/("u-boot.dtb");
+                        type = "flat_dt";
+                        arch = "sandbox";
+                        %(fdt_load)s
+                        compression = "none";
+                        signature@1 {
+                                algo = "sha1,rsa2048";
+                                key-name-hint = "dev";
+                        };
+                };
+                ramdisk@1 {
+                        description = "snow";
+                        data = /incbin/("%(ramdisk)s");
+                        type = "ramdisk";
+                        arch = "sandbox";
+                        os = "linux";
+                        %(ramdisk_load)s
+                        compression = "none";
+                };
+        };
+        configurations {
+                default = "conf@1";
+                conf@1 {
+                        kernel = "kernel@1";
+                        fdt = "fdt@1";
+                        %(ramdisk_config)s
+                };
+        };
+};
+'''
+
+# Define a base FDT - currently we don't use anything in this
+base_fdt = '''
+/dts-v1/;
+
+/ {
+        model = "Sandbox Verified Boot Test";
+        compatible = "sandbox";
+
+};
+'''
+
+# This is the U-Boot script that is run for each test. First load the fit,
+# then do the 'bootm' command, then save out memory from the places where
+# we expect 'bootm' to write things. Then quit.
+base_script = '''
+sb load host 0 %(fit_addr)x %(fit)s
+fdt addr %(fit_addr)x
+bootm start %(fit_addr)x
+bootm loados
+sb save host 0 %(kernel_out)s %(kernel_addr)x %(kernel_size)x
+sb save host 0 %(fdt_out)s %(fdt_addr)x %(fdt_size)x
+sb save host 0 %(ramdisk_out)s %(ramdisk_addr)x %(ramdisk_size)x
+reset
+'''
+
+def make_fname(leaf):
+    """Make a temporary filename
+
+    Args:
+        leaf: Leaf name of file to create (within temporary directory)
+    Return:
+        Temporary filename
+    """
+    global base_dir
+
+    return os.path.join(base_dir, leaf)
+
+def filesize(fname):
+    """Get the size of a file
+
+    Args:
+        fname: Filename to check
+    Return:
+        Size of file in bytes
+    """
+    return os.stat(fname).st_size
+
+def read_file(fname):
+    """Read the contents of a file
+
+    Args:
+        fname: Filename to read
+    Returns:
+        Contents of file as a string
+    """
+    with open(fname, 'r') as fd:
+        return fd.read()
+
+def make_dtb():
+    """Make a sample .dts file and compile it to a .dtb
+
+    Returns:
+        Filename of .dtb file created
+    """
+    src = make_fname('u-boot.dts')
+    dtb = make_fname('u-boot.dtb')
+    with open(src, 'w') as fd:
+        print >>fd, base_fdt
+    command.Output('dtc', src, '-O', 'dtb', '-o', dtb)
+    return dtb
+
+def make_its(params):
+    """Make a sample .its file with parameters embedded
+
+    Args:
+        params: Dictionary containing parameters to embed in the %() strings
+    Returns:
+        Filename of .its file created
+    """
+    its = make_fname('test.its')
+    with open(its, 'w') as fd:
+        print >>fd, base_its % params
+    return its
+
+def make_fit(mkimage, params):
+    """Make a sample .fit file ready for loading
+
+    This creates a .its script with the selected parameters and uses mkimage to
+    turn this into a .fit image.
+
+    Args:
+        mkimage: Filename of 'mkimage' utility
+        params: Dictionary containing parameters to embed in the %() strings
+    Return:
+        Filename of .fit file created
+    """
+    fit = make_fname('test.fit')
+    its = make_its(params)
+    command.Output(mkimage, '-f', its, fit)
+    with open(make_fname('u-boot.dts'), 'w') as fd:
+        print >>fd, base_fdt
+    return fit
+
+def make_kernel():
+    """Make a sample kernel with test data
+
+    Returns:
+        Filename of kernel created
+    """
+    fname = make_fname('test-kernel.bin')
+    data = ''
+    for i in range(100):
+        data += 'this kernel %d is unlikely to boot\n' % i
+    with open(fname, 'w') as fd:
+        print >>fd, data
+    return fname
+
+def make_ramdisk():
+    """Make a sample ramdisk with test data
+
+    Returns:
+        Filename of ramdisk created
+    """
+    fname = make_fname('test-ramdisk.bin')
+    data = ''
+    for i in range(100):
+        data += 'ramdisk %d was seldom used in the middle ages\n' % i
+    with open(fname, 'w') as fd:
+        print >>fd, data
+    return fname
+
+def find_matching(text, match):
+    """Find a match in a line of text, and return the unmatched line portion
+
+    This is used to extract a part of a line from some text. The match string
+    is used to locate the line - we use the first line that contains that
+    match text.
+
+    Once we find a match, we discard the match string itself from the line,
+    and return what remains.
+
+    TODO: If this function becomes more generally useful, we could change it
+    to use regex and return groups.
+
+    Args:
+        text: Text to check (each line separated by \n)
+        match: String to search for
+    Return:
+        String containing unmatched portion of line
+    Exceptions:
+        ValueError: If match is not found
+
+    >>> find_matching('first line:10\\nsecond_line:20', 'first line:')
+    '10'
+    >>> find_matching('first line:10\\nsecond_line:20', 'second linex')
+    Traceback (most recent call last):
+      ...
+    ValueError: Test aborted
+    >>> find_matching('first line:10\\nsecond_line:20', 'second_line:')
+    '20'
+    """
+    for line in text.splitlines():
+        pos = line.find(match)
+        if pos != -1:
+            return line[:pos] + line[pos + len(match):]
+
+    print "Expected '%s' but not found in output:"
+    print text
+    raise ValueError('Test aborted')
+
+def set_test(name):
+    """Set the name of the current test and print a message
+
+    Args:
+        name: Name of test
+    """
+    global test_name
+
+    test_name = name
+    print name
+
+def fail(msg):
+    """Raise an error with a helpful failure message
+
+    Args:
+        msg: Message to display
+    """
+    raise ValueError("Test '%s' failed: %s" % (test_name, msg))
+
+def run_fit_test(mkimage, u_boot):
+    """Basic sanity check of FIT loading in U-Boot
+
+    TODO: Almost everything:
+       - hash algorithms - invalid hash/contents should be detected
+       - signature algorithms - invalid sig/contents should be detected
+       - compression
+       - checking that errors are detected like:
+            - image overwriting
+            - missing images
+            - invalid configurations
+            - incorrect os/arch/type fields
+            - empty data
+            - images too large/small
+            - invalid FDT (e.g. putting a random binary in instead)
+       - default configuration selection
+       - bootm command line parameters should have desired effect
+       - run code coverage to make sure we are testing all the code
+    """
+    global test_name
+
+    # Set up invariant files
+    control_dtb = make_dtb()
+    kernel = make_kernel()
+    ramdisk = make_ramdisk()
+    kernel_out = make_fname('kernel-out.bin')
+    fdt_out = make_fname('fdt-out.dtb')
+    ramdisk_out = make_fname('ramdisk-out.bin')
+
+    # Set up basic parameters with default values
+    params = {
+        'fit_addr' : 0x1000,
+
+        'kernel' : kernel,
+        'kernel_out' : kernel_out,
+        'kernel_addr' : 0x40000,
+        'kernel_size' : filesize(kernel),
+
+        'fdt_out' : fdt_out,
+        'fdt_addr' : 0x80000,
+        'fdt_size' : filesize(control_dtb),
+        'fdt_load' : '',
+
+        'ramdisk' : ramdisk,
+        'ramdisk_out' : ramdisk_out,
+        'ramdisk_addr' : 0xc0000,
+        'ramdisk_size' : filesize(ramdisk),
+        'ramdisk_load' : '',
+        'ramdisk_config' : '',
+    }
+
+    # Make a basic FIT and a script to load it
+    fit = make_fit(mkimage, params)
+    params['fit'] = fit
+    cmd = base_script % params
+
+    # First check that we can load a kernel
+    # We could perhaps reduce duplication with some loss of readability
+    set_test('Kernel load')
+    stdout = command.Output(u_boot, '-d', control_dtb, '-c', cmd)
+    if read_file(kernel) != read_file(kernel_out):
+        fail('Kernel not loaded')
+    if read_file(control_dtb) == read_file(fdt_out):
+        fail('FDT loaded but should be ignored')
+    if read_file(ramdisk) == read_file(ramdisk_out):
+        fail('Ramdisk loaded but should not be')
+
+    # Find out the offset in the FIT where U-Boot has found the FDT
+    line = find_matching(stdout, 'Booting using the fdt blob at ')
+    fit_offset = int(line, 16) - params['fit_addr']
+    fdt_magic = struct.pack('>L', 0xd00dfeed)
+    data = read_file(fit)
+
+    # Now find where it actually is in the FIT (skip the first word)
+    real_fit_offset = data.find(fdt_magic, 4)
+    if fit_offset != real_fit_offset:
+        fail('U-Boot loaded FDT from offset %#x, FDT is actually at %#x' %
+                (fit_offset, real_fit_offset))
+
+    # Now a kernel and an FDT
+    set_test('Kernel + FDT load')
+    params['fdt_load'] = 'load = <%#x>;' % params['fdt_addr']
+    fit = make_fit(mkimage, params)
+    stdout = command.Output(u_boot, '-d', control_dtb, '-c', cmd)
+    if read_file(kernel) != read_file(kernel_out):
+        fail('Kernel not loaded')
+    if read_file(control_dtb) != read_file(fdt_out):
+        fail('FDT not loaded')
+    if read_file(ramdisk) == read_file(ramdisk_out):
+        fail('Ramdisk loaded but should not be')
+
+    # Try a ramdisk
+    set_test('Kernel + FDT + Ramdisk load')
+    params['ramdisk_config'] = 'ramdisk = "ramdisk@1";'
+    params['ramdisk_load'] = 'load = <%#x>;' % params['ramdisk_addr']
+    fit = make_fit(mkimage, params)
+    stdout = command.Output(u_boot, '-d', control_dtb, '-c', cmd)
+    if read_file(ramdisk) != read_file(ramdisk_out):
+        fail('Ramdisk not loaded')
+
+def run_tests():
+    """Parse options, run the FIT tests and print the result"""
+    global base_path, base_dir
+
+    # Work in a temporary directory
+    base_dir = tempfile.mkdtemp()
+    parser = OptionParser()
+    parser.add_option('-u', '--u-boot',
+            default=os.path.join(base_path, 'u-boot'),
+            help='Select U-Boot sandbox binary')
+    parser.add_option('-k', '--keep', action='store_true',
+            help="Don't delete temporary directory even when tests pass")
+    parser.add_option('-t', '--selftest', action='store_true',
+            help='Run internal self tests')
+    (options, args) = parser.parse_args()
+
+    # Find the path to U-Boot, and assume mkimage is in its tools/mkimage dir
+    base_path = os.path.dirname(options.u_boot)
+    mkimage = os.path.join(base_path, 'tools/mkimage')
+
+    # There are a few doctests - handle these here
+    if options.selftest:
+        doctest.testmod()
+        return
+
+    title = 'FIT Tests'
+    print title, '\n', '=' * len(title)
+
+    run_fit_test(mkimage, options.u_boot)
+
+    print '\nTests passed'
+    print 'Caveat: this is only a sanity check - test coverage is poor'
+
+    # Remove the tempoerary directory unless we are asked to keep it
+    if options.keep:
+        print "Output files are in '%s'" % base_dir
+    else:
+        shutil.rmtree(base_dir)
+
+run_tests()
index 9f23901872c9b7aa85d5d993016ba7094b016401..896e2bc985f4a24a00f5d27d1a9bb0dc230258cf 100755 (executable)
@@ -273,6 +273,7 @@ our $logFunctions = qr{(?x:
        WARN(?:_RATELIMIT|_ONCE|)|
        panic|
        debug|
+       printf|
        MODULE_[A-Z_]+
 )};
 
index e07a6157ebca0052d66b7713686e46df8d7ea655..03c6c8f5237d741cbc17793ace87fee2a855c946 100644 (file)
 
 #define ARRAY_SIZE(x)          (sizeof(x) / sizeof((x)[0]))
 
+static inline void *map_sysmem(ulong paddr, unsigned long len)
+{
+       return (void *)(uintptr_t)paddr;
+}
+
+static inline ulong map_to_sysmem(void *ptr)
+{
+       return (ulong)(uintptr_t)ptr;
+}
+
 #define MKIMAGE_TMPFILE_SUFFIX         ".tmp"
 #define MKIMAGE_MAX_TMPFILE_LEN                256
 #define MKIMAGE_DEFAULT_DTC_OPTIONS    "-I dts -O dtb -p 500"
 #define MKIMAGE_MAX_DTC_CMDLINE_LEN    512
 #define MKIMAGE_DTC                    "dtc"   /* assume dtc is in $PATH */
 
+#define IH_ARCH_DEFAULT                IH_ARCH_INVALID
+
 /*
  * This structure defines all such variables those are initialized by
  * mkimage main core and need to be referred by image type specific
index 508a747a3f6e4875eb9a9d7670cce06bd0e54e4a..5f39dc5bbfd22108e3f235a69a0eb22599285ec8 100644 (file)
 #include "pblimage.h"
 
 /*
- * The PBL can load up to 64 bytes at a time, so we split the U-Boot
- * image into 64 byte chunks. PBL needs a command for each piece, of
- * the form "81xxxxxx", where "xxxxxx" is the offset. SYS_TEXT_BASE
- * is 0xFFF80000 for PBL boot, and PBL only cares about low 24-bit,
- * so it starts from 0x81F80000.
+ * Initialize to an invalid value.
  */
-static uint32_t next_pbl_cmd = 0x81F80000;
+static uint32_t next_pbl_cmd = 0x82000000;
 /*
  * need to store all bytes in memory for calculating crc32, then write the
  * bytes to image file for PBL boot.
  */
-static unsigned char mem_buf[600000];
+static unsigned char mem_buf[1000000];
 static unsigned char *pmem_buf = mem_buf;
 static int pbl_size;
 static char *fname = "Unknown";
@@ -52,6 +48,27 @@ static union
 
 #define ENDIANNESS ((char)endian_test.l)
 
+/*
+ * The PBL can load up to 64 bytes at a time, so we split the U-Boot
+ * image into 64 byte chunks. PBL needs a command for each piece, of
+ * the form "81xxxxxx", where "xxxxxx" is the offset. Calculate the
+ * start offset by subtracting the size of the u-boot image from the
+ * top of the allowable 24-bit range.
+ */
+static void init_next_pbl_cmd(FILE *fp_uboot)
+{
+       struct stat st;
+       int fd = fileno(fp_uboot);
+
+       if (fstat(fd, &st) == -1) {
+               printf("Error: Could not determine u-boot image size. %s\n",
+                       strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
+       next_pbl_cmd = 0x82000000 - st.st_size;
+}
+
 static void generate_pbl_cmd(void)
 {
        uint32_t val = next_pbl_cmd;
@@ -80,6 +97,7 @@ static void pbl_fget(size_t size, FILE *stream)
 /* load split u-boot with PBI command 81xxxxxx. */
 static void load_uboot(FILE *fp_uboot)
 {
+       init_next_pbl_cmd(fp_uboot);
        while (next_pbl_cmd < 0x82000000) {
                generate_pbl_cmd();
                pbl_fget(64, fp_uboot);