]> git.ipfire.org Git - people/ms/u-boot.git/commitdiff
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>
Thu, 4 Apr 2013 09:49:32 +0000 (11:49 +0200)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Thu, 4 Apr 2013 09:49:32 +0000 (11:49 +0200)
488 files changed:
.checkpatch.conf
MAINTAINERS
MAKEALL
Makefile
README
arch/arm/config.mk
arch/arm/cpu/arm1136/start.S
arch/arm/cpu/arm1136/u-boot-spl.lds
arch/arm/cpu/arm1176/bcm2835/Makefile
arch/arm/cpu/arm1176/bcm2835/mbox.c [new file with mode: 0644]
arch/arm/cpu/arm1176/bcm2835/timer.c
arch/arm/cpu/arm1176/start.S
arch/arm/cpu/arm720t/start.S
arch/arm/cpu/arm920t/ep93xx/u-boot.lds
arch/arm/cpu/arm920t/start.S
arch/arm/cpu/arm925t/start.S
arch/arm/cpu/arm926ejs/davinci/spl.c
arch/arm/cpu/arm926ejs/mxs/start.S
arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds
arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds
arch/arm/cpu/arm926ejs/start.S
arch/arm/cpu/arm946es/start.S
arch/arm/cpu/arm_intcm/start.S
arch/arm/cpu/armv7/Makefile
arch/arm/cpu/armv7/am33xx/Makefile
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock_am33xx.c [moved from arch/arm/cpu/armv7/am33xx/clock.c with 91% similarity]
arch/arm/cpu/armv7/am33xx/clock_ti814x.c [new file with mode: 0644]
arch/arm/cpu/armv7/am33xx/ddr.c
arch/arm/cpu/armv7/am33xx/emif4.c
arch/arm/cpu/armv7/am33xx/mem.c
arch/arm/cpu/armv7/am33xx/sys_info.c
arch/arm/cpu/armv7/am33xx/u-boot-spl.lds
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7/exynos/power.c
arch/arm/cpu/armv7/omap-common/Makefile
arch/arm/cpu/armv7/omap-common/hwinit-common.c
arch/arm/cpu/armv7/omap-common/lowlevel_init.S
arch/arm/cpu/armv7/omap-common/timer.c
arch/arm/cpu/armv7/omap-common/u-boot-spl.lds
arch/arm/cpu/armv7/socfpga/u-boot-spl.lds
arch/arm/cpu/armv7/start.S
arch/arm/cpu/ixp/start.S
arch/arm/cpu/ixp/u-boot.lds
arch/arm/cpu/pxa/start.S
arch/arm/cpu/s3c44b0/start.S
arch/arm/cpu/sa1100/start.S
arch/arm/cpu/u-boot-spl.lds
arch/arm/cpu/u-boot.lds
arch/arm/dts/exynos5250.dtsi
arch/arm/dts/tegra114.dtsi
arch/arm/include/asm/arch-am33xx/clock.h
arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/ddr_defs.h
arch/arm/include/asm/arch-am33xx/hardware.h
arch/arm/include/asm/arch-am33xx/hardware_am33xx.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/hardware_ti814x.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/mmc_host_def.h
arch/arm/include/asm/arch-am33xx/mux.h
arch/arm/include/asm/arch-am33xx/mux_am33xx.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/mux_ti814x.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/omap.h
arch/arm/include/asm/arch-am33xx/spl.h
arch/arm/include/asm/arch-am33xx/sys_proto.h
arch/arm/include/asm/arch-bcm2835/mbox.h [new file with mode: 0644]
arch/arm/include/asm/arch-bcm2835/sdhci.h [new file with mode: 0644]
arch/arm/include/asm/arch-bcm2835/timer.h
arch/arm/include/asm/arch-exynos/power.h
arch/arm/include/asm/arch-exynos/spl.h
arch/arm/include/asm/arch-exynos/tmu.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra/board.h
arch/arm/include/asm/arch-tegra/tegra_slink.h [deleted file]
arch/arm/include/asm/arch-tegra/tegra_spi.h [deleted file]
arch/arm/include/asm/arch-tegra114/gp_padctrl.h
arch/arm/include/asm/arch-tegra114/tegra114_spi.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra20/tegra20_sflash.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra20/tegra20_slink.h [new file with mode: 0644]
arch/arm/include/asm/cache.h
arch/arm/include/asm/sections.h [moved from board/pcippc2/i2c.h with 70% similarity]
arch/arm/include/asm/spl.h
arch/arm/include/asm/system.h
arch/arm/include/asm/u-boot-arm.h
arch/arm/include/asm/u-boot.h
arch/arm/lib/Makefile
arch/arm/lib/board.c
arch/arm/lib/bss.c
arch/arm/lib/cache-cp15.c
arch/arm/lib/crt0.S
arch/arm/lib/spl.c
arch/avr32/cpu/start.S
arch/avr32/cpu/u-boot.lds
arch/avr32/include/asm/sections.h
arch/avr32/lib/board.c
arch/blackfin/cpu/cpu.c
arch/blackfin/include/asm/global_data.h
arch/blackfin/include/asm/sections.h [moved from board/pcippc2/fpga_serial.h with 66% similarity]
arch/blackfin/lib/board.c
arch/m68k/include/asm/sections.h [moved from board/pcippc2/ns16550.h with 59% similarity]
arch/m68k/lib/board.c
arch/microblaze/include/asm/sections.h [moved from board/pcippc2/sconsole.h with 50% similarity]
arch/mips/include/asm/sections.h [new file with mode: 0644]
arch/mips/include/asm/u-boot-mips.h
arch/nds32/cpu/n1213/start.S
arch/nds32/cpu/n1213/u-boot.lds
arch/nds32/include/asm/sections.h [new file with mode: 0644]
arch/nds32/include/asm/u-boot-nds32.h
arch/nds32/lib/board.c
arch/nios2/cpu/start.S
arch/nios2/cpu/u-boot.lds
arch/nios2/include/asm/sections.h [new file with mode: 0644]
arch/openrisc/include/asm/sections.h [new file with mode: 0644]
arch/powerpc/config.mk
arch/powerpc/cpu/74xx_7xx/cpu.c
arch/powerpc/cpu/74xx_7xx/start.S
arch/powerpc/cpu/74xx_7xx/u-boot.lds
arch/powerpc/cpu/mpc512x/cpu_init.c
arch/powerpc/cpu/mpc512x/fixed_sdram.c
arch/powerpc/cpu/mpc512x/iopin.c
arch/powerpc/cpu/mpc512x/start.S
arch/powerpc/cpu/mpc512x/u-boot.lds
arch/powerpc/cpu/mpc5xx/start.S
arch/powerpc/cpu/mpc5xx/u-boot.lds
arch/powerpc/cpu/mpc5xxx/spl_boot.c
arch/powerpc/cpu/mpc5xxx/start.S
arch/powerpc/cpu/mpc5xxx/u-boot-customlayout.lds
arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds
arch/powerpc/cpu/mpc5xxx/u-boot.lds
arch/powerpc/cpu/mpc8220/start.S
arch/powerpc/cpu/mpc8220/u-boot.lds
arch/powerpc/cpu/mpc824x/start.S
arch/powerpc/cpu/mpc824x/u-boot.lds
arch/powerpc/cpu/mpc8260/start.S
arch/powerpc/cpu/mpc8260/u-boot.lds
arch/powerpc/cpu/mpc83xx/start.S
arch/powerpc/cpu/mpc83xx/u-boot-spl.lds
arch/powerpc/cpu/mpc83xx/u-boot.lds
arch/powerpc/cpu/mpc85xx/start.S
arch/powerpc/cpu/mpc85xx/u-boot-nand.lds
arch/powerpc/cpu/mpc85xx/u-boot-nand_spl.lds
arch/powerpc/cpu/mpc85xx/u-boot-spl.lds
arch/powerpc/cpu/mpc85xx/u-boot.lds
arch/powerpc/cpu/mpc86xx/start.S
arch/powerpc/cpu/mpc86xx/u-boot.lds
arch/powerpc/cpu/mpc8xx/start.S
arch/powerpc/cpu/ppc4xx/start.S
arch/powerpc/cpu/ppc4xx/u-boot.lds
arch/powerpc/include/asm/immap_512x.h
arch/powerpc/include/asm/sections.h [new file with mode: 0644]
arch/powerpc/include/asm/spl.h
arch/powerpc/include/asm/u-boot.h
arch/powerpc/lib/Makefile
arch/powerpc/lib/board.c
arch/sandbox/include/asm/sections.h
arch/sh/cpu/sh2/u-boot.lds
arch/sh/cpu/sh3/u-boot.lds
arch/sh/cpu/sh4/u-boot.lds
arch/sh/include/asm/sections.h [new file with mode: 0644]
arch/sh/lib/board.c
arch/sparc/cpu/leon2/Makefile
arch/sparc/cpu/leon2/serial.c
arch/sparc/cpu/leon3/Makefile
arch/sparc/cpu/leon3/serial.c
arch/sparc/include/asm/sections.h [new file with mode: 0644]
arch/x86/config.mk
arch/x86/cpu/coreboot/sdram.c
arch/x86/cpu/u-boot.lds
arch/x86/include/asm/config.h
arch/x86/include/asm/sections.h [new file with mode: 0644]
arch/x86/include/asm/u-boot-x86.h
arch/x86/include/asm/u-boot.h
arch/x86/lib/Makefile
arch/x86/lib/board.c
arch/x86/lib/init_helpers.c
arch/x86/lib/relocate.c
board/BuS/eb_cpu5282/u-boot.lds
board/LEOX/elpt860/u-boot.lds
board/RPXClassic/u-boot.lds
board/RPXlite/u-boot.lds
board/RPXlite_dw/u-boot.lds
board/RRvision/u-boot.lds
board/a3m071/README
board/a3m071/a3m071.c
board/a3m071/is46r16320d.h [new file with mode: 0644]
board/actux1/u-boot.lds
board/actux2/u-boot.lds
board/actux3/u-boot.lds
board/adder/u-boot.lds
board/ait/cam_enc_4xx/u-boot-spl.lds
board/altera/nios2-generic/u-boot.lds
board/amcc/acadia/u-boot-nand.lds
board/amcc/bamboo/u-boot-nand.lds
board/amcc/canyonlands/u-boot-nand.lds
board/amcc/kilauea/u-boot-nand.lds
board/amcc/sequoia/u-boot-nand.lds
board/amcc/sequoia/u-boot-ram.lds
board/astro/mcf5373l/u-boot.lds
board/chromebook-x86/dts/link.dts
board/cm4008/flash.c
board/cm41xx/flash.c
board/cm_t35/cm_t35.c
board/cobra5272/u-boot.lds
board/cogent/u-boot.lds
board/dave/PPChameleonEVB/u-boot.lds
board/davedenx/aria/aria.c
board/davinci/da8xxevm/u-boot-spl-da850evm.lds
board/davinci/da8xxevm/u-boot-spl-hawk.lds
board/dvlhost/u-boot.lds
board/eltec/mhpc/u-boot.lds
board/emk/top860/u-boot.lds
board/ep88x/u-boot.lds
board/esd/dasa_sim/u-boot.lds
board/esd/mecp5123/mecp5123.c
board/esd/pmc440/u-boot-nand.lds
board/esd/tasreg/u-boot.lds
board/esteem192e/u-boot.lds
board/evb64260/u-boot.lds
board/fads/u-boot.lds
board/flagadm/u-boot.lds
board/freescale/m5208evbe/u-boot.lds
board/freescale/m52277evb/u-boot.lds
board/freescale/m5235evb/u-boot.lds
board/freescale/m5249evb/u-boot.lds
board/freescale/m5253demo/u-boot.lds
board/freescale/m5253evbe/u-boot.lds
board/freescale/m5271evb/u-boot.lds
board/freescale/m5272c3/u-boot.lds
board/freescale/m5275evb/u-boot.lds
board/freescale/m5282evb/u-boot.lds
board/freescale/m53017evb/u-boot.lds
board/freescale/m5329evb/u-boot.lds
board/freescale/m5373evb/u-boot.lds
board/freescale/m54418twr/u-boot.lds
board/freescale/m54451evb/u-boot.lds
board/freescale/m54455evb/u-boot.lds
board/freescale/m547xevb/u-boot.lds
board/freescale/m548xevb/u-boot.lds
board/freescale/mpc5121ads/mpc5121ads.c
board/freescale/mx31ads/u-boot.lds
board/gaisler/gr_cpci_ax2000/u-boot.lds
board/gaisler/gr_ep2s60/u-boot.lds
board/gaisler/gr_xc3s_1500/u-boot.lds
board/gaisler/grsim/u-boot.lds
board/gaisler/grsim_leon2/u-boot.lds
board/gen860t/u-boot-flashenv.lds
board/gen860t/u-boot.lds
board/genietv/u-boot.lds
board/hermes/u-boot.lds
board/hymod/u-boot.lds
board/icu862/u-boot.lds
board/idmr/u-boot.lds
board/ifm/ac14xx/Makefile [new file with mode: 0644]
board/ifm/ac14xx/ac14xx.c [new file with mode: 0644]
board/ip860/u-boot.lds
board/ivm/u-boot.lds
board/keymile/km82xx/km82xx.c
board/korat/u-boot-F7FC.lds
board/kup/kup4k/u-boot.lds
board/kup/kup4x/u-boot.lds
board/lwmon/u-boot.lds
board/manroland/uc100/u-boot.lds
board/matrix_vision/mvsmr/u-boot.lds
board/mbx8xx/u-boot.lds
board/mousse/u-boot.lds
board/mvblue/u-boot.lds
board/netphone/u-boot.lds
board/netta/u-boot.lds
board/netta2/u-boot.lds
board/netvia/u-boot.lds
board/nvidia/common/board.c
board/nvidia/common/common.mk
board/nvidia/common/uart-spi-switch.c [deleted file]
board/nvidia/dalmore/dalmore.c
board/nvidia/dalmore/pinmux-config-dalmore.h
board/nvidia/dts/tegra114-dalmore.dts
board/nvidia/seaboard/seaboard.c
board/nx823/u-boot.lds
board/pcippc2/cpc710.h [deleted file]
board/pcippc2/cpc710_init_ram.c [deleted file]
board/pcippc2/cpc710_pci.c [deleted file]
board/pcippc2/cpc710_pci.h [deleted file]
board/pcippc2/flash.c [deleted file]
board/pcippc2/fpga_serial.c [deleted file]
board/pcippc2/hardware.h [deleted file]
board/pcippc2/i2c.c [deleted file]
board/pcippc2/pcippc2.c [deleted file]
board/pcippc2/pcippc2.h [deleted file]
board/pcippc2/pcippc2_fpga.c [deleted file]
board/pcippc2/pcippc2_fpga.h [deleted file]
board/pcippc2/sconsole.c [deleted file]
board/pdm360ng/pdm360ng.c
board/phytec/pcm051/board.c
board/quantum/u-boot.lds
board/r360mpi/u-boot.lds
board/raspberrypi/rpi_b/rpi_b.c
board/rbc823/u-boot.lds
board/renesas/sh7752evb/u-boot.lds
board/renesas/sh7757lcr/u-boot.lds
board/rsdproto/u-boot.lds
board/samsung/dts/exynos5250-smdk5250.dts
board/samsung/dts/exynos5250-snow.dts [new file with mode: 0644]
board/samsung/smdk5250/smdk5250-uboot-spl.lds
board/samsung/smdk5250/smdk5250.c
board/samsung/smdk6400/u-boot-nand.lds
board/samsung/trats/trats.c
board/sandpoint/u-boot.lds
board/sixnet/u-boot.lds
board/snmc/qs850/u-boot.lds
board/snmc/qs860t/u-boot.lds
board/spc1920/u-boot.lds
board/spd8xx/u-boot.lds
board/stx/stxxtc/u-boot.lds
board/svm_sc8xx/u-boot.lds
board/ti/am335x/board.c
board/ti/ti814x/Makefile [moved from board/pcippc2/Makefile with 54% similarity]
board/ti/ti814x/evm.c [new file with mode: 0644]
board/ti/ti814x/evm.h [new file with mode: 0644]
board/ti/ti814x/mux.c [new file with mode: 0644]
board/tqc/tqm8xx/u-boot.lds
board/v37/u-boot.lds
board/vpac270/u-boot-spl.lds
board/woodburn/woodburn.c
boards.cfg
common/Makefile
common/board_f.c [new file with mode: 0644]
common/board_r.c [new file with mode: 0644]
common/cmd_bootm.c
common/cmd_df.c [deleted file]
common/cmd_dfu.c
common/cmd_dtt.c
common/cmd_ext4.c
common/cmd_fat.c
common/cmd_mem.c
common/cmd_mtdparts.c
common/cmd_nvedit.c
common/cmd_part.c
common/cmd_sf.c
common/cmd_usb_mass_storage.c [new file with mode: 0644]
common/env_callback.c
common/image.c
common/lcd.c
common/main.c
config.mk
doc/README.memory-test [new file with mode: 0644]
doc/README.scrapyard
doc/README.silent
doc/device-tree-bindings/exynos/tmu.txt [new file with mode: 0644]
doc/driver-model/UDM-pci.txt
doc/driver-model/UDM-watchdog.txt
doc/feature-removal-schedule.txt
drivers/block/mvsata_ide.c
drivers/dfu/dfu_mmc.c
drivers/i2c/s3c24x0_i2c.c
drivers/mmc/Makefile
drivers/mmc/bcm2835_sdhci.c [new file with mode: 0644]
drivers/mmc/mmc.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/sdhci.c
drivers/mtd/nand/omap_gpmc.c
drivers/mtd/spi/atmel.c
drivers/mtd/spi/eon.c
drivers/mtd/spi/macronix.c
drivers/mtd/spi/ramtron.c
drivers/mtd/spi/spansion.c
drivers/mtd/spi/spi_flash.c
drivers/mtd/spi/sst.c
drivers/mtd/spi/stmicro.c
drivers/mtd/spi/winbond.c
drivers/net/cpsw.c
drivers/power/Makefile
drivers/power/exynos-tmu.c [new file with mode: 0644]
drivers/rtc/mk48t59.c
drivers/serial/ns16550.c
drivers/serial/usbtty.c
drivers/sound/Makefile
drivers/sound/max98095.c [new file with mode: 0644]
drivers/sound/max98095.h [new file with mode: 0644]
drivers/sound/sound.c
drivers/spi/Makefile
drivers/spi/altera_spi.c
drivers/spi/andes_spi.c
drivers/spi/armada100_spi.c
drivers/spi/atmel_spi.c
drivers/spi/bfin_spi.c
drivers/spi/bfin_spi6xx.c
drivers/spi/cf_qspi.c
drivers/spi/cf_spi.c
drivers/spi/davinci_spi.c
drivers/spi/exynos_spi.c
drivers/spi/fdt_spi.c [new file with mode: 0644]
drivers/spi/fsl_espi.c
drivers/spi/ich.c [new file with mode: 0644]
drivers/spi/ich.h [new file with mode: 0644]
drivers/spi/kirkwood_spi.c
drivers/spi/mpc52xx_spi.c
drivers/spi/mpc8xxx_spi.c
drivers/spi/mxc_spi.c
drivers/spi/mxs_spi.c
drivers/spi/oc_tiny_spi.c
drivers/spi/omap3_spi.c
drivers/spi/sh_spi.c
drivers/spi/soft_spi.c
drivers/spi/spi.c [new file with mode: 0644]
drivers/spi/tegra114_spi.c [new file with mode: 0644]
drivers/spi/tegra20_sflash.c [moved from drivers/spi/tegra_spi.c with 56% similarity]
drivers/spi/tegra20_slink.c [moved from drivers/spi/tegra_slink.c with 71% similarity]
drivers/spi/xilinx_spi.c
drivers/usb/eth/smsc95xx.c
drivers/usb/gadget/Makefile
drivers/usb/gadget/composite.c
drivers/usb/gadget/f_dfu.c
drivers/usb/gadget/f_mass_storage.c [new file with mode: 0644]
drivers/usb/gadget/g_dnl.c
drivers/usb/gadget/storage_common.c [new file with mode: 0644]
drivers/usb/host/Makefile
drivers/usb/host/ehci-exynos.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-spear.c [new file with mode: 0644]
drivers/usb/host/ehci.h
drivers/video/Makefile
drivers/video/bcm2835.c [new file with mode: 0644]
examples/standalone/stubs.c
include/asm-generic/global_data.h
include/asm-generic/sections.h [new file with mode: 0644]
include/asm-generic/u-boot.h [new file with mode: 0644]
include/common.h
include/config_cmd_all.h
include/config_cmd_default.h
include/config_defaults.h
include/configs/PCIPPC2.h [deleted file]
include/configs/PCIPPC6.h [deleted file]
include/configs/a3m071.h
include/configs/ac14xx.h [new file with mode: 0644]
include/configs/am335x_evm.h
include/configs/aria.h
include/configs/cardhu.h
include/configs/cm_t35.h
include/configs/coreboot.h
include/configs/dalmore.h
include/configs/exynos5250-dt.h
include/configs/igep00x0.h
include/configs/km/keymile-common.h
include/configs/km/km-powerpc.h
include/configs/mecp5123.h
include/configs/mpc5121ads.h
include/configs/pcm051.h
include/configs/pdm360ng.h
include/configs/rpi_b.h
include/configs/snow.h [new file with mode: 0644]
include/configs/tegra-common-post.h
include/configs/tegra-common.h
include/configs/tegra20-common.h
include/configs/ti814x_evm.h [new file with mode: 0644]
include/configs/trats.h
include/configs/trimslice.h
include/env_callback.h
include/fdtdec.h
include/ide.h
include/image.h
include/initcall.h [moved from arch/arm/include/asm/arch-tegra20/uart-spi-switch.h with 53% similarity]
include/power/max77686_pmic.h
include/sound.h
include/spi.h
include/spi_flash.h
include/tmu.h [new file with mode: 0644]
include/usb_mass_storage.h [new file with mode: 0644]
include/usbdevice.h
include/watchdog.h
lib/Makefile
lib/display_options.c
lib/fdtdec.c
lib/initcall.c [new file with mode: 0644]
nand_spl/board/amcc/acadia/u-boot.lds
nand_spl/board/amcc/bamboo/u-boot.lds
nand_spl/board/amcc/canyonlands/u-boot.lds
nand_spl/board/amcc/kilauea/u-boot.lds
nand_spl/board/amcc/sequoia/u-boot.lds
nand_spl/board/freescale/mpc8315erdb/u-boot.lds
nand_spl/board/freescale/mx31pdk/u-boot.lds
nand_spl/board/karo/tx25/u-boot.lds
nand_spl/board/samsung/smdk6400/u-boot.lds
nand_spl/board/sheldon/simpc8313/u-boot.lds
spl/Makefile
tools/checkpatch.pl
tools/env/README
tools/env/fw_env.c
tools/env/fw_env.config

index 977db9edbbddcb202d02704854731e033794b744..d88af57129a82cf1b8cf772e9ca02d7c7a20efbb 100644 (file)
@@ -12,3 +12,9 @@
 
 # For min/max
 --ignore MINMAX
+
+# enable more tests
+--strict
+
+# Not Linux, so we don't recommend usleep_range() over udelay()
+--ignore USLEEP_RANGE
index 0f19078bc447db0476e0422b71bb71f58f422068..e131f80534578ca23bf860721b4082a08192e4a1 100644 (file)
@@ -150,9 +150,6 @@ Wolfgang Denk <wd@denx.de>
 
        P3G4            MPC7410
 
-       PCIPPC2         MPC750
-       PCIPPC6         MPC750
-
 Phil Edworthy <phil.edworthy@renesas.com>
 
        rsk7264         SH7264
@@ -234,6 +231,7 @@ Wolfgang Grandegger <wg@denx.de>
 
 Anatolij Gustschin <agust@denx.de>
 
+       ac14xx          MPC5121e
        O2D             MPC5200
        O2D300          MPC5200
        O2DNT2          MPC5200
@@ -397,6 +395,7 @@ Ricardo Ribalda <ricardo.ribalda@uam.es>
 Stefan Roese <sr@denx.de>
 
        a3m071          MPC5200
+       a4m2k           MPC5200
 
        P3M7448         MPC7448
 
@@ -690,6 +689,10 @@ Stefan Herbrechtsmeier <stefan@code.herbrechtsmeier.net>
 
        dns325          ARM926EJS (Kirkwood SoC)
 
+Lauri Hintsala <lauri.hintsala@bluegiga.com>
+
+       apx4devkit      i.MX28
+
 Vaibhav Hiremath <hvaibhav@ti.com>
 
        am3517_evm      ARM ARMV7 (AM35x SoC)
@@ -808,10 +811,6 @@ Linus Walleij <linus.walleij@linaro.org>
        integratorap    various
        integratorcp    various
 
-Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
-
-       apx4devkit      i.MX28
-
 Luka Perkov <luka@openwrt.org>
 
        ib62x0          ARM926EJS
@@ -835,6 +834,10 @@ Stelian Pop <stelian@popies.net>
        at91sam9263ek   ARM926EJS (AT91SAM9263 SoC)
        at91sam9rlek    ARM926EJS (AT91SAM9RL SoC)
 
+Matt Porter <mporter@ti.com>
+
+       ti814x_evm      ARM ARMV7 (TI814x Soc)
+
 Dave Purdy <david.c.purdy@gmail.com>
 
        pogo_e02        ARM926EJS (Kirkwood SoC)
@@ -912,6 +915,10 @@ Matt Sealey <matt@genesi-usa.com>
 Bo Shen <voice.shen@atmel.com>
        at91sam9x5ek            ARM926EJS (AT91SAM9G15,G25,G35,X25,X35 SoC)
 
+Rajeshwari Shinde <rajeshwari.s@samsung.com>
+
+       snow                    ARM ARMV7 (EXYNOS5250 SoC)
+
 Michal Simek <monstr@monstr.eu>
 
        zynq            ARM ARMV7 (Zynq SoC)
diff --git a/MAKEALL b/MAKEALL
index 397adef920a4f9e281ad7f44fe941b42c399f314..91fa495ea7f43ce2b7edb6ca6ca5b8d0d8ebd643 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -104,9 +104,9 @@ while true ; do
        -s|--soc)
                # echo "Option SoC: argument \`$2'"
                if [ "$opt_s" ] ; then
-                       opt_s="${opt_s%)} || \$6 == \"$2\")"
+                       opt_s="${opt_s%)} || \$6 == \"$2\" || \$6 ~ /$2/)"
                else
-                       opt_s="(\$6 == \"$2\")"
+                       opt_s="(\$6 == \"$2\" || \$6 ~ /$2/)"
                fi
                SELECTED='y'
                shift 2 ;;
@@ -802,8 +802,20 @@ build_targets() {
 #-----------------------------------------------------------------------
 
 kill_children() {
-       local pgid=`ps -p $$ --no-headers -o "%r" | tr -d ' '`
-       local children=`pgrep -g $pgid | grep -v $$ | grep -v $pgid`
+       local OS=$(uname -s)
+       local children=""
+       case "${OS}" in
+               "Darwin")
+                       # Mac OS X is known to have BSD style ps
+                       local pgid=$(ps -p $$ -o pgid | sed -e "/PGID/d")
+                       children=$(ps -g $pgid -o pid | sed -e "/PID\|$$\|$pgid/d")
+                       ;;
+               *)
+                       # everything else tries the GNU style
+                       local pgid=$(ps -p $$ --no-headers -o "%r" | tr -d ' ')
+                       children=$(pgrep -g $pgid | sed -e "/$$\|$pgid/d")
+                       ;;
+       esac
 
        kill $children 2> /dev/null
        wait $children 2> /dev/null
index 12763ce0f971f704862fbca6ef893323343426df..d60a14b5877e43e2360498e0effdb3edd6f04954 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -331,7 +331,7 @@ LIBS-y += api/libapi.o
 LIBS-y += post/libpost.o
 LIBS-y += test/libtest.o
 
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
 LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
 endif
 
diff --git a/README b/README
index e45ae4a1351fd785566f978cb7bf92a8ee8b2d1e..a35ef318da100b51f66c5515f6660fa2014ed90a 100644 (file)
--- a/README
+++ b/README
@@ -485,6 +485,7 @@ The following options need to be configured:
                Thumb2 this flag will result in Thumb2 code generated by
                GCC.
 
+               CONFIG_ARM_ERRATA_716044
                CONFIG_ARM_ERRATA_742230
                CONFIG_ARM_ERRATA_743622
                CONFIG_ARM_ERRATA_751472
@@ -870,7 +871,8 @@ The following options need to be configured:
                                          (requires CONFIG_CMD_MEMORY and CONFIG_MD5)
                CONFIG_CMD_MEMINFO      * Display detailed memory information
                CONFIG_CMD_MEMORY         md, mm, nm, mw, cp, cmp, crc, base,
-                                         loop, loopw, mtest
+                                         loop, loopw
+               CONFIG_CMD_MEMTEST        mtest
                CONFIG_CMD_MISC           Misc functions like sleep etc
                CONFIG_CMD_MMC          * MMC memory mapped support
                CONFIG_CMD_MII          * MII utility commands
@@ -3240,6 +3242,23 @@ Configuration Settings:
        If defined, don't allow the -f switch to env set override variable
        access flags.
 
+- CONFIG_SYS_GENERIC_BOARD
+       This selects the architecture-generic board system instead of the
+       architecture-specific board files. It is intended to move boards
+       to this new framework over time. Defining this will disable the
+       arch/foo/lib/board.c file and use common/board_f.c and
+       common/board_r.c instead. To use this option your architecture
+       must support it (i.e. must define __HAVE_ARCH_GENERIC_BOARD in
+       its config.mk file). If you find problems enabling this option on
+       your board please report the problem and send patches!
+
+- CONFIG_SYS_SYM_OFFSETS
+       This is set by architectures that use offsets for link symbols
+       instead of absolute values. So bss_start is obtained using an
+       offset _bss_start_ofs from CONFIG_SYS_TEXT_BASE, rather than
+       directly. You should not need to touch this setting.
+
+
 The following definitions that deal with the placement and management
 of environment data (variable area); in general, we support the
 following configurations:
@@ -3860,6 +3879,10 @@ Low Level (hardware related) configuration options:
                If defined, the x86 reset vector code is included. This is not
                needed when U-Boot is running from Coreboot.
 
+- CONFIG_SYS_MPUCLK
+               Defines the MPU clock speed (in MHz).
+
+               NOTE : currently only supported on AM335x platforms.
 
 Freescale QE/FMAN Firmware Support:
 -----------------------------------
index 24b9d7c8025710932da3800b030a7321a7f4ee75..e7839beceda5f7cffde15004307c3c96558dd29d 100644 (file)
 CROSS_COMPILE ?= arm-linux-
 
 ifndef CONFIG_STANDALONE_LOAD_ADDR
-ifeq ($(SOC),omap3)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
 CONFIG_STANDALONE_LOAD_ADDR = 0x80300000
 else
 CONFIG_STANDALONE_LOAD_ADDR = 0xc100000
 endif
 endif
 
+# Support generic board on ARM
+__HAVE_ARCH_GENERIC_BOARD := y
+
 PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
 
 # Choose between ARM/Thumb instruction sets
index a067b8a1868182f33e6b9e11a980d19ae004186d..eba23248d5b6f5a6052657971593949e702c2b34 100644 (file)
@@ -106,7 +106,7 @@ _image_copy_end_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index a0462ab97a1e98e9bf47a229cd5320463f5e012e..b09b4ebfaf3ac5e59b0a35be6e7f20ab7d87a772 100644 (file)
@@ -57,6 +57,6 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        } >.sdram
 }
index 95da6a822a113bd24afa09f01d10fa86de838c64..135de42d37b077ecc0c874f26225c0aa76bca61d 100644 (file)
@@ -17,7 +17,7 @@ include $(TOPDIR)/config.mk
 LIB    = $(obj)lib$(SOC).o
 
 SOBJS  := lowlevel_init.o
-COBJS  := init.o reset.o timer.o
+COBJS  := init.o reset.o timer.o mbox.o
 
 SRCS   := $(SOBJS:.o=.c) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/arm/cpu/arm1176/bcm2835/mbox.c b/arch/arm/cpu/arm1176/bcm2835/mbox.c
new file mode 100644 (file)
index 0000000..fd65e33
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mbox.h>
+
+#define TIMEOUT (100 * 1000) /* 100mS in uS */
+
+int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv)
+{
+       struct bcm2835_mbox_regs *regs =
+               (struct bcm2835_mbox_regs *)BCM2835_MBOX_PHYSADDR;
+       ulong endtime = get_timer(0) + TIMEOUT;
+       u32 val;
+
+       debug("time: %lu timeout: %lu\n", get_timer(0), endtime);
+
+       if (send & BCM2835_CHAN_MASK) {
+               printf("mbox: Illegal mbox data 0x%08x\n", send);
+               return -1;
+       }
+
+       /* Drain any stale responses */
+
+       for (;;) {
+               val = readl(&regs->status);
+               if (val & BCM2835_MBOX_STATUS_RD_EMPTY)
+                       break;
+               if (get_timer(0) >= endtime) {
+                       printf("mbox: Timeout draining stale responses\n");
+                       return -1;
+               }
+               val = readl(&regs->read);
+       }
+
+       /* Wait for space to send */
+
+       for (;;) {
+               val = readl(&regs->status);
+               if (!(val & BCM2835_MBOX_STATUS_WR_FULL))
+                       break;
+               if (get_timer(0) >= endtime) {
+                       printf("mbox: Timeout waiting for send space\n");
+                       return -1;
+               }
+       }
+
+       /* Send the request */
+
+       val = BCM2835_MBOX_PACK(chan, send);
+       debug("mbox: TX raw: 0x%08x\n", val);
+       writel(val, &regs->write);
+
+       /* Wait for the response */
+
+       for (;;) {
+               val = readl(&regs->status);
+               if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY))
+                       break;
+               if (get_timer(0) >= endtime) {
+                       printf("mbox: Timeout waiting for response\n");
+                       return -1;
+               }
+       }
+
+       /* Read the response */
+
+       val = readl(&regs->read);
+       debug("mbox: RX raw: 0x%08x\n", val);
+
+       /* Validate the response */
+
+       if (BCM2835_MBOX_UNPACK_CHAN(val) != chan) {
+               printf("mbox: Response channel mismatch\n");
+               return -1;
+       }
+
+       *recv = BCM2835_MBOX_UNPACK_DATA(val);
+
+       return 0;
+}
+
+#ifdef DEBUG
+void dump_buf(struct bcm2835_mbox_hdr *buffer)
+{
+       u32 *p;
+       u32 words;
+       int i;
+
+       p = (u32 *)buffer;
+       words = buffer->buf_size / 4;
+       for (i = 0; i < words; i++)
+               printf("    0x%04x: 0x%08x\n", i * 4, p[i]);
+}
+#endif
+
+int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer)
+{
+       int ret;
+       u32 rbuffer;
+       struct bcm2835_mbox_tag_hdr *tag;
+       int tag_index;
+
+#ifdef DEBUG
+       printf("mbox: TX buffer\n");
+       dump_buf(buffer);
+#endif
+
+       ret = bcm2835_mbox_call_raw(chan, (u32)buffer, &rbuffer);
+       if (ret)
+               return ret;
+       if (rbuffer != (u32)buffer) {
+               printf("mbox: Response buffer mismatch\n");
+               return -1;
+       }
+
+#ifdef DEBUG
+       printf("mbox: RX buffer\n");
+       dump_buf(buffer);
+#endif
+
+       /* Validate overall response status */
+
+       if (buffer->code != BCM2835_MBOX_RESP_CODE_SUCCESS) {
+               printf("mbox: Header response code invalid\n");
+               return -1;
+       }
+
+       /* Validate each tag's response status */
+
+       tag = (void *)(buffer + 1);
+       tag_index = 0;
+       while (tag->tag) {
+               if (!(tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE)) {
+                       printf("mbox: Tag %d missing val_len response bit\n",
+                               tag_index);
+                       return -1;
+               }
+               /*
+                * Clear the reponse bit so clients can just look right at the
+                * length field without extra processing
+                */
+               tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
+               tag = (void *)(((u8 *)tag) + sizeof(*tag) + tag->val_buf_size);
+               tag_index++;
+       }
+
+       return 0;
+}
index d232d7e067c3a01b6aea8dfe6ee43bc9b8bfaa71..2edd6711da5711ed88d46f6a8c7323b01e84d2d5 100644 (file)
@@ -23,7 +23,7 @@ int timer_init(void)
        return 0;
 }
 
-ulong get_timer(ulong base)
+ulong get_timer_us(ulong base)
 {
        struct bcm2835_timer_regs *regs =
                (struct bcm2835_timer_regs *)BCM2835_TIMER_PHYSADDR;
@@ -31,6 +31,14 @@ ulong get_timer(ulong base)
        return readl(&regs->clo) - base;
 }
 
+ulong get_timer(ulong base)
+{
+       ulong us = get_timer_us(0);
+       us /= (1000000 / CONFIG_SYS_HZ);
+       us -= base;
+       return us;
+}
+
 unsigned long long get_ticks(void)
 {
        return get_timer(0);
@@ -46,10 +54,10 @@ void __udelay(unsigned long usec)
        ulong endtime;
        signed long diff;
 
-       endtime = get_timer(0) + usec;
+       endtime = get_timer_us(0) + usec;
 
        do {
-               ulong now = get_timer(0);
+               ulong now = get_timer_us(0);
                diff = endtime - now;
        } while (diff >= 0);
 }
index 40df4b161428dd3343ba0eb8730908a98bdd1720..3c291fbe42e17ff6f31a947e9013e85dcd114624 100644 (file)
@@ -121,7 +121,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index 771d3869c157969f4fdb2039d01bf176e7a79fe7..43bd6edd2834d4d13e87558022898fd9c8e1322d 100644 (file)
@@ -103,7 +103,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index c19285d2108ebf93b1ddc212d31ac08ff30ac5dd..e483820f3f93b0ab02cc8bfc86daf5f97b11986b 100644 (file)
@@ -57,7 +57,7 @@ SECTIONS
        . = ALIGN(4);
        __bss_start = .;
        .bss : { *(.bss) }
-       __bss_end__ = .;
+       __bss_end = .;
 
        _end = .;
 }
index 511d21d3344eec1f68b835b85a66584d6f261173..2864d128c7b49046e7c94b6c5ba6f7566f8154db 100644 (file)
@@ -87,7 +87,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index e8d6d71c1701613e7781846c6ecfe25d57ee0b1e..827fee24922c646468b0102c41e9e378a9c30032 100644 (file)
@@ -93,7 +93,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index 714fa928465bfc9aac2cb979d97318c46781e139..ca8a412626dd8a5f98c252d7404e9f588ad4d682 100644 (file)
@@ -64,7 +64,7 @@ void board_init_f(ulong dummy)
 #endif
 
        /* Third, we clear the BSS. */
-       memset(__bss_start, 0, __bss_end__ - __bss_start);
+       memset(__bss_start, 0, __bss_end - __bss_start);
 
        /* Finally, setup gd and move to the next step. */
        gd = &gdata;
index 7ccd3371746d8fd91284311ff6387d0cbf3c9f28..373e6d8d7c865bf3372f334e46269246d58e1d34 100644 (file)
@@ -133,7 +133,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index 0f3222c76a4346334a4ce940b2c1d34f680d3550..67b204e4475edc9da412a7020f9a0537f478990a 100644 (file)
@@ -67,7 +67,7 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        }
 
        _end = .;
index 0af3e0a2315118e56a882e58d04c1e5f56029b1b..7405917595e6ea8fe3bd9dec25c66b4cff1452a6 100644 (file)
@@ -67,7 +67,7 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        }
 
        _end = .;
index 66a8b654bdf465d9fc1ad711de4925ca42006c8c..f5d15828d314500b4a75f09a32c034f2e542268e 100644 (file)
@@ -142,7 +142,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
@@ -151,7 +151,7 @@ _end_ofs:
 #ifdef CONFIG_NAND_U_BOOT
 .globl _end
 _end:
-       .word __bss_end__
+       .word __bss_end
 #endif
 
 #ifdef CONFIG_USE_IRQ
index a7a98a4e58a94b0a5e4515f66119d13c0a0a39c6..9dec35b557876e9b2a4c0b66d172417edd8fe769 100644 (file)
@@ -103,7 +103,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index c189849fa844775b4cfa9234291aca9ff39f53b6..04d08458f374edd106634745c07f47f2cd7cc0a6 100644 (file)
@@ -99,7 +99,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index 4668b3cf2fe1cfa64189944c1d16f71007aab3f0..7a8c2d0e59ea328f78a9253f01801cfa13f3a150 100644 (file)
@@ -32,7 +32,7 @@ COBJS += cache_v7.o
 COBJS  += cpu.o
 COBJS  += syslib.o
 
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI814X),)
 SOBJS  += lowlevel_init.o
 endif
 
index 70c443edbbb0a4ebd53f741cc0e53a3de15129e2..c97e30d441ca8f1d0eaf201933fd0cccd2aa73c5 100644 (file)
@@ -16,7 +16,8 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(SOC).o
 
-COBJS  += clock.o
+COBJS-$(CONFIG_AM33XX) += clock_am33xx.o
+COBJS-$(CONFIG_TI814X) += clock_ti814x.o
 COBJS  += sys_info.o
 COBJS  += mem.o
 COBJS  += ddr.o
index e35a3e3a704e122ca381eae766dbe9e78f2cc565..885fb2d20e5a516432ed07a8ecce327dded9edb0 100644 (file)
@@ -141,11 +141,11 @@ int arch_misc_init(void)
 {
 #ifdef CONFIG_AM335X_USB0
        musb_register(&otg0_plat, &otg0_board_data,
-               (void *)AM335X_USB0_OTG_BASE);
+               (void *)USB0_OTG_BASE);
 #endif
 #ifdef CONFIG_AM335X_USB1
        musb_register(&otg1_plat, &otg1_board_data,
-               (void *)AM335X_USB1_OTG_BASE);
+               (void *)USB1_OTG_BASE);
 #endif
        return 0;
 }
similarity index 91%
rename from arch/arm/cpu/armv7/am33xx/clock.c
rename to arch/arm/cpu/armv7/am33xx/clock_am33xx.c
index d7d98d1111e0ed5495caa98045bbc5ab8bb897fc..afc0d9205937354b70fa64e1c7ebc83eea746c08 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * clock.c
+ * clock_am33xx.c
  *
  * clocks for AM33XX based boards
  *
- * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
 #define CPGMAC0_IDLE           0x30000
 #define DPLL_CLKDCOLDO_GATE_CTRL        0x300
 
+#define OSC    (V_OSCK/1000000)
+
+#define MPUPLL_M       CONFIG_SYS_MPUCLK
+#define MPUPLL_N       (OSC-1)
+#define MPUPLL_M2      1
+
+/* Core PLL Fdll = 1 GHZ, */
+#define COREPLL_M      1000
+#define COREPLL_N      (OSC-1)
+
+#define COREPLL_M4     10      /* CORE_CLKOUTM4 = 200 MHZ */
+#define COREPLL_M5     8       /* CORE_CLKOUTM5 = 250 MHZ */
+#define COREPLL_M6     4       /* CORE_CLKOUTM6 = 500 MHZ */
+
+/*
+ * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
+ * frequency needs to be set to 960 MHZ. Hence,
+ * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
+ */
+#define PERPLL_M       960
+#define PERPLL_N       (OSC-1)
+#define PERPLL_M2      5
+
+/* DDR Freq is 266 MHZ for now */
+/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
+#define DDRPLL_M       266
+#define DDRPLL_N       (OSC-1)
+#define DDRPLL_M2      1
+
 const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
 const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
 const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
diff --git a/arch/arm/cpu/armv7/am33xx/clock_ti814x.c b/arch/arm/cpu/armv7/am33xx/clock_ti814x.c
new file mode 100644 (file)
index 0000000..cb4210f
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * clock_ti814x.c
+ *
+ * Clocks for TI814X based boards
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+/* PRCM */
+#define PRCM_MOD_EN            0x2
+
+/* CLK_SRC */
+#define OSC_SRC0               0
+#define OSC_SRC1               1
+
+#define L3_OSC_SRC             OSC_SRC0
+
+#define OSC_0_FREQ             20
+
+#define DCO_HS2_MIN            500
+#define DCO_HS2_MAX            1000
+#define DCO_HS1_MIN            1000
+#define DCO_HS1_MAX            2000
+
+#define SELFREQDCO_HS2         0x00000801
+#define SELFREQDCO_HS1         0x00001001
+
+#define MPU_N                  0x1
+#define MPU_M                  0x3C
+#define MPU_M2                 1
+#define MPU_CLKCTRL            0x1
+
+#define L3_N                   19
+#define L3_M                   880
+#define L3_M2                  4
+#define L3_CLKCTRL             0x801
+
+#define DDR_N                  19
+#define DDR_M                  666
+#define DDR_M2                 2
+#define DDR_CLKCTRL            0x801
+
+/* ADPLLJ register values */
+#define ADPLLJ_CLKCTRL_HS2     0x00000801 /* HS2 mode, TINT2 = 1 */
+#define ADPLLJ_CLKCTRL_HS1     0x00001001 /* HS1 mode, TINT2 = 1 */
+#define ADPLLJ_CLKCTRL_CLKDCOLDOEN     (1 << 29)
+#define ADPLLJ_CLKCTRL_IDLE            (1 << 23)
+#define ADPLLJ_CLKCTRL_CLKOUTEN                (1 << 20)
+#define ADPLLJ_CLKCTRL_CLKOUTLDOEN     (1 << 19)
+#define ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ  (1 << 17)
+#define ADPLLJ_CLKCTRL_LPMODE          (1 << 12)
+#define ADPLLJ_CLKCTRL_DRIFTGUARDIAN   (1 << 11)
+#define ADPLLJ_CLKCTRL_REGM4XEN                (1 << 10)
+#define ADPLLJ_CLKCTRL_TINITZ          (1 << 0)
+#define ADPLLJ_CLKCTRL_CLKDCO          (ADPLLJ_CLKCTRL_CLKDCOLDOEN | \
+                                        ADPLLJ_CLKCTRL_CLKOUTEN | \
+                                        ADPLLJ_CLKCTRL_CLKOUTLDOEN | \
+                                        ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ)
+
+#define ADPLLJ_STATUS_PHASELOCK                (1 << 10)
+#define ADPLLJ_STATUS_FREQLOCK         (1 << 9)
+#define ADPLLJ_STATUS_PHSFRQLOCK       (ADPLLJ_STATUS_PHASELOCK | \
+                                        ADPLLJ_STATUS_FREQLOCK)
+#define ADPLLJ_STATUS_BYPASSACK                (1 << 8)
+#define ADPLLJ_STATUS_BYPASS           (1 << 0)
+#define ADPLLJ_STATUS_BYPASSANDACK     (ADPLLJ_STATUS_BYPASSACK | \
+                                        ADPLLJ_STATUS_BYPASS)
+
+#define ADPLLJ_TENABLE_ENB             (1 << 0)
+#define ADPLLJ_TENABLEDIV_ENB          (1 << 0)
+
+#define ADPLLJ_M2NDIV_M2SHIFT          16
+
+#define MPU_PLL_BASE                   (PLL_SUBSYS_BASE + 0x048)
+#define L3_PLL_BASE                    (PLL_SUBSYS_BASE + 0x110)
+#define DDR_PLL_BASE                   (PLL_SUBSYS_BASE + 0x290)
+
+struct ad_pll {
+       unsigned int pwrctrl;
+       unsigned int clkctrl;
+       unsigned int tenable;
+       unsigned int tenablediv;
+       unsigned int m2ndiv;
+       unsigned int mn2div;
+       unsigned int fracdiv;
+       unsigned int bwctrl;
+       unsigned int fracctrl;
+       unsigned int status;
+       unsigned int m3div;
+       unsigned int rampctrl;
+};
+
+#define OSC_SRC_CTRL                   (PLL_SUBSYS_BASE + 0x2C0)
+
+/* PRCM */
+#define CM_DEFAULT_BASE                        (PRCM_BASE + 0x0500)
+
+struct cm_def {
+       unsigned int resv0[2];
+       unsigned int l3fastclkstctrl;
+       unsigned int resv1[1];
+       unsigned int pciclkstctrl;
+       unsigned int resv2[1];
+       unsigned int ducaticlkstctrl;
+       unsigned int resv3[1];
+       unsigned int emif0clkctrl;
+       unsigned int emif1clkctrl;
+       unsigned int dmmclkctrl;
+       unsigned int fwclkctrl;
+       unsigned int resv4[10];
+       unsigned int usbclkctrl;
+       unsigned int resv5[1];
+       unsigned int sataclkctrl;
+       unsigned int resv6[4];
+       unsigned int ducaticlkctrl;
+       unsigned int pciclkctrl;
+};
+
+#define CM_ALWON_BASE                  (PRCM_BASE + 0x1400)
+
+struct cm_alwon {
+       unsigned int l3slowclkstctrl;
+       unsigned int ethclkstctrl;
+       unsigned int l3medclkstctrl;
+       unsigned int mmu_clkstctrl;
+       unsigned int mmucfg_clkstctrl;
+       unsigned int ocmc0clkstctrl;
+       unsigned int vcpclkstctrl;
+       unsigned int mpuclkstctrl;
+       unsigned int sysclk4clkstctrl;
+       unsigned int sysclk5clkstctrl;
+       unsigned int sysclk6clkstctrl;
+       unsigned int rtcclkstctrl;
+       unsigned int l3fastclkstctrl;
+       unsigned int resv0[67];
+       unsigned int mcasp0clkctrl;
+       unsigned int mcasp1clkctrl;
+       unsigned int mcasp2clkctrl;
+       unsigned int mcbspclkctrl;
+       unsigned int uart0clkctrl;
+       unsigned int uart1clkctrl;
+       unsigned int uart2clkctrl;
+       unsigned int gpio0clkctrl;
+       unsigned int gpio1clkctrl;
+       unsigned int i2c0clkctrl;
+       unsigned int i2c1clkctrl;
+       unsigned int mcasp345clkctrl;
+       unsigned int atlclkctrl;
+       unsigned int mlbclkctrl;
+       unsigned int pataclkctrl;
+       unsigned int resv1[1];
+       unsigned int uart3clkctrl;
+       unsigned int uart4clkctrl;
+       unsigned int uart5clkctrl;
+       unsigned int wdtimerclkctrl;
+       unsigned int spiclkctrl;
+       unsigned int mailboxclkctrl;
+       unsigned int spinboxclkctrl;
+       unsigned int mmudataclkctrl;
+       unsigned int resv2[2];
+       unsigned int mmucfgclkctrl;
+       unsigned int resv3[2];
+       unsigned int ocmc0clkctrl;
+       unsigned int vcpclkctrl;
+       unsigned int resv4[2];
+       unsigned int controlclkctrl;
+       unsigned int resv5[2];
+       unsigned int gpmcclkctrl;
+       unsigned int ethernet0clkctrl;
+       unsigned int resv6[1];
+       unsigned int mpuclkctrl;
+       unsigned int debugssclkctrl;
+       unsigned int l3clkctrl;
+       unsigned int l4hsclkctrl;
+       unsigned int l4lsclkctrl;
+       unsigned int rtcclkctrl;
+       unsigned int tpccclkctrl;
+       unsigned int tptc0clkctrl;
+       unsigned int tptc1clkctrl;
+       unsigned int tptc2clkctrl;
+       unsigned int tptc3clkctrl;
+       unsigned int resv7[4];
+       unsigned int dcan01clkctrl;
+       unsigned int mmchs0clkctrl;
+       unsigned int mmchs1clkctrl;
+       unsigned int mmchs2clkctrl;
+       unsigned int custefuseclkctrl;
+};
+
+
+const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE;
+const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE;
+
+/*
+ * Enable the peripheral clock for required peripherals
+ */
+static void enable_per_clocks(void)
+{
+       /* UART0 */
+       writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl);
+       while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN)
+               ;
+
+       /* HSMMC1 */
+       writel(PRCM_MOD_EN, &cmalwon->mmchs1clkctrl);
+       while (readl(&cmalwon->mmchs1clkctrl) != PRCM_MOD_EN)
+               ;
+}
+
+/*
+ * select the HS1 or HS2 for DCO Freq
+ * return : CLKCTRL
+ */
+static u32 pll_dco_freq_sel(u32 clkout_dco)
+{
+       if (clkout_dco >= DCO_HS2_MIN && clkout_dco < DCO_HS2_MAX)
+               return SELFREQDCO_HS2;
+       else if (clkout_dco >= DCO_HS1_MIN && clkout_dco < DCO_HS1_MAX)
+               return SELFREQDCO_HS1;
+       else
+               return -1;
+}
+
+/*
+ * select the sigma delta config
+ * return: sigma delta val
+ */
+static u32 pll_sigma_delta_val(u32 clkout_dco)
+{
+       u32 sig_val = 0;
+       float frac_div;
+
+       frac_div = (float) clkout_dco / 250;
+       frac_div = frac_div + 0.90;
+       sig_val = (int)frac_div;
+       sig_val = sig_val << 24;
+
+       return sig_val;
+}
+
+/*
+ * configure individual ADPLLJ
+ */
+static void pll_config(u32 base, u32 n, u32 m, u32 m2,
+                      u32 clkctrl_val, int adpllj)
+{
+       const struct ad_pll *adpll = (struct ad_pll *)base;
+       u32 m2nval, mn2val, read_clkctrl = 0, clkout_dco = 0;
+       u32 sig_val = 0, hs_mod = 0;
+
+       m2nval = (m2 << ADPLLJ_M2NDIV_M2SHIFT) | n;
+       mn2val = m;
+
+       /* calculate clkout_dco */
+       clkout_dco = ((OSC_0_FREQ / (n+1)) * m);
+
+       /* sigma delta & Hs mode selection skip for ADPLLS*/
+       if (adpllj) {
+               sig_val = pll_sigma_delta_val(clkout_dco);
+               hs_mod = pll_dco_freq_sel(clkout_dco);
+       }
+
+       /* by-pass pll */
+       read_clkctrl = readl(&adpll->clkctrl);
+       writel((read_clkctrl | ADPLLJ_CLKCTRL_IDLE), &adpll->clkctrl);
+       while ((readl(&adpll->status) & ADPLLJ_STATUS_BYPASSANDACK)
+               != ADPLLJ_STATUS_BYPASSANDACK)
+               ;
+
+       /* clear TINITZ */
+       read_clkctrl = readl(&adpll->clkctrl);
+       writel((read_clkctrl & ~ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl);
+
+       /*
+        * ref_clk = 20/(n + 1);
+        * clkout_dco = ref_clk * m;
+        * clk_out = clkout_dco/m2;
+       */
+       read_clkctrl = readl(&adpll->clkctrl) &
+                            ~(ADPLLJ_CLKCTRL_LPMODE |
+                            ADPLLJ_CLKCTRL_DRIFTGUARDIAN |
+                            ADPLLJ_CLKCTRL_REGM4XEN);
+       writel(m2nval, &adpll->m2ndiv);
+       writel(mn2val, &adpll->mn2div);
+
+       /* Skip for modena(ADPLLS) */
+       if (adpllj) {
+               writel(sig_val, &adpll->fracdiv);
+               writel((read_clkctrl | hs_mod), &adpll->clkctrl);
+       }
+
+       /* Load M2, N2 dividers of ADPLL */
+       writel(ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv);
+       writel(~ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv);
+
+       /* Load M, N dividers of ADPLL */
+       writel(ADPLLJ_TENABLE_ENB, &adpll->tenable);
+       writel(~ADPLLJ_TENABLE_ENB, &adpll->tenable);
+
+       /* Configure CLKDCOLDOEN,CLKOUTLDOEN,CLKOUT Enable BITS */
+       read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_CLKDCO;
+       if (adpllj)
+               writel((read_clkctrl | ADPLLJ_CLKCTRL_CLKDCO),
+                                               &adpll->clkctrl);
+
+       /* Enable TINTZ and disable IDLE(PLL in Active & Locked Mode */
+       read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_IDLE;
+       writel((read_clkctrl | ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl);
+
+       /* Wait for phase and freq lock */
+       while ((readl(&adpll->status) & ADPLLJ_STATUS_PHSFRQLOCK) !=
+              ADPLLJ_STATUS_PHSFRQLOCK)
+               ;
+}
+
+static void unlock_pll_control_mmr(void)
+{
+       /* TRM 2.10.1.4 and 3.2.7-3.2.11 */
+       writel(0x1EDA4C3D, 0x481C5040);
+       writel(0x2FF1AC2B, 0x48140060);
+       writel(0xF757FDC0, 0x48140064);
+       writel(0xE2BC3A6D, 0x48140068);
+       writel(0x1EBF131D, 0x4814006c);
+       writel(0x6F361E05, 0x48140070);
+}
+
+static void mpu_pll_config(void)
+{
+       pll_config(MPU_PLL_BASE, MPU_N, MPU_M, MPU_M2, MPU_CLKCTRL, 0);
+}
+
+static void l3_pll_config(void)
+{
+       u32 l3_osc_src, rd_osc_src = 0;
+
+       l3_osc_src = L3_OSC_SRC;
+       rd_osc_src = readl(OSC_SRC_CTRL);
+
+       if (OSC_SRC0 == l3_osc_src)
+               writel((rd_osc_src & 0xfffffffe)|0x0, OSC_SRC_CTRL);
+       else
+               writel((rd_osc_src & 0xfffffffe)|0x1, OSC_SRC_CTRL);
+
+       pll_config(L3_PLL_BASE, L3_N, L3_M, L3_M2, L3_CLKCTRL, 1);
+}
+
+void ddr_pll_config(unsigned int ddrpll_m)
+{
+       pll_config(DDR_PLL_BASE, DDR_N, DDR_M, DDR_M2, DDR_CLKCTRL, 1);
+}
+
+void enable_emif_clocks(void) {};
+
+void enable_dmm_clocks(void)
+{
+       writel(PRCM_MOD_EN, &cmdef->fwclkctrl);
+       writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl);
+       writel(PRCM_MOD_EN, &cmdef->emif0clkctrl);
+       while ((readl(&cmdef->emif0clkctrl)) != PRCM_MOD_EN)
+               ;
+       writel(PRCM_MOD_EN, &cmdef->emif1clkctrl);
+       while ((readl(&cmdef->emif1clkctrl)) != PRCM_MOD_EN)
+               ;
+       while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300)
+               ;
+       writel(PRCM_MOD_EN, &cmdef->dmmclkctrl);
+       while ((readl(&cmdef->dmmclkctrl)) != PRCM_MOD_EN)
+               ;
+       writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl);
+       while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100)
+               ;
+}
+
+/*
+ * Configure the PLL/PRCM for necessary peripherals
+ */
+void pll_init()
+{
+       unlock_pll_control_mmr();
+
+       /* Enable the control module */
+       writel(PRCM_MOD_EN, &cmalwon->controlclkctrl);
+
+       mpu_pll_config();
+
+       l3_pll_config();
+
+       /* Enable the required peripherals */
+       enable_per_clocks();
+}
index 448cc4015766215ca9aeee645db332aacb668cde..d1e2fd3f2157cfda4b2dfd732f4308f0567204ed 100644 (file)
@@ -24,15 +24,20 @@ http://www.ti.com/
 /**
  * Base address for EMIF instances
  */
-static struct emif_reg_struct *emif_reg = {
-                               (struct emif_reg_struct *)EMIF4_0_CFG_BASE};
+static struct emif_reg_struct *emif_reg[2] = {
+                               (struct emif_reg_struct *)EMIF4_0_CFG_BASE,
+                               (struct emif_reg_struct *)EMIF4_1_CFG_BASE};
 
 /**
- * Base address for DDR instance
+ * Base addresses for DDR PHY cmd/data regs
  */
-static struct ddr_regs *ddr_reg[2] = {
-                               (struct ddr_regs *)DDR_PHY_BASE_ADDR,
-                               (struct ddr_regs *)DDR_PHY_BASE_ADDR2};
+static struct ddr_cmd_regs *ddr_cmd_reg[2] = {
+                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR,
+                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2};
+
+static struct ddr_data_regs *ddr_data_reg[2] = {
+                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR,
+                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2};
 
 /**
  * Base address for ddr io control instances
@@ -43,7 +48,7 @@ static struct ddr_cmdtctrl *ioctrl_reg = {
 /**
  * Configure SDRAM
  */
-void config_sdram(const struct emif_regs *regs)
+void config_sdram(const struct emif_regs *regs, int nr)
 {
        if (regs->zq_config) {
                /*
@@ -51,68 +56,85 @@ void config_sdram(const struct emif_regs *regs)
                 * about 570us for a delay, which will be long enough
                 * to configure things.
                 */
-               writel(0x2800, &emif_reg->emif_sdram_ref_ctrl);
-               writel(regs->zq_config, &emif_reg->emif_zq_config);
+               writel(0x2800, &emif_reg[nr]->emif_sdram_ref_ctrl);
+               writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
                writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
+               writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
+               writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+               writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
        }
-       writel(regs->sdram_config, &emif_reg->emif_sdram_config);
-       writel(regs->ref_ctrl, &emif_reg->emif_sdram_ref_ctrl);
-       writel(regs->ref_ctrl, &emif_reg->emif_sdram_ref_ctrl_shdw);
+       writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+       writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
+       writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
 }
 
 /**
  * Set SDRAM timings
  */
-void set_sdram_timings(const struct emif_regs *regs)
+void set_sdram_timings(const struct emif_regs *regs, int nr)
 {
-       writel(regs->sdram_tim1, &emif_reg->emif_sdram_tim_1);
-       writel(regs->sdram_tim1, &emif_reg->emif_sdram_tim_1_shdw);
-       writel(regs->sdram_tim2, &emif_reg->emif_sdram_tim_2);
-       writel(regs->sdram_tim2, &emif_reg->emif_sdram_tim_2_shdw);
-       writel(regs->sdram_tim3, &emif_reg->emif_sdram_tim_3);
-       writel(regs->sdram_tim3, &emif_reg->emif_sdram_tim_3_shdw);
+       writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1);
+       writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1_shdw);
+       writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2);
+       writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2_shdw);
+       writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3);
+       writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw);
 }
 
 /**
  * Configure DDR PHY
  */
-void config_ddr_phy(const struct emif_regs *regs)
+void config_ddr_phy(const struct emif_regs *regs, int nr)
 {
-       writel(regs->emif_ddr_phy_ctlr_1, &emif_reg->emif_ddr_phy_ctrl_1);
-       writel(regs->emif_ddr_phy_ctlr_1, &emif_reg->emif_ddr_phy_ctrl_1_shdw);
+       writel(regs->emif_ddr_phy_ctlr_1,
+               &emif_reg[nr]->emif_ddr_phy_ctrl_1);
+       writel(regs->emif_ddr_phy_ctlr_1,
+               &emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw);
 }
 
 /**
  * Configure DDR CMD control registers
  */
-void config_cmd_ctrl(const struct cmd_control *cmd)
+void config_cmd_ctrl(const struct cmd_control *cmd, int nr)
 {
-       writel(cmd->cmd0csratio, &ddr_reg[0]->cm0csratio);
-       writel(cmd->cmd0dldiff, &ddr_reg[0]->cm0dldiff);
-       writel(cmd->cmd0iclkout, &ddr_reg[0]->cm0iclkout);
+       writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio);
+       writel(cmd->cmd0dldiff, &ddr_cmd_reg[nr]->cm0dldiff);
+       writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout);
 
-       writel(cmd->cmd1csratio, &ddr_reg[0]->cm1csratio);
-       writel(cmd->cmd1dldiff, &ddr_reg[0]->cm1dldiff);
-       writel(cmd->cmd1iclkout, &ddr_reg[0]->cm1iclkout);
+       writel(cmd->cmd1csratio, &ddr_cmd_reg[nr]->cm1csratio);
+       writel(cmd->cmd1dldiff, &ddr_cmd_reg[nr]->cm1dldiff);
+       writel(cmd->cmd1iclkout, &ddr_cmd_reg[nr]->cm1iclkout);
 
-       writel(cmd->cmd2csratio, &ddr_reg[0]->cm2csratio);
-       writel(cmd->cmd2dldiff, &ddr_reg[0]->cm2dldiff);
-       writel(cmd->cmd2iclkout, &ddr_reg[0]->cm2iclkout);
+       writel(cmd->cmd2csratio, &ddr_cmd_reg[nr]->cm2csratio);
+       writel(cmd->cmd2dldiff, &ddr_cmd_reg[nr]->cm2dldiff);
+       writel(cmd->cmd2iclkout, &ddr_cmd_reg[nr]->cm2iclkout);
 }
 
 /**
  * Configure DDR DATA registers
  */
-void config_ddr_data(int macrono, const struct ddr_data *data)
+void config_ddr_data(const struct ddr_data *data, int nr)
 {
-       writel(data->datardsratio0, &ddr_reg[macrono]->dt0rdsratio0);
-       writel(data->datawdsratio0, &ddr_reg[macrono]->dt0wdsratio0);
-       writel(data->datawiratio0, &ddr_reg[macrono]->dt0wiratio0);
-       writel(data->datagiratio0, &ddr_reg[macrono]->dt0giratio0);
-       writel(data->datafwsratio0, &ddr_reg[macrono]->dt0fwsratio0);
-       writel(data->datawrsratio0, &ddr_reg[macrono]->dt0wrsratio0);
-       writel(data->datauserank0delay, &ddr_reg[macrono]->dt0rdelays0);
-       writel(data->datadldiff0, &ddr_reg[macrono]->dt0dldiff0);
+       int i;
+
+       for (i = 0; i < DDR_DATA_REGS_NR; i++) {
+               writel(data->datardsratio0,
+                       &(ddr_data_reg[nr]+i)->dt0rdsratio0);
+               writel(data->datawdsratio0,
+                       &(ddr_data_reg[nr]+i)->dt0wdsratio0);
+               writel(data->datawiratio0,
+                       &(ddr_data_reg[nr]+i)->dt0wiratio0);
+               writel(data->datagiratio0,
+                       &(ddr_data_reg[nr]+i)->dt0giratio0);
+               writel(data->datafwsratio0,
+                       &(ddr_data_reg[nr]+i)->dt0fwsratio0);
+               writel(data->datawrsratio0,
+                       &(ddr_data_reg[nr]+i)->dt0wrsratio0);
+               writel(data->datauserank0delay,
+                       &(ddr_data_reg[nr]+i)->dt0rdelays0);
+               writel(data->datadldiff0,
+                       &(ddr_data_reg[nr]+i)->dt0dldiff0);
+       }
 }
 
 void config_io_ctrl(unsigned long val)
index 01e3a5204ea96f7a91d2ab9da6d64ee31a311d94..aa84e961736a67cc64b8343fe6066588fca0604e 100644 (file)
@@ -44,44 +44,65 @@ void dram_init_banksize(void)
 
 
 #ifdef CONFIG_SPL_BUILD
-static struct vtp_reg *vtpreg = (struct vtp_reg *)VTP0_CTRL_ADDR;
+static struct dmm_lisa_map_regs *hw_lisa_map_regs =
+                               (struct dmm_lisa_map_regs *)DMM_BASE;
+static struct vtp_reg *vtpreg[2] = {
+                               (struct vtp_reg *)VTP0_CTRL_ADDR,
+                               (struct vtp_reg *)VTP1_CTRL_ADDR};
+#ifdef CONFIG_AM33XX
 static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+#endif
+
+void config_dmm(const struct dmm_lisa_map_regs *regs)
+{
+       enable_dmm_clocks();
+
+       writel(0, &hw_lisa_map_regs->dmm_lisa_map_3);
+       writel(0, &hw_lisa_map_regs->dmm_lisa_map_2);
+       writel(0, &hw_lisa_map_regs->dmm_lisa_map_1);
+       writel(0, &hw_lisa_map_regs->dmm_lisa_map_0);
 
-static void config_vtp(void)
+       writel(regs->dmm_lisa_map_3, &hw_lisa_map_regs->dmm_lisa_map_3);
+       writel(regs->dmm_lisa_map_2, &hw_lisa_map_regs->dmm_lisa_map_2);
+       writel(regs->dmm_lisa_map_1, &hw_lisa_map_regs->dmm_lisa_map_1);
+       writel(regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0);
+}
+
+static void config_vtp(int nr)
 {
-       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_ENABLE,
-                       &vtpreg->vtp0ctrlreg);
-       writel(readl(&vtpreg->vtp0ctrlreg) & (~VTP_CTRL_START_EN),
-                       &vtpreg->vtp0ctrlreg);
-       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_START_EN,
-                       &vtpreg->vtp0ctrlreg);
+       writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_ENABLE,
+                       &vtpreg[nr]->vtp0ctrlreg);
+       writel(readl(&vtpreg[nr]->vtp0ctrlreg) & (~VTP_CTRL_START_EN),
+                       &vtpreg[nr]->vtp0ctrlreg);
+       writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_START_EN,
+                       &vtpreg[nr]->vtp0ctrlreg);
 
        /* Poll for READY */
-       while ((readl(&vtpreg->vtp0ctrlreg) & VTP_CTRL_READY) !=
+       while ((readl(&vtpreg[nr]->vtp0ctrlreg) & VTP_CTRL_READY) !=
                        VTP_CTRL_READY)
                ;
 }
 
 void config_ddr(unsigned int pll, unsigned int ioctrl,
                const struct ddr_data *data, const struct cmd_control *ctrl,
-               const struct emif_regs *regs)
+               const struct emif_regs *regs, int nr)
 {
        enable_emif_clocks();
        ddr_pll_config(pll);
-       config_vtp();
-       config_cmd_ctrl(ctrl);
-
-       config_ddr_data(0, data);
-       config_ddr_data(1, data);
+       config_vtp(nr);
+       config_cmd_ctrl(ctrl, nr);
 
+       config_ddr_data(data, nr);
+#ifdef CONFIG_AM33XX
        config_io_ctrl(ioctrl);
 
        /* Set CKE to be controlled by EMIF/DDR PHY */
        writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
+#endif
 
        /* Program EMIF instance */
-       config_ddr_phy(regs);
-       set_sdram_timings(regs);
-       config_sdram(regs);
+       config_ddr_phy(regs, nr);
+       set_sdram_timings(regs, nr);
+       config_sdram(regs, nr);
 }
 #endif
index b8f54abae2f99ada121803785939b8ecae5a0a56..b86b0ded3fdec651df6d3a346982b900c04d3441 100644 (file)
@@ -83,7 +83,7 @@ void gpmc_init(void)
        /* global settings */
        writel(0x00000008, &gpmc_cfg->sysconfig);
        writel(0x00000100, &gpmc_cfg->irqstatus);
-       writel(0x00000200, &gpmc_cfg->irqenable);
+       writel(0x00000100, &gpmc_cfg->irqenable);
        writel(0x00000012, &gpmc_cfg->config);
        /*
         * Disable the GPMC0 config set by ROM code
index 507b6180e62f1afc500bd11e1dd10c5730097414..5fd8b47b2d24e1b41b87df653abd4118b37ba05c 100644 (file)
@@ -98,6 +98,9 @@ int print_cpuinfo(void)
        case AM335X:
                cpu_s = "AM335X";
                break;
+       case TI81XX:
+               cpu_s = "TI81XX";
+               break;
        default:
                cpu_s = "Unknown cpu type";
                break;
@@ -120,7 +123,7 @@ int print_cpuinfo(void)
                sec_s = "?";
        }
 
-       printf("AM%s-%s rev %d\n",
+       printf("%s-%s rev %d\n",
                        cpu_s, sec_s, get_cpu_rev());
 
        /* TODO: Print ARM and DDR frequencies  */
index 69f6d48dab1b8ac831b5f35d52f99e1af95c2751..b6a929ff7ef69b8e080882209923504b634ffaf3 100644 (file)
@@ -62,6 +62,6 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        } >.sdram
 }
index 5f6d0396f3af877c5cbc7abf4eef9f16c28a9699..8748c145c44a6d15805a4adcb79ecfdb6de49d55 100644 (file)
@@ -340,6 +340,9 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop)
 {
 }
 
+void arm_init_domains(void)
+{
+}
 #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
 
 #ifndef CONFIG_SYS_ICACHE_OFF
index d4bce6d4ddad74ab150e61e6d4dd9e470839999d..6375a81fd436386f2382b1c631bbd1ea1ad7fe8a 100644 (file)
@@ -95,3 +95,48 @@ void set_dp_phy_ctrl(unsigned int enable)
        if (cpu_is_exynos5())
                exynos5_dp_phy_control(enable);
 }
+
+static void exynos5_set_ps_hold_ctrl(void)
+{
+       struct exynos5_power *power =
+               (struct exynos5_power *)samsung_get_base_power();
+
+       /* Set PS-Hold high */
+       setbits_le32(&power->ps_hold_control,
+                       EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
+}
+
+void set_ps_hold_ctrl(void)
+{
+       if (cpu_is_exynos5())
+               exynos5_set_ps_hold_ctrl();
+}
+
+
+static void exynos5_set_xclkout(void)
+{
+       struct exynos5_power *power =
+               (struct exynos5_power *)samsung_get_base_power();
+
+       /* use xxti for xclk out */
+       clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK,
+                               PMU_DEBUG_XXTI);
+}
+
+void set_xclkout(void)
+{
+       if (cpu_is_exynos5())
+               exynos5_set_xclkout();
+}
+
+/* Enables hardware tripping to power off the system when TMU fails */
+void set_hw_thermal_trip(void)
+{
+       if (cpu_is_exynos5()) {
+               struct exynos5_power *power =
+                       (struct exynos5_power *)samsung_get_base_power();
+
+               /* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/
+               setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP);
+       }
+}
index 0efc80ddeb486e5e154091304225ae042d3f1f16..55e82ba3694c88be669553b575d25b938983daa8 100644 (file)
@@ -36,7 +36,7 @@ COBJS += emif-common.o
 COBJS  += vc.o
 endif
 
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
 COBJS  += boot-common.o
 SOBJS  += lowlevel_init.o
 endif
index 05ff2e868f2b4f5a99bafde85eca035d8639db25..70d16a816070b779cb3b6f1fac5bf9b734220f99 100644 (file)
 #include <asm/emif.h>
 #include <asm/omap_common.h>
 #include <linux/compiler.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+
+#define ARMV7_DCACHE_WRITEBACK  0xe
+#define        ARMV7_DOMAIN_CLIENT     1
+#define ARMV7_DOMAIN_MASK      (0x3 << 0)
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -269,4 +275,33 @@ void enable_caches(void)
        /* Enable D-cache. I-cache is already enabled in start.S */
        dcache_enable();
 }
+
+void dram_bank_mmu_setup(int bank)
+{
+       bd_t *bd = gd->bd;
+       int     i;
+
+       u32 start = bd->bi_dram[bank].start >> 20;
+       u32 size = bd->bi_dram[bank].size >> 20;
+       u32 end = start + size;
+
+       debug("%s: bank: %d\n", __func__, bank);
+       for (i = start; i < end; i++)
+               set_section_dcache(i, ARMV7_DCACHE_WRITEBACK);
+
+}
+
+void arm_init_domains(void)
+{
+       u32 reg;
+
+       reg = get_dacr();
+       /*
+       * Set DOMAIN to client access so that all permissions
+       * set in pagetables are validated by the mmu.
+       */
+       reg &= ~ARMV7_DOMAIN_MASK;
+       reg |= ARMV7_DOMAIN_CLIENT;
+       set_dacr(reg);
+}
 #endif
index 358107776d54337a898f383eb5c68d00acf9f992..b933fe843703d8c71f32e32187f5efd8f0e00dc4 100644 (file)
@@ -26,6 +26,7 @@
  * MA 02111-1307 USA
  */
 
+#include <config.h>
 #include <asm/arch/omap.h>
 #include <asm/arch/spl.h>
 #include <linux/linkage.h>
index 36bea5f94c118c8adeb69e83eb99800107c41921..507f6873e91d27f8a56e67fffc7ea073c793de21 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/arch/cpu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
index 88f40698b6765047ff95cef3c39e44605e8805cb..efae381bdb5028146cdf0d674e3ad506f05c3f9c 100644 (file)
@@ -58,6 +58,6 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        } >.sdram
 }
index 7cd409cca20c1f94316bcd64f22bc71b7a3ed6fb..79cc93cb57c3e77fa18032ccd47afcbbe45dd4bf 100644 (file)
@@ -46,7 +46,7 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        } >.sdram
 
        . = ALIGN(8);
index 30f02d3943570c523ea7830ad6b4d8d1810f15f5..36a4c3cfda1cfdcd4a0431305ae79068fb2fa795 100644 (file)
@@ -96,7 +96,7 @@ _image_copy_end_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
@@ -254,7 +254,6 @@ ENTRY(c_runtime_cpu_setup)
 #if !defined(CONFIG_TEGRA)
        /* Set vector address in CP15 VBAR register */
        ldr     r0, =_start
-       add     r0, r0, r9
        mcr     p15, 0, r0, c12, c0, 0  @Set VBAR
 #endif /* !Tegra */
 
@@ -310,6 +309,12 @@ ENTRY(cpu_init_cp15)
 #endif
        mcr     p15, 0, r0, c1, c0, 0
 
+#ifdef CONFIG_ARM_ERRATA_716044
+       mrc     p15, 0, r0, c1, c0, 0   @ read system control register
+       orr     r0, r0, #1 << 11        @ set bit #11
+       mcr     p15, 0, r0, c1, c0, 0   @ write system control register
+#endif
+
 #ifdef CONFIG_ARM_ERRATA_742230
        mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
        orr     r0, r0, #1 << 4         @ set bit #4
index efb5a400cf67cc9c2732af97714a751b4c2c5c07..b7259645e5c88150cf8a738585829a7ef3675f44 100644 (file)
@@ -112,7 +112,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index 5e66dd142ce36e01534cc57628bcd0857a6499bf..8345b55032395c8459b5c30e401af180865559f8 100644 (file)
@@ -74,10 +74,10 @@ SECTIONS
        .bss __bss_start (OVERLAY) : {
                *(.bss*)
                 . = ALIGN(4);
-                ___bssend___ = .;
+                __bss_end = .;
        }
-       .bss_end ___bssend___ (OVERLAY) : {
-               KEEP(*(.__bss_end__));
+       .bss_end __bss_end (OVERLAY) : {
+               KEEP(*(__bss_end));
        }
 
        /DISCARD/ : { *(.dynstr*) }
index e71803eb2e5777e4a029d8b39c24cac3954e3860..456a7836dae705e68084e0ff98c36b9205643e81 100644 (file)
@@ -120,7 +120,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index 4528c91983837cea91bcb254fa9ee34104a46be1..c0961770860f0affecde28b692d5cea199eed1aa 100644 (file)
@@ -78,7 +78,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index 3144299afef81c256223311259351998f27f9251..4bf6f5fe97ee103d53ad012af9a64c891dcf19be 100644 (file)
@@ -88,7 +88,7 @@ _bss_start_ofs:
 
 .globl _bss_end_ofs
 _bss_end_ofs:
-       .word __bss_end__ - _start
+       .word __bss_end - _start
 
 .globl _end_ofs
 _end_ofs:
index 8321afb959acaf57f1e5f82bc6189efd4bfe03fc..3c0d99ca3664c1021b754aa81fb23fb2a1ca70be 100644 (file)
@@ -78,7 +78,7 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                 . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        }
 
        /DISCARD/ : { *(.dynstr*) }
@@ -89,5 +89,5 @@ SECTIONS
 }
 
 #if defined(CONFIG_SPL_TEXT_BASE) && defined(CONFIG_SPL_MAX_SIZE)
-ASSERT(__bss_end__ < (CONFIG_SPL_TEXT_BASE + CONFIG_SPL_MAX_SIZE), "SPL image too big");
+ASSERT(__bss_end < (CONFIG_SPL_TEXT_BASE + CONFIG_SPL_MAX_SIZE), "SPL image too big");
 #endif
index d4ad3529b250b4056a6ebb45a2725bf0aad7e21a..3a1083d9a9b65c9bd00dad2bbaabf2a7a450aae6 100644 (file)
@@ -88,10 +88,11 @@ SECTIONS
        .bss __bss_start (OVERLAY) : {
                *(.bss*)
                 . = ALIGN(4);
-                ___bssend___ = .;
+                __bss_end = .;
        }
-       .bss_end ___bssend___ (OVERLAY) : {
-               KEEP(*(.__bss_end__));
+
+       .bss_end __bss_end (OVERLAY) : {
+               KEEP(*(__bss_end));
        }
 
        /DISCARD/ : { *(.dynstr*) }
@@ -102,5 +103,5 @@ SECTIONS
 }
 
 #if defined(CONFIG_SPL_TEXT_BASE) && defined(CONFIG_SPL_MAX_SIZE)
-ASSERT(__bss_end__ < (CONFIG_SPL_TEXT_BASE + CONFIG_SPL_MAX_SIZE), "SPL image too big");
+ASSERT(__bss_end < (CONFIG_SPL_TEXT_BASE + CONFIG_SPL_MAX_SIZE), "SPL image too big");
 #endif
index ed8c8dd6063ca94aa35de097bf4b73ec4f8747e1..61d35a83eacdc28c20ce0dd0b7f729a8efb4d10d 100644 (file)
                };
        };
 
+       tmu@10060000 {
+               compatible = "samsung,exynos-tmu";
+               reg = <0x10060000 0x10000>;
+       };
+
 };
index 701c0f9aff6ef3b1f7fe2461018ca502c79e4a18..f86d18dd7c9c1b8922019bf3917d7cd09149443c 100644 (file)
@@ -9,6 +9,43 @@
                #clock-cells = <1>;
        };
 
+       apbdma: dma {
+               compatible = "nvidia,tegra114-apbdma", "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
+               reg = <0x6000a000 0x1400>;
+               interrupts = <0 104 0x04
+                             0 105 0x04
+                             0 106 0x04
+                             0 107 0x04
+                             0 108 0x04
+                             0 109 0x04
+                             0 110 0x04
+                             0 111 0x04
+                             0 112 0x04
+                             0 113 0x04
+                             0 114 0x04
+                             0 115 0x04
+                             0 116 0x04
+                             0 117 0x04
+                             0 118 0x04
+                             0 119 0x04
+                             0 128 0x04
+                             0 129 0x04
+                             0 130 0x04
+                             0 131 0x04
+                             0 132 0x04
+                             0 133 0x04
+                             0 134 0x04
+                             0 135 0x04
+                             0 136 0x04
+                             0 137 0x04
+                             0 138 0x04
+                             0 139 0x04
+                             0 140 0x04
+                             0 141 0x04
+                             0 142 0x04
+                             0 143 0x04>;
+       };
+
        gpio: gpio {
                compatible = "nvidia,tegra114-gpio", "nvidia,tegra30-gpio";
                reg = <0x6000d000 0x1000>;
                clocks = <&tegra_car 47>;
                status = "disabled";
        };
+
+       spi@7000d400 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000d400 0x200>;
+               interrupts = <0 59 0x04>;
+               nvidia,dma-request-selector = <&apbdma 15>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC1, PLLP_OUT0 */
+               clocks = <&tegra_car 41>;
+       };
+
+       spi@7000d600 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000d600 0x200>;
+               interrupts = <0 82 0x04>;
+               nvidia,dma-request-selector = <&apbdma 16>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC2, PLLP_OUT0 */
+               clocks = <&tegra_car 44>;
+       };
+
+       spi@7000d800 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000d480 0x200>;
+               interrupts = <0 83 0x04>;
+               nvidia,dma-request-selector = <&apbdma 17>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC3, PLLP_OUT0 */
+               clocks = <&tegra_car 46>;
+       };
+
+       spi@7000da00 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000da00 0x200>;
+               interrupts = <0 93 0x04>;
+               nvidia,dma-request-selector = <&apbdma 18>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC4, PLLP_OUT0 */
+               clocks = <&tegra_car 68>;
+       };
+
+       spi@7000dc00 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000dc00 0x200>;
+               interrupts = <0 94 0x04>;
+               nvidia,dma-request-selector = <&apbdma 27>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC5, PLLP_OUT0 */
+               clocks = <&tegra_car 104>;
+       };
+
+       spi@7000de00 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000de00 0x200>;
+               interrupts = <0 79 0x04>;
+               nvidia,dma-request-selector = <&apbdma 28>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               /* PERIPH_ID_SBC6, PLLP_OUT0 */
+               clocks = <&tegra_car 105>;
+       };
+
+       sdhci@78000000 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000000 0x200>;
+               interrupts = <0 14 0x04>;
+               clocks = <&tegra_car 14>;
+               status = "disable";
+       };
+
+       sdhci@78000200 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000200 0x200>;
+               interrupts = <0 15 0x04>;
+               clocks = <&tegra_car 9>;
+               status = "disable";
+       };
+
+       sdhci@78000400 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000400 0x200>;
+               interrupts = <0 19 0x04>;
+               clocks = <&tegra_car 69>;
+               status = "disable";
+       };
+
+       sdhci@78000600 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000600 0x200>;
+               interrupts = <0 31 0x04>;
+               clocks = <&tegra_car 15>;
+               status = "disable";
+       };
 };
index 872ff820af30a10d5a4864dceea63240b9549dff..ecb590185730f47c9d91fa4698fdf8e8989e1017 100644 (file)
@@ -3,7 +3,7 @@
  *
  * clock header
  *
- * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2011, Texas Instruments Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
index d748dd27873a0bac3e75c00c63f8471fcd2c2108..89b63d9a8ced5132fd66f8cc8eeb7da428c752f8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * AM33xx clock define
  *
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
 #ifndef _CLOCKS_AM33XX_H_
 #define _CLOCKS_AM33XX_H_
 
-#define OSC    (V_OSCK/1000000)
-
-/* MAIN PLL Fdll = 550 MHZ, */
-#define MPUPLL_M       550
-#define MPUPLL_N       (OSC-1)
-#define MPUPLL_M2      1
-
-/* Core PLL Fdll = 1 GHZ, */
-#define COREPLL_M      1000
-#define COREPLL_N      (OSC-1)
-
-#define COREPLL_M4     10      /* CORE_CLKOUTM4 = 200 MHZ */
-#define COREPLL_M5     8       /* CORE_CLKOUTM5 = 250 MHZ */
-#define COREPLL_M6     4       /* CORE_CLKOUTM6 = 500 MHZ */
-
-/*
- * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
- * frequency needs to be set to 960 MHZ. Hence,
- * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
- */
-#define PERPLL_M       960
-#define PERPLL_N       (OSC-1)
-#define PERPLL_M2      5
-
-/* DDR Freq is 266 MHZ for now */
-/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
-#define DDRPLL_M       266
-#define DDRPLL_N       (OSC-1)
-#define DDRPLL_M2      1
+/* MAIN PLL Fdll = 550 MHz, by default */
+#ifndef CONFIG_SYS_MPUCLK
+#define CONFIG_SYS_MPUCLK      550
+#endif
 
 extern void pll_init(void);
 extern void enable_emif_clocks(void);
+extern void enable_dmm_clocks(void);
 
 #endif /* endif _CLOCKS_AM33XX_H_ */
index 16e8a80700a497936f8c14cd4f023892b7a4c6b7..3d3a7c8ac213ac74f8f0f4de2f38529f3438c0b2 100644 (file)
 #define HS_DEVICE                      0x2
 #define GP_DEVICE                      0x3
 
-/* cpu-id for AM33XX family */
+/* cpu-id for AM33XX and TI81XX family */
 #define AM335X                         0xB944
-#define DEVICE_ID                      0x44E10600
+#define TI81XX                         0xB81E
+#define DEVICE_ID                      (CTRL_BASE + 0x0600)
 
 /* This gives the status of the boot mode pins on the evm */
 #define SYSBOOT_MASK                   (BIT(0) | BIT(1) | BIT(2)\
 
 /* Reset control */
 #ifdef CONFIG_AM33XX
-#define PRM_RSTCTRL                    0x44E00F00
-#define PRM_RSTST                      0x44E00F08
+#define PRM_RSTCTRL                    (PRCM_BASE + 0x0F00)
+#elif defined(CONFIG_TI814X)
+#define PRM_RSTCTRL                    (PRCM_BASE + 0x00A0)
 #endif
+#define PRM_RSTST                      (PRM_RSTCTRL + 8)
 #define PRM_RSTCTRL_RESET              0x01
 #define PRM_RSTST_WARM_RESET_MASK      0x232
 
index ae43ef8778580aba42f8784d6eaa55e35be2073a..260cc3484f09330fdcb19707a1db89c1f3058c8d 100644 (file)
@@ -28,6 +28,7 @@
 #define VTP_CTRL_START_EN      (0x1)
 #define PHY_DLL_LOCK_DIFF      0x0
 #define DDR_CKE_CTRL_NORMAL    0x1
+#define PHY_EN_DYN_PWRDN       (0x1 << 20)
 
 /* Micron MT47H128M16RT-25E */
 #define MT47H128M16RT25E_EMIF_READ_LATENCY     0x100005
 #define MT41J256M8HX15E_PHY_FIFO_WE            0x100
 #define MT41J256M8HX15E_IOCTRL_VALUE           0x18B
 
+/* Micron MT41K256M16HA-125E */
+#define MT41K256M16HA125E_EMIF_READ_LATENCY    0x100006
+#define MT41K256M16HA125E_EMIF_TIM1            0x0888A39B
+#define MT41K256M16HA125E_EMIF_TIM2            0x26517FDA
+#define MT41K256M16HA125E_EMIF_TIM3            0x501F84EF
+#define MT41K256M16HA125E_EMIF_SDCFG           0x61C04BB2
+#define MT41K256M16HA125E_EMIF_SDREF           0x0000093B
+#define MT41K256M16HA125E_ZQ_CFG               0x50074BE4
+#define MT41K256M16HA125E_DLL_LOCK_DIFF                0x1
+#define MT41K256M16HA125E_RATIO                        0x40
+#define MT41K256M16HA125E_INVERT_CLKOUT                0x0
+#define MT41K256M16HA125E_RD_DQS               0x3C
+#define MT41K256M16HA125E_WR_DQS               0x45
+#define MT41K256M16HA125E_PHY_WR_DATA          0x7F
+#define MT41K256M16HA125E_PHY_FIFO_WE          0x9B
+#define MT41K256M16HA125E_IOCTRL_VALUE         0x18B
+
 /* Micron MT41J512M8RH-125 on EVM v1.5 */
 #define MT41J512M8RH125_EMIF_READ_LATENCY      0x06
 #define MT41J512M8RH125_EMIF_TIM1              0x0888A39B
 #define MT41J512M8RH125_PHY_WR_DATA            0x74
 #define MT41J512M8RH125_IOCTRL_VALUE           0x18B
 
+/**
+ * Configure DMM
+ */
+void config_dmm(const struct dmm_lisa_map_regs *regs);
+
 /**
  * Configure SDRAM
  */
-void config_sdram(const struct emif_regs *regs);
+void config_sdram(const struct emif_regs *regs, int nr);
 
 /**
  * Set SDRAM timings
  */
-void set_sdram_timings(const struct emif_regs *regs);
+void set_sdram_timings(const struct emif_regs *regs, int nr);
 
 /**
  * Configure DDR PHY
  */
-void config_ddr_phy(const struct emif_regs *regs);
+void config_ddr_phy(const struct emif_regs *regs, int nr);
+
+struct ddr_cmd_regs {
+       unsigned int resv0[7];
+       unsigned int cm0csratio;        /* offset 0x01C */
+       unsigned int resv1[2];
+       unsigned int cm0dldiff;         /* offset 0x028 */
+       unsigned int cm0iclkout;        /* offset 0x02C */
+       unsigned int resv2[8];
+       unsigned int cm1csratio;        /* offset 0x050 */
+       unsigned int resv3[2];
+       unsigned int cm1dldiff;         /* offset 0x05C */
+       unsigned int cm1iclkout;        /* offset 0x060 */
+       unsigned int resv4[8];
+       unsigned int cm2csratio;        /* offset 0x084 */
+       unsigned int resv5[2];
+       unsigned int cm2dldiff;         /* offset 0x090 */
+       unsigned int cm2iclkout;        /* offset 0x094 */
+       unsigned int resv6[3];
+};
+
+struct ddr_data_regs {
+       unsigned int dt0rdsratio0;      /* offset 0x0C8 */
+       unsigned int resv1[4];
+       unsigned int dt0wdsratio0;      /* offset 0x0DC */
+       unsigned int resv2[4];
+       unsigned int dt0wiratio0;       /* offset 0x0F0 */
+       unsigned int resv3;
+       unsigned int dt0wimode0;        /* offset 0x0F8 */
+       unsigned int dt0giratio0;       /* offset 0x0FC */
+       unsigned int resv4;
+       unsigned int dt0gimode0;        /* offset 0x104 */
+       unsigned int dt0fwsratio0;      /* offset 0x108 */
+       unsigned int resv5[4];
+       unsigned int dt0dqoffset;       /* offset 0x11C */
+       unsigned int dt0wrsratio0;      /* offset 0x120 */
+       unsigned int resv6[4];
+       unsigned int dt0rdelays0;       /* offset 0x134 */
+       unsigned int dt0dldiff0;        /* offset 0x138 */
+       unsigned int resv7[12];
+};
 
 /**
  * This structure represents the DDR registers on AM33XX devices.
@@ -193,12 +256,12 @@ struct ddr_data {
 /**
  * Configure DDR CMD control registers
  */
-void config_cmd_ctrl(const struct cmd_control *cmd);
+void config_cmd_ctrl(const struct cmd_control *cmd, int nr);
 
 /**
  * Configure DDR DATA registers
  */
-void config_ddr_data(int data_macrono, const struct ddr_data *data);
+void config_ddr_data(const struct ddr_data *data, int nr);
 
 /**
  * This structure represents the DDR io control on AM33XX devices.
@@ -226,6 +289,6 @@ struct ddr_ctrl {
 
 void config_ddr(unsigned int pll, unsigned int ioctrl,
                const struct ddr_data *data, const struct cmd_control *ctrl,
-               const struct emif_regs *regs);
+               const struct emif_regs *regs, int nr);
 
 #endif  /* _DDR_DEFS_H */
index 6dd3296907acce5671364bc09b8b6b65824108f0..5a27f9cf5e0fe4e5caa43951abdafe265a79ecf6 100644 (file)
@@ -3,7 +3,7 @@
  *
  * hardware specific header
  *
- * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
 #ifndef __AM33XX_HARDWARE_H
 #define __AM33XX_HARDWARE_H
 
+#include <config.h>
 #include <asm/arch/omap.h>
+#ifdef CONFIG_AM33XX
+#include <asm/arch/hardware_am33xx.h>
+#elif defined(CONFIG_TI814X)
+#include <asm/arch/hardware_ti814x.h>
+#endif
 
-/* Module base addresses */
-#define UART0_BASE                     0x44E09000
+/*
+ * Common hardware definitions
+ */
 
 /* DM Timer base addresses */
 #define DM_TIMER0_BASE                 0x4802C000
 /* GPIO Base address */
 #define GPIO0_BASE                     0x48032000
 #define GPIO1_BASE                     0x4804C000
-#define GPIO2_BASE                     0x481AC000
 
 /* BCH Error Location Module */
 #define ELM_BASE                       0x48080000
 
-/* Watchdog Timer */
-#define WDT_BASE                       0x44E35000
-
-/* Control Module Base Address */
-#define CTRL_BASE                      0x44E10000
-#define CTRL_DEVICE_BASE               0x44E10600
-
-/* PRCM Base Address */
-#define PRCM_BASE                      0x44E00000
-
 /* EMIF Base address */
 #define EMIF4_0_CFG_BASE               0x4C000000
 #define EMIF4_1_CFG_BASE               0x4D000000
 #define PRM_DEVICE                     0x44E00F00
 
 /* VTP Base address */
-#define VTP0_CTRL_ADDR                 0x44E10E0C
+#define VTP1_CTRL_ADDR                 0x48140E10
 
 /* DDR Base address */
 #define DDR_CTRL_ADDR                  0x44E10E04
 #define DDR_CONTROL_BASE_ADDR          0x44E11404
-#define DDR_PHY_BASE_ADDR              0x44E12000
-#define DDR_PHY_BASE_ADDR2             0x44E120A4
+#define DDR_PHY_CMD_ADDR2              0x47C0C800
+#define DDR_PHY_DATA_ADDR2             0x47C0C8C8
 
 /* UART */
 #define DEFAULT_UART_BASE              UART0_BASE
 #define GPMC_BASE                      0x50000000
 
 /* CPSW Config space */
-#define AM335X_CPSW_BASE               0x4A100000
-#define AM335X_CPSW_MDIO_BASE          0x4A101000
-
-/* RTC base address */
-#define AM335X_RTC_BASE                        0x44E3E000
+#define CPSW_BASE                      0x4A100000
 
 /* OTG */
-#define AM335X_USB0_OTG_BASE           0x47401000
-#define AM335X_USB1_OTG_BASE           0x47401800
+#define USB0_OTG_BASE                  0x47401000
+#define USB1_OTG_BASE                  0x47401800
 
 #endif /* __AM33XX_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware_am33xx.h b/arch/arm/include/asm/arch-am33xx/hardware_am33xx.h
new file mode 100644 (file)
index 0000000..fa02f19
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * hardware_am33xx.h
+ *
+ * AM33xx hardware specific header
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __AM33XX_HARDWARE_AM33XX_H
+#define __AM33XX_HARDWARE_AM33XX_H
+
+/* Module base addresses */
+
+/* UART Base Address */
+#define UART0_BASE                     0x44E09000
+
+/* GPIO Base address */
+#define GPIO2_BASE                     0x481AC000
+
+/* Watchdog Timer */
+#define WDT_BASE                       0x44E35000
+
+/* Control Module Base Address */
+#define CTRL_BASE                      0x44E10000
+#define CTRL_DEVICE_BASE               0x44E10600
+
+/* PRCM Base Address */
+#define PRCM_BASE                      0x44E00000
+
+/* VTP Base address */
+#define VTP0_CTRL_ADDR                 0x44E10E0C
+
+/* DDR Base address */
+#define DDR_PHY_CMD_ADDR               0x44E12000
+#define DDR_PHY_DATA_ADDR              0x44E120C8
+#define DDR_DATA_REGS_NR               2
+
+/* CPSW Config space */
+#define CPSW_MDIO_BASE                 0x4A101000
+
+/* RTC base address */
+#define RTC_BASE                       0x44E3E000
+
+#endif /* __AM33XX_HARDWARE_AM33XX_H */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware_ti814x.h b/arch/arm/include/asm/arch-am33xx/hardware_ti814x.h
new file mode 100644 (file)
index 0000000..a950ac3
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * hardware_ti814x.h
+ *
+ * TI814x hardware specific header
+ *
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __AM33XX_HARDWARE_TI814X_H
+#define __AM33XX_HARDWARE_TI814X_H
+
+/* Module base addresses */
+
+/* UART Base Address */
+#define UART0_BASE                     0x48020000
+
+/* Watchdog Timer */
+#define WDT_BASE                       0x481C7000
+
+/* Control Module Base Address */
+#define CTRL_BASE                      0x48140000
+
+/* PRCM Base Address */
+#define PRCM_BASE                      0x48180000
+
+/* PLL Subsystem Base Address */
+#define PLL_SUBSYS_BASE                        0x481C5000
+
+/* VTP Base address */
+#define VTP0_CTRL_ADDR                 0x48140E0C
+
+/* DDR Base address */
+#define DDR_PHY_CMD_ADDR               0x47C0C400
+#define DDR_PHY_DATA_ADDR              0x47C0C4C8
+#define DDR_DATA_REGS_NR               4
+
+/* CPSW Config space */
+#define CPSW_MDIO_BASE                 0x4A100800
+
+/* RTC base address */
+#define RTC_BASE                       0x480C0000
+
+#endif /* __AM33XX_HARDWARE_TI814X_H */
index 33c9c838924d663a8fb2e8a6f464155ccbd12610..51ba79190a72b958f193da55bc0cb08be82f6776 100644 (file)
@@ -24,4 +24,9 @@
 #define OMAP_HSMMC1_BASE               0x48060100
 #define OMAP_HSMMC2_BASE               0x481D8100
 
+#if defined(CONFIG_TI814X)
+#undef MMC_CLOCK_REFERENCE
+#define MMC_CLOCK_REFERENCE    192 /* MHz */
+#endif
+
 #endif /* MMC_HOST_DEF_H */
index 460ac1c02dc6db3ee5ae5dab8b4b13623d329acc..1c6b65f4a008c03f46f5074274dcd92fe6e200c5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * mux.h
  *
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
 #include <common.h>
 #include <asm/io.h>
 
-#define MUX_CFG(value, offset) \
-       __raw_writel(value, (CTRL_BASE + offset));
-
-/* PAD Control Fields */
-#define SLEWCTRL       (0x1 << 6)
-#define RXACTIVE       (0x1 << 5)
-#define PULLDOWN_EN    (0x0 << 4) /* Pull Down Selection */
-#define PULLUP_EN      (0x1 << 4) /* Pull Up Selection */
-#define PULLUDEN       (0x0 << 3) /* Pull up enabled */
-#define PULLUDDIS      (0x1 << 3) /* Pull up disabled */
-#define MODE(val)      val     /* used for Readability */
-
-/*
- * PAD CONTROL OFFSETS
- * Field names corresponds to the pad signal name
- */
-struct pad_signals {
-       int gpmc_ad0;
-       int gpmc_ad1;
-       int gpmc_ad2;
-       int gpmc_ad3;
-       int gpmc_ad4;
-       int gpmc_ad5;
-       int gpmc_ad6;
-       int gpmc_ad7;
-       int gpmc_ad8;
-       int gpmc_ad9;
-       int gpmc_ad10;
-       int gpmc_ad11;
-       int gpmc_ad12;
-       int gpmc_ad13;
-       int gpmc_ad14;
-       int gpmc_ad15;
-       int gpmc_a0;
-       int gpmc_a1;
-       int gpmc_a2;
-       int gpmc_a3;
-       int gpmc_a4;
-       int gpmc_a5;
-       int gpmc_a6;
-       int gpmc_a7;
-       int gpmc_a8;
-       int gpmc_a9;
-       int gpmc_a10;
-       int gpmc_a11;
-       int gpmc_wait0;
-       int gpmc_wpn;
-       int gpmc_be1n;
-       int gpmc_csn0;
-       int gpmc_csn1;
-       int gpmc_csn2;
-       int gpmc_csn3;
-       int gpmc_clk;
-       int gpmc_advn_ale;
-       int gpmc_oen_ren;
-       int gpmc_wen;
-       int gpmc_be0n_cle;
-       int lcd_data0;
-       int lcd_data1;
-       int lcd_data2;
-       int lcd_data3;
-       int lcd_data4;
-       int lcd_data5;
-       int lcd_data6;
-       int lcd_data7;
-       int lcd_data8;
-       int lcd_data9;
-       int lcd_data10;
-       int lcd_data11;
-       int lcd_data12;
-       int lcd_data13;
-       int lcd_data14;
-       int lcd_data15;
-       int lcd_vsync;
-       int lcd_hsync;
-       int lcd_pclk;
-       int lcd_ac_bias_en;
-       int mmc0_dat3;
-       int mmc0_dat2;
-       int mmc0_dat1;
-       int mmc0_dat0;
-       int mmc0_clk;
-       int mmc0_cmd;
-       int mii1_col;
-       int mii1_crs;
-       int mii1_rxerr;
-       int mii1_txen;
-       int mii1_rxdv;
-       int mii1_txd3;
-       int mii1_txd2;
-       int mii1_txd1;
-       int mii1_txd0;
-       int mii1_txclk;
-       int mii1_rxclk;
-       int mii1_rxd3;
-       int mii1_rxd2;
-       int mii1_rxd1;
-       int mii1_rxd0;
-       int rmii1_refclk;
-       int mdio_data;
-       int mdio_clk;
-       int spi0_sclk;
-       int spi0_d0;
-       int spi0_d1;
-       int spi0_cs0;
-       int spi0_cs1;
-       int ecap0_in_pwm0_out;
-       int uart0_ctsn;
-       int uart0_rtsn;
-       int uart0_rxd;
-       int uart0_txd;
-       int uart1_ctsn;
-       int uart1_rtsn;
-       int uart1_rxd;
-       int uart1_txd;
-       int i2c0_sda;
-       int i2c0_scl;
-       int mcasp0_aclkx;
-       int mcasp0_fsx;
-       int mcasp0_axr0;
-       int mcasp0_ahclkr;
-       int mcasp0_aclkr;
-       int mcasp0_fsr;
-       int mcasp0_axr1;
-       int mcasp0_ahclkx;
-       int xdma_event_intr0;
-       int xdma_event_intr1;
-       int nresetin_out;
-       int porz;
-       int nnmi;
-       int osc0_in;
-       int osc0_out;
-       int rsvd1;
-       int tms;
-       int tdi;
-       int tdo;
-       int tck;
-       int ntrst;
-       int emu0;
-       int emu1;
-       int osc1_in;
-       int osc1_out;
-       int pmic_power_en;
-       int rtc_porz;
-       int rsvd2;
-       int ext_wakeup;
-       int enz_kaldo_1p8v;
-       int usb0_dm;
-       int usb0_dp;
-       int usb0_ce;
-       int usb0_id;
-       int usb0_vbus;
-       int usb0_drvvbus;
-       int usb1_dm;
-       int usb1_dp;
-       int usb1_ce;
-       int usb1_id;
-       int usb1_vbus;
-       int usb1_drvvbus;
-       int ddr_resetn;
-       int ddr_csn0;
-       int ddr_cke;
-       int ddr_ck;
-       int ddr_nck;
-       int ddr_casn;
-       int ddr_rasn;
-       int ddr_wen;
-       int ddr_ba0;
-       int ddr_ba1;
-       int ddr_ba2;
-       int ddr_a0;
-       int ddr_a1;
-       int ddr_a2;
-       int ddr_a3;
-       int ddr_a4;
-       int ddr_a5;
-       int ddr_a6;
-       int ddr_a7;
-       int ddr_a8;
-       int ddr_a9;
-       int ddr_a10;
-       int ddr_a11;
-       int ddr_a12;
-       int ddr_a13;
-       int ddr_a14;
-       int ddr_a15;
-       int ddr_odt;
-       int ddr_d0;
-       int ddr_d1;
-       int ddr_d2;
-       int ddr_d3;
-       int ddr_d4;
-       int ddr_d5;
-       int ddr_d6;
-       int ddr_d7;
-       int ddr_d8;
-       int ddr_d9;
-       int ddr_d10;
-       int ddr_d11;
-       int ddr_d12;
-       int ddr_d13;
-       int ddr_d14;
-       int ddr_d15;
-       int ddr_dqm0;
-       int ddr_dqm1;
-       int ddr_dqs0;
-       int ddr_dqsn0;
-       int ddr_dqs1;
-       int ddr_dqsn1;
-       int ddr_vref;
-       int ddr_vtp;
-       int ddr_strben0;
-       int ddr_strben1;
-       int ain7;
-       int ain6;
-       int ain5;
-       int ain4;
-       int ain3;
-       int ain2;
-       int ain1;
-       int ain0;
-       int vrefp;
-       int vrefn;
-};
+#ifdef CONFIG_AM33XX
+#include <asm/arch/mux_am33xx.h>
+#elif defined(CONFIG_TI814X)
+#include <asm/arch/mux_ti814x.h>
+#endif
 
 struct module_pin_mux {
        short reg_offset;
-       unsigned char val;
+       unsigned int val;
 };
 
 /* Pad control register offset */
@@ -259,4 +40,4 @@ struct module_pin_mux {
  */
 void configure_module_pin_mux(struct module_pin_mux *mod_pin_mux);
 
-#endif
+#endif /* endif _MUX_H */
diff --git a/arch/arm/include/asm/arch-am33xx/mux_am33xx.h b/arch/arm/include/asm/arch-am33xx/mux_am33xx.h
new file mode 100644 (file)
index 0000000..d5cab3e
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * mux_am33xx.h
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MUX_AM33XX_H_
+#define _MUX_AM33XX_H_
+
+#include <common.h>
+#include <asm/io.h>
+
+#define MUX_CFG(value, offset) \
+       __raw_writel(value, (CTRL_BASE + offset));
+
+/* PAD Control Fields */
+#define SLEWCTRL       (0x1 << 6)
+#define RXACTIVE       (0x1 << 5)
+#define PULLDOWN_EN    (0x0 << 4) /* Pull Down Selection */
+#define PULLUP_EN      (0x1 << 4) /* Pull Up Selection */
+#define PULLUDEN       (0x0 << 3) /* Pull up enabled */
+#define PULLUDDIS      (0x1 << 3) /* Pull up disabled */
+#define MODE(val)      val     /* used for Readability */
+
+/*
+ * PAD CONTROL OFFSETS
+ * Field names corresponds to the pad signal name
+ */
+struct pad_signals {
+       int gpmc_ad0;
+       int gpmc_ad1;
+       int gpmc_ad2;
+       int gpmc_ad3;
+       int gpmc_ad4;
+       int gpmc_ad5;
+       int gpmc_ad6;
+       int gpmc_ad7;
+       int gpmc_ad8;
+       int gpmc_ad9;
+       int gpmc_ad10;
+       int gpmc_ad11;
+       int gpmc_ad12;
+       int gpmc_ad13;
+       int gpmc_ad14;
+       int gpmc_ad15;
+       int gpmc_a0;
+       int gpmc_a1;
+       int gpmc_a2;
+       int gpmc_a3;
+       int gpmc_a4;
+       int gpmc_a5;
+       int gpmc_a6;
+       int gpmc_a7;
+       int gpmc_a8;
+       int gpmc_a9;
+       int gpmc_a10;
+       int gpmc_a11;
+       int gpmc_wait0;
+       int gpmc_wpn;
+       int gpmc_be1n;
+       int gpmc_csn0;
+       int gpmc_csn1;
+       int gpmc_csn2;
+       int gpmc_csn3;
+       int gpmc_clk;
+       int gpmc_advn_ale;
+       int gpmc_oen_ren;
+       int gpmc_wen;
+       int gpmc_be0n_cle;
+       int lcd_data0;
+       int lcd_data1;
+       int lcd_data2;
+       int lcd_data3;
+       int lcd_data4;
+       int lcd_data5;
+       int lcd_data6;
+       int lcd_data7;
+       int lcd_data8;
+       int lcd_data9;
+       int lcd_data10;
+       int lcd_data11;
+       int lcd_data12;
+       int lcd_data13;
+       int lcd_data14;
+       int lcd_data15;
+       int lcd_vsync;
+       int lcd_hsync;
+       int lcd_pclk;
+       int lcd_ac_bias_en;
+       int mmc0_dat3;
+       int mmc0_dat2;
+       int mmc0_dat1;
+       int mmc0_dat0;
+       int mmc0_clk;
+       int mmc0_cmd;
+       int mii1_col;
+       int mii1_crs;
+       int mii1_rxerr;
+       int mii1_txen;
+       int mii1_rxdv;
+       int mii1_txd3;
+       int mii1_txd2;
+       int mii1_txd1;
+       int mii1_txd0;
+       int mii1_txclk;
+       int mii1_rxclk;
+       int mii1_rxd3;
+       int mii1_rxd2;
+       int mii1_rxd1;
+       int mii1_rxd0;
+       int rmii1_refclk;
+       int mdio_data;
+       int mdio_clk;
+       int spi0_sclk;
+       int spi0_d0;
+       int spi0_d1;
+       int spi0_cs0;
+       int spi0_cs1;
+       int ecap0_in_pwm0_out;
+       int uart0_ctsn;
+       int uart0_rtsn;
+       int uart0_rxd;
+       int uart0_txd;
+       int uart1_ctsn;
+       int uart1_rtsn;
+       int uart1_rxd;
+       int uart1_txd;
+       int i2c0_sda;
+       int i2c0_scl;
+       int mcasp0_aclkx;
+       int mcasp0_fsx;
+       int mcasp0_axr0;
+       int mcasp0_ahclkr;
+       int mcasp0_aclkr;
+       int mcasp0_fsr;
+       int mcasp0_axr1;
+       int mcasp0_ahclkx;
+       int xdma_event_intr0;
+       int xdma_event_intr1;
+       int nresetin_out;
+       int porz;
+       int nnmi;
+       int osc0_in;
+       int osc0_out;
+       int rsvd1;
+       int tms;
+       int tdi;
+       int tdo;
+       int tck;
+       int ntrst;
+       int emu0;
+       int emu1;
+       int osc1_in;
+       int osc1_out;
+       int pmic_power_en;
+       int rtc_porz;
+       int rsvd2;
+       int ext_wakeup;
+       int enz_kaldo_1p8v;
+       int usb0_dm;
+       int usb0_dp;
+       int usb0_ce;
+       int usb0_id;
+       int usb0_vbus;
+       int usb0_drvvbus;
+       int usb1_dm;
+       int usb1_dp;
+       int usb1_ce;
+       int usb1_id;
+       int usb1_vbus;
+       int usb1_drvvbus;
+       int ddr_resetn;
+       int ddr_csn0;
+       int ddr_cke;
+       int ddr_ck;
+       int ddr_nck;
+       int ddr_casn;
+       int ddr_rasn;
+       int ddr_wen;
+       int ddr_ba0;
+       int ddr_ba1;
+       int ddr_ba2;
+       int ddr_a0;
+       int ddr_a1;
+       int ddr_a2;
+       int ddr_a3;
+       int ddr_a4;
+       int ddr_a5;
+       int ddr_a6;
+       int ddr_a7;
+       int ddr_a8;
+       int ddr_a9;
+       int ddr_a10;
+       int ddr_a11;
+       int ddr_a12;
+       int ddr_a13;
+       int ddr_a14;
+       int ddr_a15;
+       int ddr_odt;
+       int ddr_d0;
+       int ddr_d1;
+       int ddr_d2;
+       int ddr_d3;
+       int ddr_d4;
+       int ddr_d5;
+       int ddr_d6;
+       int ddr_d7;
+       int ddr_d8;
+       int ddr_d9;
+       int ddr_d10;
+       int ddr_d11;
+       int ddr_d12;
+       int ddr_d13;
+       int ddr_d14;
+       int ddr_d15;
+       int ddr_dqm0;
+       int ddr_dqm1;
+       int ddr_dqs0;
+       int ddr_dqsn0;
+       int ddr_dqs1;
+       int ddr_dqsn1;
+       int ddr_vref;
+       int ddr_vtp;
+       int ddr_strben0;
+       int ddr_strben1;
+       int ain7;
+       int ain6;
+       int ain5;
+       int ain4;
+       int ain3;
+       int ain2;
+       int ain1;
+       int ain0;
+       int vrefp;
+       int vrefn;
+};
+
+#endif /* endif _MUX_AM33XX_H_ */
diff --git a/arch/arm/include/asm/arch-am33xx/mux_ti814x.h b/arch/arm/include/asm/arch-am33xx/mux_ti814x.h
new file mode 100644 (file)
index 0000000..a26e503
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * mux_ti814x.h
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MUX_TI814X_H_
+#define _MUX_TI814X_H_
+
+/* PAD Control Fields */
+#define PINCNTL_RSV_MSK        (0x3 << 18) /* Reserved bitmask */
+#define PULLUP_EN      (0x1 << 17) /* Pull UP Selection */
+#define PULLUDEN       (0x0 << 16) /* Pull up enabled */
+#define PULLUDDIS      (0x1 << 16) /* Pull up disabled */
+#define MODE(val)      val     /* used for Readability */
+
+#define MUX_CFG(value, offset)                         \
+{                                                      \
+       int tmp;                                        \
+       tmp = __raw_readl(CTRL_BASE + offset);          \
+       tmp &= PINCNTL_RSV_MSK;                         \
+       __raw_writel(tmp | value, (CTRL_BASE + offset));\
+}
+
+/*
+ * PAD CONTROL OFFSETS
+ * Field names corresponds to the pad signal name
+ */
+struct pad_signals {
+       int pincntl1;
+       int pincntl2;
+       int pincntl3;
+       int pincntl4;
+       int pincntl5;
+       int pincntl6;
+       int pincntl7;
+       int pincntl8;
+       int pincntl9;
+       int pincntl10;
+       int pincntl11;
+       int pincntl12;
+       int pincntl13;
+       int pincntl14;
+       int pincntl15;
+       int pincntl16;
+       int pincntl17;
+       int pincntl18;
+       int pincntl19;
+       int pincntl20;
+       int pincntl21;
+       int pincntl22;
+       int pincntl23;
+       int pincntl24;
+       int pincntl25;
+       int pincntl26;
+       int pincntl27;
+       int pincntl28;
+       int pincntl29;
+       int pincntl30;
+       int pincntl31;
+       int pincntl32;
+       int pincntl33;
+       int pincntl34;
+       int pincntl35;
+       int pincntl36;
+       int pincntl37;
+       int pincntl38;
+       int pincntl39;
+       int pincntl40;
+       int pincntl41;
+       int pincntl42;
+       int pincntl43;
+       int pincntl44;
+       int pincntl45;
+       int pincntl46;
+       int pincntl47;
+       int pincntl48;
+       int pincntl49;
+       int pincntl50;
+       int pincntl51;
+       int pincntl52;
+       int pincntl53;
+       int pincntl54;
+       int pincntl55;
+       int pincntl56;
+       int pincntl57;
+       int pincntl58;
+       int pincntl59;
+       int pincntl60;
+       int pincntl61;
+       int pincntl62;
+       int pincntl63;
+       int pincntl64;
+       int pincntl65;
+       int pincntl66;
+       int pincntl67;
+       int pincntl68;
+       int pincntl69;
+       int pincntl70;
+       int pincntl71;
+       int pincntl72;
+       int pincntl73;
+       int pincntl74;
+       int pincntl75;
+       int pincntl76;
+       int pincntl77;
+       int pincntl78;
+       int pincntl79;
+       int pincntl80;
+       int pincntl81;
+       int pincntl82;
+       int pincntl83;
+       int pincntl84;
+       int pincntl85;
+       int pincntl86;
+       int pincntl87;
+       int pincntl88;
+       int pincntl89;
+       int pincntl90;
+       int pincntl91;
+       int pincntl92;
+       int pincntl93;
+       int pincntl94;
+       int pincntl95;
+       int pincntl96;
+       int pincntl97;
+       int pincntl98;
+       int pincntl99;
+       int pincntl100;
+       int pincntl101;
+       int pincntl102;
+       int pincntl103;
+       int pincntl104;
+       int pincntl105;
+       int pincntl106;
+       int pincntl107;
+       int pincntl108;
+       int pincntl109;
+       int pincntl110;
+       int pincntl111;
+       int pincntl112;
+       int pincntl113;
+       int pincntl114;
+       int pincntl115;
+       int pincntl116;
+       int pincntl117;
+       int pincntl118;
+       int pincntl119;
+       int pincntl120;
+       int pincntl121;
+       int pincntl122;
+       int pincntl123;
+       int pincntl124;
+       int pincntl125;
+       int pincntl126;
+       int pincntl127;
+       int pincntl128;
+       int pincntl129;
+       int pincntl130;
+       int pincntl131;
+       int pincntl132;
+       int pincntl133;
+       int pincntl134;
+       int pincntl135;
+       int pincntl136;
+       int pincntl137;
+       int pincntl138;
+       int pincntl139;
+       int pincntl140;
+       int pincntl141;
+       int pincntl142;
+       int pincntl143;
+       int pincntl144;
+       int pincntl145;
+       int pincntl146;
+       int pincntl147;
+       int pincntl148;
+       int pincntl149;
+       int pincntl150;
+       int pincntl151;
+       int pincntl152;
+       int pincntl153;
+       int pincntl154;
+       int pincntl155;
+       int pincntl156;
+       int pincntl157;
+       int pincntl158;
+       int pincntl159;
+       int pincntl160;
+       int pincntl161;
+       int pincntl162;
+       int pincntl163;
+       int pincntl164;
+       int pincntl165;
+       int pincntl166;
+       int pincntl167;
+       int pincntl168;
+       int pincntl169;
+       int pincntl170;
+       int pincntl171;
+       int pincntl172;
+       int pincntl173;
+       int pincntl174;
+       int pincntl175;
+       int pincntl176;
+       int pincntl177;
+       int pincntl178;
+       int pincntl179;
+       int pincntl180;
+       int pincntl181;
+       int pincntl182;
+       int pincntl183;
+       int pincntl184;
+       int pincntl185;
+       int pincntl186;
+       int pincntl187;
+       int pincntl188;
+       int pincntl189;
+       int pincntl190;
+       int pincntl191;
+       int pincntl192;
+       int pincntl193;
+       int pincntl194;
+       int pincntl195;
+       int pincntl196;
+       int pincntl197;
+       int pincntl198;
+       int pincntl199;
+       int pincntl200;
+       int pincntl201;
+       int pincntl202;
+       int pincntl203;
+       int pincntl204;
+       int pincntl205;
+       int pincntl206;
+       int pincntl207;
+       int pincntl208;
+       int pincntl209;
+       int pincntl210;
+       int pincntl211;
+       int pincntl212;
+       int pincntl213;
+       int pincntl214;
+       int pincntl215;
+       int pincntl216;
+       int pincntl217;
+       int pincntl218;
+       int pincntl219;
+       int pincntl220;
+       int pincntl221;
+       int pincntl222;
+       int pincntl223;
+       int pincntl224;
+       int pincntl225;
+       int pincntl226;
+       int pincntl227;
+       int pincntl228;
+       int pincntl229;
+       int pincntl230;
+       int pincntl231;
+       int pincntl232;
+       int pincntl233;
+       int pincntl234;
+       int pincntl235;
+       int pincntl236;
+       int pincntl237;
+       int pincntl238;
+       int pincntl239;
+       int pincntl240;
+       int pincntl241;
+       int pincntl242;
+       int pincntl243;
+       int pincntl244;
+       int pincntl245;
+       int pincntl246;
+       int pincntl247;
+       int pincntl248;
+       int pincntl249;
+       int pincntl250;
+       int pincntl251;
+       int pincntl252;
+       int pincntl253;
+       int pincntl254;
+       int pincntl255;
+       int pincntl256;
+       int pincntl257;
+       int pincntl258;
+       int pincntl259;
+       int pincntl260;
+       int pincntl261;
+       int pincntl262;
+       int pincntl263;
+       int pincntl264;
+       int pincntl265;
+       int pincntl266;
+       int pincntl267;
+       int pincntl268;
+       int pincntl269;
+       int pincntl270;
+};
+
+#endif /* endif _MUX_TI814X_H_ */
index 850f8a551d8381c5896a19e3ee101f8fb876a20a..d28f9a83ff25b249d76eb3485a9f5352a110a92c 100644 (file)
  * Non-secure RAM starts at 0x40300000 for GP devices. But we keep SRAM_BASE
  * at 0x40304000(EMU base) so that our code works for both EMU and GP
  */
+#ifdef CONFIG_AM33XX
 #define NON_SECURE_SRAM_START  0x40304000
 #define NON_SECURE_SRAM_END    0x4030E000
+#elif defined(CONFIG_TI814X)
+#define NON_SECURE_SRAM_START  0x40300000
+#define NON_SECURE_SRAM_END    0x40320000
+#endif
 
 /* ROM code defines */
 /* Boot device */
index e961ce0578a8e7839bc7c1ba9c3899c00e4241c2..f60b086366ce39511cdaedde80833241e05924da 100644 (file)
 
 #define BOOT_DEVICE_XIP        2
 #define BOOT_DEVICE_NAND       5
+#ifdef CONFIG_AM33XX
 #define BOOT_DEVICE_MMC1       8
 #define BOOT_DEVICE_MMC2       9       /* eMMC or daughter card */
+#elif defined(CONFIG_TI814X)
+#define BOOT_DEVICE_MMC1       9
+#define BOOT_DEVICE_MMC2       8       /* ROM only supports 2nd instance */
+#endif
 #define BOOT_DEVICE_SPI                11
 #define BOOT_DEVICE_UART       65
 #define BOOT_DEVICE_USBETH     68
index 97ab60d1b2bae9e2ab52d7ea97d3e0d1a1f20e9e..0910a9451a0b22ea7cbdba68e82639651a845bf4 100644 (file)
@@ -34,6 +34,8 @@ void setup_clocks_for_console(void);
 void ddr_pll_config(unsigned int ddrpll_M);
 
 void sdelay(unsigned long);
+
+struct gpmc_cs;
 void gpmc_init(void);
 void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
                        u32 size);
diff --git a/arch/arm/include/asm/arch-bcm2835/mbox.h b/arch/arm/include/asm/arch-bcm2835/mbox.h
new file mode 100644 (file)
index 0000000..b07c4a0
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * 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.
+ */
+
+#ifndef _BCM2835_MBOX_H
+#define _BCM2835_MBOX_H
+
+#include <linux/compiler.h>
+
+/*
+ * The BCM2835 SoC contains (at least) two CPUs; the VideoCore (a/k/a "GPU")
+ * and the ARM CPU. The ARM CPU is often thought of as the main CPU.
+ * However, the VideoCore actually controls the initial SoC boot, and hides
+ * much of the hardware behind a protocol. This protocol is transported
+ * using the SoC's mailbox hardware module.
+ *
+ * The mailbox hardware supports passing 32-bit values back and forth.
+ * Presumably by software convention of the firmware, the bottom 4 bits of the
+ * value are used to indicate a logical channel, and the upper 28 bits are the
+ * actual payload. Various channels exist using these simple raw messages. See
+ * https://github.com/raspberrypi/firmware/wiki/Mailboxes for a list. As an
+ * example, the messages on the power management channel are a bitmask of
+ * devices whose power should be enabled.
+ *
+ * The property mailbox channel passes messages that contain the (16-byte
+ * aligned) ARM physical address of a memory buffer. This buffer is passed to
+ * the VC for processing, is modified in-place by the VC, and the address then
+ * passed back to the ARM CPU as the response mailbox message to indicate
+ * request completion. The buffers have a generic and extensible format; each
+ * buffer contains a standard header, a list of "tags", and a terminating zero
+ * entry. Each tag contains an ID indicating its type, and length fields for
+ * generic parsing. With some limitations, an arbitrary set of tags may be
+ * combined together into a single message buffer. This file defines structs
+ * representing the header and many individual tag layouts and IDs.
+ */
+
+/* Raw mailbox HW */
+
+#define BCM2835_MBOX_PHYSADDR  0x2000b880
+
+struct bcm2835_mbox_regs {
+       u32 read;
+       u32 rsvd0[5];
+       u32 status;
+       u32 config;
+       u32 write;
+};
+
+#define BCM2835_MBOX_STATUS_WR_FULL    0x80000000
+#define BCM2835_MBOX_STATUS_RD_EMPTY   0x40000000
+
+/* Lower 4-bits are channel ID */
+#define BCM2835_CHAN_MASK              0xf
+#define BCM2835_MBOX_PACK(chan, data)  (((data) & (~BCM2835_CHAN_MASK)) | \
+                                        (chan & BCM2835_CHAN_MASK))
+#define BCM2835_MBOX_UNPACK_CHAN(val)  ((val) & BCM2835_CHAN_MASK)
+#define BCM2835_MBOX_UNPACK_DATA(val)  ((val) & (~BCM2835_CHAN_MASK))
+
+/* Property mailbox buffer structures */
+
+#define BCM2835_MBOX_PROP_CHAN         8
+
+/* All message buffers must start with this header */
+struct bcm2835_mbox_hdr {
+       u32 buf_size;
+       u32 code;
+};
+
+#define BCM2835_MBOX_REQ_CODE          0
+#define BCM2835_MBOX_RESP_CODE_SUCCESS 0x80000000
+
+#define BCM2835_MBOX_INIT_HDR(_m_) { \
+               memset((_m_), 0, sizeof(*(_m_))); \
+               (_m_)->hdr.buf_size = sizeof(*(_m_)); \
+               (_m_)->hdr.code = 0; \
+               (_m_)->end_tag = 0; \
+       }
+
+/*
+ * A message buffer contains a list of tags. Each tag must also start with
+ * a standardized header.
+ */
+struct bcm2835_mbox_tag_hdr {
+       u32 tag;
+       u32 val_buf_size;
+       u32 val_len;
+};
+
+#define BCM2835_MBOX_INIT_TAG(_t_, _id_) { \
+               (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
+               (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
+               (_t_)->tag_hdr.val_len = sizeof((_t_)->body.req); \
+       }
+
+#define BCM2835_MBOX_INIT_TAG_NO_REQ(_t_, _id_) { \
+               (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
+               (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
+               (_t_)->tag_hdr.val_len = 0; \
+       }
+
+/* When responding, the VC sets this bit in val_len to indicate a response */
+#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE      0x80000000
+
+/*
+ * Below we define the ID and struct for many possible tags. This header only
+ * defines individual tag structs, not entire message structs, since in
+ * general an arbitrary set of tags may be combined into a single message.
+ * Clients of the mbox API are expected to define their own overall message
+ * structures by combining the header, a set of tags, and a terminating
+ * entry. For example,
+ *
+ * struct msg {
+ *     struct bcm2835_mbox_hdr hdr;
+ *     struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
+ *     ... perhaps other tags here ...
+ *     u32 end_tag;
+ * };
+ */
+
+#define BCM2835_MBOX_TAG_GET_ARM_MEMORY                0x00010005
+
+struct bcm2835_mbox_tag_get_arm_mem {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+                       u32 mem_base;
+                       u32 mem_size;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_CLOCK_RATE        0x00030002
+
+#define BCM2835_MBOX_CLOCK_ID_EMMC     1
+#define BCM2835_MBOX_CLOCK_ID_UART     2
+#define BCM2835_MBOX_CLOCK_ID_ARM      3
+#define BCM2835_MBOX_CLOCK_ID_CORE     4
+#define BCM2835_MBOX_CLOCK_ID_V3D      5
+#define BCM2835_MBOX_CLOCK_ID_H264     6
+#define BCM2835_MBOX_CLOCK_ID_ISP      7
+#define BCM2835_MBOX_CLOCK_ID_SDRAM    8
+#define BCM2835_MBOX_CLOCK_ID_PIXEL    9
+#define BCM2835_MBOX_CLOCK_ID_PWM      10
+
+struct bcm2835_mbox_tag_get_clock_rate {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       u32 clock_id;
+               } req;
+               struct {
+                       u32 clock_id;
+                       u32 rate_hz;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_ALLOCATE_BUFFER       0x00040001
+
+struct bcm2835_mbox_tag_allocate_buffer {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       u32 alignment;
+               } req;
+               struct {
+                       u32 fb_address;
+                       u32 fb_size;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_RELEASE_BUFFER                0x00048001
+
+struct bcm2835_mbox_tag_release_buffer {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_BLANK_SCREEN          0x00040002
+
+struct bcm2835_mbox_tag_blank_screen {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       /* bit 0 means on, other bots reserved */
+                       u32 state;
+               } req;
+               struct {
+                       u32 state;
+               } resp;
+       } body;
+};
+
+/* Physical means output signal */
+#define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H      0x00040003
+#define BCM2835_MBOX_TAG_TEST_PHYSICAL_W_H     0x00044003
+#define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H      0x00048003
+
+struct bcm2835_mbox_tag_physical_w_h {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 width;
+                       u32 height;
+               } req;
+               struct {
+                       u32 width;
+                       u32 height;
+               } resp;
+       } body;
+};
+
+/* Virtual means display buffer */
+#define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H       0x00040004
+#define BCM2835_MBOX_TAG_TEST_VIRTUAL_W_H      0x00044004
+#define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H       0x00048004
+
+struct bcm2835_mbox_tag_virtual_w_h {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 width;
+                       u32 height;
+               } req;
+               struct {
+                       u32 width;
+                       u32 height;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_DEPTH             0x00040005
+#define BCM2835_MBOX_TAG_TEST_DEPTH            0x00044005
+#define BCM2835_MBOX_TAG_SET_DEPTH             0x00048005
+
+struct bcm2835_mbox_tag_depth {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 bpp;
+               } req;
+               struct {
+                       u32 bpp;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PIXEL_ORDER       0x00040006
+#define BCM2835_MBOX_TAG_TEST_PIXEL_ORDER      0x00044005
+#define BCM2835_MBOX_TAG_SET_PIXEL_ORDER       0x00048006
+
+#define BCM2835_MBOX_PIXEL_ORDER_BGR           0
+#define BCM2835_MBOX_PIXEL_ORDER_RGB           1
+
+struct bcm2835_mbox_tag_pixel_order {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 order;
+               } req;
+               struct {
+                       u32 order;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_ALPHA_MODE                0x00040007
+#define BCM2835_MBOX_TAG_TEST_ALPHA_MODE       0x00044007
+#define BCM2835_MBOX_TAG_SET_ALPHA_MODE                0x00048007
+
+#define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE       0
+#define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT  1
+#define BCM2835_MBOX_ALPHA_MODE_IGNORED                2
+
+struct bcm2835_mbox_tag_alpha_mode {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 alpha;
+               } req;
+               struct {
+                       u32 alpha;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PITCH             0x00040008
+
+struct bcm2835_mbox_tag_pitch {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+                       u32 pitch;
+               } resp;
+       } body;
+};
+
+/* Offset of display window within buffer */
+#define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET    0x00040009
+#define BCM2835_MBOX_TAG_TEST_VIRTUAL_OFFSET   0x00044009
+#define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET    0x00048009
+
+struct bcm2835_mbox_tag_virtual_offset {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 x;
+                       u32 y;
+               } req;
+               struct {
+                       u32 x;
+                       u32 y;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_OVERSCAN          0x0004000a
+#define BCM2835_MBOX_TAG_TEST_OVERSCAN         0x0004400a
+#define BCM2835_MBOX_TAG_SET_OVERSCAN          0x0004800a
+
+struct bcm2835_mbox_tag_overscan {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               /* req not used for get */
+               struct {
+                       u32 top;
+                       u32 bottom;
+                       u32 left;
+                       u32 right;
+               } req;
+               struct {
+                       u32 top;
+                       u32 bottom;
+                       u32 left;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PALETTE           0x0004000b
+
+struct bcm2835_mbox_tag_get_palette {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+                       u32 data[1024];
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_TEST_PALETTE          0x0004400b
+
+struct bcm2835_mbox_tag_test_palette {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       u32 offset;
+                       u32 num_entries;
+                       u32 data[256];
+               } req;
+               struct {
+                       u32 is_invalid;
+               } resp;
+       } body;
+};
+
+#define BCM2835_MBOX_TAG_SET_PALETTE           0x0004800b
+
+struct bcm2835_mbox_tag_set_palette {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+                       u32 offset;
+                       u32 num_entries;
+                       u32 data[256];
+               } req;
+               struct {
+                       u32 is_invalid;
+               } resp;
+       } body;
+};
+
+/*
+ * Pass a raw u32 message to the VC, and receive a raw u32 back.
+ *
+ * Returns 0 for success, any other value for error.
+ */
+int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv);
+
+/*
+ * Pass a complete property-style buffer to the VC, and wait until it has
+ * been processed.
+ *
+ * This function expects a pointer to the mbox_hdr structure in an attempt
+ * to ensure some degree of type safety. However, some number of tags and
+ * a termination value are expected to immediately follow the header in
+ * memory, as required by the property protocol.
+ *
+ * Returns 0 for success, any other value for error.
+ */
+int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer);
+
+#endif
diff --git a/arch/arm/include/asm/arch-bcm2835/sdhci.h b/arch/arm/include/asm/arch-bcm2835/sdhci.h
new file mode 100644 (file)
index 0000000..a4f867b
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * 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
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef _BCM2835_SDHCI_H_
+#define _BCM2835_SDHCI_H_
+
+#define BCM2835_SDHCI_BASE 0x20300000
+
+int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq);
+
+#endif
index 30c70e03df467f60e93e71b5d66ba59877a681d8..c2001b6f932a4bb27ab19cb410f95ee083b0415d 100644 (file)
@@ -34,4 +34,6 @@ struct bcm2835_timer_regs {
 #define BCM2835_TIMER_CS_M1    (1 << 1)
 #define BCM2835_TIMER_CS_M0    (1 << 0)
 
+extern ulong get_timer_us(ulong base);
+
 #endif
index d2fdb598174172a9f5ddd5ed3c91dd704911f583..3549667d91844b5a757e7831d2df552d3ba4223c 100644 (file)
@@ -857,6 +857,9 @@ void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
 
 void set_usbhost_phy_ctrl(unsigned int enable);
 
+/* Enables hardware tripping to power off the system when TMU fails */
+void set_hw_thermal_trip(void);
+
 #define POWER_USB_HOST_PHY_CTRL_EN             (1 << 0)
 #define POWER_USB_HOST_PHY_CTRL_DISABLE                (0 << 0)
 
@@ -864,4 +867,25 @@ void set_dp_phy_ctrl(unsigned int enable);
 
 #define EXYNOS_DP_PHY_ENABLE           (1 << 0)
 
+#define EXYNOS_PS_HOLD_CONTROL_DATA_HIGH       (1 << 8)
+#define POWER_ENABLE_HW_TRIP                   (1UL << 31)
+
+/*
+ * Set ps_hold data driving value high
+ * This enables the machine to stay powered on
+ * after the initial power-on condition goes away
+ * (e.g. power button).
+ */
+void set_ps_hold_ctrl(void);
+
+/* PMU_DEBUG bits [12:8] = 0x1000 selects XXTI clock source */
+#define PMU_DEBUG_XXTI                          0x1000
+/* Mask bit[12:8] for xxti clock selection */
+#define PMU_DEBUG_CLKOUT_SEL_MASK               0x1f00
+
+/*
+ * Pmu debug is used for xclkout, enable xclkout with
+ * source as XXTI
+ */
+void set_xclkout(void);
 #endif
index 306b41d8256a8f7626773f930b4bdbc520a90bba..46b25a608ba1f96007e15655fec3e593dfe036f8 100644 (file)
@@ -78,11 +78,12 @@ struct spl_machine_param {
         */
        u32             uboot_size;
        enum boot_mode  boot_source;    /* Boot device */
-       enum mem_manuf  mem_manuf;      /* Memory Manufacturer */
        unsigned        frequency_mhz;  /* Frequency of memory in MHz */
        unsigned        arm_freq_mhz;   /* ARM Frequency in MHz */
        u32             serial_base;    /* Serial base address */
        u32             i2c_base;       /* i2c base address */
+       u32             board_rev_gpios;        /* Board revision GPIOs */
+       enum mem_manuf  mem_manuf;      /* Memory Manufacturer */
 } __attribute__((__packed__));
 #endif
 
diff --git a/arch/arm/include/asm/arch-exynos/tmu.h b/arch/arm/include/asm/arch-exynos/tmu.h
new file mode 100644 (file)
index 0000000..7e0158e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *      http://www.samsung.com
+ * Akshay Saraswat <akshay.s@samsung.com>
+ *
+ * EXYNOS - Thermal Management Unit
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ * 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 __ASM_ARCH_TMU_H
+#define __ASM_ARCH_TMU_H
+
+struct exynos5_tmu_reg {
+       unsigned triminfo;
+       unsigned rsvd1;
+       unsigned rsvd2;
+       unsigned rsvd3;
+       unsigned rsvd4;
+       unsigned triminfo_control;
+       unsigned rsvd5;
+       unsigned rsvd6;
+       unsigned tmu_control;
+       unsigned rsvd7;
+       unsigned tmu_status;
+       unsigned sampling_internal;
+       unsigned counter_value0;
+       unsigned counter_value1;
+       unsigned rsvd8;
+       unsigned rsvd9;
+       unsigned current_temp;
+       unsigned rsvd10;
+       unsigned rsvd11;
+       unsigned rsvd12;
+       unsigned threshold_temp_rise;
+       unsigned threshold_temp_fall;
+       unsigned rsvd13;
+       unsigned rsvd14;
+       unsigned past_temp3_0;
+       unsigned past_temp7_4;
+       unsigned past_temp11_8;
+       unsigned past_temp15_12;
+       unsigned inten;
+       unsigned intstat;
+       unsigned intclear;
+       unsigned rsvd15;
+       unsigned emul_con;
+};
+#endif /* __ASM_ARCH_TMU_H */
index 3db0d93b89a31dd60ac0464f0fea6d7fd7fe67c6..1a6699096b1682e843c0dead3a393f379d51e261 100644 (file)
@@ -25,8 +25,7 @@
 #define _TEGRA_BOARD_H_
 
 /* Set up pinmux to make UART usable */
-void gpio_config_uart(void);      /* CONFIG_SPI_UART_SWITCH */
-void gpio_early_init_uart(void);  /*!CONFIG_SPI_UART_SWITCH */
+void gpio_early_init_uart(void);
 
 /* Set up early UART output */
 void board_init_uart_f(void);
diff --git a/arch/arm/include/asm/arch-tegra/tegra_slink.h b/arch/arm/include/asm/arch-tegra/tegra_slink.h
deleted file mode 100644 (file)
index 74804b5..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * NVIDIA Tegra SPI-SLINK controller
- *
- * Copyright 2010-2013 NVIDIA Corporation
- *
- * This software may be used and distributed according to the
- * terms of the GNU Public License, Version 2, incorporated
- * herein by reference.
- *
- * 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 published by the Free Software Foundation.
- *
- * 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 _TEGRA_SLINK_H_
-#define _TEGRA_SLINK_H_
-
-#include <asm/types.h>
-
-struct slink_tegra {
-       u32 command;    /* SLINK_COMMAND_0 register  */
-       u32 command2;   /* SLINK_COMMAND2_0 reg */
-       u32 status;     /* SLINK_STATUS_0 register */
-       u32 reserved;   /* Reserved offset 0C */
-       u32 mas_data;   /* SLINK_MAS_DATA_0 reg */
-       u32 slav_data;  /* SLINK_SLAVE_DATA_0 reg */
-       u32 dma_ctl;    /* SLINK_DMA_CTL_0 register */
-       u32 status2;    /* SLINK_STATUS2_0 reg */
-       u32 rsvd[56];   /* 0x20 to 0xFF reserved */
-       u32 tx_fifo;    /* SLINK_TX_FIFO_0 reg off 100h */
-       u32 rsvd2[31];  /* 0x104 to 0x17F reserved */
-       u32 rx_fifo;    /* SLINK_RX_FIFO_0 reg off 180h */
-};
-
-/* COMMAND */
-#define SLINK_CMD_ENB                  (1 << 31)
-#define SLINK_CMD_GO                   (1 << 30)
-#define SLINK_CMD_M_S                  (1 << 28)
-#define SLINK_CMD_CK_SDA               (1 << 21)
-#define SLINK_CMD_CS_POL               (1 << 13)
-#define SLINK_CMD_CS_VAL               (1 << 12)
-#define SLINK_CMD_CS_SOFT              (1 << 11)
-#define SLINK_CMD_BIT_LENGTH           (1 << 4)
-#define SLINK_CMD_BIT_LENGTH_MASK      0x0000001F
-/* COMMAND2 */
-#define SLINK_CMD2_TXEN                        (1 << 30)
-#define SLINK_CMD2_RXEN                        (1 << 31)
-#define SLINK_CMD2_SS_EN               (1 << 18)
-#define SLINK_CMD2_SS_EN_SHIFT         18
-#define SLINK_CMD2_SS_EN_MASK          0x000C0000
-#define SLINK_CMD2_CS_ACTIVE_BETWEEN   (1 << 17)
-/* STATUS */
-#define SLINK_STAT_BSY                 (1 << 31)
-#define SLINK_STAT_RDY                 (1 << 30)
-#define SLINK_STAT_ERR                 (1 << 29)
-#define SLINK_STAT_RXF_FLUSH           (1 << 27)
-#define SLINK_STAT_TXF_FLUSH           (1 << 26)
-#define SLINK_STAT_RXF_OVF             (1 << 25)
-#define SLINK_STAT_TXF_UNR             (1 << 24)
-#define SLINK_STAT_RXF_EMPTY           (1 << 23)
-#define SLINK_STAT_RXF_FULL            (1 << 22)
-#define SLINK_STAT_TXF_EMPTY           (1 << 21)
-#define SLINK_STAT_TXF_FULL            (1 << 20)
-#define SLINK_STAT_TXF_OVF             (1 << 19)
-#define SLINK_STAT_RXF_UNR             (1 << 18)
-#define SLINK_STAT_CUR_BLKCNT          (1 << 15)
-/* STATUS2 */
-#define SLINK_STAT2_RXF_FULL_CNT       (1 << 16)
-#define SLINK_STAT2_TXF_FULL_CNT       (1 << 0)
-
-#define SPI_TIMEOUT            1000
-#define TEGRA_SPI_MAX_FREQ     52000000
-
-#endif /* _TEGRA_SLINK_H_ */
diff --git a/arch/arm/include/asm/arch-tegra/tegra_spi.h b/arch/arm/include/asm/arch-tegra/tegra_spi.h
deleted file mode 100644 (file)
index d53a93f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * NVIDIA Tegra20 SPI-FLASH controller
- *
- * Copyright 2010-2012 NVIDIA Corporation
- *
- * This software may be used and distributed according to the
- * terms of the GNU Public License, Version 2, incorporated
- * herein by reference.
- *
- * 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 published by the Free Software Foundation.
- *
- * 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 _TEGRA_SPI_H_
-#define _TEGRA_SPI_H_
-
-#include <asm/types.h>
-
-struct spi_tegra {
-       u32 command;    /* SPI_COMMAND_0 register  */
-       u32 status;     /* SPI_STATUS_0 register */
-       u32 rx_cmp;     /* SPI_RX_CMP_0 register  */
-       u32 dma_ctl;    /* SPI_DMA_CTL_0 register */
-       u32 tx_fifo;    /* SPI_TX_FIFO_0 register */
-       u32 rsvd[3];    /* offsets 0x14 to 0x1F reserved */
-       u32 rx_fifo;    /* SPI_RX_FIFO_0 register */
-};
-
-#define SPI_CMD_GO                     (1 << 30)
-#define SPI_CMD_ACTIVE_SCLK_SHIFT      26
-#define SPI_CMD_ACTIVE_SCLK_MASK       (3 << SPI_CMD_ACTIVE_SCLK_SHIFT)
-#define SPI_CMD_CK_SDA                 (1 << 21)
-#define SPI_CMD_ACTIVE_SDA_SHIFT       18
-#define SPI_CMD_ACTIVE_SDA_MASK                (3 << SPI_CMD_ACTIVE_SDA_SHIFT)
-#define SPI_CMD_CS_POL                 (1 << 16)
-#define SPI_CMD_TXEN                   (1 << 15)
-#define SPI_CMD_RXEN                   (1 << 14)
-#define SPI_CMD_CS_VAL                 (1 << 13)
-#define SPI_CMD_CS_SOFT                        (1 << 12)
-#define SPI_CMD_CS_DELAY               (1 << 9)
-#define SPI_CMD_CS3_EN                 (1 << 8)
-#define SPI_CMD_CS2_EN                 (1 << 7)
-#define SPI_CMD_CS1_EN                 (1 << 6)
-#define SPI_CMD_CS0_EN                 (1 << 5)
-#define SPI_CMD_BIT_LENGTH             (1 << 4)
-#define SPI_CMD_BIT_LENGTH_MASK                0x0000001F
-
-#define SPI_STAT_BSY                   (1 << 31)
-#define SPI_STAT_RDY                   (1 << 30)
-#define SPI_STAT_RXF_FLUSH             (1 << 29)
-#define SPI_STAT_TXF_FLUSH             (1 << 28)
-#define SPI_STAT_RXF_UNR               (1 << 27)
-#define SPI_STAT_TXF_OVF               (1 << 26)
-#define SPI_STAT_RXF_EMPTY             (1 << 25)
-#define SPI_STAT_RXF_FULL              (1 << 24)
-#define SPI_STAT_TXF_EMPTY             (1 << 23)
-#define SPI_STAT_TXF_FULL              (1 << 22)
-#define SPI_STAT_SEL_TXRX_N            (1 << 16)
-#define SPI_STAT_CUR_BLKCNT            (1 << 15)
-
-#define SPI_TIMEOUT            1000
-#define TEGRA_SPI_MAX_FREQ     52000000
-
-#endif /* _TEGRA_SPI_H_ */
index 1ef1a1484df61f1457dbca7f0e2af7d124e23a57..41ce67780754278fac4e92e53376aa0aed32c4ee 100644 (file)
@@ -74,4 +74,10 @@ struct apb_misc_gp_ctlr {
        u32     aocfg0;         /* 0x1AC: APB_MISC_GP_AOCFG0PADCTRL */
 };
 
+/* SDMMC1/3 settings from section 27.5 of T114 TRM */
+#define SDIOCFG_DRVUP_SLWF     0
+#define SDIOCFG_DRVDN_SLWR     0
+#define SDIOCFG_DRVUP          0x24
+#define SDIOCFG_DRVDN          0x14
+
 #endif /* _TEGRA114_GP_PADCTRL_H_ */
diff --git a/arch/arm/include/asm/arch-tegra114/tegra114_spi.h b/arch/arm/include/asm/arch-tegra114/tegra114_spi.h
new file mode 100644 (file)
index 0000000..48197bc
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * NVIDIA Tegra SPI controller
+ *
+ * Copyright 2010-2013 NVIDIA Corporation
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * 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 published by the Free Software Foundation.
+ *
+ * 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 _TEGRA114_SPI_H_
+#define _TEGRA114_SPI_H_
+
+#include <asm/types.h>
+
+int tegra114_spi_init(int *node_list, int count);
+int tegra114_spi_cs_is_valid(unsigned int bus, unsigned int cs);
+struct spi_slave *tegra114_spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode);
+void tegra114_spi_free_slave(struct spi_slave *slave);
+int tegra114_spi_claim_bus(struct spi_slave *slave);
+void tegra114_spi_cs_activate(struct spi_slave *slave);
+void tegra114_spi_cs_deactivate(struct spi_slave *slave);
+int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+                    const void *data_out, void *data_in, unsigned long flags);
+
+#endif /* _TEGRA114_SPI_H_ */
diff --git a/arch/arm/include/asm/arch-tegra20/tegra20_sflash.h b/arch/arm/include/asm/arch-tegra20/tegra20_sflash.h
new file mode 100644 (file)
index 0000000..e8cc68c
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * NVIDIA Tegra20 SPI-FLASH controller
+ *
+ * Copyright 2010-2012 NVIDIA Corporation
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * 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 published by the Free Software Foundation.
+ *
+ * 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 _TEGRA20_SPI_H_
+#define _TEGRA20_SPI_H_
+
+#include <asm/types.h>
+
+int tegra20_spi_cs_is_valid(unsigned int bus, unsigned int cs);
+struct spi_slave *tegra20_spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode);
+void tegra20_spi_free_slave(struct spi_slave *slave);
+int tegra20_spi_init(int *node_list, int count);
+int tegra20_spi_claim_bus(struct spi_slave *slave);
+void tegra20_spi_cs_activate(struct spi_slave *slave);
+void tegra20_spi_cs_deactivate(struct spi_slave *slave);
+int tegra20_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+            const void *data_out, void *data_in, unsigned long flags);
+
+#endif /* _TEGRA20_SPI_H_ */
diff --git a/arch/arm/include/asm/arch-tegra20/tegra20_slink.h b/arch/arm/include/asm/arch-tegra20/tegra20_slink.h
new file mode 100644 (file)
index 0000000..5aa74dd
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * NVIDIA Tegra SPI-SLINK controller
+ *
+ * Copyright 2010-2013 NVIDIA Corporation
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * 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 published by the Free Software Foundation.
+ *
+ * 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 _TEGRA30_SPI_H_
+#define _TEGRA30_SPI_H_
+
+#include <asm/types.h>
+
+int tegra30_spi_init(int *node_list, int count);
+int tegra30_spi_cs_is_valid(unsigned int bus, unsigned int cs);
+struct spi_slave *tegra30_spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode);
+void tegra30_spi_free_slave(struct spi_slave *slave);
+int tegra30_spi_claim_bus(struct spi_slave *slave);
+void tegra30_spi_cs_activate(struct spi_slave *slave);
+void tegra30_spi_cs_deactivate(struct spi_slave *slave);
+int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+                    const void *data_out, void *data_in, unsigned long flags);
+
+#endif /* _TEGRA30_SPI_H_ */
index eef6a5a8f23c84722a4c72c1270b9004f5c59283..8153484899106f456b1cf928307cc4cae4453012 100644 (file)
@@ -41,7 +41,9 @@ static inline void invalidate_l2_cache(void)
 
 void l2_cache_enable(void);
 void l2_cache_disable(void);
+void set_section_dcache(int section, enum dcache_option option);
 
+void dram_bank_mmu_setup(int bank);
 /*
  * The current upper bound for ARM L1 data cache line sizes is 64 bytes.  We
  * use that value for aligning DMA buffers unless the board config has specified
similarity index 70%
rename from board/pcippc2/i2c.h
rename to arch/arm/include/asm/sections.h
index 1224b428993264b74779c135200a27f738e1a9a7..c042cb604b995dc9bee7abbec0ff0b8309400397 100644 (file)
@@ -1,7 +1,5 @@
 /*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
+ * Copyright (c) 2012 The Chromium OS Authors.
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -12,7 +10,7 @@
  *
  * 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
+ * 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
  * MA 02111-1307 USA
  */
 
-#ifndef _I2C_H_
-#define _I2C_H_
-
-#include <common.h>
-
-extern int     i2c_read_byte   (u8 *           data,
-                                u8             dev,
-                                u8 offset);
-
-extern unsigned int i2c_reset (void);
+#ifndef __ASM_ARM_SECTIONS_H
+#define __ASM_ARM_SECTIONS_H
 
+#include <asm-generic/sections.h>
 
 #endif
index 62011aaada411fdfbb9fe5af857df23f421633d6..2b7218edad2c222c1b4bf03ce973696a61a8f6fd 100644 (file)
@@ -27,7 +27,7 @@
 #include <asm/arch/spl.h>
 
 /* Linker symbols. */
-extern char __bss_start[], __bss_end__[];
+extern char __bss_start[], __bss_end[];
 
 extern gd_t gdata;
 
index 1918492eaed7e6f19845a283d78ab6341446b038..760345f847fd711f916ba5ac4bacffeeaf424a49 100644 (file)
@@ -81,6 +81,20 @@ static inline void set_cr(unsigned int val)
        isb();
 }
 
+static inline unsigned int get_dacr(void)
+{
+       unsigned int val;
+       asm("mrc p15, 0, %0, c3, c0, 0  @ get DACR" : "=r" (val) : : "cc");
+       return val;
+}
+
+static inline void set_dacr(unsigned int val)
+{
+       asm volatile("mcr p15, 0, %0, c3, c0, 0 @ set DACR"
+         : : "r" (val) : "cc");
+       isb();
+}
+
 /* options available for data cache on each page */
 enum dcache_option {
        DCACHE_OFF = 0x12,
index 9f3cae5ece49dda74466f840a1792f4930b978b2..f16861ad2f7f64899ae006c948471b9fa24598f2 100644 (file)
 #define _U_BOOT_ARM_H_ 1
 
 /* for the following variables, see start.S */
-extern ulong _bss_start_ofs;   /* BSS start relative to _start */
-extern ulong _bss_end_ofs;             /* BSS end relative to _start */
-extern ulong _end_ofs;         /* end of image relative to _start */
 extern ulong IRQ_STACK_START;  /* top of IRQ stack */
 extern ulong FIQ_STACK_START;  /* top of FIQ stack */
-extern ulong _TEXT_BASE;       /* code start */
 extern ulong _datarel_start_ofs;
 extern ulong _datarelrolocal_start_ofs;
 extern ulong _datarellocal_start_ofs;
index 2ba98bca7da953e8493205bb806aa5c0a6af44fe..a33fefa6d4e89c8011a7e0e750fed64b8d0c3d78 100644 (file)
 #ifndef _U_BOOT_H_
 #define _U_BOOT_H_     1
 
+#ifdef CONFIG_SYS_GENERIC_BOARD
+/* Use the generic board which requires a unified bd_info */
+#include <asm-generic/u-boot.h>
+#else
+
+#ifndef __ASSEMBLY__
 typedef struct bd_info {
        unsigned int    bi_baudrate;    /* serial console baudrate */
     ulong              bi_arch_number; /* unique id for this board */
@@ -49,6 +55,9 @@ typedef struct bd_info {
        ulong size;
     }                  bi_dram[CONFIG_NR_DRAM_BANKS];
 } bd_t;
+#endif
+
+#endif /* !CONFIG_SYS_GENERIC_BOARD */
 
 /* For image.h:image_check_target_arch() */
 #define IH_ARCH_DEFAULT IH_ARCH_ARM
index 11c267451afaedfb4fdeb6b34763621416605455..6ae161a51dc147327925c158f31e845ba74b75ca 100644 (file)
@@ -39,8 +39,11 @@ GLCOBJS      += div0.o
 SOBJS-y += crt0.o
 
 ifndef CONFIG_SPL_BUILD
-COBJS-y += bss.o
+ifndef CONFIG_SYS_GENERIC_BOARD
 COBJS-y        += board.o
+endif
+COBJS-y += bss.o
+
 COBJS-y        += bootm.o
 COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
 SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o
index 162e2cc86385df0f7489eef0ae2ac00c3be12fc9..0521178ac3c9bb66c10bcadaae00ea9ef6555ec8 100644 (file)
@@ -53,6 +53,7 @@
 #include <fdtdec.h>
 #include <post.h>
 #include <logbuff.h>
+#include <asm/sections.h>
 
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
index 7c0b1545ea0687116911e9a3400c72c9354c1288..99eda5913760eab77955559bb9b56c453a9e1518 100644 (file)
@@ -36,4 +36,4 @@
  */
 
 char __bss_start[0] __attribute__((used, section(".__bss_start")));
-char __bss_end__[0] __attribute__((used, section(".__bss_end__")));
+char __bss_end[0] __attribute__((used, section(".__bss_end")));
index b6e5e95530b3793f0be70289eb53ed7207cb305b..4abe1cf061a879d65170ad8c6697d9c9e1954751 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <common.h>
 #include <asm/system.h>
+#include <asm/cache.h>
+#include <linux/compiler.h>
 
 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
 
@@ -34,6 +36,10 @@ void __arm_init_before_mmu(void)
 void arm_init_before_mmu(void)
        __attribute__((weak, alias("__arm_init_before_mmu")));
 
+__weak void arm_init_domains(void)
+{
+}
+
 static void cp_delay (void)
 {
        volatile int i;
@@ -77,7 +83,7 @@ void mmu_set_region_dcache_behaviour(u32 start, int size,
        mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
 }
 
-static inline void dram_bank_mmu_setup(int bank)
+__weak void dram_bank_mmu_setup(int bank)
 {
        bd_t *bd = gd->bd;
        int     i;
@@ -115,6 +121,9 @@ static inline void mmu_setup(void)
        /* Set the access control to all-supervisor */
        asm volatile("mcr p15, 0, %0, c3, c0, 0"
                     : : "r" (~0));
+
+       arm_init_domains();
+
        /* and enable the mmu */
        reg = get_cr(); /* get control reg. */
        cp_delay();
index 4f60958b1dbf1782863cebd7ffe884733a452b26..37d9927d2ca329f11b929a3e7ca6f2cf87cca106 100644 (file)
@@ -85,7 +85,7 @@
  */
 
 .globl __bss_start
-.globl __bss_end__
+.globl __bss_end
 
 /*
  * entry point of crt0 sequence
@@ -141,7 +141,7 @@ here:
        bl      c_runtime_cpu_setup     /* we still call old routine here */
 
        ldr     r0, =__bss_start        /* this is auto-relocated! */
-       ldr     r1, =__bss_end__        /* this is auto-relocated! */
+       ldr     r1, =__bss_end          /* this is auto-relocated! */
 
        mov     r2, #0x00000000         /* prepare zero to clear BSS */
 
index f568f619cb0c8f58eab91178ba68accda845ef41..301f082ea3e877c4e186909105e96362d26d60e2 100644 (file)
@@ -45,7 +45,7 @@ void __weak board_init_f(ulong dummy)
        asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK));
 
        /* Clear the BSS. */
-       memset(__bss_start, 0, __bss_end__ - __bss_start);
+       memset(__bss_start, 0, __bss_end - __bss_start);
 
        /* Set global data pointer. */
        gd = &gdata;
index 71cbc524c90d4692bc1bf06b17560ba9e0a7c25a..c8decea127c7b925afa608a586fbe8dd964e9db3 100644 (file)
@@ -244,7 +244,7 @@ relocate_code:
        /* zero out .bss */
        mov     r0, 0
        mov     r1, 0
-       lda.w   r9, __bss_end__
+       lda.w   r9, __bss_end
        sub     r9, r8
 1:     st.d    r10++, r0
        sub     r9, 8
index 4a3fc2a1c65d7cb6a58d77155708f187d3ee5b93..4e4a436dc9ca669adad60bb4816e66508475be7d 100644 (file)
@@ -68,5 +68,5 @@ SECTIONS
                *(.bss.*)
        }
        . = ALIGN(8);
-       __bss_end__ = .;
+       __bss_end = .;
 }
index 3f157888ee8c773299a990a33fd2093f88cb4d62..056d7a05d5ef5840283413bb6dec7955441eede4 100644 (file)
 #ifndef __ASM_AVR32_SECTIONS_H
 #define __ASM_AVR32_SECTIONS_H
 
+#include <asm-generic/sections.h>
+
 /* References to section boundaries */
 
-extern char _text[], _etext[];
-extern char _data[], __data_lma[], _edata[], __edata_lma[];
+extern char __data_lma[], __edata_lma[];
 extern char __got_start[], __got_lma[], __got_end[];
-extern char __bss_end__[];
 
 #endif /* __ASM_AVR32_SECTIONS_H */
index bd1be73ae4cc3a87c9f7bfec2e2e57e14738bfa0..57e07dfb89b7fd63d19efe386fad4694182cdc75 100644 (file)
@@ -116,7 +116,7 @@ static int display_banner (void)
        printf ("\n\n%s\n\n", version_string);
        printf ("U-Boot code: %08lx -> %08lx  data: %08lx -> %08lx\n",
                (unsigned long)_text, (unsigned long)_etext,
-               (unsigned long)_data, (unsigned long)__bss_end__);
+               (unsigned long)_data, (unsigned long)__bss_end);
        return 0;
 }
 
@@ -188,7 +188,7 @@ void board_init_f(ulong board_type)
         *  - stack
         */
        addr = CONFIG_SYS_SDRAM_BASE + sdram_size;
-       monitor_len = __bss_end__ - _text;
+       monitor_len = (char *)__bss_end - _text;
 
        /*
         * Reserve memory for u-boot code, data and bss.
@@ -211,11 +211,11 @@ void board_init_f(ulong board_type)
 #ifdef CONFIG_FB_ADDR
        printf("LCD: Frame buffer allocated at preset 0x%08x\n",
               CONFIG_FB_ADDR);
-       gd->fb_base = (void *)CONFIG_FB_ADDR;
+       gd->fb_base = CONFIG_FB_ADDR;
 #else
        addr = lcd_setmem(addr);
        printf("LCD: Frame buffer allocated at 0x%08lx\n", addr);
-       gd->fb_base = (void *)addr;
+       gd->fb_base = addr;
 #endif /* CONFIG_FB_ADDR */
 #endif /* CONFIG_LCD */
 
index b9fdb078bdd6e14319f150bd6bc67c2761ba8d4e..0be2e2b835b23ab5c9cded732588faffd231f8d9 100644 (file)
@@ -23,7 +23,6 @@
 
 ulong bfin_poweron_retx;
 
-__attribute__ ((__noreturn__))
 void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
 {
 #ifndef CONFIG_BFIN_BOOTROM_USES_EVT1
index c2c4d4d41dfd7d699e5f1a3c7e8789ef6c30bec8..44245b4a1b2fb4c83697a2b2819171421ca95071 100644 (file)
@@ -32,6 +32,7 @@
 
 /* Architecture-specific global data */
 struct arch_global_data {
+       unsigned long board_type;
 };
 
 #include <asm-generic/global_data.h>
similarity index 66%
rename from board/pcippc2/fpga_serial.h
rename to arch/blackfin/include/asm/sections.h
index 106fbf7a500cfb0b0299827aa2ddb84751227372..85af42c321b9e63d278f19b5fa80fe77ceef0369 100644 (file)
@@ -1,7 +1,5 @@
 /*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
+ * Copyright (c) 2012 The Chromium OS Authors.
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -12,7 +10,7 @@
  *
  * 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
+ * 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
  * MA 02111-1307 USA
  */
 
-#ifndef _FPGA_SERIAL_H_
-#define _FPGA_SERIAL_H_
+#ifndef __ASM_BLACKFIN_SECTIONS_H
+#define __ASM_BLACKFIN_SECTIONS_H
 
-extern void    fpga_serial_init        (int);
-extern void    fpga_serial_putc        (char);
-extern int     fpga_serial_getc        (void);
-extern int     fpga_serial_tstc        (void);
-extern void    fpga_serial_setbrg      (void);
+#include <asm-generic/sections.h>
 
 #endif
index 288dc829d4d64567f10ee3e23948ec3d5727a401..75b6c463d87ba0348af947a5a1466a51c94aae4b 100644 (file)
@@ -77,7 +77,7 @@ static void display_global_data(void)
        bd = gd->bd;
        printf(" gd: %p\n", gd);
        printf(" |-flags: %lx\n", gd->flags);
-       printf(" |-board_type: %lx\n", gd->board_type);
+       printf(" |-board_type: %lx\n", gd->arch.board_type);
        printf(" |-baudrate: %u\n", gd->baudrate);
        printf(" |-have_console: %lx\n", gd->have_console);
        printf(" |-ram_size: %lx\n", gd->ram_size);
similarity index 59%
rename from board/pcippc2/ns16550.h
rename to arch/m68k/include/asm/sections.h
index 7023f13a35bc2c481509641fb47e2c878cfc380f..92289878e11df3759126a01866d0873c2d728e8d 100644 (file)
@@ -1,7 +1,5 @@
 /*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
+ * Copyright (c) 2012 The Chromium OS Authors.
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -12,7 +10,7 @@
  *
  * 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
+ * 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
  * MA 02111-1307 USA
  */
 
-#ifndef _NS16550_H_
-#define _NS16550_H_
-
-#define NS16550_RBR    0x00
-#define NS16550_IER    0x01
-#define NS16550_FCR    0x02
-#define NS16550_LCR    0x03
-#define NS16550_MCR    0x04
-#define NS16550_LSR    0x05
-#define NS16550_MSR    0x06
-#define NS16550_SCR    0x07
+#ifndef __ASM_M68K_SECTIONS_H
+#define __ASM_M68K_SECTIONS_H
 
-#define NS16550_THR    NS16550_RBR
-#define NS16550_IIR    NS16550_FCR
-#define NS16550_DLL    NS16550_RBR
-#define NS16550_DLM    NS16550_IER
+#include <asm-generic/sections.h>
 
 #endif
index 33acffe4316a7d1ff7b40cc6b84eb121636ae983..adaccfe69eee08db5328950b577feebe4bfaa720 100644 (file)
@@ -77,9 +77,10 @@ static char *failed = "*** failed ***\n";
 #include <environment.h>
 
 extern ulong __init_end;
-extern ulong __bss_end__;
+extern ulong __bss_end;
 
 #if defined(CONFIG_WATCHDOG)
+# undef INIT_FUNC_WATCHDOG_INIT
 # define INIT_FUNC_WATCHDOG_INIT       watchdog_init,
 # define WATCHDOG_DISABLE              watchdog_disable
 
@@ -244,7 +245,7 @@ board_init_f (ulong bootflag)
         *      - monitor code
         *      - board info struct
         */
-       len = (ulong)&__bss_end__ - CONFIG_SYS_MONITOR_BASE;
+       len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
 
        addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
 
similarity index 50%
rename from board/pcippc2/sconsole.h
rename to arch/microblaze/include/asm/sections.h
index ff0ccabcdbd4aab11e58ef1093389844e5142424..156c149159d70116d73d56a4f3b765cef438b519 100644 (file)
@@ -1,7 +1,5 @@
 /*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
+ * Copyright (c) 2012 The Chromium OS Authors.
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -12,7 +10,7 @@
  *
  * 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
+ * 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
  * MA 02111-1307 USA
  */
 
-#ifndef _SCONSOLE_H_
-#define _SCONSOLE_H_
-
-#include <config.h>
-
-typedef struct sconsole_buffer_s {
-       unsigned long size;
-       unsigned long max_size;
-       unsigned long pos;
-       unsigned long baud;
-       char data[1];
-} sconsole_buffer_t;
-
-#define SCONSOLE_BUFFER                ((sconsole_buffer_t *) CONFIG_SYS_SCONSOLE_ADDR)
-
-extern void    (* sconsole_putc)       (char);
-extern void    (* sconsole_puts)       (const char *);
-extern int     (* sconsole_getc)       (void);
-extern int     (* sconsole_tstc)       (void);
-extern void    (* sconsole_setbrg)     (void);
+#ifndef __ASM_MICROBLAZE_SECTIONS_H
+#define __ASM_MICROBLAZE_SECTIONS_H
 
-extern void    sconsole_flush          (void);
-extern int     sconsole_get_baudrate   (void);
+#include <asm-generic/sections.h>
 
 #endif
diff --git a/arch/mips/include/asm/sections.h b/arch/mips/include/asm/sections.h
new file mode 100644 (file)
index 0000000..54cd8b3
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * 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 __ASM_MIPS_SECTIONS_H
+#define __ASM_MIPS_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif
index a483166a9c992eeca804fa03f3b31f226b2c803c..e77636eaaf67b46e20cd6b3b26f6e5716dde3a54 100644 (file)
@@ -7,7 +7,7 @@
 
 static inline unsigned long bss_start(void)
 {
-       extern ulong __bss_start;
+       extern char __bss_start[];
        return (unsigned long) &__bss_start;
 }
 
@@ -19,7 +19,7 @@ static inline unsigned long bss_end(void)
 
 static inline unsigned long image_copy_end(void)
 {
-       extern ulong __image_copy_end;
+       extern char __image_copy_end[];
        return (unsigned long) &__image_copy_end;
 }
 
index 889bf8b87101723f73457e35370a249ad8fc75fb..558fd0ee6cb478512070cc385606cb45350240c4 100644 (file)
@@ -240,7 +240,7 @@ fix_got_loop:
 clear_bss:
        la      $r0, __bss_start        /* r0 <- rel __bss_start in FLASH */
        add     $r0, $r0, $r9           /* r0 <- rel __bss_start in FLASH */
-       la      $r1, __bss_end__        /* r1 <- rel __bss_end in RAM */
+       la      $r1, __bss_end          /* r1 <- rel __bss_end in RAM */
        add     $r1, $r1, $r9           /* r0 <- rel __bss_end in RAM */
        li      $r2, 0x00000000         /* clear */
 
index 57909481a968e03f2ed0acbef435eafe23352363..e9fbcd380469b6cf8d68f7cfec60766bc1ae0ffd 100644 (file)
@@ -66,7 +66,7 @@ SECTIONS
                __bss_start = .;
                *(.bss)
                 . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        }
 
 }
diff --git a/arch/nds32/include/asm/sections.h b/arch/nds32/include/asm/sections.h
new file mode 100644 (file)
index 0000000..a65735e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * 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 __ASM_NDS32_SECTIONS_H
+#define __ASM_NDS32_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif
index ae1918d5d47c985e727537e19a1fb10e88dcaca4..f3c7b271e97ba20c78d9107f9dde1e5d3436cfe7 100644 (file)
 #define _U_BOOT_NDS32_H_       1
 
 /* for the following variables, see start.S */
-extern ulong __bss_start;      /* BSS start relative to _start */
-extern ulong __bss_end__;      /* BSS end relative to _start */
-extern ulong _end;             /* end of image relative to _start */
-extern ulong _start;           /* start of image relative to _start */
+extern char __bss_start[];     /* BSS start relative to _start */
+extern ulong __bss_end;                /* BSS end relative to _start */
+extern char _end[];            /* end of image relative to _start */
+extern void _start(void);      /* start of image relative to _start */
 extern ulong _TEXT_BASE;       /* code start */
 extern ulong IRQ_STACK_START;  /* top of IRQ stack */
 extern ulong FIQ_STACK_START;  /* top of FIQ stack */
index c919928a371620ca156e8a92d06f3db11d1f6e88..a7d27fc7f8e78ec43ef635f181e84e5209cf16e1 100644 (file)
@@ -192,7 +192,7 @@ void board_init_f(ulong bootflag)
 
        memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
-       gd->mon_len = (unsigned int)(&__bss_end__) - (unsigned int)(&_start);
+       gd->mon_len = (unsigned int)(&__bss_end) - (unsigned int)(&_start);
 
        for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
                if ((*init_fnc_ptr)() != 0)
index 0f4ab286b925d19f87cca0247fd7aaae4d059215..1787b65874a3cfe0b67e172ab48b4ea182575a19 100644 (file)
@@ -99,12 +99,12 @@ _cur:       movhi   r5, %hi(_cur - _start)
 3:
 
        /* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
-        * and between __bss_start and __bss_end__.
+        * and between __bss_start and __bss_end.
         */
         movhi  r5, %hi(__bss_start)
         ori    r5, r5, %lo(__bss_start)
-        movhi  r6, %hi(__bss_end__)
-        ori    r6, r6, %lo(__bss_end__)
+        movhi  r6, %hi(__bss_end)
+        ori    r6, r6, %lo(__bss_end)
         beq    r5, r6, 5f
 
 4:     stwio   r0, 0(r5)
index f937396233edadf16a5eec49170fbff15fdb6c77..4c45336d4ae40536f06dbde3e01cdc40d01b5c85 100644 (file)
@@ -101,7 +101,7 @@ SECTIONS
          *(.scommon)
        }
        . = ALIGN(4);
-       __bss_end__ = .;
+       __bss_end = .;
        PROVIDE (end = .);
 
        /* DEBUG -- symbol table, string table, etc. etc.
diff --git a/arch/nios2/include/asm/sections.h b/arch/nios2/include/asm/sections.h
new file mode 100644 (file)
index 0000000..d813563
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * 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 __ASM_NIOS2_SECTIONS_H
+#define __ASM_NIOS2_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif
diff --git a/arch/openrisc/include/asm/sections.h b/arch/openrisc/include/asm/sections.h
new file mode 100644 (file)
index 0000000..6eb5a66
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * 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 __ASM_OPENRISC_SECTIONS_H
+#define __ASM_OPENRISC_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif
index b7062818bbf45c458ebf34c713eedaefa7939c06..e32d2bf4090167c82c841b923a9fbdaa55bc8d33 100644 (file)
@@ -29,6 +29,9 @@ PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections
 PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__
 PLATFORM_LDFLAGS  += -n
 
+# Support generic board on PPC
+__HAVE_ARCH_GENERIC_BOARD := y
+
 #
 # When cross-compiling on NetBSD, we have to define __PPC__ or else we
 # will pick up a va_list declaration that is incompatible with the
index b6a31b4372f2e77dfbdd1ff744699b5f3b3eb46a..17694a1cfe5d3e900de45a75aeeb9a97176ee2ca 100644 (file)
@@ -229,8 +229,7 @@ soft_restart(unsigned long addr)
 }
 
 
-#if !defined(CONFIG_PCIPPC2) && \
-    !defined(CONFIG_BAB7xx)  && \
+#if !defined(CONFIG_BAB7xx)  && \
     !defined(CONFIG_ELPPC)   && \
     !defined(CONFIG_PPMC7XX)
 /* no generic way to do board reset. simply call soft_reset. */
@@ -288,13 +287,13 @@ unsigned long get_tbclk(void)
 /* ------------------------------------------------------------------------- */
 
 #if defined(CONFIG_WATCHDOG)
-#if !defined(CONFIG_PCIPPC2) && !defined(CONFIG_BAB7xx)
+#if !defined(CONFIG_BAB7xx)
 void
 watchdog_reset(void)
 {
 
 }
-#endif  /* !CONFIG_PCIPPC2 && !CONFIG_BAB7xx */
+#endif  /* !CONFIG_BAB7xx */
 #endif /* CONFIG_WATCHDOG */
 
 /* ------------------------------------------------------------------------- */
index 75fb77389468fa1bc6c7e33fecdf8ecbe0c26ccf..cd8dea841ff0663e8e008e79fbae6d30659119b6 100644 (file)
@@ -72,7 +72,7 @@
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
        END_GOT
 
@@ -715,7 +715,7 @@ in_ram:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 
        cmplw   0, r3, r4
        beq     6f
index c58d9797573222a0f10f98b73898a38cbe137be1..40b89abac67fa6e02cf310a9197ebbc973e0c877 100644 (file)
@@ -89,6 +89,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 32ade1b0b9215eff9a66ff65a026acdde4ca8811..b308cb4be3e18a7d67d6744fb8bcae40de491c82 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/mpc512x.h>
 #include <asm/processor.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -43,6 +44,101 @@ void cpu_init_f (volatile immap_t * im)
        /* Clear initial global data */
        memset ((void *) gd, 0, sizeof (gd_t));
 
+       /* Local Window and chip select configuration */
+#if defined(CONFIG_SYS_CS0_START) && defined(CONFIG_SYS_CS0_SIZE)
+       out_be32(&im->sysconf.lpcs0aw,
+               CSAW_START(CONFIG_SYS_CS0_START) |
+               CSAW_STOP(CONFIG_SYS_CS0_START, CONFIG_SYS_CS0_SIZE));
+       sync_law(&im->sysconf.lpcs0aw);
+#endif
+#if defined(CONFIG_SYS_CS0_CFG)
+       out_be32(&im->lpc.cs_cfg[0], CONFIG_SYS_CS0_CFG);
+#endif
+
+#if defined(CONFIG_SYS_CS1_START) && defined(CONFIG_SYS_CS1_SIZE)
+       out_be32(&im->sysconf.lpcs1aw,
+               CSAW_START(CONFIG_SYS_CS1_START) |
+               CSAW_STOP(CONFIG_SYS_CS1_START, CONFIG_SYS_CS1_SIZE));
+       sync_law(&im->sysconf.lpcs1aw);
+#endif
+#if defined(CONFIG_SYS_CS1_CFG)
+       out_be32(&im->lpc.cs_cfg[1], CONFIG_SYS_CS1_CFG);
+#endif
+
+#if defined(CONFIG_SYS_CS2_START) && (defined CONFIG_SYS_CS2_SIZE)
+       out_be32(&im->sysconf.lpcs2aw,
+               CSAW_START(CONFIG_SYS_CS2_START) |
+               CSAW_STOP(CONFIG_SYS_CS2_START, CONFIG_SYS_CS2_SIZE));
+       sync_law(&im->sysconf.lpcs2aw);
+#endif
+#if defined(CONFIG_SYS_CS2_CFG)
+       out_be32(&im->lpc.cs_cfg[2], CONFIG_SYS_CS2_CFG);
+#endif
+
+#if defined(CONFIG_SYS_CS3_START) && defined(CONFIG_SYS_CS3_SIZE)
+       out_be32(&im->sysconf.lpcs3aw,
+               CSAW_START(CONFIG_SYS_CS3_START) |
+               CSAW_STOP(CONFIG_SYS_CS3_START, CONFIG_SYS_CS3_SIZE));
+       sync_law(&im->sysconf.lpcs3aw);
+#endif
+#if defined(CONFIG_SYS_CS3_CFG)
+       out_be32(&im->lpc.cs_cfg[3], CONFIG_SYS_CS3_CFG);
+#endif
+
+#if defined(CONFIG_SYS_CS4_START) && defined(CONFIG_SYS_CS4_SIZE)
+       out_be32(&im->sysconf.lpcs4aw,
+               CSAW_START(CONFIG_SYS_CS4_START) |
+               CSAW_STOP(CONFIG_SYS_CS4_START, CONFIG_SYS_CS4_SIZE));
+       sync_law(&im->sysconf.lpcs4aw);
+#endif
+#if defined(CONFIG_SYS_CS4_CFG)
+       out_be32(&im->lpc.cs_cfg[4], CONFIG_SYS_CS4_CFG);
+#endif
+
+#if defined(CONFIG_SYS_CS5_START) && defined(CONFIG_SYS_CS5_SIZE)
+       out_be32(&im->sysconf.lpcs5aw,
+               CSAW_START(CONFIG_SYS_CS5_START) |
+               CSAW_STOP(CONFIG_SYS_CS5_START, CONFIG_SYS_CS5_SIZE));
+       sync_law(&im->sysconf.lpcs5aw);
+#endif
+#if defined(CONFIG_SYS_CS5_CFG)
+       out_be32(&im->lpc.cs_cfg[5], CONFIG_SYS_CS5_CFG);
+#endif
+
+#if defined(CONFIG_SYS_CS6_START) && defined(CONFIG_SYS_CS6_SIZE)
+       out_be32(&im->sysconf.lpcs6aw,
+               CSAW_START(CONFIG_SYS_CS6_START) |
+               CSAW_STOP(CONFIG_SYS_CS6_START, CONFIG_SYS_CS6_SIZE));
+       sync_law(&im->sysconf.lpcs6aw);
+#endif
+#if defined(CONFIG_SYS_CS6_CFG)
+       out_be32(&im->lpc.cs_cfg[6], CONFIG_SYS_CS6_CFG);
+#endif
+
+#if defined(CONFIG_SYS_CS7_START) && defined(CONFIG_SYS_CS7_SIZE)
+       out_be32(&im->sysconf.lpcs7aw,
+               CSAW_START(CONFIG_SYS_CS7_START) |
+               CSAW_STOP(CONFIG_SYS_CS7_START, CONFIG_SYS_CS7_SIZE));
+       sync_law(&im->sysconf.lpcs7aw);
+#endif
+#if defined(CONFIG_SYS_CS7_CFG)
+       out_be32(&im->lpc.cs_cfg[7], CONFIG_SYS_CS7_CFG);
+#endif
+
+#if defined CONFIG_SYS_CS_ALETIMING
+       if (SVR_MJREV(in_be32(&im->sysconf.spridr)) >= 2)
+               out_be32(&im->lpc.altr, CONFIG_SYS_CS_ALETIMING);
+#endif
+#if defined CONFIG_SYS_CS_BURST
+       out_be32(&im->lpc.cs_bcr, CONFIG_SYS_CS_BURST);
+#endif
+#if defined CONFIG_SYS_CS_DEADCYCLE
+       out_be32(&im->lpc.cs_dccr, CONFIG_SYS_CS_DEADCYCLE);
+#endif
+#if defined CONFIG_SYS_CS_HOLDCYCLE
+       out_be32(&im->lpc.cs_hccr, CONFIG_SYS_CS_HOLDCYCLE);
+#endif
+
        /* system performance tweaking */
 
 #ifdef CONFIG_SYS_ACR_PIPE_DEP
@@ -76,6 +172,21 @@ void cpu_init_f (volatile immap_t * im)
        ips_div |= SCFR1_IPS_DIV << SCFR1_IPS_DIV_SHIFT;
        out_be32(&im->clk.scfr[0], ips_div);
 
+#ifdef SCFR1_LPC_DIV
+       clrsetbits_be32(&im->clk.scfr[0], SCFR1_LPC_DIV_MASK,
+                       SCFR1_LPC_DIV << SCFR1_LPC_DIV_SHIFT);
+#endif
+
+#ifdef SCFR1_NFC_DIV
+       clrsetbits_be32(&im->clk.scfr[0], SCFR1_NFC_DIV_MASK,
+                       SCFR1_NFC_DIV << SCFR1_NFC_DIV_SHIFT);
+#endif
+
+#ifdef SCFR1_DIU_DIV
+       clrsetbits_be32(&im->clk.scfr[0], SCFR1_DIU_DIV_MASK,
+                       SCFR1_DIU_DIV << SCFR1_DIU_DIV_SHIFT);
+#endif
+
        /*
         * Enable Time Base/Decrementer
         *
@@ -84,6 +195,15 @@ void cpu_init_f (volatile immap_t * im)
         * during FLASH chip identification etc.
         */
        setbits_be32(&im->sysconf.spcr, SPCR_TBEN);
+
+       /*
+        * Enable clocks
+        */
+       out_be32(&im->clk.sccr[0], SCCR1_CLOCKS_EN);
+       out_be32(&im->clk.sccr[1], SCCR2_CLOCKS_EN);
+#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE)
+       setbits_be32(&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN);
+#endif
 }
 
 int cpu_init_r (void)
index 550cbd0bd6fcf1484e1c88158ceed156d25c0fff..6635fb036e8aa9c6d8d6f3107f7241bb8275413d 100644 (file)
@@ -99,7 +99,19 @@ long int fixed_sdram(ddr512x_config_t *mddrc_config,
        sync_law(&im->sysconf.ddrlaw.ar);
 
        /* DDR Enable */
-       out_be32(&im->mddrc.ddr_sys_config, MDDRC_SYS_CFG_EN);
+       /*
+        * the "enable" combination: DRAM controller out of reset,
+        * clock enabled, command mode -- BUT leave CKE low for now
+        */
+       i = MDDRC_SYS_CFG_EN & ~MDDRC_SYS_CFG_CKE_MASK;
+       out_be32(&im->mddrc.ddr_sys_config, i);
+       /* maintain 200 microseconds of stable power and clock */
+       udelay(200);
+       /* apply a NOP, it shouldn't harm */
+       out_be32(&im->mddrc.ddr_command, CONFIG_SYS_DDRCMD_NOP);
+       /* now assert CKE (high) */
+       i |= MDDRC_SYS_CFG_CKE_MASK;
+       out_be32(&im->mddrc.ddr_sys_config, i);
 
        /* Initialize DDR Priority Manager */
        out_be32(&im->mddrc.prioman_config1, CONFIG_SYS_MDDRCGRP_PM_CFG1);
@@ -148,6 +160,9 @@ long int fixed_sdram(ddr512x_config_t *mddrc_config,
        out_be32(&im->mddrc.ddr_time_config0, mddrc_config->ddr_time_config0);
        out_be32(&im->mddrc.ddr_sys_config, mddrc_config->ddr_sys_config);
 
+       /* Allow for the DLL to startup before accessing data */
+       udelay(10);
+
        msize = get_ram_size(CONFIG_SYS_DDR_BASE, CONFIG_SYS_MAX_RAM_SIZE);
        /* Fix DDR Local Window for new size */
        out_be32(&im->sysconf.ddrlaw.ar, __ilog2(msize) - 1);
index be209476232603c33968a77621774a82fb0e8a1d..1a391016229558aceb0dde01f5943e845cae9dbd 100644 (file)
@@ -47,3 +47,57 @@ void iopin_initialize(iopin_t *ioregs_init, int len)
        }
        return;
 }
+
+void iopin_initialize_bits(iopin_t *ioregs_init, int len)
+{
+       short i, j, p;
+       u32 *reg, mask;
+       immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+
+       reg = (u32 *)&(im->io_ctrl);
+
+       /* iterate over table entries */
+       for (i = 0; i < len; i++) {
+               /* iterate over pins within a table entry */
+               for (p = 0, j = ioregs_init[i].p_offset / sizeof(u_long);
+                       p < ioregs_init[i].nr_pins; p++, j++) {
+                       if (ioregs_init[i].bit_or & IO_PIN_OVER_EACH) {
+                               /* replace all settings at once */
+                               out_be32(reg + j, ioregs_init[i].val);
+                       } else {
+                               /*
+                                * only replace individual parts, but
+                                * REPLACE them instead of just ORing
+                                * them in and "inheriting" previously
+                                * set bits which we don't want
+                                */
+                               mask = 0;
+                               if (ioregs_init[i].bit_or & IO_PIN_OVER_FMUX)
+                                       mask |= IO_PIN_FMUX(3);
+
+                               if (ioregs_init[i].bit_or & IO_PIN_OVER_HOLD)
+                                       mask |= IO_PIN_HOLD(3);
+
+                               if (ioregs_init[i].bit_or & IO_PIN_OVER_PULL)
+                                       mask |= IO_PIN_PUD(1) | IO_PIN_PUE(1);
+
+                               if (ioregs_init[i].bit_or & IO_PIN_OVER_STRIG)
+                                       mask |= IO_PIN_ST(1);
+
+                               if (ioregs_init[i].bit_or & IO_PIN_OVER_DRVSTR)
+                                       mask |= IO_PIN_DS(3);
+                               /*
+                                * DON'T do the "mask, then insert"
+                                * in place on the register, it may
+                                * break access to external hardware
+                                * (like boot ROMs) when configuring
+                                * LPB related pins, while the code to
+                                * configure the pin is read from this
+                                * very address region
+                                */
+                               clrsetbits_be32(reg + j, mask,
+                                               ioregs_init[i].val & mask);
+                       }
+               }
+       }
+}
index ed362d87aa440ee04b2c9cb347fde923ccbcd5f8..6d1a99ac5c788504e4397bbfd4bbe2bcc5914a5c 100644 (file)
@@ -77,7 +77,7 @@
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
        END_GOT
 
@@ -622,7 +622,7 @@ clear_bss:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 
        cmplw   0, r3, r4
        beq     6f
index a34501b6315c1576f8b0604482cf33f42629123c..0d8697901f66f22ad68280658443848db55b984b 100644 (file)
@@ -84,7 +84,7 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
 ENTRY(_start)
index cc4c33ebbd1041962449a220a653d50e4ad2c681..1b275c66a1d894f4d031b37092876d2813b29b26 100644 (file)
@@ -65,7 +65,7 @@
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
        END_GOT
 
@@ -459,7 +459,7 @@ clear_bss:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
        cmplw   0, r3, r4
        beq     6f
 
index 0d87c8cf1e5088616d76a7aed53359622c6d9dfc..8385a29bcb411e6bcf4592f72671cd393b1166ab 100644 (file)
@@ -93,7 +93,7 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
   . = env_start;
   .ppcenv :
index 9f14127dcaa433b436645f394ea5d0cdbbda5f6a..35611cce77aa82de425d46a3e5c8776cd27645f5 100644 (file)
@@ -41,13 +41,12 @@ void board_init_f(ulong bootflag)
        end_align = (u32)__spl_flash_end;
 
        /*
-        * First we need to initialize the SDRAM, so that the real
-        * U-Boot or the OS (Linux) can be loaded
+        * On MPC5200, the initial RAM (and gd) is located in the internal
+        * SRAM. So we can actually call the preloader console init code
+        * before calling initdram(). This makes serial output (printf)
+        * available very early, even before SDRAM init, which has been
+        * an U-Boot priciple from day 1.
         */
-       initdram(0);
-
-       /* Clear bss */
-       memset(__bss_start, '\0', __bss_end__ - __bss_start);
 
        /*
         * Init global_data pointer. Has to be done before calling
@@ -70,6 +69,15 @@ void board_init_f(ulong bootflag)
         */
        preloader_console_init();
 
+       /*
+        * First we need to initialize the SDRAM, so that the real
+        * U-Boot or the OS (Linux) can be loaded
+        */
+       initdram(0);
+
+       /* Clear bss */
+       memset(__bss_start, '\0', __bss_end - __bss_start);
+
        /*
         * Call board_init_r() (SPL framework version) to load and boot
         * real U-Boot or OS
index ad5bc0a17947ed7261a1c1b3243510cf6dd97d30..2b6a800dea539bd65d7044f5c91dfbd7c28c5ea7 100644 (file)
@@ -66,7 +66,7 @@
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
        END_GOT
 #endif
@@ -694,7 +694,7 @@ clear_bss:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 
        cmplw   0, r3, r4
        beq     6f
index cdb36c088466480dd27429815c8b2bb33324ab61..590952fd1551e0a34213905ff8d8dda32a8e4ac7 100644 (file)
@@ -91,6 +91,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index cab9b9265c83e15ff1835a50c42ef3813f3e878d..05007396172b11f30c7a02ad9179d8c18b57ab13 100644 (file)
@@ -52,6 +52,6 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        } > sdram
 }
index 6bd646b93ee128375df69bdea441cb81c2b3b6d3..06ece78361adaf7fb3e23e0123625e76e47561df 100644 (file)
@@ -87,6 +87,6 @@ SECTIONS
    *(.sbss*)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index a1a2dc5acd8ac20e9b6487c79ecf61bb3689bb97..6295631913d240459d6cf978f725009080ffbfb1 100644 (file)
@@ -64,7 +64,7 @@
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
        END_GOT
 
@@ -647,7 +647,7 @@ clear_bss:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 
        cmplw   0, r3, r4
        beq     6f
index 6e9967cf879311f52e511e4463253df257cced94..dc63d2081bd585b3ecd7bd5f45a3247f4408d63b 100644 (file)
@@ -86,6 +86,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 076df70a9f128e7cdc94a7bf540877005ba9e0f4..0b9d89828554eed1f3b054f34825863d781b54f3 100644 (file)
@@ -72,7 +72,7 @@
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
 #if defined(CONFIG_FADS)
        GOT_ENTRY(environment)
@@ -584,7 +584,7 @@ clear_bss:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 
        cmplw   0, r3, r4
        beq     6f
index 699fb85857bd56cdc2e1bf1076322883e0ac5341..4590fab338501020fec8ff8127745e815d220a57 100644 (file)
@@ -87,6 +87,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 3299d7292a6e5b8ed1a36eac9740b2de2bbb9ab8..bd8d7ac53de2312874c74b1ee1e4abce9702ff2e 100644 (file)
@@ -65,7 +65,7 @@
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
 #if defined(CONFIG_HYMOD)
        GOT_ENTRY(environment)
@@ -920,7 +920,7 @@ clear_bss:
         */
        lwz     r4,GOT(environment)
 #else
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 #endif
 
        cmplw   0, r3, r4
index 2709f37667192b46f77154769c0c17430bcbdccd..eb1c611f908678fd811d31098f7590c884d41e20 100644 (file)
@@ -86,6 +86,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 44a64b7acd9cda4ea674ce250e55f960b0551f4f..1bfc9714126b6d1165ff3f677d0a85cfd5c4fbb2 100644 (file)
@@ -76,7 +76,7 @@
        START_GOT
        GOT_ENTRY(_GOT2_TABLE_)
        GOT_ENTRY(__bss_start)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
 
 #ifndef MINIMAL_SPL
        GOT_ENTRY(_FIXUP_TABLE_)
@@ -980,7 +980,7 @@ clear_bss:
         */
        lwz     r4,GOT(environment)
 #else
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 #endif
 
        cmplw   0, r3, r4
index d140453d49734a29c0c3cd9da8b25ebfcb1fd40e..870b47d6af4ab910e60f6ea407c19a2260c4e4ef 100644 (file)
@@ -49,7 +49,7 @@ SECTIONS
        .bss (NOLOAD) : {
                *(.*bss)
        }
-       __bss_end__ = .;
+       __bss_end = .;
 }
 ENTRY(_start)
-ASSERT(__bss_end__ <= 0xfff01000, "NAND bootstrap too big");
+ASSERT(__bss_end <= 0xfff01000, "NAND bootstrap too big");
index 905823cb9a3153d207812fdb26de36ca2eae8ce6..a9d8598839948a9534ef3f146049afc74ecd0d07 100644 (file)
@@ -85,7 +85,7 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
 ENTRY(_start)
index fb674694e4363bdc14c8e73f0db377f8cb46843d..3f76ee66cfb01fc7e4ce3d700bcaf66705c0f849 100644 (file)
@@ -70,7 +70,7 @@
 #endif
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
        END_GOT
 
@@ -1784,7 +1784,7 @@ clear_bss:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 
        cmplw   0,r3,r4
        beq     6f
index 3bb757231b4dd63ae2507e35b1837165fef9b532..65106f5e1f008fb91d6ac70c30b2ae061f8a85ab 100644 (file)
@@ -103,6 +103,6 @@ SECTIONS
   } :bss
 
   . = ALIGN(4);
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 87522b83d009b2ffb0083d78eb3be9a259b0f3a2..80cd98093a4010ba33bd583d829cb0a1c967fee8 100644 (file)
@@ -80,6 +80,6 @@ SECTIONS
                *(.sbss*)
                *(.bss*)
        }
-       __bss_end__ = .;
+       __bss_end = .;
 }
 ASSERT(__init_end <= (0xfff00000 + RESET_VECTOR_OFFSET), "NAND bootstrap too big");
index 1c408e29f507bdae602e2d983f5a421849387a27..f2b7bffdabefeda1d6862df45aae7c6f3c6918e6 100644 (file)
@@ -83,5 +83,5 @@ SECTIONS
                *(.sbss*)
                *(.bss*)
        }
-       __bss_end__ = .;
+       __bss_end = .;
 }
index 8c6e66ec1b5cb8932e457092a1ce3c1c4c4386d2..0503dce5ae4345edf6221b8d169720c05c5231e3 100644 (file)
@@ -127,6 +127,6 @@ SECTIONS
   } :bss
 
   . = ALIGN(4);
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ef80ecf6e53801c31ecc3e31cb063925e9d2876c..20dfb9e0e250ab843f18f8f38ee1a1ac0f580047 100644 (file)
@@ -61,7 +61,7 @@
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
        END_GOT
 
@@ -800,7 +800,7 @@ in_ram:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 
        cmplw   0, r3, r4
        beq     6f
index 81804e357c8b7bb7d0df83ee358d5a9cab65e485..7e357baf9531527ad222865ce864f00d7a036854 100644 (file)
@@ -90,6 +90,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ebca3acbaaaff6b1b4ad3f469367a4ede39c2282..5aa50c512c13e05d8fa2b4c2bc62e63d792a6b79 100644 (file)
@@ -72,7 +72,7 @@
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
        END_GOT
 
@@ -590,7 +590,7 @@ clear_bss:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 
        cmplw   0, r3, r4
        beq     6f
index 7aef43b210de25ca5ded376a399e1804ed758bbb..52f2623373ec7df4753c9642b4efafee8ebcf1df 100644 (file)
        GOT_ENTRY(transfer_to_handler)
 
        GOT_ENTRY(__init_end)
-       GOT_ENTRY(__bss_end__)
+       GOT_ENTRY(__bss_end)
        GOT_ENTRY(__bss_start)
        END_GOT
 #endif /* CONFIG_NAND_SPL */
@@ -1509,7 +1509,7 @@ clear_bss:
         * Now clear BSS segment
         */
        lwz     r3,GOT(__bss_start)
-       lwz     r4,GOT(__bss_end__)
+       lwz     r4,GOT(__bss_end)
 
        cmplw   0, r3, r4
        beq     7f
index 2cadcc94d5aa3e1adc7ed27c6e2f5bc32bcf25da..06010d6b149605829abbf5a7f361cfcbc58da99e 100644 (file)
@@ -142,6 +142,6 @@ SECTIONS
   } :bss
 
   . = ALIGN(4);
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index f763a5413e3f2892e5982ce3e6513f704c03cdfb..d96e53646ad88cff9a00bdadad9f71d5331610a1 100644 (file)
@@ -227,7 +227,9 @@ typedef struct clk512x {
 #define CLOCK_SCCR2_IIM_EN             0x00080000
 
 /* SCFR1 System Clock Frequency Register 1 */
+#ifndef SCFR1_IPS_DIV
 #define SCFR1_IPS_DIV          0x3
+#endif
 #define SCFR1_IPS_DIV_MASK     0x03800000
 #define SCFR1_IPS_DIV_SHIFT    23
 
@@ -238,6 +240,12 @@ typedef struct clk512x {
 #define SCFR1_LPC_DIV_MASK     0x00003800
 #define SCFR1_LPC_DIV_SHIFT    11
 
+#define SCFR1_NFC_DIV_MASK     0x00000700
+#define SCFR1_NFC_DIV_SHIFT    8
+
+#define SCFR1_DIU_DIV_MASK     0x000000FF
+#define SCFR1_DIU_DIV_SHIFT    0
+
 /* SCFR2 System Clock Frequency Register 2 */
 #define SCFR2_SYS_DIV          0xFC000000
 #define SCFR2_SYS_DIV_SHIFT    26
@@ -343,6 +351,7 @@ typedef struct ddr512x {
 
 /* MDDRC SYS CFG and Timing CFG0 Registers */
 #define MDDRC_SYS_CFG_EN       0xF0000000
+#define MDDRC_SYS_CFG_CKE_MASK 0x40000000
 #define MDDRC_SYS_CFG_CMD_MASK 0x10000000
 #define MDDRC_REFRESH_ZERO_MASK        0x0000FFFF
 
@@ -870,6 +879,19 @@ typedef struct iopin_t {
 
 void iopin_initialize(iopin_t *,int);
 
+/*
+ * support to adjust individual parts of the IO pin setup
+ */
+
+#define IO_PIN_OVER_EACH       (1 << 0) /* for compatibility */
+#define IO_PIN_OVER_FMUX       (1 << 1)
+#define IO_PIN_OVER_HOLD       (1 << 2)
+#define IO_PIN_OVER_PULL       (1 << 3)
+#define IO_PIN_OVER_STRIG      (1 << 4)
+#define IO_PIN_OVER_DRVSTR     (1 << 5)
+
+void iopin_initialize_bits(iopin_t *, int);
+
 /*
  * IIM
  */
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
new file mode 100644 (file)
index 0000000..0a94102
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * 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 __ASM_POWERPC_SECTIONS_H
+#define __ASM_POWERPC_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif
index f43bc23c92d72e04528f70395bfa356c5e02d93d..7d5f9a0a3391369fd8f28093cdb13429783f4342 100644 (file)
@@ -26,6 +26,6 @@
 #define BOOT_DEVICE_NOR                1
 
 /* Linker symbols */
-extern char __bss_start[], __bss_end__[];
+extern char __bss_start[], __bss_end[];
 
 #endif
index 7229a98eaa35a5ad077e4c5c79155bcff95da1fc..cf972d20ce9e2b856aeb5dabdb6a7274eccca0df 100644 (file)
  * include/asm-ppc/u-boot.h
  */
 
+#ifdef CONFIG_SYS_GENERIC_BOARD
+/* Use the generic board which requires a unified bd_info */
+#include <asm-generic/u-boot.h>
+#else
+
 #ifndef __ASSEMBLY__
 
 typedef struct bd_info {
@@ -144,6 +149,8 @@ typedef struct bd_info {
 
 #endif /* __ASSEMBLY__ */
 
+#endif /* !CONFIG_SYS_GENERIC_BOARD */
+
 /* For image.h:image_check_target_arch() */
 #define IH_ARCH_DEFAULT IH_ARCH_PPC
 
index 86cf02ace4147f8fc29ad727dc5e44879844b632..59c723b07091d0c8b111c217ef92b7034c32e9d9 100644 (file)
@@ -59,8 +59,10 @@ SOBJS-y      += reloc.o
 
 COBJS-$(CONFIG_BAT_RW) += bat_rw.o
 ifndef CONFIG_SPL_BUILD
+ifndef CONFIG_SYS_GENERIC_BOARD
 COBJS-y        += board.o
 endif
+endif
 COBJS-y        += bootm.o
 COBJS-y        += cache.o
 COBJS-y        += extable.o
index 12270a4533a3c79de111ce64941c2ccd379ffff1..422b4a39bb8a5c08d2f0f195cbc41902e4fe6ae3 100644 (file)
@@ -123,7 +123,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif
 
 extern ulong __init_end;
-extern ulong __bss_end__;
+extern ulong __bss_end;
 ulong monitor_flash_len;
 
 #if defined(CONFIG_CMD_BEDBUG)
@@ -237,25 +237,18 @@ static int init_func_spi(void)
 /***********************************************************************/
 
 #if defined(CONFIG_WATCHDOG)
-static int init_func_watchdog_init(void)
+int init_func_watchdog_init(void)
 {
        puts("       Watchdog enabled\n");
        WATCHDOG_RESET();
        return 0;
 }
 
-#define INIT_FUNC_WATCHDOG_INIT        init_func_watchdog_init,
-
-static int init_func_watchdog_reset(void)
+int init_func_watchdog_reset(void)
 {
        WATCHDOG_RESET();
        return 0;
 }
-
-#define INIT_FUNC_WATCHDOG_RESET       init_func_watchdog_reset,
-#else
-#define INIT_FUNC_WATCHDOG_INIT                /* undef */
-#define INIT_FUNC_WATCHDOG_RESET       /* undef */
 #endif /* CONFIG_WATCHDOG */
 
 /*
@@ -326,7 +319,8 @@ static init_fnc_t *init_sequence[] = {
 #ifdef CONFIG_POST
        post_init_f,
 #endif
-       INIT_FUNC_WATCHDOG_RESET init_func_ram,
+       INIT_FUNC_WATCHDOG_RESET
+       init_func_ram,
 #if defined(CONFIG_SYS_DRAM_TEST)
        testdram,
 #endif /* CONFIG_SYS_DRAM_TEST */
@@ -419,7 +413,7 @@ void board_init_f(ulong bootflag)
         *  - monitor code
         *  - board info struct
         */
-       len = (ulong)&__bss_end__ - CONFIG_SYS_MONITOR_BASE;
+       len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
 
        /*
         * Subtract specified amount of memory to hide so that it won't
index eafce7d8ab97b51dfc1c28918529774b67b6a4d7..4c378600b0f383382d86a4af5f4767e9393e5d0d 100644 (file)
@@ -9,6 +9,8 @@
 #ifndef __SANDBOX_SECTIONS_H
 #define __SANDBOX_SECTIONS_H
 
+#include <asm-generic/sections.h>
+
 struct sb_cmdline_option;
 
 extern struct sb_cmdline_option *__u_boot_sandbox_option_start[],
index 9bf1d8562197001b106cda5c5f5486fba82576c9..3cd5699c89a4f465491502c8886b983e7d3417b7 100644 (file)
@@ -88,5 +88,5 @@ SECTIONS
        }
        PROVIDE (bss_end = .);
 
-       PROVIDE (__bss_end__ = .);
+       PROVIDE (__bss_end = .);
 }
index 29352ad821ded3c43d13c4985689caa265f760a9..654c52cda7ac903c8b6286b4e20340ae8eb6c275 100644 (file)
@@ -95,5 +95,5 @@ SECTIONS
        }
        PROVIDE (bss_end = .);
 
-       PROVIDE (__bss_end__ = .);
+       PROVIDE (__bss_end = .);
 }
index cf3da0db1473fab69f7c2867dba323bb2d508fa8..11d7ffab7ec47853ed9989eecdc9cdfbb2f3dc33 100644 (file)
@@ -92,5 +92,5 @@ SECTIONS
        }
        PROVIDE (bss_end = .);
 
-       PROVIDE (__bss_end__ = .);
+       PROVIDE (__bss_end = .);
 }
diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h
new file mode 100644 (file)
index 0000000..8824560
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * 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 __ASM_SH_SECTIONS_H
+#define __ASM_SH_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif
index 34d7881f446728d1634cbf3e380c3bdf7c9918cf..6e43acfbd35778165843651f724bf646d368c69c 100644 (file)
@@ -65,6 +65,7 @@ static int sh_flash_init(void)
 #if defined(CONFIG_WATCHDOG)
 extern int watchdog_init(void);
 extern int watchdog_disable(void);
+# undef INIT_FUNC_WATCHDOG_INIT
 # define INIT_FUNC_WATCHDOG_INIT       watchdog_init,
 # define WATCHDOG_DISABLE              watchdog_disable
 #else
index a9a18eb1ff2d0cb6a3437f88de886f97dbff0c72..d4dc397034cb13887ac8a3b434e2d05583890344 100644 (file)
@@ -43,13 +43,6 @@ $(LIB):      $(OBJS)
 # defines $(obj).depend target
 include $(SRCTREE)/rules.mk
 
-$(START): $(START:.o=.S)
-       $(CC) -D__ASSEMBLY__ $(DBGFLAGS) $(OPTFLAGS) -D__KERNEL__ \
-       -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) -I$(TOPDIR)/include \
-       -fno-builtin -ffreestanding -nostdinc -isystem $(gccincdir) -pipe \
-       $(PLATFORM_CPPFLAGS) -Wall -Wstrict-prototypes \
-       -I$(TOPDIR)/board -c -o $(START) $(START:.o=.S)
-
 sinclude $(obj).depend
 
 #########################################################################
index 40d5b01d2710af86750efd0d342ac0214fa7c6c1..b41ee01818ca0dcf5aef507958ca18d7cacecdc6 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Force cache miss each time a serial controller reg is read */
-#define CACHE_BYPASS 1
-
-#ifdef CACHE_BYPASS
-#define READ_BYTE(var)  SPARC_NOCACHE_READ_BYTE((unsigned int)&(var))
-#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)&(var))
-#define READ_WORD(var)  SPARC_NOCACHE_READ((unsigned int)&(var))
-#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)&(var))
-#endif
-
 static int leon2_serial_init(void)
 {
        LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
index 16d3377c7304e0119b78547c9a4463ccf8d402f8..1d051e17a3aa67b70b9b4fd370e5c1e1ebe55c54 100644 (file)
@@ -43,13 +43,6 @@ $(LIB):      $(OBJS)
 # defines $(obj).depend target
 include $(SRCTREE)/rules.mk
 
-$(START): $(START:.o=.S)
-       $(CC) -D__ASSEMBLY__ $(DBGFLAGS) $(OPTFLAGS) -D__KERNEL__ \
-       -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) -I$(TOPDIR)/include \
-       -fno-builtin -ffreestanding -nostdinc -isystem $(gccincdir) -pipe \
-       $(PLATFORM_CPPFLAGS) -Wall -Wstrict-prototypes \
-       -I$(TOPDIR)/board -c -o $(START) $(START:.o=.S)
-
 sinclude $(obj).depend
 
 #########################################################################
index 838d4514eeb2ff4d794e2782468a522db688420f..af9ce55673820b0df3621d1ac3a08421726f9a44 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Force cache miss each time a serial controller reg is read */
-#define CACHE_BYPASS 1
-
-#ifdef CACHE_BYPASS
-#define READ_BYTE(var)  SPARC_NOCACHE_READ_BYTE((unsigned int)&(var))
-#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)&(var))
-#define READ_WORD(var)  SPARC_NOCACHE_READ((unsigned int)&(var))
-#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)&(var))
-#endif
-
 ambapp_dev_apbuart *leon3_apbuart = NULL;
 
 static int leon3_serial_init(void)
diff --git a/arch/sparc/include/asm/sections.h b/arch/sparc/include/asm/sections.h
new file mode 100644 (file)
index 0000000..90f7fa7
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * 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 __ASM_SPARC_SECTIONS_H
+#define __ASM_SPARC_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif
index 23cacffdedeae65bca6464df98569fc2c5cb4907..168dc24fda3584b2c8c727ce406188f27ac75cf8 100644 (file)
@@ -36,6 +36,9 @@ PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_X86)
 PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm
 PLATFORM_CPPFLAGS += -DREALMODE_BASE=0x7c0
 
+# Support generic board on x86
+__HAVE_ARCH_GENERIC_BOARD := y
+
 PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden
 
 PLATFORM_LDFLAGS += --emit-relocs -Bsymbolic -Bsymbolic-functions
index a8136a06ab4e3a0a442a5b7aa82b47eb11309855..786009c746d924255db184e22b998cc50de68c8e 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/u-boot-x86.h>
 #include <asm/global_data.h>
 #include <asm/processor.h>
+#include <asm/sections.h>
 #include <asm/arch/sysinfo.h>
 #include <asm/arch/tables.h>
 
index ef5aa951c9517d5d4c194af08551380df94f86dd..2d6911aa4196b58278eedbab54b833ba3e38d976 100644 (file)
@@ -53,6 +53,7 @@ SECTIONS
 
        . = ALIGN(4);
        __data_end = .;
+       __init_end = .;
 
        . = ALIGN(4);
        .dynsym : { *(.dynsym*) }
@@ -64,9 +65,6 @@ SECTIONS
        . = ALIGN(4);
        _end = .;
 
-       . = ALIGN(4);
-
-       __end = .;
        .bss __rel_dyn_start (OVERLAY) : {
                __bss_start = .;
                *(.bss)
index 049c44eaf84de0ce67d86afcf0cd016d4bd6c407..3961b828112fddc770a512896381bf48eb3a46af 100644 (file)
@@ -21,4 +21,5 @@
 #ifndef _ASM_CONFIG_H_
 #define _ASM_CONFIG_H_
 
+#define CONFIG_SYS_GENERIC_BOARD
 #endif
diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h
new file mode 100644 (file)
index 0000000..602df86
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * 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 __ASM_X86_SECTIONS_H
+#define __ASM_X86_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif
index 948615d4385ef32bd41c95ad26ac1a1c90824ddd..ae0c3883e413ab2cfaa71243143d941fe1324f24 100644 (file)
 #ifndef _U_BOOT_I386_H_
 #define _U_BOOT_I386_H_        1
 
-/* Exports from the Linker Script */
-extern ulong __text_start;
-extern ulong __data_end;
-extern ulong __rel_dyn_start;
-extern ulong __rel_dyn_end;
-extern ulong __bss_start;
-extern ulong __bss_end;
-extern ulong _end;
-
 /* cpu/.../cpu.c */
 int x86_cpu_init_r(void);
 int cpu_init_r(void);
index 2f45c7b3d749fada710dc8f7605f58f169c25d41..df759faec403099ddf7d91beeb99816e829734d8 100644 (file)
 #include <config.h>
 #include <compiler.h>
 
+#ifdef CONFIG_SYS_GENERIC_BOARD
+/* Use the generic board which requires a unified bd_info */
+#include <asm-generic/u-boot.h>
+#else
+
+#ifndef __ASSEMBLY__
+
 typedef struct bd_info {
        unsigned long   bi_memstart;    /* start of DRAM memory */
        phys_size_t     bi_memsize;     /* size  of DRAM memory in bytes */
@@ -60,6 +67,10 @@ typedef struct bd_info {
        }bi_dram[CONFIG_NR_DRAM_BANKS];
 } bd_t;
 
+#endif /* __ASSEMBLY__ */
+
+#endif /* !CONFIG_SYS_GENERIC_BOARD */
+
 /* For image.h:image_check_target_arch() */
 #define IH_ARCH_DEFAULT IH_ARCH_I386
 
index 9b24dc5fdf025eac7e727c84ee6eb998124c26a4..ee89354808659d24177931b47db133c5ffa19f2d 100644 (file)
@@ -25,7 +25,10 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(ARCH).o
 
+ifeq ($(CONFIG_SYS_GENERIC_BOARD),)
 COBJS-y        += board.o
+endif
+
 COBJS-y        += bootm.o
 COBJS-y        += cmd_boot.o
 COBJS-y        += gcc.o
index 2441a66ae226dee55e029f0d26777791d3fd7615..f372898f61276ea0dced65499d613797c9283f27 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/u-boot-x86.h>
 #include <asm/relocate.h>
 #include <asm/processor.h>
+#include <asm/sections.h>
 
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
@@ -163,13 +164,13 @@ init_fnc_t *init_sequence_r[] = {
 #ifndef CONFIG_SYS_NO_FLASH
        flash_init_r,
 #endif
-#ifdef CONFIG_SPI
-       init_func_spi;
-#endif
-       env_relocate_r,
 #ifdef CONFIG_PCI
        pci_init_r,
 #endif
+#ifdef CONFIG_SPI
+       init_func_spi,
+#endif
+       env_relocate_r,
        stdio_init,
        jumptable_init_r,
        console_init_r,
@@ -219,7 +220,7 @@ static void do_init_loop(init_fnc_t **init_fnc_ptr)
 
 void board_init_f(ulong boot_flags)
 {
-       gd->fdt_blob = gd->arch.new_fdt = NULL;
+       gd->fdt_blob = gd->new_fdt = NULL;
        gd->flags = boot_flags;
 
        do_init_loop(init_sequence_f);
index 414fdcc4c901bd4599eb2a5ef64b241ac490723c..af9dbc146a3c7beef6f4adec33828d42cb270e3a 100644 (file)
@@ -32,6 +32,7 @@
 #include <spi.h>
 #include <status_led.h>
 #include <asm/processor.h>
+#include <asm/sections.h>
 #include <asm/u-boot-x86.h>
 #include <linux/compiler.h>
 
@@ -111,7 +112,7 @@ int calculate_relocation_address(void)
         */
        if (gd->fdt_blob) {
                dest_addr -= fdt_size;
-               gd->arch.new_fdt = (void *)dest_addr;
+               gd->new_fdt = (void *)dest_addr;
                dest_addr &= ~15;
        }
 #endif
index 3e370f2906a277f8a6b7812d028b60609d1880af..f178db9c81ccf4d7d55ec2310e5ecb1f21fbadbd 100644 (file)
@@ -36,6 +36,7 @@
 #include <malloc.h>
 #include <asm/u-boot-x86.h>
 #include <asm/relocate.h>
+#include <asm/sections.h>
 #include <elf.h>
 
 int copy_uboot_to_ram(void)
@@ -49,15 +50,15 @@ int copy_uboot_to_ram(void)
 
 int copy_fdt_to_ram(void)
 {
-       if (gd->arch.new_fdt) {
+       if (gd->new_fdt) {
                ulong fdt_size;
 
                fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
 
-               memcpy(gd->arch.new_fdt, gd->fdt_blob, fdt_size);
+               memcpy(gd->new_fdt, gd->fdt_blob, fdt_size);
                debug("Relocated fdt from %p to %p, size %lx\n",
-                      gd->fdt_blob, gd->arch.new_fdt, fdt_size);
-               gd->fdt_blob = gd->arch.new_fdt;
+                      gd->fdt_blob, gd->new_fdt, fdt_size);
+               gd->fdt_blob = gd->new_fdt;
        }
 
        return 0;
index 43bd9b74ac90cda054452ca55ce7686afa96cc69..c72043d2359a405174e5e788c2c8220ad5eacc1d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 3ff38713f01f6fb2ed8ad062965bf65d7087a3a5..2b76e92e4f1a8deabcb4dac2e9374f25e13c4fa2 100644 (file)
@@ -112,6 +112,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index f9d2ec2aa9883eae5f6136476d192630c0c4c710..84bb763c7bdd3fcb64b35342486593e951d65733 100644 (file)
@@ -98,6 +98,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 7698614a621fb19d2f902b5227eea37c3be737d1..a0fe832fb2471dc37d6ee447bdc2b98776640156 100644 (file)
@@ -62,7 +62,7 @@ the following command:
 
 All this can be integrated into an environment command:
 => setenv upd_fdt 'tftp 1800000 a3m071/a3m071.dtb;run mtdargs addip2 addtty; \
-       fdt addr 1800000;fdt boardsetup;erase fc060000 fc07ffff; \
+       fdt addr 1800000;fdt boardsetup;fdt chosen;erase fc060000 fc07ffff; \
        cp.b 1800000 fc060000 10000'
 => saveenv
 
index 89ced824eb6721c7425195c0152be06fe7074f60..0f9f883e9089e83ca5f9b1b939f455e41b4a0b8a 100644 (file)
 #include <mpc5xxx.h>
 #include <pci.h>
 #include <miiphy.h>
+#include <linux/compiler.h>
 #include <asm/processor.h>
 #include <asm/io.h>
 
+#ifdef CONFIG_A4M2K
+#include "is46r16320d.h"
+#else
 #include "mt46v16m16-75.h"
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -63,6 +68,12 @@ static void sdram_start(int hi_addr)
 
        /* normal operation */
        out_be32((void *)MPC5XXX_SDRAM_CTRL, control);
+
+       /*
+        * Wait a short while for the DLL to lock before accessing
+        * the SDRAM
+        */
+       udelay(100);
 }
 #endif
 
@@ -157,12 +168,6 @@ static void get_revisions(int *failsavelevel, int *digiboardversion,
        struct mpc5xxx_gpt_0_7 *gpt = (struct mpc5xxx_gpt_0_7 *)MPC5XXX_GPT;
        u8 val;
 
-       /*
-        * Figure out failsavelevel
-        * see ticket dsvk#59
-        */
-       *failsavelevel = 0;     /* 0=failsave, 1=board ok, 2=fpga ok */
-
        /* read digitalboard-version from TMR[2..4] */
        val = 0;
        val |= (gpt->gpt2.sr & (1 << (31 - 23))) ? (1) : 0;
@@ -170,6 +175,17 @@ static void get_revisions(int *failsavelevel, int *digiboardversion,
        val |= (gpt->gpt4.sr & (1 << (31 - 23))) ? (1 << 2) : 0;
        *digiboardversion = val;
 
+       /*
+        * A4M2K only supports digiboardversion. No failsavelevel and
+        * fpgaversion here.
+        */
+#if !defined(CONFIG_A4M2K)
+       /*
+        * Figure out failsavelevel
+        * see ticket dsvk#59
+        */
+       *failsavelevel = 0;     /* 0=failsave, 1=board ok, 2=fpga ok */
+
        if (*digiboardversion == 0) {
                *failsavelevel = 1;     /* digiboard-version ok */
 
@@ -183,6 +199,7 @@ static void get_revisions(int *failsavelevel, int *digiboardversion,
                if (*fpgaversion == 1)
                        *failsavelevel = 2;     /* fpga-version ok */
        }
+#endif
 }
 
 /*
@@ -196,6 +213,11 @@ void spl_board_init(void)
        struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5XXX_GPIO;
        struct mpc5xxx_mmap_ctl *mm =
                (struct mpc5xxx_mmap_ctl *)CONFIG_SYS_MBAR;
+
+#if defined(CONFIG_A4M2K)
+       /* enable CS3 and CS5 (FPGA) */
+       setbits_be32(&mm->ipbi_ws_ctrl, (1 << 19) | (1 << 21));
+#else
        int digiboardversion;
        int failsavelevel;
        int fpgaversion;
@@ -219,6 +241,7 @@ void spl_board_init(void)
 
        /* And write new value back to register */
        out_be32(&mm->ipbi_ws_ctrl, val);
+#endif
 
        /*
         * No need to change the pin multiplexing (MPC5XXX_GPS_PORT_CONFIG)
@@ -232,8 +255,57 @@ void spl_board_init(void)
         * MPC5XXX_WU_GPIO_DIR direction is already 0 (INPUT)
         * set bit 0(msb) to 1
         */
-       setbits_be32((void *)MPC5XXX_WU_GPIO_ENABLE, 1 << (31 - 0));
+       setbits_be32((void *)MPC5XXX_WU_GPIO_ENABLE, CONFIG_WDOG_GPIO_PIN);
+
+#if defined(CONFIG_A4M2K)
+       /* Setup USB[x] as MPCDiag[0..3] GPIO outputs */
+
+       /* set USB0,6,7,8 (MPCDiag[0..3]) direction to output */
+       gpio->simple_ddr |= 1 << (31 - 15);
+       gpio->simple_ddr |= 1 << (31 - 14);
+       gpio->simple_ddr |= 1 << (31 - 13);
+       gpio->simple_ddr |= 1 << (31 - 12);
+
+       /* enable USB0,6,7,8 (MPCDiag[0..3]) as GPIO */
+       gpio->simple_gpioe |= 1 << (31 - 15);
+       gpio->simple_gpioe |= 1 << (31 - 14);
+       gpio->simple_gpioe |= 1 << (31 - 13);
+       gpio->simple_gpioe |= 1 << (31 - 12);
+
+       /* Setup PSC2[0..2] as STSLED[0..2] GPIO outputs */
+
+       /* set PSC2[0..2] (STSLED[0..2]) direction to output */
+       gpio->simple_ddr |= 1 << (31 - 27);
+       gpio->simple_ddr |= 1 << (31 - 26);
+       gpio->simple_ddr |= 1 << (31 - 25);
+
+       /* enable PSC2[0..2] (STSLED[0..2]) as GPIO */
+       gpio->simple_gpioe |= 1 << (31 - 27);
+       gpio->simple_gpioe |= 1 << (31 - 26);
+       gpio->simple_gpioe |= 1 << (31 - 25);
+
+       /* Setup PSC6[2] as MRST2 self reset GPIO output */
+
+       /* set PSC6[2]/IRDA_TX (MRST2) direction to output */
+       gpio->simple_ddr |= 1 << (31 - 3);
+
+       /* set PSC6[2]/IRDA_TX (MRST2) output as open drain */
+       gpio->simple_ode |= 1 << (31 - 3);
 
+       /* set PSC6[2]/IRDA_TX (MRST2) output as default high */
+       gpio->simple_dvo |= 1 << (31 - 3);
+
+       /* enable PSC6[2]/IRDA_TX (MRST2) as GPIO */
+       gpio->simple_gpioe |= 1 << (31 - 3);
+
+       /* Setup PSC6[3] as HARNSSCD harness code GPIO input */
+
+       /* set PSC6[3]/IR_USB_CLK (HARNSSCD) direction to input */
+       gpio->simple_ddr |= 0 << (31 - 2);
+
+       /* enable PSC6[3]/IR_USB_CLK (HARNSSCD) as GPIO */
+       gpio->simple_gpioe |= 1 << (31 - 2);
+#else
        /* setup GPIOs for status-leds if needed - see ticket #57 */
        if (failsavelevel > 0) {
                /* digiboard-version is OK */
@@ -267,7 +339,7 @@ void spl_board_init(void)
                 * already cleared (intr_ctrl) MBAR+0x0510 ECLR[0] bit above
                 */
        }
-
+#endif
 }
 
 int checkboard(void)
@@ -278,11 +350,16 @@ int checkboard(void)
 
        get_revisions(&failsavelevel, &digiboardversion, &fpgaversion);
 
+#ifdef CONFIG_A4M2K
+       puts("Board: A4M2K\n");
+       printf("       digiboard IO version %u\n", digiboardversion);
+#else
        puts("Board: A3M071\n");
        printf("Rev:   failsave level       %u\n", failsavelevel);
        printf("       digiboard IO version %u\n", digiboardversion);
        if (failsavelevel > 0)  /* only if fpga-version red */
                printf("       fpga IO version      %u\n", fpgaversion);
+#endif
 
        return 0;
 }
@@ -333,3 +410,57 @@ int spl_start_uboot(void)
        return 1;
 }
 #endif
+
+#if defined(CONFIG_HW_WATCHDOG)
+static int watchdog_toggle;
+
+void hw_watchdog_reset(void)
+{
+       int val;
+
+       /*
+        * Check if watchdog is enabled via user command
+        */
+       if ((gd->flags & GD_FLG_RELOC) && watchdog_toggle) {
+               /* Set direction to output */
+               setbits_be32((void *)MPC5XXX_WU_GPIO_DIR, CONFIG_WDOG_GPIO_PIN);
+
+               /*
+                * Toggle watchdog output
+                */
+               val = (in_be32((void *)MPC5XXX_WU_GPIO_DATA_O) &
+                      CONFIG_WDOG_GPIO_PIN);
+               if (val) {
+                       clrbits_be32((void *)MPC5XXX_WU_GPIO_DATA_O,
+                                    CONFIG_WDOG_GPIO_PIN);
+               } else {
+                       setbits_be32((void *)MPC5XXX_WU_GPIO_DATA_O,
+                                    CONFIG_WDOG_GPIO_PIN);
+               }
+       }
+}
+
+int do_wdog_toggle(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       if (argc != 2)
+               goto usage;
+
+       if (strncmp(argv[1], "on", 2) == 0)
+               watchdog_toggle = 1;
+       else if (strncmp(argv[1], "off", 3) == 0)
+               watchdog_toggle = 0;
+       else
+               goto usage;
+
+       return 0;
+usage:
+       printf("Usage: wdogtoggle %s\n", cmdtp->usage);
+       return 1;
+}
+
+U_BOOT_CMD(
+       wdogtoggle, CONFIG_SYS_MAXARGS, 2, do_wdog_toggle,
+       "toggle GPIO pin to service watchdog",
+       "[on/off] - Switch watchdog toggling via GPIO pin on/off"
+);
+#endif
diff --git a/board/a3m071/is46r16320d.h b/board/a3m071/is46r16320d.h
new file mode 100644 (file)
index 0000000..8183d81
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2004
+ * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.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.
+ */
+
+#define SDRAM_DDR              /* is DDR */
+
+#if defined(CONFIG_MPC5200)
+/* Settings for XLB = 132 MHz */
+/* see is46r16320d datasheet and MPC5200UM chap. 8.6.1. */
+
+/* SDRAM Config Standard timing */
+#define SDRAM_MODE     0x008d0000
+#define SDRAM_EMODE    0x40010000
+#define SDRAM_CONTROL  0x70430f00
+#define SDRAM_CONFIG1  0x33622930
+#define SDRAM_CONFIG2  0x46670000
+#define SDRAM_TAPDELAY 0x10000000
+
+#else
+#error CONFIG_MPC5200 not defined
+#endif
index 7cf5b46b885870858e455d866ed4d91952eadb70..c76728a7fbd3ff9cf06787bf205be4cb32f3fa78 100644 (file)
@@ -81,10 +81,10 @@ SECTIONS
        .bss __bss_start (OVERLAY) : {
                *(.bss*)
                 . = ALIGN(4);
-                ___bssend___ = .;
+                __bss_end = .;
        }
-       .bss_end ___bssend___ (OVERLAY) : {
-               KEEP(*(.__bss_end__));
+       .bss_end __bss_end (OVERLAY) : {
+               KEEP(*(__bss_end));
        }
 
        /DISCARD/ : { *(.dynstr*) }
index e9b5547b7afe65ee0d5f09bcfe44f05abe2ffe2e..984f70e510b17d121babb4e6c41bbda65258582f 100644 (file)
@@ -81,10 +81,10 @@ SECTIONS
        .bss __bss_start (OVERLAY) : {
                *(.bss*)
                 . = ALIGN(4);
-                ___bssend___ = .;
+                __bss_end = .;
        }
-       .bss_end ___bssend___ (OVERLAY) : {
-               KEEP(*(.__bss_end__));
+       .bss_end __bss_end (OVERLAY) : {
+               KEEP(*(__bss_end));
        }
 
        /DISCARD/ : { *(.dynstr*) }
index b79ea3ce2fdd13bc66067c076276594eba78beb1..fc48cf03fde15a93b02699dd1cc72e537e495137 100644 (file)
@@ -81,10 +81,10 @@ SECTIONS
        .bss __bss_start (OVERLAY) : {
                *(.bss*)
                 . = ALIGN(4);
-                ___bssend___ = .;
+                __bss_end = .;
        }
-       .bss_end ___bssend___ (OVERLAY) : {
-               KEEP(*(.__bss_end__));
+       .bss_end __bss_end (OVERLAY) : {
+               KEEP(*(__bss_end));
        }
 
        /DISCARD/ : { *(.dynstr*) }
index 5e0ed002ec99f06ae91c9d1cf8043aed62064ab5..def2f1f93842f3c237b0f415b34405b32609798e 100644 (file)
@@ -89,7 +89,7 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
 ENTRY(_start)
index 52c986e8a9ef0b11a18dbcdf96cd2281ac3ba159..dd9d52db4b2a8c3a961644a3eb3091635d802126 100644 (file)
@@ -65,7 +65,7 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        } >.sram
 
        __image_copy_end = .;
index 900fe65dc288525dd28af9f5d28dc4d16c6b91f6..f3095982b69bc1d8587f1ea61d613e1c4fa0547f 100644 (file)
@@ -102,7 +102,7 @@ SECTIONS
          *(.scommon)
        }
        . = ALIGN(4);
-       __bss_end__ = .;
+       __bss_end = .;
        PROVIDE (end = .);
 
        /* DEBUG -- symbol table, string table, etc. etc.
index 3861b67a01aca9fbba66eb79e173cb927350b21b..e9f026fb7e56b2da850105a411d9943fcb746248 100644 (file)
@@ -98,6 +98,6 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 6308d49c1dcea2cf300980963119aa2bc401d00c..209f48450acad472cf51796d2623d51165be82ca 100644 (file)
@@ -99,6 +99,6 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 5fc906277b98cc136288b1364407f0ddb512a5a6..3d616133d03bd625fb6d5b4c7b9bc0a3337b150a 100644 (file)
@@ -99,6 +99,6 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 3861b67a01aca9fbba66eb79e173cb927350b21b..e9f026fb7e56b2da850105a411d9943fcb746248 100644 (file)
@@ -98,6 +98,6 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index b4600de69532e2feea50e95e7bbdb2047260ba23..2ea394441208b89d3eb03db53a5415e765534998 100644 (file)
@@ -99,6 +99,6 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 521d12a56f80b4ec2f5f2793d1ec2d6a8e3c1800..1b537f6f407262d15c5ce4f25991730471942391 100644 (file)
@@ -90,6 +90,6 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 5ee8fcc50bf216d70cd303daa039b27ec2be2fd5..264e43f54ddef22bc65a553e0efcfacb0aea63d0 100644 (file)
@@ -97,6 +97,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ae8217d02e538a6ebb1d1d79882d8fb6045078f3..d0738cbf46cd9f2f1d5ce5fbdc492817305a50de 100644 (file)
 
         chosen { };
         memory { device_type = "memory"; reg = <0 0>; };
+
+       spi {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "intel,ich9";
+               spi-flash@0 {
+                       reg = <0>;
+                       compatible = "winbond,w25q64", "spi-flash";
+                       memory-map = <0xff800000 0x00800000>;
+               };
+       };
 };
index 5522bf085ecd6024af4519247c2469512b02d697..0faf1970421a6b2a9633602d43783dc4024d0c9a 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <common.h>
 #include <linux/byteorder/swab.h>
+#include <asm/sections.h>
 
 
 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];   /* info for FLASH chips */
index 5522bf085ecd6024af4519247c2469512b02d697..0faf1970421a6b2a9633602d43783dc4024d0c9a 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <common.h>
 #include <linux/byteorder/swab.h>
+#include <asm/sections.h>
 
 
 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];   /* info for FLASH chips */
index e0e8235d7389d14ab5846ab2962ee76656afb037..629ce4a5054e4ab4f6f65c6f88e3c24b9895247d 100644 (file)
@@ -34,7 +34,9 @@
 #include <i2c.h>
 #include <usb.h>
 #include <mmc.h>
+#include <nand.h>
 #include <twl4030.h>
+#include <bmp_layout.h>
 #include <linux/compiler.h>
 
 #include <asm/io.h>
@@ -76,6 +78,65 @@ static u32 gpmc_nand_config[GPMC_MAX_REG] = {
        0,
 };
 
+#ifdef CONFIG_LCD
+#ifdef CONFIG_CMD_NAND
+static int splash_load_from_nand(u32 bmp_load_addr)
+{
+       struct bmp_header *bmp_hdr;
+       int res, splash_screen_nand_offset = 0x100000;
+       size_t bmp_size, bmp_header_size = sizeof(struct bmp_header);
+
+       if (bmp_load_addr + bmp_header_size >= gd->start_addr_sp)
+               goto splash_address_too_high;
+
+       res = nand_read_skip_bad(&nand_info[nand_curr_device],
+                       splash_screen_nand_offset, &bmp_header_size,
+                       (u_char *)bmp_load_addr);
+       if (res < 0)
+               return res;
+
+       bmp_hdr = (struct bmp_header *)bmp_load_addr;
+       bmp_size = le32_to_cpu(bmp_hdr->file_size);
+
+       if (bmp_load_addr + bmp_size >= gd->start_addr_sp)
+               goto splash_address_too_high;
+
+       return nand_read_skip_bad(&nand_info[nand_curr_device],
+                       splash_screen_nand_offset, &bmp_size,
+                       (u_char *)bmp_load_addr);
+
+splash_address_too_high:
+       printf("Error: splashimage address too high. Data overwrites U-Boot "
+               "and/or placed beyond DRAM boundaries.\n");
+
+       return -1;
+}
+#else
+static inline int splash_load_from_nand(void)
+{
+       return -1;
+}
+#endif /* CONFIG_CMD_NAND */
+
+int board_splash_screen_prepare(void)
+{
+       char *env_splashimage_value;
+       u32 bmp_load_addr;
+
+       env_splashimage_value = getenv("splashimage");
+       if (env_splashimage_value == NULL)
+               return -1;
+
+       bmp_load_addr = simple_strtoul(env_splashimage_value, 0, 16);
+       if (bmp_load_addr == 0) {
+               printf("Error: bad splashimage address specified\n");
+               return -1;
+       }
+
+       return splash_load_from_nand(bmp_load_addr);
+}
+#endif /* CONFIG_LCD */
+
 /*
  * Routine: board_init
  * Description: hardware init.
index 7421eeca67cd02b2f199404be116f1829d1bc045..809a7055fd3a8af2a47c89b9375fd2ea61f18005 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 357f59da7ed53806d8890ed88c1f6bf08a8e9cc3..1f006d786704abf4819724a77b5b95c262d06cc3 100644 (file)
@@ -97,6 +97,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 987b52d25cc872e46e920612d152c563d2635d95..663100e58038c52a43bff4bf45545c06551e85fe 100644 (file)
@@ -126,6 +126,6 @@ SECTIONS
   } :bss
 
   . = ALIGN(4);
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 31b079b1c38105d65a22ebb42df20d3fc576d6c8..229025735826fdbed2b69f8f265aab28210ca4e8 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Clocks in use */
-#define SCCR1_CLOCKS_EN        (CLOCK_SCCR1_CFG_EN |                           \
-                        CLOCK_SCCR1_LPC_EN |                           \
-                        CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) |       \
-                        CLOCK_SCCR1_PSCFIFO_EN |                       \
-                        CLOCK_SCCR1_DDR_EN |                           \
-                        CLOCK_SCCR1_FEC_EN |                           \
-                        CLOCK_SCCR1_NFC_EN |                           \
-                        CLOCK_SCCR1_PATA_EN |                          \
-                        CLOCK_SCCR1_PCI_EN |                           \
-                        CLOCK_SCCR1_TPR_EN)
-
-#define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_MEM_EN |           \
-                        CLOCK_SCCR2_SPDIF_EN |         \
-                        CLOCK_SCCR2_DIU_EN |           \
-                        CLOCK_SCCR2_I2C_EN)
-
-int board_early_init_f(void)
-{
-       volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
-       u32 spridr;
-
-       /*
-        * Initialize Local Window for the On Board FPGA access
-        */
-       out_be32(&im->sysconf.lpcs2aw,
-               CSAW_START(CONFIG_SYS_ARIA_FPGA_BASE) |
-               CSAW_STOP(CONFIG_SYS_ARIA_FPGA_BASE, CONFIG_SYS_ARIA_FPGA_SIZE)
-       );
-       out_be32(&im->lpc.cs_cfg[2], CONFIG_SYS_CS2_CFG);
-       sync_law(&im->sysconf.lpcs2aw);
-
-       /*
-        * Initialize Local Window for the On Board SRAM access
-        */
-       out_be32(&im->sysconf.lpcs6aw,
-               CSAW_START(CONFIG_SYS_ARIA_SRAM_BASE) |
-               CSAW_STOP(CONFIG_SYS_ARIA_SRAM_BASE, CONFIG_SYS_ARIA_SRAM_SIZE)
-       );
-       out_be32(&im->lpc.cs_cfg[6], CONFIG_SYS_CS6_CFG);
-       sync_law(&im->sysconf.lpcs6aw);
-
-       /*
-        * Configure Flash Speed
-        */
-       out_be32(&im->lpc.cs_cfg[0], CONFIG_SYS_CS0_CFG);
-
-       spridr = in_be32(&im->sysconf.spridr);
-
-       if (SVR_MJREV(spridr) >= 2)
-               out_be32(&im->lpc.altr, CONFIG_SYS_CS_ALETIMING);
-
-       /*
-        * Enable clocks
-        */
-       out_be32(&im->clk.sccr[0], SCCR1_CLOCKS_EN);
-       out_be32(&im->clk.sccr[1], SCCR2_CLOCKS_EN);
-#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE)
-       setbits_be32(&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN);
-#endif
-
-       return 0;
-}
-
 phys_size_t initdram (int board_type)
 {
        return fixed_sdram(NULL, NULL, 0);
index dd5f266127eab90929ec6a26a9e4973be44eee10..bc34fb58193a25273bdc2182f434d6d15d58159d 100644 (file)
@@ -66,7 +66,7 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        } >.sram
 
        __image_copy_end = .;
index b3a41afc42daa331e6761aabf749d6ec043603ff..2557830f949ca3536e62a54dbd37c72d17d90543 100644 (file)
@@ -74,7 +74,7 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        }
 
        _end = .;
index eb83b6f2ce3a90a281126f9644bf3693d451789d..b13d3e1ec319f1b0736f2fafdb517b8888b9f5e1 100644 (file)
@@ -81,10 +81,10 @@ SECTIONS
        .bss __bss_start (OVERLAY) : {
                *(.bss*)
                 . = ALIGN(4);
-                ___bssend___ = .;
+                __bss_end = .;
        }
-       .bss_end ___bssend___ (OVERLAY) : {
-               KEEP(*(.__bss_end__));
+       .bss_end __bss_end (OVERLAY) : {
+               KEEP(*(__bss_end));
        }
 
        /DISCARD/ : { *(.dynstr*) }
index bd74d746a367f11dcb50339d9d4d57f83ea41e77..a1481c869912f916196142323f815644b0ea0ab5 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ea04eca3aac8730942421f9333162fa1850a7b74..e3f7d809b6c1b2e41d96eb790aaeec604068ed85 100644 (file)
@@ -94,6 +94,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index e5fa63edd6669e9479a5597761bed739ba7a61b3..c00b3c39f85fd561f4f0983694615575bd24b34e 100644 (file)
@@ -89,7 +89,7 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
 ENTRY(_start)
index cca527f26a89a44bd3a5a298bbbb9bdaccb47574..4297b8ba05036c2f7910275a0d07eff196aa56f4 100644 (file)
@@ -100,6 +100,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 748ad7cec61c234472c8c07227c282b1264cb5c3..e38678fc299deae5edb6e4c6ec8db926f896d78c 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Clocks in use */
-#define SCCR1_CLOCKS_EN        (CLOCK_SCCR1_CFG_EN |                           \
-                        CLOCK_SCCR1_LPC_EN |                           \
-                        CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) |       \
-                        CLOCK_SCCR1_PSCFIFO_EN |                       \
-                        CLOCK_SCCR1_DDR_EN |                           \
-                        CLOCK_SCCR1_FEC_EN |                           \
-                        CLOCK_SCCR1_NFC_EN |                           \
-                        CLOCK_SCCR1_PCI_EN |                           \
-                        CLOCK_SCCR1_TPR_EN)
-
-#define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_MEM_EN |   \
-                        CLOCK_SCCR2_I2C_EN)
-
 int eeprom_write_enable(unsigned dev_addr, int state)
 {
        volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
@@ -65,17 +51,8 @@ int eeprom_write_enable(unsigned dev_addr, int state)
 int board_early_init_f(void)
 {
        volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
-       u32 spridr;
        int i;
 
-       /*
-        * Initialize Local Window for NOR FLASH access
-        */
-       out_be32(&im->sysconf.lpcs0aw,
-                CSAW_START(CONFIG_SYS_FLASH_BASE) |
-                CSAW_STOP(CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_SIZE));
-       sync_law(&im->sysconf.lpcs0aw);
-
        /*
         * Initialize Local Window for boot access
         */
@@ -83,37 +60,6 @@ int board_early_init_f(void)
                 CSAW_START(0xffb00000) | CSAW_STOP(0xffb00000, 0x00010000));
        sync_law(&im->sysconf.lpbaw);
 
-       /*
-        * Initialize Local Window for VPC3 access
-        */
-       out_be32(&im->sysconf.lpcs1aw,
-                CSAW_START(CONFIG_SYS_VPC3_BASE) |
-                CSAW_STOP(CONFIG_SYS_VPC3_BASE, CONFIG_SYS_VPC3_SIZE));
-       sync_law(&im->sysconf.lpcs1aw);
-
-       /*
-        * Configure Flash Speed
-        */
-       out_be32(&im->lpc.cs_cfg[0], CONFIG_SYS_CS0_CFG);
-
-       /*
-        * Configure VPC3 Speed
-        */
-       out_be32(&im->lpc.cs_cfg[1], CONFIG_SYS_CS1_CFG);
-
-       spridr = in_be32(&im->sysconf.spridr);
-       if (SVR_MJREV(spridr) >= 2)
-               out_be32(&im->lpc.altr, CONFIG_SYS_CS_ALETIMING);
-
-       /*
-        * Enable clocks
-        */
-       out_be32(&im->clk.sccr[0], SCCR1_CLOCKS_EN);
-       out_be32(&im->clk.sccr[1], SCCR2_CLOCKS_EN);
-#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE)
-       setbits_be32(&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN);
-#endif
-
        /*
         * Configure MSCAN clocks
         */
index 4469b80dc952842b7af5cacde73881ddf5ad3eed..6a5cef6c8c8ad1f7deef16c11aa270ea12ab09be 100644 (file)
@@ -129,6 +129,6 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 7642bba7eef1d3acd2a068a2381f6c8d7b9f137b..a4d9da7aaf2bfd85ed8929623dd0c48e9e7d699e 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 357a794e6960c154e7ac202afc054e5decc11dd3..642f1c9ecf14b2ae2ef059a81214f007330044d1 100644 (file)
@@ -101,6 +101,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index e2cfcfefec07b4d233dd5d77d0f6e1f30d8a15dd..44c61eb82cb9419e7559944e4212e456ee6e7088 100644 (file)
@@ -97,6 +97,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 450103d377b460fa999cee8a662d0af5c37906fa..0e2206c222c633e08a0378c64bd691f87cdca540 100644 (file)
@@ -95,7 +95,7 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
 ENTRY(_start)
index bd74d746a367f11dcb50339d9d4d57f83ea41e77..a1481c869912f916196142323f815644b0ea0ab5 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index f3c9ed8c6138f644ea3de0fe15a8a89c0ff64f98..6f80e41159906200931f6fc9361bff8b82e790b0 100644 (file)
@@ -97,6 +97,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ae0a48dfbbad8f9bc39090c23a37db0576018e57..9db171ed4ee249be294bff9cb5ad3253e39c206f 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 603858bc0cabd8086649004f6983eec5f25d9272..f11d4831bea07603e4f44b7d6f180dd784c3f762 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 7421eeca67cd02b2f199404be116f1829d1bc045..809a7055fd3a8af2a47c89b9375fd2ea61f18005 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 6838247a8b31d8c540877f816041a589cc2506f5..9de88852abc467dfb3e641cf1e0001453313f407 100644 (file)
@@ -97,6 +97,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 7421eeca67cd02b2f199404be116f1829d1bc045..809a7055fd3a8af2a47c89b9375fd2ea61f18005 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index e222e80f82bf61816cafe417021fc8a6315023fe..82b67d50a9057dc6c7bf3addb672f1ff172bf9c9 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 7421eeca67cd02b2f199404be116f1829d1bc045..809a7055fd3a8af2a47c89b9375fd2ea61f18005 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index c18758a911449fe9927d130f07fed8951d8ae26c..fda4cf426d2cf9812fe9b692cb3b236212731f1b 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 20f6c47bed9e5a4d20ac9dc4343b46eb51fced28..cdfd0e41642e077092f8ee502dae885c5bb20692 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 15dfa7dd7cf7f06d0b8f21736438cda3001c5801..c40c565922d25f43db57694867e7a9ac320cbccb 100644 (file)
@@ -99,6 +99,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 5013ff4a69665c2024bc7c1ab40c912368c6f64f..f803e4af053d12eb76fa8fd1fb30dfe7ea8cdb62 100644 (file)
@@ -97,6 +97,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 5ee8fcc50bf216d70cd303daa039b27ec2be2fd5..264e43f54ddef22bc65a553e0efcfacb0aea63d0 100644 (file)
@@ -97,6 +97,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 2df386bcb0662ef32446d3132f190e7e373e860f..3247dbf6d109d6e1e15e79a5f2820f6a60a49136 100644 (file)
@@ -94,6 +94,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 4440d611b75273ac5e9434b777f5f3e9f264006c..fd1289ec8788fdfb3ff066b926bf4a7cac682460 100644 (file)
@@ -94,6 +94,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 2df386bcb0662ef32446d3132f190e7e373e860f..3247dbf6d109d6e1e15e79a5f2820f6a60a49136 100644 (file)
@@ -94,6 +94,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 269bf8a9e563506994d8a23db0df4bfbef8e58a7..bbe36f087a7f4d62fe48b9d0340496343dcb9136 100644 (file)
@@ -94,6 +94,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 68bdad4a46cc5cd52f214fae64b17e845a112534..93159277614e79202b636261df5a53b6b39b3633 100644 (file)
@@ -94,6 +94,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 97eeab3a23415ab34b0202e326532b11020eec1c..33a8aa51847d4e91b6287889349c11f6f9f5e988 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Clocks in use */
-#define SCCR1_CLOCKS_EN        (CLOCK_SCCR1_CFG_EN |                           \
-                        CLOCK_SCCR1_DDR_EN |                           \
-                        CLOCK_SCCR1_FEC_EN |                           \
-                        CLOCK_SCCR1_LPC_EN |                           \
-                        CLOCK_SCCR1_NFC_EN |                           \
-                        CLOCK_SCCR1_PATA_EN |                          \
-                        CLOCK_SCCR1_PCI_EN |                           \
-                        CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) |       \
-                        CLOCK_SCCR1_PSCFIFO_EN |                       \
-                        CLOCK_SCCR1_TPR_EN)
-
-#define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_DIU_EN |           \
-                        CLOCK_SCCR2_I2C_EN |           \
-                        CLOCK_SCCR2_MEM_EN |           \
-                        CLOCK_SCCR2_SPDIF_EN |         \
-                        CLOCK_SCCR2_USB1_EN |          \
-                        CLOCK_SCCR2_USB2_EN)
-
 void __mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip);
 
 /* Active chip number set in board_nand_select_device() (mpc5121_nfc.c) */
@@ -83,20 +64,6 @@ void mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip)
 
 int board_early_init_f(void)
 {
-       volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
-       u32 spridr;
-
-       /*
-        * Initialize Local Window for the CPLD registers access (CS2 selects
-        * the CPLD chip)
-        */
-       out_be32(&im->sysconf.lpcs2aw,
-               CSAW_START(CONFIG_SYS_CPLD_BASE) |
-               CSAW_STOP(CONFIG_SYS_CPLD_BASE, CONFIG_SYS_CPLD_SIZE)
-       );
-       out_be32(&im->lpc.cs_cfg[2], CONFIG_SYS_CS2_CFG);
-       sync_law(&im->sysconf.lpcs2aw);
-
        /*
         * Disable Boot NOR FLASH write protect - CPLD Reg 8 NOR FLASH Control
         *
@@ -114,25 +81,6 @@ int board_early_init_f(void)
                out_8((u8 *)(CONFIG_SYS_CPLD_BASE + 0x08), 0x32);
        }
 #endif
-       /*
-        * Configure Flash Speed
-        */
-       out_be32(&im->lpc.cs_cfg[0], CONFIG_SYS_CS0_CFG);
-
-       spridr = in_be32(&im->sysconf.spridr);
-
-       if (SVR_MJREV (spridr) >= 2)
-               out_be32 (&im->lpc.altr, CONFIG_SYS_CS_ALETIMING);
-
-       /*
-        * Enable clocks
-        */
-       out_be32 (&im->clk.sccr[0], SCCR1_CLOCKS_EN);
-       out_be32 (&im->clk.sccr[1], SCCR2_CLOCKS_EN);
-#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE)
-       setbits_be32 (&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN);
-#endif
-
        return 0;
 }
 
index 2d08fea52245e0b81bf1d50db1ab247506ef29e6..264c4e80adfc16b6dc6f4a0225e705f0ff824617 100644 (file)
@@ -87,10 +87,10 @@ SECTIONS
        .bss __bss_start (OVERLAY) : {
                *(.bss*)
                 . = ALIGN(4);
-                ___bssend___ = .;
+                __bss_end = .;
        }
-       .bss_end ___bssend___ (OVERLAY) : {
-               KEEP(*(.__bss_end__));
+       .bss_end __bss_end (OVERLAY) : {
+               KEEP(*(__bss_end));
        }
 
        /DISCARD/ : { *(.bss*) }
index dac87db6207487052fbba16fa4bae0362940bc24..60039ccfb4a5b317a6afd9a3713cfacae644fc18 100644 (file)
@@ -134,7 +134,7 @@ SECTIONS
        . = ALIGN(16); /* to speed clearing of bss up */
        }
        __bss_end = . ;
-       __bss_end__ = . ;
+       __bss_end = . ;
        PROVIDE (end = .);
 
 /* Relocated into main memory */
index 78e0e2df6c4cc342b6772506bbebe726f55ad47d..ec73f737cd3d02b710871585622eaa26d3577d53 100644 (file)
@@ -134,7 +134,7 @@ SECTIONS
        . = ALIGN(16); /* to speed clearing of bss up */
        }
        __bss_end = . ;
-       __bss_end__ = . ;
+       __bss_end = . ;
        PROVIDE (end = .);
 
 /* Relocated into main memory */
index 87ea473b0a9b42158748fc0a3f1c311a23fa563a..18dfb814bf61eb9873967af6cc8218fc5f046fb6 100644 (file)
@@ -135,7 +135,7 @@ SECTIONS
        . = ALIGN(16); /* to speed clearing of bss up */
        }
        __bss_end = . ;
-       __bss_end__ = . ;
+       __bss_end = . ;
        PROVIDE (end = .);
 
 /* Relocated into main memory */
index e854a169a86ec07abaaf3f9c4386e9ab845e4900..8de272e4cbdef8a0a13dcb425ebef8707427a292 100644 (file)
@@ -134,7 +134,7 @@ SECTIONS
        . = ALIGN(16); /* to speed clearing of bss up */
        }
        __bss_end = . ;
-       __bss_end__ = . ;
+       __bss_end = . ;
        PROVIDE (end = .);
 
 /* Relocated into main memory */
index f247e56b0a2f25721f155e51bbdcf032918c910c..e57f73412170ef2e3140b625e72ff3d492c6a10e 100644 (file)
@@ -133,7 +133,7 @@ SECTIONS
        . = ALIGN(16); /* to speed clearing of bss up */
        }
        __bss_end = . ;
-       __bss_end__ = . ;
+       __bss_end = . ;
        PROVIDE (end = .);
 
 /* Relocated into main memory */
index b06144196f473a4a3ed90095a2baa9a54c6613be..30138dd814a7b9f60e590bc3981b07f2002522b9 100644 (file)
@@ -97,7 +97,7 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 
   .ppcenv:
index 9e9449d1a13223b4332e0801bf83ed1b41fbf71a..08fb4aa1fd8b7dd5dc9e3d0b51d35c7ec04d70fd 100644 (file)
@@ -98,6 +98,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 958dd8482e2c9a0dc2d963bf92c52b90e72985e6..b351a6811061998c2396e162ccf7d227f3944d24 100644 (file)
@@ -112,6 +112,6 @@ SECTIONS
     common/env_embedded.o (.ppcenv)
   }
   . = ALIGN(4);
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index b2bb50d596e2def00295382b4f092096203afcc2..8e5896375931dcc690caa8b1fa46647dac0def4b 100644 (file)
@@ -99,6 +99,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 3133c55a08692a14220e9ec805a368b2791f6475..5d1c2ad3cb62a9ec0c513733a0b8e3f9a467b973 100644 (file)
@@ -143,6 +143,6 @@ SECTIONS
     common/env_embedded.o (.ppcenv)
   }
   . = ALIGN(4);
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 40f4a38f55c47e0f652cad9c84ae570d18b58ce9..6e4939b8bf9c086994e965bf8dc32a33157c4663 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 6d138313e2811e27196b2b61da1f5dfff01bd5f6..5b8d3b3715792ae101c895300dc319ac564d55ab 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    . = ALIGN(4);
    _ebss = .;
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
diff --git a/board/ifm/ac14xx/Makefile b/board/ifm/ac14xx/Makefile
new file mode 100644 (file)
index 0000000..9a76f32
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2009 Wolfgang Denk <wd@denx.de>
+#
+# 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.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    = $(obj)lib$(BOARD).o
+
+COBJS-y        := $(BOARD).o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+SOBJS  := $(addprefix $(obj),$(SOBJS))
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/ifm/ac14xx/ac14xx.c b/board/ifm/ac14xx/ac14xx.c
new file mode 100644 (file)
index 0000000..7442591
--- /dev/null
@@ -0,0 +1,617 @@
+/*
+ * (C) Copyright 2009 Wolfgang Denk <wd@denx.de>
+ * (C) Copyright 2009 Dave Srl www.dave.eu
+ * (C) Copyright 2010 ifm ecomatic GmbH
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/bitops.h>
+#include <command.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/mpc512x.h>
+#include <fdt_support.h>
+#ifdef CONFIG_MISC_INIT_R
+#include <i2c.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void gpio_configure(void)
+{
+       immap_t *im;
+       gpio512x_t *gpioregs;
+
+       im = (immap_t *) CONFIG_SYS_IMMR;
+       gpioregs = &im->gpio;
+       out_be32(&gpioregs->gpodr, 0x00290000); /* open drain */
+       out_be32(&gpioregs->gpdat, 0x80001040); /* data (when output) */
+
+       /*
+        * out_be32(&gpioregs->gpdir, 0xC2293020);
+        * workaround for a hardware affect: configure direction in pieces,
+        * setting all outputs at once drops the reset line too low and
+        * makes us lose the MII connection (breaks ethernet for us)
+        */
+       out_be32(&gpioregs->gpdir, 0x02003060); /* direction */
+       setbits_be32(&gpioregs->gpdir, 0x00200000); /* += reset asi */
+       udelay(10);
+       setbits_be32(&gpioregs->gpdir, 0x00080000); /* += reset safety */
+       udelay(10);
+       setbits_be32(&gpioregs->gpdir, 0x00010000); /* += reset comm */
+       udelay(10);
+       setbits_be32(&gpioregs->gpdir, 0xC0000000); /* += backlight, KB sel */
+
+       /* to turn from red to yellow when U-Boot runs */
+       setbits_be32(&gpioregs->gpdat, 0x00002020);
+       out_be32(&gpioregs->gpimr, 0x00000000); /* interrupt mask */
+       out_be32(&gpioregs->gpicr1, 0x00000004); /* interrupt sense part 1 */
+       out_be32(&gpioregs->gpicr2, 0x00A80000); /* interrupt sense part 2 */
+       out_be32(&gpioregs->gpier, 0xFFFFFFFF); /* interrupt events, clear */
+}
+
+/* the physical location of the pins */
+#define GPIOKEY_ROW_BITMASK    0x40000000
+#define GPIOKEY_ROW_UPPER      0
+#define GPIOKEY_ROW_LOWER      1
+
+#define GPIOKEY_COL0_BITMASK   0x20000000
+#define GPIOKEY_COL1_BITMASK   0x10000000
+#define GPIOKEY_COL2_BITMASK   0x08000000
+
+/* the logical presentation of pressed keys */
+#define GPIOKEY_BIT_FNLEFT     (1 << 5)
+#define GPIOKEY_BIT_FNRIGHT    (1 << 4)
+#define GPIOKEY_BIT_DIRUP      (1 << 3)
+#define GPIOKEY_BIT_DIRLEFT    (1 << 2)
+#define GPIOKEY_BIT_DIRRIGHT   (1 << 1)
+#define GPIOKEY_BIT_DIRDOWN    (1 << 0)
+
+/* the hotkey combination which starts recovery */
+#define GPIOKEY_BITS_RECOVERY  (GPIOKEY_BIT_FNLEFT | GPIOKEY_BIT_DIRUP | \
+                                GPIOKEY_BIT_DIRDOWN)
+
+static void gpio_selectrow(gpio512x_t *gpioregs, u32 row)
+{
+
+       if (row)
+               setbits_be32(&gpioregs->gpdat, GPIOKEY_ROW_BITMASK);
+       else
+               clrbits_be32(&gpioregs->gpdat, GPIOKEY_ROW_BITMASK);
+       udelay(10);
+}
+
+static u32 gpio_querykbd(void)
+{
+       immap_t *im;
+       gpio512x_t *gpioregs;
+       u32 keybits;
+       u32 input;
+
+       im = (immap_t *)CONFIG_SYS_IMMR;
+       gpioregs = &im->gpio;
+       keybits = 0;
+
+       /* query upper row */
+       gpio_selectrow(gpioregs, GPIOKEY_ROW_UPPER);
+       input = in_be32(&gpioregs->gpdat);
+       if ((input & GPIOKEY_COL0_BITMASK) == 0)
+               keybits |= GPIOKEY_BIT_FNLEFT;
+       if ((input & GPIOKEY_COL1_BITMASK) == 0)
+               keybits |= GPIOKEY_BIT_DIRUP;
+       if ((input & GPIOKEY_COL2_BITMASK) == 0)
+               keybits |= GPIOKEY_BIT_FNRIGHT;
+
+       /* query lower row */
+       gpio_selectrow(gpioregs, GPIOKEY_ROW_LOWER);
+       input = in_be32(&gpioregs->gpdat);
+       if ((input & GPIOKEY_COL0_BITMASK) == 0)
+               keybits |= GPIOKEY_BIT_DIRLEFT;
+       if ((input & GPIOKEY_COL1_BITMASK) == 0)
+               keybits |= GPIOKEY_BIT_DIRRIGHT;
+       if ((input & GPIOKEY_COL2_BITMASK) == 0)
+               keybits |= GPIOKEY_BIT_DIRDOWN;
+
+       /* return bit pattern for keys */
+       return keybits;
+}
+
+/* excerpt from the recovery's hw_info.h */
+
+static int eeprom_diag = 1;
+
+struct __attribute__ ((__packed__)) eeprom_layout {
+       char    magic[3];       /** 'ifm' */
+       u8      len[2];         /** content length without magic/len fields */
+       u8      version[3];     /** structure version */
+       u8      type;           /** type of PCB */
+       u8      reserved[0x37]; /** padding up to offset 0x40 */
+       u8      macaddress[6];  /** ethernet MAC (for the mainboard) @0x40 */
+};
+
+#define HW_COMP_MAINCPU 2
+
+static struct eeprom_layout eeprom_content;
+static int eeprom_was_read;    /* has_been_read */
+static int eeprom_is_valid;
+static int eeprom_version;
+
+#define get_eeprom_field_int(name) ({ \
+       int value; \
+       int idx; \
+       value = 0; \
+       for (idx = 0; idx < sizeof(name); idx++) { \
+               value <<= 8; \
+               value |= name[idx]; \
+       } \
+       value; \
+})
+
+static int read_eeprom(void)
+{
+       int eeprom_datalen;
+       int ret;
+
+       if (eeprom_was_read)
+               return 0;
+
+       eeprom_is_valid = 0;
+       ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
+                       CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
+                       (uchar *)&eeprom_content, sizeof(eeprom_content));
+       if (eeprom_diag) {
+               printf("DIAG: %s() read rc[%d], size[%d]\n",
+                       __func__, ret, sizeof(eeprom_content));
+       }
+
+       if (ret != 0)
+               return -1;
+
+       eeprom_was_read = 1;
+
+       /*
+        * check validity of EEPROM content
+        * (check version, length, optionally checksum)
+        */
+       eeprom_is_valid = 1;
+       eeprom_datalen = get_eeprom_field_int(eeprom_content.len);
+       eeprom_version = get_eeprom_field_int(eeprom_content.version);
+
+       if (eeprom_diag) {
+               printf("DIAG: %s() magic[%c%c%c] len[%d] ver[%d] type[%d]\n",
+                       __func__, eeprom_content.magic[0],
+                       eeprom_content.magic[1], eeprom_content.magic[2],
+                       eeprom_datalen, eeprom_version, eeprom_content.type);
+       }
+       if (strncmp(eeprom_content.magic, "ifm", strlen("ifm")) != 0)
+               eeprom_is_valid = 0;
+       if (eeprom_datalen < sizeof(struct eeprom_layout) - 5)
+               eeprom_is_valid = 0;
+       if ((eeprom_version != 1) && (eeprom_version != 2))
+               eeprom_is_valid = 0;
+       if (eeprom_content.type != HW_COMP_MAINCPU)
+               eeprom_is_valid = 0;
+
+       if (eeprom_diag)
+               printf("DIAG: %s() valid[%d]\n", __func__, eeprom_is_valid);
+
+       return ret;
+}
+
+int mac_read_from_eeprom(void)
+{
+       const u8 *mac;
+
+       if (read_eeprom()) {
+               printf("I2C EEPROM read failed.\n");
+               return -1;
+       }
+
+       if (!eeprom_is_valid) {
+               printf("I2C EEPROM content not valid\n");
+               return -1;
+       }
+
+       mac = NULL;
+       switch (eeprom_version) {
+       case 1:
+       case 2:
+               mac = (const u8 *)&eeprom_content.macaddress;
+               break;
+       }
+
+       if (mac && is_valid_ether_addr(mac)) {
+               eth_setenv_enetaddr("ethaddr", mac);
+               printf("DIAG: %s() MAC value [%s]\n",
+                       __func__, getenv("ethaddr"));
+       }
+
+       return 0;
+}
+
+/*
+ * BEWARE!
+ * this board uses DDR1(!) Micron SDRAM, *NOT* the DDR2
+ * which the ADS, Aria or PDM360NG boards are using
+ * (the steps outlined here refer to the Micron datasheet)
+ */
+u32 sdram_init_seq[] = {
+       /* item 6, at least one NOP after CKE went high */
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       /* item 7, precharge all; item 8, tRP (20ns) */
+       CONFIG_SYS_DDRCMD_PCHG_ALL,
+       CONFIG_SYS_DDRCMD_NOP,
+       /* item 9, extended mode register; item 10, tMRD 10ns) */
+       CONFIG_SYS_MICRON_EMODE | CONFIG_SYS_MICRON_EMODE_PARAM,
+       CONFIG_SYS_DDRCMD_NOP,
+       /*
+        * item 11, (base) mode register _with_ reset DLL;
+        * item 12, tMRD (10ns)
+        */
+       CONFIG_SYS_MICRON_BMODE | CONFIG_SYS_MICRON_BMODE_RSTDLL |
+       CONFIG_SYS_MICRON_BMODE_PARAM,
+       CONFIG_SYS_DDRCMD_NOP,
+       /* item 13, precharge all; item 14, tRP (20ns) */
+       CONFIG_SYS_DDRCMD_PCHG_ALL,
+       CONFIG_SYS_DDRCMD_NOP,
+       /*
+        * item 15, auto refresh (i.e. refresh with CKE held high);
+        * item 16, tRFC (70ns)
+        */
+       CONFIG_SYS_DDRCMD_RFSH,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       /*
+        * item 17, auto refresh (i.e. refresh with CKE held high);
+        * item 18, tRFC (70ns)
+        */
+       CONFIG_SYS_DDRCMD_RFSH,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       CONFIG_SYS_DDRCMD_NOP,
+       /* item 19, optional, unassert DLL reset; item 20, tMRD (20ns) */
+       CONFIG_SYS_MICRON_BMODE | CONFIG_SYS_MICRON_BMODE_PARAM,
+       CONFIG_SYS_DDRCMD_NOP,
+       /*
+        * item 21, "actually done", but make sure 200 DRAM clock cycles
+        * have passed after DLL reset before READ requests are issued
+        * (200 cycles at 160MHz -> 1.25 usec)
+        */
+       /* EMPTY, optional, we don't do it */
+};
+
+phys_size_t initdram(int board_type)
+{
+       return fixed_sdram(NULL, sdram_init_seq, ARRAY_SIZE(sdram_init_seq));
+}
+
+int misc_init_r(void)
+{
+       u32 keys;
+       char *s;
+       int want_recovery;
+
+       /* we use bus I2C-0 for the on-board eeprom */
+       i2c_set_bus_num(0);
+
+       /* setup GPIO directions and initial values */
+       gpio_configure();
+
+       /*
+        * check the GPIO keyboard,
+        * enforced start of the recovery when
+        * - the appropriate keys were pressed
+        * - a previous installation was aborted or has failed
+        * - "some" external software told us to
+        */
+       want_recovery = 0;
+       keys = gpio_querykbd();
+       printf("GPIO keyboard status [0x%08X]\n", keys);
+       /* XXX insist in the _exact_ combination? */
+       if ((keys & GPIOKEY_BITS_RECOVERY) == GPIOKEY_BITS_RECOVERY) {
+               printf("GPIO keyboard requested RECOVERY\n");
+               /* XXX TODO
+                * refine the logic to detect the first keypress, and
+                * wait to recheck IF it was the recovery combination?
+                */
+               want_recovery = 1;
+       }
+       s = getenv("install_in_progress");
+       if ((s != NULL) && (*s != '\0')) {
+               printf("previous installation aborted, running RECOVERY\n");
+               want_recovery = 1;
+       }
+       s = getenv("install_failed");
+       if ((s != NULL) && (*s != '\0')) {
+               printf("previous installation FAILED, running RECOVERY\n");
+               want_recovery = 1;
+       }
+       s = getenv("want_recovery");
+       if ((s != NULL) && (*s != '\0')) {
+               printf("running RECOVERY according to the request\n");
+               want_recovery = 1;
+       }
+
+       if (want_recovery)
+               setenv("bootcmd", "run recovery");
+
+       /*
+        * boot the recovery system without waiting; boot the
+        * production system without waiting by default, only
+        * insert a pause (to provide a chance to get a prompt)
+        * when GPIO keys were pressed during power on
+        */
+       if (want_recovery)
+               setenv("bootdelay", "0");
+       else if (!keys)
+               setenv("bootdelay", "0");
+       else
+               setenv("bootdelay", "2");
+
+       /* get the ethernet MAC from I2C EEPROM */
+       mac_read_from_eeprom();
+
+       return 0;
+}
+
+/* setup specific IO pad configuration */
+static  iopin_t ioregs_init[] = {
+       {       /* LPC CS3 */
+               offsetof(struct ioctrl512x, io_control_nfc_ce0), 1,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(1) | IO_PIN_DS(2),
+       },
+       {       /* LPC CS1 */
+               offsetof(struct ioctrl512x, io_control_lpc_cs1), 1,
+               IO_PIN_OVER_DRVSTR,
+               IO_PIN_DS(2),
+       },
+       {       /* LPC CS2 */
+               offsetof(struct ioctrl512x, io_control_lpc_cs2), 1,
+               IO_PIN_OVER_DRVSTR,
+               IO_PIN_DS(2),
+       },
+       {       /* LPC CS4, CS5 */
+               offsetof(struct ioctrl512x, io_control_pata_ce1), 2,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(1) | IO_PIN_DS(2),
+       },
+       {       /* SDHC CLK, CMD, D0, D1, D2, D3 */
+               offsetof(struct ioctrl512x, io_control_pata_ior), 6,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(1) | IO_PIN_DS(2),
+       },
+       {       /* GPIO keyboard */
+               offsetof(struct ioctrl512x, io_control_pci_ad30), 4,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO DN1 PF, LCD power, DN2 PF */
+               offsetof(struct ioctrl512x, io_control_pci_ad26), 3,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO reset AS-i */
+               offsetof(struct ioctrl512x, io_control_pci_ad21), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO reset safety */
+               offsetof(struct ioctrl512x, io_control_pci_ad19), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO reset netX */
+               offsetof(struct ioctrl512x, io_control_pci_ad16), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO ma2 en */
+               offsetof(struct ioctrl512x, io_control_pci_ad15), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO SD CD, SD WP */
+               offsetof(struct ioctrl512x, io_control_pci_ad08), 2,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* FEC RX DV */
+               offsetof(struct ioctrl512x, io_control_pci_ad06), 1,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(2) | IO_PIN_DS(2),
+       },
+       {       /* GPIO AS-i prog, AS-i done, LCD backlight */
+               offsetof(struct ioctrl512x, io_control_pci_ad05), 3,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO AS-i wdg */
+               offsetof(struct ioctrl512x, io_control_pci_req2), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO safety wdg */
+               offsetof(struct ioctrl512x, io_control_pci_req1), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO netX wdg */
+               offsetof(struct ioctrl512x, io_control_pci_req0), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO IRQ powerfail */
+               offsetof(struct ioctrl512x, io_control_pci_inta), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO AS-i PWRD */
+               offsetof(struct ioctrl512x, io_control_pci_frame), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO LED0, LED1 */
+               offsetof(struct ioctrl512x, io_control_pci_idsel), 2,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* GPIO IRQ AS-i 1, IRQ AS-i 2, IRQ safety */
+               offsetof(struct ioctrl512x, io_control_pci_irdy), 3,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /* DIU clk */
+               offsetof(struct ioctrl512x, io_control_spdif_txclk), 1,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(2) | IO_PIN_DS(2),
+       },
+       {       /* FEC TX ER, CRS */
+               offsetof(struct ioctrl512x, io_control_spdif_tx), 2,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(1) | IO_PIN_DS(2),
+       },
+       {       /* GPIO/GPT */ /* to *NOT* have the EXT IRQ0 float */
+               offsetof(struct ioctrl512x, io_control_irq0), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       {       /*
+                * FEC col, tx en, tx clk, txd 0-3, mdc, rx er,
+                * rdx 3-0, mdio, rx clk
+                */
+               offsetof(struct ioctrl512x, io_control_psc0_0), 15,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(1) | IO_PIN_DS(2),
+       },
+       /* optional: make sure PSC3 remains the serial console */
+       {       /* LPC CS6 */
+               offsetof(struct ioctrl512x, io_control_psc3_4), 1,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(1) | IO_PIN_DS(2),
+       },
+       /* make sure PSC4 remains available for SPI,
+           *BUT* PSC4_1 is a GPIO kind of SS! */
+       {       /* enforce drive strength on the SPI pin */
+               offsetof(struct ioctrl512x, io_control_psc4_0), 5,
+               IO_PIN_OVER_DRVSTR,
+               IO_PIN_DS(2),
+       },
+       {
+               offsetof(struct ioctrl512x, io_control_psc4_1), 1,
+               IO_PIN_OVER_FMUX,
+               IO_PIN_FMUX(3),
+       },
+       /* optional: make sure PSC5 remains available for SPI */
+       {       /* enforce drive strength on the SPI pin */
+               offsetof(struct ioctrl512x, io_control_psc5_0), 5,
+               IO_PIN_OVER_DRVSTR,
+               IO_PIN_DS(1),
+       },
+       {       /* LPC TSIZ1 */
+               offsetof(struct ioctrl512x, io_control_psc6_0), 1,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(1) | IO_PIN_DS(2),
+       },
+       {       /* DIU hsync */
+               offsetof(struct ioctrl512x, io_control_psc6_1), 1,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(2) | IO_PIN_DS(1),
+       },
+       {       /* DIU vsync */
+               offsetof(struct ioctrl512x, io_control_psc6_4), 1,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(2) | IO_PIN_DS(1),
+       },
+       {       /* PSC7, part of DIU RGB */
+               offsetof(struct ioctrl512x, io_control_psc7_0), 2,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(2) | IO_PIN_DS(1),
+       },
+       {       /* PSC7, safety UART */
+               offsetof(struct ioctrl512x, io_control_psc7_2), 2,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(0) | IO_PIN_DS(1),
+       },
+       {       /* DIU (part of) RGB[] */
+               offsetof(struct ioctrl512x, io_control_psc8_3), 16,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(2) | IO_PIN_DS(1),
+       },
+       {       /* DIU data enable */
+               offsetof(struct ioctrl512x, io_control_psc11_4), 1,
+               IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
+               IO_PIN_FMUX(2) | IO_PIN_DS(1),
+       },
+       /* reduce LPB drive strength for improved EMI */
+       {       /* LPC OE, LPC RW */
+               offsetof(struct ioctrl512x, io_control_lpc_oe), 2,
+               IO_PIN_OVER_DRVSTR,
+               IO_PIN_DS(2),
+       },
+       {       /* LPC AX03 through LPC AD00 */
+               offsetof(struct ioctrl512x, io_control_lpc_ax03), 36,
+               IO_PIN_OVER_DRVSTR,
+               IO_PIN_DS(2),
+       },
+       {       /* LPC CS5 */
+               offsetof(struct ioctrl512x, io_control_pata_ce2), 1,
+               IO_PIN_OVER_DRVSTR,
+               IO_PIN_DS(2),
+       },
+       {       /* SDHC CLK */
+               offsetof(struct ioctrl512x, io_control_nfc_wp), 1,
+               IO_PIN_OVER_DRVSTR,
+               IO_PIN_DS(2),
+       },
+       {       /* SDHC DATA */
+               offsetof(struct ioctrl512x, io_control_nfc_ale), 4,
+               IO_PIN_OVER_DRVSTR,
+               IO_PIN_DS(2),
+       },
+};
+
+int checkboard(void)
+{
+       puts("Board: ifm AC14xx\n");
+
+       /* initialize function mux & slew rate IO inter alia on IO Pins  */
+       iopin_initialize_bits(ioregs_init, ARRAY_SIZE(ioregs_init));
+
+       return 0;
+}
+
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
+void ft_board_setup(void *blob, bd_t *bd)
+{
+       ft_cpu_setup(blob, bd);
+}
+#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index dcd53ec9af06117a117828c7dfd5bb37307d8a66..1b43dbe7882745398ea6766f5a31857cbcc38937 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index defc885db70adaa06e5d5b470079f859308254f8..f98844d317db7ce34b603f2a05923f26c21c65ed 100644 (file)
 #include <libfdt.h>
 #endif
 
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
 #include <i2c.h>
-#endif
-
 #include "../common/common.h"
 
 /*
@@ -370,7 +367,7 @@ static void set_pin(int state, unsigned long mask);
  * will toggle once what forces the mgocge3un part to restart
  * immediately.
  */
-void handle_mgcoge3un_reset(void)
+static void handle_mgcoge3un_reset(void)
 {
        char *bobcatreset = getenv("bobcatreset");
        if (bobcatreset) {
index b6fa79f0a213d22db43c0ba43776cab3fb12d6fc..52c929cab95da261f715043f7db5da03e179cf84 100644 (file)
@@ -135,6 +135,6 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 30523dca469e22f67e6a2ffcd607516e67b053e3..ce11a91da6de3ee571911c31b2ad8dfc1621c90a 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 8c75dea0fd074b81eb331576ad487e3a3d554440..d1bb1278886461d37a94e7c90d2a04d7bef98cff 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 57077701cab72aa4186be72a88980125d92108db..3225c0bb2ae0b5991ec290c402335f224a52ba34 100644 (file)
@@ -100,6 +100,6 @@ SECTIONS
    *(.sbss*)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 080829b4360607f7a8777a60026ce4db165b5678..17ff94e5da62e438e70c139829bc4f5754fdd5d5 100644 (file)
@@ -88,6 +88,6 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index e186ee6657ff89ecbd9cafc621bd547a9adb92d4..adbb5f9dac6bedcf13b3040a9716df185d0ba6ab 100644 (file)
@@ -97,6 +97,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ddb5a72b2ba8a77c5eede85e4313b5e41c707a9f..03891e937f1123349d8576860f1aa9bc2d6c37df 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ddb5a72b2ba8a77c5eede85e4313b5e41c707a9f..03891e937f1123349d8576860f1aa9bc2d6c37df 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ddb5a72b2ba8a77c5eede85e4313b5e41c707a9f..03891e937f1123349d8576860f1aa9bc2d6c37df 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ddb5a72b2ba8a77c5eede85e4313b5e41c707a9f..03891e937f1123349d8576860f1aa9bc2d6c37df 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 7d9f361a8abeb50ca870de9114048351ac7bf289..8d7a22765a19f9f1cface6362c6fedf1ee8f2fdb 100644 (file)
@@ -132,10 +132,7 @@ int board_init(void)
        clock_init();
        clock_verify();
 
-#ifdef CONFIG_SPI_UART_SWITCH
-       gpio_config_uart();
-#endif
-#if defined(CONFIG_TEGRA_SPI) || defined(CONFIG_TEGRA_SLINK)
+#ifdef CONFIG_FDT_SPI
        pin_mux_spi();
        spi_init();
 #endif
index bd6202c2999ba6b2ef986a97caab534fd2b8673f..d9bcb854011afe2196544eb9116e2eb466645408 100644 (file)
@@ -1,4 +1,3 @@
 # common options for all tegra boards
 COBJS-y        += ../../nvidia/common/board.o
-COBJS-$(CONFIG_SPI_UART_SWITCH) += ../../nvidia/common/uart-spi-switch.o
 COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += ../../nvidia/common/emc.o
diff --git a/board/nvidia/common/uart-spi-switch.c b/board/nvidia/common/uart-spi-switch.c
deleted file mode 100644 (file)
index e9d445d..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2011 The Chromium OS Authors.
- *
- * 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/gpio.h>
-#include <asm/arch/pinmux.h>
-#include <asm/arch/uart-spi-switch.h>
-#include <asm/arch/tegra.h>
-#include <asm/arch-tegra/tegra_spi.h>
-#include <asm/arch-tegra/board.h>
-
-/* position of the UART/SPI select switch */
-enum spi_uart_switch {
-       SWITCH_UNKNOWN,
-       SWITCH_SPI,
-       SWITCH_UART,
-       SWITCH_BOTH
-};
-
-/* Information about the spi/uart switch */
-struct spi_uart {
-       int gpio;                       /* GPIO to control switch */
-       u32 port;                       /* Port number of UART affected */
-};
-
-static struct spi_uart local;
-static enum spi_uart_switch switch_pos; /* Current switch position */
-
-
-static void get_config(struct spi_uart *config)
-{
-#if defined CONFIG_SPI_CORRUPTS_UART
-       config->gpio = CONFIG_UART_DISABLE_GPIO;
-       config->port = CONFIG_SPI_CORRUPTS_UART_NR;
-#else
-       config->gpio = -1;
-#endif
-}
-
-/*
- * Init the UART / SPI switch. This can be called before relocation so we must
- * not access BSS.
- */
-void gpio_early_init_uart(void)
-{
-       struct spi_uart config;
-
-       get_config(&config);
-       if (config.gpio != -1) {
-               /* Cannot provide a label prior to relocation */
-               gpio_request(config.gpio, NULL);
-               gpio_direction_output(config.gpio, 0);
-       }
-}
-
-/*
- * Configure the UART / SPI switch.
- */
-void gpio_config_uart(void)
-{
-       get_config(&local);
-       if (local.gpio != -1) {
-               gpio_direction_output(local.gpio, 0);
-               switch_pos = SWITCH_UART;
-       } else {
-               /*
-                * If we're here we don't have a SPI switch; go ahead and
-                * enable the SPI now.  We didn't in spi_init() so we wouldn't
-                * kill the UART.
-                */
-               pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH);
-               switch_pos = SWITCH_BOTH;
-       }
-}
-
-static void spi_uart_switch(struct spi_uart *config,
-                             enum spi_uart_switch new_pos)
-{
-       if (switch_pos == SWITCH_BOTH || new_pos == switch_pos)
-               return;
-
-       /* pre-delay, allow SPI/UART to settle, FIFO to empty, etc. */
-       udelay(CONFIG_SPI_CORRUPTS_UART_DLY);
-
-       /* We need to dynamically change the pinmux, shared w/UART RXD/CTS */
-       pinmux_set_func(PINGRP_GMC, new_pos == SWITCH_SPI ?
-                               PMUX_FUNC_SFLASH : PMUX_FUNC_UARTD);
-
-       /*
-        * On Seaboard, MOSI/MISO are shared w/UART.
-        * Use GPIO I3 (UART_DISABLE) to tristate UART during SPI activity.
-        * Enable UART later (cs_deactivate) so we can use it for U-Boot comms.
-        */
-       gpio_direction_output(config->gpio, new_pos == SWITCH_SPI);
-       switch_pos = new_pos;
-}
-
-void pinmux_select_uart(void)
-{
-               spi_uart_switch(&local, SWITCH_UART);
-}
-
-void pinmux_select_spi(void)
-{
-       spi_uart_switch(&local, SWITCH_SPI);
-}
index 2020a5f00d2fa62c15a8a735a18377ab94ebbc25..2c23a29db78a079f2faba21785f0188654d00dbd 100644 (file)
 
 #include <common.h>
 #include <asm/arch/pinmux.h>
+#include <asm/arch/gp_padctrl.h>
 #include "pinmux-config-dalmore.h"
+#include <i2c.h>
+
+#define BAT_I2C_ADDRESS                0x48    /* TPS65090 charger */
+#define PMU_I2C_ADDRESS                0x58    /* TPS65913 PMU */
 
 /*
  * Routine: pinmux_init
@@ -32,4 +37,65 @@ void pinmux_init(void)
 
        pinmux_config_table(unused_pins_lowpower,
                ARRAY_SIZE(unused_pins_lowpower));
+
+       /* Initialize any non-default pad configs (APB_MISC_GP regs) */
+       padgrp_config_table(dalmore_padctrl, ARRAY_SIZE(dalmore_padctrl));
+}
+
+#if defined(CONFIG_TEGRA_MMC)
+/*
+ * Do I2C/PMU writes to bring up SD card bus power
+ *
+ */
+void board_sdmmc_voltage_init(void)
+{
+       uchar reg, data_buffer[1];
+       int ret;
+
+       ret = i2c_set_bus_num(0);/* PMU is on bus 0 */
+       if (ret)
+               printf("%s: i2c_set_bus_num returned %d\n", __func__, ret);
+
+       /* TPS65913: LDO9_VOLTAGE = 3.3V */
+       data_buffer[0] = 0x31;
+       reg = 0x61;
+
+       ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
+       if (ret)
+               printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
+                       __func__, reg, data_buffer[0], ret);
+
+       /* TPS65913: LDO9_CTRL = Active */
+       data_buffer[0] = 0x01;
+       reg = 0x60;
+
+       ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
+       if (ret)
+               printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
+                       __func__, reg, data_buffer[0], ret);
+
+       /* TPS65090: FET6_CTRL = enable output auto discharge, enable FET6 */
+       data_buffer[0] = 0x03;
+       reg = 0x14;
+
+       ret = i2c_write(BAT_I2C_ADDRESS, reg, 1, data_buffer, 1);
+       if (ret)
+               printf("%s: BAT i2c_write %02X<-%02X returned %d\n",
+                       __func__, reg, data_buffer[0], ret);
+}
+
+/*
+ * Routine: pin_mux_mmc
+ * Description: setup the MMC muxes, power rails, etc.
+ */
+void pin_mux_mmc(void)
+{
+       /*
+        * NOTE: We don't do mmc-specific pin muxes here.
+        * They were done globally in pinmux_init().
+        */
+
+       /* Bring up the SDIO3 power rail */
+       board_sdmmc_voltage_init();
 }
+#endif /* MMC */
index 3ef6f4eaf6f39bad36cc11f6a97240cd442f0df4..8c05a1517c1171337ec7d1baa8013f509d6fb496 100644 (file)
@@ -361,4 +361,10 @@ static struct pingroup_config tegra114_pinmux_set_nontristate[] = {
 
        DEFAULT_PINMUX(SDMMC3_CD_N,     SDMMC3, UP,       NORMAL,   INPUT),
 };
+
+static struct padctrl_config dalmore_padctrl[] = {
+       /* (_padgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) */
+       DEFAULT_PADCFG(SDIO3, SDIOCFG_DRVUP_SLWF, SDIOCFG_DRVDN_SLWR, \
+               SDIOCFG_DRVUP, SDIOCFG_DRVDN, NONE, NONE, NONE),
+};
 #endif /* PINMUX_CONFIG_COMMON_H */
index 30cf1fb7305587edbc46f05823ea4dc963aee43f..86e9459b3aae7d6b202501388fdc9f8145781548 100644 (file)
@@ -12,6 +12,8 @@
                i2c2 = "/i2c@7000c400";
                i2c3 = "/i2c@7000c500";
                i2c4 = "/i2c@7000c700";
+               sdhci0 = "/sdhci@78000600";
+               sdhci1 = "/sdhci@78000400";
        };
 
        memory {
                status = "okay";
                clock-frequency = <400000>;
        };
+
+       spi@7000da00 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+       };
+
+       sdhci@78000400 {
+               cd-gpios = <&gpio 170 1>; /* gpio PV2 */
+               bus-width = <4>;
+               status = "okay";
+       };
+
+       sdhci@78000600 {
+               bus-width = <8>;
+               status = "okay";
+       };
 };
index e581fddf4349c3ccae1a420edd0aed18f22e7900..498e5137a33d031b33e7c0e3dbcbc9d030f763aa 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/gpio.h>
 
 /* TODO: Remove this code when the SPI switch is working */
-#if !defined(CONFIG_SPI_UART_SWITCH) && (CONFIG_MACH_TYPE != MACH_TYPE_VENTANA)
+#if (CONFIG_MACH_TYPE != MACH_TYPE_VENTANA)
 void gpio_early_init_uart(void)
 {
        /* Enable UART via GPIO_PI3 (port 8, bit 3) so serial console works */
index bd74d746a367f11dcb50339d9d4d57f83ea41e77..a1481c869912f916196142323f815644b0ea0ab5 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
diff --git a/board/pcippc2/cpc710.h b/board/pcippc2/cpc710.h
deleted file mode 100644 (file)
index 8167270..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 _CPC710_H_
-#define _CPC710_H_
-
-/* Revision */
-#define CPC710_TYPE_100        0x80
-#define CPC710_TYPE_100P       0x90
-
-/* System control area */
-#define HW_PHYS_SCA            0xff000000
-
-#define HW_SCA_CPC0            0x000000
-#define HW_SCA_SDRAM0          0x000000
-#define HW_SCA_DMA0            0x1C0000
-
-#define HW_PHYS_CPC0           (HW_PHYS_SCA + HW_SCA_CPC0)
-#define HW_PHYS_SDRAM0         (HW_PHYS_SCA + HW_SCA_SDRAM0)
-
-#define HW_CPC0_PCICNFR                0x000c
-#define HW_CPC0_RSTR           0x0010
-#define HW_CPC0_SPOR           0x00e8
-#define HW_CPC0_UCTL           0x1000
-#define HW_CPC0_SIOC0          0x1020
-#define HW_CPC0_ABCNTL         0x1030
-#define HW_CPC0_SESR           0x1060
-#define HW_CPC0_SEAR           0x1070
-#define HW_CPC0_PGCHP          0x1100
-#define HW_CPC0_RGBAN0         0x1110
-#define HW_CPC0_RGBAN1         0x1120
-
-#define HW_CPC0_GPDIR          0x1130
-#define HW_CPC0_GPIN           0x1140
-#define HW_CPC0_GPOUT          0x1150
-
-#define HW_CPC0_ATAS           0x1160
-
-#define HW_CPC0_PCIBAR         0x200018
-#define HW_CPC0_PCIENB         0x201000
-
-#define HW_SDRAM0_MCCR         0x1200
-#define HW_SDRAM0_MESR         0x1220
-#define HW_SDRAM0_MEAR         0x1230
-
-#define HW_SDRAM0_MCER0                0x1300
-#define HW_SDRAM0_MCER1                0x1310
-#define HW_SDRAM0_MCER2                0x1320
-#define HW_SDRAM0_MCER3                0x1330
-#define HW_SDRAM0_MCER4                0x1340
-#define HW_SDRAM0_MCER5                0x1350
-#define HW_SDRAM0_MCER6                0x1360
-#define HW_SDRAM0_MCER7                0x1370
-
-#define HW_BRIDGE_PCIDG                0xf6120
-#define HW_BRIDGE_INTACK       0xf7700
-#define HW_BRIDGE_PIBAR                0xf7800
-#define HW_BRIDGE_PMBAR                0xf7810
-#define HW_BRIDGE_CRR          0xf7ef0
-#define HW_BRIDGE_PR           0xf7f20
-#define HW_BRIDGE_ACR          0xf7f30
-#define HW_BRIDGE_MSIZE                0xf7f40
-#define HW_BRIDGE_IOSIZE       0xf7f60
-#define HW_BRIDGE_SMBAR                0xf7f80
-#define HW_BRIDGE_SIBAR                0xf7fc0
-#define HW_BRIDGE_CFGADDR      0xf8000
-#define HW_BRIDGE_CFGDATA      0xf8010
-#define HW_BRIDGE_PSSIZE       0xf8100
-#define HW_BRIDGE_BARPS                0xf8120
-#define HW_BRIDGE_PSBAR                0xf8140
-
-/* Configuration space registers */
-#define CPC710_BUS_NUMBER      0x40
-#define CPC710_SUB_BUS_NUMBER  0x41
-
-#endif
diff --git a/board/pcippc2/cpc710_init_ram.c b/board/pcippc2/cpc710_init_ram.c
deleted file mode 100644 (file)
index 8945351..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 <config.h>
-#include <common.h>
-#include <asm/io.h>
-
-#include "pcippc2.h"
-#include "i2c.h"
-
-typedef struct cpc710_mem_org_s {
-       u8 rows;
-       u8 cols;
-       u8 banks2;
-       u8 org;
-} cpc710_mem_org_t;
-
-static int cpc710_compute_mcer (u32 * mcer,
-                               unsigned long *size, unsigned int sdram);
-static int cpc710_eeprom_checksum (unsigned int sdram);
-static u8 cpc710_eeprom_read (unsigned int sdram, unsigned int offset);
-
-static u32 cpc710_mcer_mem[] = {
-       0x000003f3,             /* 18 lines,    4 Mb */
-       0x000003e3,             /* 19 lines,    8 Mb */
-       0x000003c3,             /* 20 lines,   16 Mb */
-       0x00000383,             /* 21 lines,   32 Mb */
-       0x00000303,             /* 22 lines,   64 Mb */
-       0x00000203,             /* 23 lines,  128 Mb */
-       0x00000003,             /* 24 lines,  256 Mb */
-       0x00000002,             /* 25 lines,  512 Mb */
-       0x00000001              /* 26 lines, 1024 Mb */
-};
-static cpc710_mem_org_t cpc710_mem_org[] = {
-       {0x0c, 0x09, 0x02, 0x00},       /* 0000: 12/ 9/2 */
-       {0x0d, 0x09, 0x02, 0x00},       /* 0000: 13/ 9/2 */
-       {0x0d, 0x0a, 0x02, 0x00},       /* 0000: 13/10/2 */
-       {0x0d, 0x0b, 0x02, 0x00},       /* 0000: 13/11/2 */
-       {0x0d, 0x0c, 0x02, 0x00},       /* 0000: 13/12/2 */
-       {0x0e, 0x0c, 0x02, 0x00},       /* 0000: 14/12/2 */
-       {0x0b, 0x08, 0x02, 0x01},       /* 0001: 11/ 8/2 */
-       {0x0b, 0x09, 0x01, 0x02},       /* 0010: 11/ 9/1 */
-       {0x0b, 0x0a, 0x01, 0x03},       /* 0011: 11/10/1 */
-       {0x0c, 0x08, 0x02, 0x04},       /* 0100: 12/ 8/2 */
-       {0x0c, 0x0a, 0x02, 0x05},       /* 0101: 12/10/2 */
-       {0x0d, 0x08, 0x01, 0x06},       /* 0110: 13/ 8/1 */
-       {0x0d, 0x08, 0x02, 0x07},       /* 0111: 13/ 8/2 */
-       {0x0d, 0x09, 0x01, 0x08},       /* 1000: 13/ 9/1 */
-       {0x0d, 0x0a, 0x01, 0x09},       /* 1001: 13/10/1 */
-       {0x0b, 0x08, 0x01, 0x0a},       /* 1010: 11/ 8/1 */
-       {0x0c, 0x08, 0x01, 0x0b},       /* 1011: 12/ 8/1 */
-       {0x0c, 0x09, 0x01, 0x0c},       /* 1100: 12/ 9/1 */
-       {0x0e, 0x09, 0x02, 0x0d},       /* 1101: 14/ 9/2 */
-       {0x0e, 0x0a, 0x02, 0x0e},       /* 1110: 14/10/2 */
-       {0x0e, 0x0b, 0x02, 0x0f}        /* 1111: 14/11/2 */
-};
-
-unsigned long cpc710_ram_init (void)
-{
-       unsigned long memsize = 0;
-       unsigned long bank_size;
-       u32 mcer;
-
-#ifndef CONFIG_SYS_RAMBOOT
-       /* Clear memory banks
-        */
-       out32 (REG (SDRAM0, MCER0), 0);
-       out32 (REG (SDRAM0, MCER1), 0);
-       out32 (REG (SDRAM0, MCER2), 0);
-       out32 (REG (SDRAM0, MCER3), 0);
-       out32 (REG (SDRAM0, MCER4), 0);
-       out32 (REG (SDRAM0, MCER5), 0);
-       out32 (REG (SDRAM0, MCER6), 0);
-       out32 (REG (SDRAM0, MCER7), 0);
-       iobarrier_rw ();
-
-       /* Disable memory
-        */
-       out32 (REG (SDRAM0, MCCR), 0x13b06000);
-       iobarrier_rw ();
-#endif
-
-       /* Only the first memory bank is initialised now
-        */
-       if (!cpc710_compute_mcer (&mcer, &bank_size, 0)) {
-               puts ("Unsupported SDRAM type !\n");
-               hang ();
-       }
-       memsize += bank_size;
-#ifndef CONFIG_SYS_RAMBOOT
-       /* Enable bank, zero start
-        */
-       out32 (REG (SDRAM0, MCER0), mcer | 0x80000000);
-       iobarrier_rw ();
-#endif
-
-#ifndef CONFIG_SYS_RAMBOOT
-       /* Enable memory
-        */
-       out32 (REG (SDRAM0, MCCR), in32 (REG (SDRAM0, MCCR)) | 0x80000000);
-
-       /* Wait until initialisation finished
-        */
-       while (!(in32 (REG (SDRAM0, MCCR)) & 0x20000000)) {
-               iobarrier_rw ();
-       }
-
-       /* Clear Memory Error Status and Address registers
-        */
-       out32 (REG (SDRAM0, MESR), 0);
-       out32 (REG (SDRAM0, MEAR), 0);
-       iobarrier_rw ();
-
-       /* ECC is not configured now
-        */
-#endif
-
-       /* Memory size counter
-        */
-       out32 (REG (CPC0, RGBAN1), memsize);
-
-       return memsize;
-}
-
-static int cpc710_compute_mcer (u32 * mcer, unsigned long *size, unsigned int sdram)
-{
-       u8 rows;
-       u8 cols;
-       u8 banks2;
-       unsigned int lines;
-       u32 mc = 0;
-       unsigned int i;
-       cpc710_mem_org_t *org = 0;
-
-       if (!i2c_reset ()) {
-               puts ("Can't reset I2C!\n");
-               hang ();
-       }
-
-       if (!cpc710_eeprom_checksum (sdram)) {
-               puts ("Invalid EEPROM checksum !\n");
-               hang ();
-       }
-
-       rows = cpc710_eeprom_read (sdram, 3);
-       cols = cpc710_eeprom_read (sdram, 4);
-       /* Can be 2 or 4 banks; divide by 2
-        */
-       banks2 = cpc710_eeprom_read (sdram, 17) / 2;
-
-       lines = rows + cols + banks2;
-
-       if (lines < 18 || lines > 26) {
-               /* Unsupported configuration
-                */
-               return 0;
-       }
-
-       mc |= cpc710_mcer_mem[lines - 18] << 6;
-
-       for (i = 0; i < sizeof (cpc710_mem_org) / sizeof (cpc710_mem_org_t);
-            i++) {
-               cpc710_mem_org_t *corg = cpc710_mem_org + i;
-
-               if (corg->rows == rows && corg->cols == cols
-                   && corg->banks2 == banks2) {
-                       org = corg;
-
-                       break;
-               }
-       }
-
-       if (!org) {
-               /* Unsupported configuration
-                */
-               return 0;
-       }
-
-       mc |= (u32) org->org << 2;
-
-       /* Supported configuration
-        */
-       *mcer = mc;
-       *size = 1l << (lines + 4);
-
-       return 1;
-}
-
-static int cpc710_eeprom_checksum (unsigned int sdram)
-{
-       u8 sum = 0;
-       unsigned int i;
-
-       for (i = 0; i < 63; i++) {
-               sum += cpc710_eeprom_read (sdram, i);
-       }
-
-       return sum == cpc710_eeprom_read (sdram, 63);
-}
-
-static u8 cpc710_eeprom_read (unsigned int sdram, unsigned int offset)
-{
-       u8 dev = (sdram << 1) | 0xa0;
-       u8 data;
-
-       if (!i2c_read_byte (&data, dev, offset)) {
-               puts ("I2C error !\n");
-               hang ();
-       }
-
-       return data;
-}
diff --git a/board/pcippc2/cpc710_pci.c b/board/pcippc2/cpc710_pci.c
deleted file mode 100644 (file)
index ccd18e1..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 <config.h>
-#include <common.h>
-#include <asm/io.h>
-#include <pci.h>
-
-#include "hardware.h"
-#include "pcippc2.h"
-
-struct pci_controller local_hose, cpci_hose;
-
-static u32     cpc710_mapped_ram;
-
-  /* Enable PCI retry timeouts
-   */
-void cpc710_pci_enable_timeout (void)
-{
-  out32(BRIDGE(LOCAL, CFGADDR), 0x50000080);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, CFGDATA), 0x32000000);
-  iobarrier_rw();
-
-  out32(BRIDGE(CPCI, CFGADDR), 0x50000180);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, CFGDATA), 0x32000000);
-  iobarrier_rw();
-}
-
-void cpc710_pci_init (void)
-{
-  u32                  sdram_size = pcippc2_sdram_size();
-
-  cpc710_mapped_ram = sdram_size < PCI_MEMORY_MAXSIZE ?
-                     sdram_size : PCI_MEMORY_MAXSIZE;
-
-    /* Select the local PCI
-     */
-  out32(REG(CPC0, PCICNFR), 0x80000002);
-  iobarrier_rw();
-
-  out32(REG(CPC0, PCIBAR), BRIDGE_LOCAL_PHYS);
-  iobarrier_rw();
-
-    /* Enable PCI bridge address decoding
-     */
-  out32(REG(CPC0, PCIENB), 0x80000000);
-  iobarrier_rw();
-
-    /* Select the CPCI bridge
-     */
-  out32(REG(CPC0, PCICNFR), 0x80000003);
-  iobarrier_rw();
-
-  out32(REG(CPC0, PCIBAR), BRIDGE_CPCI_PHYS);
-  iobarrier_rw();
-
-    /* Enable PCI bridge address decoding
-     */
-  out32(REG(CPC0, PCIENB), 0x80000000);
-  iobarrier_rw();
-
-    /* Disable configuration accesses
-     */
-  out32(REG(CPC0, PCICNFR), 0x80000000);
-  iobarrier_rw();
-
-    /* Initialise the local PCI
-     */
-  out32(BRIDGE(LOCAL, CRR), 0x7c000000);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, PCIDG), 0x40000000);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, PIBAR), BRIDGE_LOCAL_IO_BUS);
-  out32(BRIDGE(LOCAL, SIBAR), BRIDGE_LOCAL_IO_PHYS);
-  out32(BRIDGE(LOCAL, IOSIZE), -BRIDGE_LOCAL_IO_SIZE);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, PMBAR), BRIDGE_LOCAL_MEM_BUS);
-  out32(BRIDGE(LOCAL, SMBAR), BRIDGE_LOCAL_MEM_PHYS);
-  out32(BRIDGE(LOCAL, MSIZE), -BRIDGE_LOCAL_MEM_SIZE);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, PR), 0x00ffe000);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, ACR), 0xfe000000);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, PSBAR), PCI_MEMORY_BUS >> 24);
-  out32(BRIDGE(LOCAL, BARPS), PCI_MEMORY_PHYS >> 24);
-  out32(BRIDGE(LOCAL, PSSIZE), 256 - (cpc710_mapped_ram >> 24));
-  iobarrier_rw();
-
-    /* Initialise the CPCI bridge
-     */
-  out32(BRIDGE(CPCI, CRR), 0x7c000000);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, PCIDG), 0xC0000000);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, PIBAR), BRIDGE_CPCI_IO_BUS);
-  out32(BRIDGE(CPCI, SIBAR), BRIDGE_CPCI_IO_PHYS);
-  out32(BRIDGE(CPCI, IOSIZE), -BRIDGE_CPCI_IO_SIZE);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, PMBAR), BRIDGE_CPCI_MEM_BUS);
-  out32(BRIDGE(CPCI, SMBAR), BRIDGE_CPCI_MEM_PHYS);
-  out32(BRIDGE(CPCI, MSIZE), -BRIDGE_CPCI_MEM_SIZE);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, PR), 0x80ffe000);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, ACR), 0xdf000000);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, PSBAR), PCI_MEMORY_BUS >> 24);
-  out32(BRIDGE(CPCI, BARPS), PCI_MEMORY_PHYS >> 24);
-  out32(BRIDGE(CPCI, PSSIZE), 256 - (cpc710_mapped_ram >> 24));
-  iobarrier_rw();
-
-    /* Local PCI
-     */
-
-  out32(BRIDGE(LOCAL, CFGADDR), 0x04000080);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, CFGDATA), 0x56010000);
-  iobarrier_rw();
-
-  out32(BRIDGE(LOCAL, CFGADDR), 0x0c000080);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, CFGDATA), PCI_LATENCY_TIMER_VAL << 16);
-  iobarrier_rw();
-
-    /* Set bus and subbus numbers
-     */
-  out32(BRIDGE(LOCAL, CFGADDR), 0x40000080);
-  iobarrier_rw();
-  out32(BRIDGE(LOCAL, CFGDATA), 0x00000000);
-  iobarrier_rw();
-
-  out32(BRIDGE(LOCAL, CFGADDR), 0x50000080);
-  iobarrier_rw();
-    /* PCI retry timeouts will be enabled later
-     */
-  out32(BRIDGE(LOCAL, CFGDATA), 0x00000000);
-  iobarrier_rw();
-
-    /* CPCI
-     */
-
-    /* Set bus and subbus numbers
-     */
-  out32(BRIDGE(CPCI, CFGADDR), 0x40000080);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, CFGDATA), 0x01010000);
-  iobarrier_rw();
-
-  out32(BRIDGE(CPCI, CFGADDR), 0x04000180);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, CFGDATA), 0x56010000);
-  iobarrier_rw();
-
-  out32(BRIDGE(CPCI, CFGADDR), 0x0c000180);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, CFGDATA), PCI_LATENCY_TIMER_VAL << 16);
-  iobarrier_rw();
-
-    /* Write to the PSBAR */
-  out32(BRIDGE(CPCI, CFGADDR), 0x10000180);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, CFGDATA), cpu_to_le32(PCI_MEMORY_BUS));
-  iobarrier_rw();
-
-    /* Set bus and subbus numbers
-     */
-  out32(BRIDGE(CPCI, CFGADDR), 0x40000180);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, CFGDATA), 0x01ff0000);
-  iobarrier_rw();
-
-  out32(BRIDGE(CPCI, CFGADDR), 0x50000180);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, CFGDATA), 0x32000000);
-    /* PCI retry timeouts will be enabled later
-     */
-  out32(BRIDGE(CPCI, CFGDATA), 0x00000000);
-  iobarrier_rw();
-
-    /* Remove reset on the PCI buses
-     */
-  out32(BRIDGE(LOCAL, CRR), 0xfc000000);
-  iobarrier_rw();
-  out32(BRIDGE(CPCI, CRR), 0xfc000000);
-  iobarrier_rw();
-
-  local_hose.first_busno = 0;
-  local_hose.last_busno = 0xff;
-
-  /* System memory space */
-  pci_set_region(local_hose.regions + 0,
-                PCI_MEMORY_BUS,
-                PCI_MEMORY_PHYS,
-                PCI_MEMORY_MAXSIZE,
-                PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
-
-  /* PCI memory space */
-  pci_set_region(local_hose.regions + 1,
-                BRIDGE_LOCAL_MEM_BUS,
-                BRIDGE_LOCAL_MEM_PHYS,
-                BRIDGE_LOCAL_MEM_SIZE,
-                PCI_REGION_MEM);
-
-  /* PCI I/O space */
-  pci_set_region(local_hose.regions + 2,
-                BRIDGE_LOCAL_IO_BUS,
-                BRIDGE_LOCAL_IO_PHYS,
-                BRIDGE_LOCAL_IO_SIZE,
-                PCI_REGION_IO);
-
-  local_hose.region_count = 3;
-
-  pci_setup_indirect(&local_hose,
-                    BRIDGE_LOCAL_PHYS + HW_BRIDGE_CFGADDR,
-                    BRIDGE_LOCAL_PHYS + HW_BRIDGE_CFGDATA);
-
-  pci_register_hose(&local_hose);
-
-  /* Initialize PCI32 bus registers */
-  pci_hose_write_config_byte(&local_hose,
-                         PCI_BDF(local_hose.first_busno,0,0),
-                         CPC710_BUS_NUMBER,
-                         local_hose.first_busno);
-  pci_hose_write_config_byte(&local_hose,
-                         PCI_BDF(local_hose.first_busno,0,0),
-                         CPC710_SUB_BUS_NUMBER,
-                         local_hose.last_busno);
-
-  local_hose.last_busno = pci_hose_scan(&local_hose);
-
-  /* Write out correct max subordinate bus number for local hose */
-  pci_hose_write_config_byte(&local_hose,
-                         PCI_BDF(local_hose.first_busno,0,0),
-                         CPC710_SUB_BUS_NUMBER,
-                         local_hose.last_busno);
-
-  cpci_hose.first_busno = local_hose.last_busno + 1;
-  cpci_hose.last_busno = 0xff;
-
-  /* System memory space */
-  pci_set_region(cpci_hose.regions + 0,
-                PCI_MEMORY_BUS,
-                PCI_MEMORY_PHYS,
-                PCI_MEMORY_MAXSIZE,
-                PCI_REGION_SYS_MEMORY);
-
-  /* PCI memory space */
-  pci_set_region(cpci_hose.regions + 1,
-                BRIDGE_CPCI_MEM_BUS,
-                BRIDGE_CPCI_MEM_PHYS,
-                BRIDGE_CPCI_MEM_SIZE,
-                PCI_REGION_MEM);
-
-  /* PCI I/O space */
-  pci_set_region(cpci_hose.regions + 2,
-                BRIDGE_CPCI_IO_BUS,
-                BRIDGE_CPCI_IO_PHYS,
-                BRIDGE_CPCI_IO_SIZE,
-                PCI_REGION_IO);
-
-  cpci_hose.region_count = 3;
-
-  pci_setup_indirect(&cpci_hose,
-                    BRIDGE_CPCI_PHYS + HW_BRIDGE_CFGADDR,
-                    BRIDGE_CPCI_PHYS + HW_BRIDGE_CFGDATA);
-
-  pci_register_hose(&cpci_hose);
-
-  /* Initialize PCI64 bus registers */
-  pci_hose_write_config_byte(&cpci_hose,
-                         PCI_BDF(cpci_hose.first_busno,0,0),
-                         CPC710_BUS_NUMBER,
-                         cpci_hose.first_busno);
-  pci_hose_write_config_byte(&cpci_hose,
-                         PCI_BDF(cpci_hose.first_busno,0,0),
-                         CPC710_SUB_BUS_NUMBER,
-                         cpci_hose.last_busno);
-
-  cpci_hose.last_busno = pci_hose_scan(&cpci_hose);
-
-  /* Write out correct max subordinate bus number for cpci hose */
-  pci_hose_write_config_byte(&cpci_hose,
-                         PCI_BDF(cpci_hose.first_busno,0,0),
-                         CPC710_SUB_BUS_NUMBER,
-                         cpci_hose.last_busno);
-}
diff --git a/board/pcippc2/cpc710_pci.h b/board/pcippc2/cpc710_pci.h
deleted file mode 100644 (file)
index 24d0db6..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 _CPC710_PCI_H_
-#define _CPC710_PCI_H_
-
-#define PCI_MEMORY_PHYS                0x00000000
-#define PCI_MEMORY_BUS         0x80000000
-#define PCI_MEMORY_MAXSIZE      0x20000000
-
-#define BRIDGE_CPCI_PHYS       0xff500000
-#define BRIDGE_CPCI_MEM_SIZE   0x08000000
-#define BRIDGE_CPCI_MEM_PHYS    0xf0000000
-#define BRIDGE_CPCI_MEM_BUS     0x00000000
-#define BRIDGE_CPCI_IO_SIZE    0x02000000
-#define BRIDGE_CPCI_IO_PHYS     0xfc000000
-#define BRIDGE_CPCI_IO_BUS      0x00000000
-
-#define BRIDGE_LOCAL_PHYS      0xff400000
-#define BRIDGE_LOCAL_MEM_SIZE  0x04000000
-#define BRIDGE_LOCAL_MEM_PHYS   0xf8000000
-#define BRIDGE_LOCAL_MEM_BUS    0x40000000
-#define BRIDGE_LOCAL_IO_SIZE   0x01000000
-#define BRIDGE_LOCAL_IO_PHYS    0xfe000000
-#define BRIDGE_LOCAL_IO_BUS     0x04000000
-
-#define BRIDGE(r, x)           (BRIDGE_##r##_PHYS + HW_BRIDGE_##x)
-
-#define PCI_LATENCY_TIMER_VAL  0xff
-
-#endif
diff --git a/board/pcippc2/flash.c b/board/pcippc2/flash.c
deleted file mode 100644 (file)
index ec604e0..0000000
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * (C) Copyright 2001
- * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
- *
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 <config.h>
-#include <common.h>
-#include <flash.h>
-#include <asm/io.h>
-
-/*---------------------------------------------------------------------*/
-#undef DEBUG_FLASH
-
-#ifdef DEBUG_FLASH
-#define DEBUGF(fmt,args...) printf(fmt ,##args)
-#else
-#define DEBUGF(fmt,args...)
-#endif
-/*---------------------------------------------------------------------*/
-
-flash_info_t   flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
-
-static ulong flash_get_size (ulong addr, flash_info_t *info);
-static int flash_get_offsets (ulong base, flash_info_t *info);
-static int write_word (flash_info_t *info, ulong dest, ulong data);
-static void flash_reset (ulong addr);
-
-unsigned long flash_init (void)
-{
-       unsigned int i;
-       unsigned long flash_size = 0;
-
-       /* Init: no FLASHes known */
-       for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
-               flash_info[i].flash_id = FLASH_UNKNOWN;
-               flash_info[i].sector_count = 0;
-               flash_info[i].size = 0;
-       }
-
-       DEBUGF("\n## Get flash size @ 0x%08x\n", CONFIG_SYS_FLASH_BASE);
-
-       flash_size = flash_get_size (CONFIG_SYS_FLASH_BASE, flash_info);
-
-       DEBUGF("## Flash bank size: %08lx\n", flash_size);
-
-       if (flash_size) {
-#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE && \
-    CONFIG_SYS_MONITOR_BASE < CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_MAX_SIZE
-               /* monitor protection ON by default */
-               flash_protect(FLAG_PROTECT_SET,
-                             CONFIG_SYS_MONITOR_BASE,
-                             CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
-                             &flash_info[0]);
-#endif
-
-#ifdef CONFIG_ENV_IS_IN_FLASH
-               /* ENV protection ON by default */
-               flash_protect(FLAG_PROTECT_SET,
-                             CONFIG_ENV_ADDR,
-                             CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
-                             &flash_info[0]);
-#endif
-
-       } else {
-               puts ("Warning: the BOOT Flash is not initialised !");
-       }
-
-       return flash_size;
-}
-
-/*
- * The following code cannot be run from FLASH!
- */
-static ulong flash_get_size (ulong addr, flash_info_t *info)
-{
-       short i;
-       uchar value;
-
-       /* Write auto select command: read Manufacturer ID */
-       out8(addr + 0x0555, 0xAA);
-       iobarrier_rw();
-       out8(addr + 0x02AA, 0x55);
-       iobarrier_rw();
-       out8(addr + 0x0555, 0x90);
-       iobarrier_rw();
-
-       value = in8(addr);
-       iobarrier_rw();
-
-       DEBUGF("Manuf. ID @ 0x%08lx: 0x%08x\n", (ulong)addr, value);
-
-       switch (value | (value << 16)) {
-               case AMD_MANUFACT:
-                       info->flash_id = FLASH_MAN_AMD;
-                       break;
-
-               case FUJ_MANUFACT:
-                       info->flash_id = FLASH_MAN_FUJ;
-                       break;
-
-               case STM_MANUFACT:
-                       info->flash_id = FLASH_MAN_STM;
-                       break;
-
-               default:
-                       info->flash_id = FLASH_UNKNOWN;
-                       info->sector_count = 0;
-                       info->size = 0;
-                       flash_reset (addr);
-                       return 0;
-       }
-
-       value = in8(addr + 1);                  /* device ID            */
-       iobarrier_rw();
-
-       DEBUGF("Device ID @ 0x%08lx: 0x%08x\n", addr+1, value);
-
-       switch ((ulong)value) {
-               case AMD_ID_F040B:
-                       DEBUGF("Am29F040B\n");
-                       info->flash_id += FLASH_AM040;
-                       info->sector_count = 8;
-                       info->size = 0x00080000;
-                       break;                  /* => 512 kB            */
-
-               case AMD_ID_LV040B:
-                       DEBUGF("Am29LV040B\n");
-                       info->flash_id += FLASH_AM040;
-                       info->sector_count = 8;
-                       info->size = 0x00080000;
-                       break;                  /* => 512 kB            */
-
-               case AMD_ID_LV400T:
-                       DEBUGF("Am29LV400T\n");
-                       info->flash_id += FLASH_AM400T;
-                       info->sector_count = 11;
-                       info->size = 0x00100000;
-                       break;                  /* => 1 MB              */
-
-               case AMD_ID_LV400B:
-                       DEBUGF("Am29LV400B\n");
-                       info->flash_id += FLASH_AM400B;
-                       info->sector_count = 11;
-                       info->size = 0x00100000;
-                       break;                  /* => 1 MB              */
-
-               case AMD_ID_LV800T:
-                       DEBUGF("Am29LV800T\n");
-                       info->flash_id += FLASH_AM800T;
-                       info->sector_count = 19;
-                       info->size = 0x00200000;
-                       break;                  /* => 2 MB              */
-
-               case AMD_ID_LV800B:
-                       DEBUGF("Am29LV400B\n");
-                       info->flash_id += FLASH_AM800B;
-                       info->sector_count = 19;
-                       info->size = 0x00200000;
-                       break;                  /* => 2 MB              */
-
-               case AMD_ID_LV160T:
-                       DEBUGF("Am29LV160T\n");
-                       info->flash_id += FLASH_AM160T;
-                       info->sector_count = 35;
-                       info->size = 0x00400000;
-                       break;                  /* => 4 MB              */
-
-               case AMD_ID_LV160B:
-                       DEBUGF("Am29LV160B\n");
-                       info->flash_id += FLASH_AM160B;
-                       info->sector_count = 35;
-                       info->size = 0x00400000;
-                       break;                  /* => 4 MB              */
-
-               case AMD_ID_LV320T:
-                       DEBUGF("Am29LV320T\n");
-                       info->flash_id += FLASH_AM320T;
-                       info->sector_count = 67;
-                       info->size = 0x00800000;
-                       break;                  /* => 8 MB              */
-
-#if 0
-               /* Has the same ID as AMD_ID_LV320T, to be fixed */
-               case AMD_ID_LV320B:
-                       DEBUGF("Am29LV320B\n");
-                       info->flash_id += FLASH_AM320B;
-                       info->sector_count = 67;
-                       info->size = 0x00800000;
-                       break;                  /* => 8 MB              */
-#endif
-
-               case AMD_ID_LV033C:
-                       DEBUGF("Am29LV033C\n");
-                       info->flash_id += FLASH_AM033C;
-                       info->sector_count = 64;
-                       info->size = 0x01000000;
-                       break;                  /* => 16Mb              */
-
-               case STM_ID_F040B:
-                       DEBUGF("M29F040B\n");
-                       info->flash_id += FLASH_AM040;
-                       info->sector_count = 8;
-                       info->size = 0x00080000;
-                       break;                  /* => 512 kB            */
-
-               default:
-                       info->flash_id = FLASH_UNKNOWN;
-                       flash_reset (addr);
-                       return (0);             /* => no or unknown flash */
-
-       }
-
-       if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
-               printf ("** ERROR: sector count %d > max (%d) **\n",
-                       info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
-               info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
-       }
-
-       if (! flash_get_offsets (addr, info)) {
-               flash_reset (addr);
-               return 0;
-       }
-
-       /* check for protected sectors */
-       for (i = 0; i < info->sector_count; i++) {
-               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
-               /* D0 = 1 if protected */
-               value = in8(info->start[i] + 2);
-               iobarrier_rw();
-               info->protect[i] = (value & 1) != 0;
-       }
-
-       /*
-        * Reset bank to read mode
-        */
-       flash_reset (addr);
-
-       return (info->size);
-}
-
-static int flash_get_offsets (ulong base, flash_info_t *info)
-{
-       unsigned int i;
-
-       switch (info->flash_id & FLASH_TYPEMASK) {
-               case FLASH_AM040:
-                       /* set sector offsets for uniform sector type   */
-                       for (i = 0; i < info->sector_count; i++) {
-                               info->start[i] = base + i * info->size /
-                                                           info->sector_count;
-                       }
-                       break;
-               default:
-                       return 0;
-       }
-
-       return 1;
-}
-
-int flash_erase (flash_info_t *info, int s_first, int s_last)
-{
-       volatile ulong addr = info->start[0];
-       int flag, prot, sect, l_sect;
-       ulong start, now, last;
-
-       if (s_first < 0 || s_first > s_last) {
-               if (info->flash_id == FLASH_UNKNOWN) {
-                       printf ("- missing\n");
-               } else {
-                       printf ("- no sectors to erase\n");
-               }
-               return 1;
-       }
-
-       if (info->flash_id == FLASH_UNKNOWN) {
-               printf ("Can't erase unknown flash type %08lx - aborted\n",
-                       info->flash_id);
-               return 1;
-       }
-
-       prot = 0;
-       for (sect=s_first; sect<=s_last; ++sect) {
-               if (info->protect[sect]) {
-                       prot++;
-               }
-       }
-
-       if (prot) {
-               printf ("- Warning: %d protected sectors will not be erased!\n",
-                       prot);
-       } else {
-               printf ("\n");
-       }
-
-       l_sect = -1;
-
-       /* Disable interrupts which might cause a timeout here */
-       flag = disable_interrupts();
-
-       out8(addr + 0x555, 0xAA);
-       iobarrier_rw();
-       out8(addr + 0x2AA, 0x55);
-       iobarrier_rw();
-       out8(addr + 0x555, 0x80);
-       iobarrier_rw();
-       out8(addr + 0x555, 0xAA);
-       iobarrier_rw();
-       out8(addr + 0x2AA, 0x55);
-       iobarrier_rw();
-
-       /* Start erase on unprotected sectors */
-       for (sect = s_first; sect<=s_last; sect++) {
-               if (info->protect[sect] == 0) { /* not protected */
-                       addr = info->start[sect];
-                       out8(addr, 0x30);
-                       iobarrier_rw();
-                       l_sect = sect;
-               }
-       }
-
-       /* re-enable interrupts if necessary */
-       if (flag)
-               enable_interrupts();
-
-       /* wait at least 80us - let's wait 1 ms */
-       udelay (1000);
-
-       /*
-        * We wait for the last triggered sector
-        */
-       if (l_sect < 0)
-               goto DONE;
-
-       start = get_timer (0);
-       last  = start;
-       addr = info->start[l_sect];
-
-       DEBUGF ("Start erase timeout: %d\n", CONFIG_SYS_FLASH_ERASE_TOUT);
-
-       while ((in8(addr) & 0x80) != 0x80) {
-               if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
-                       printf ("Timeout\n");
-                       flash_reset (info->start[0]);
-                       return 1;
-               }
-               /* show that we're waiting */
-               if ((now - last) > 1000) {      /* every second */
-                       putc ('.');
-                       last = now;
-               }
-               iobarrier_rw();
-       }
-
-DONE:
-       /* reset to read mode */
-       flash_reset (info->start[0]);
-
-       printf (" done\n");
-       return 0;
-}
-
-/*
- * Copy memory to flash, returns:
- * 0 - OK
- * 1 - write timeout
- * 2 - Flash not erased
- */
-int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
-{
-       ulong cp, wp, data;
-       int i, l, rc;
-
-       wp = (addr & ~3);       /* get lower word aligned address */
-
-       /*
-        * handle unaligned start bytes
-        */
-       if ((l = addr - wp) != 0) {
-               data = 0;
-               for (i=0, cp=wp; i<l; ++i, ++cp) {
-                       data = (data << 8) | (*(uchar *)cp);
-               }
-               for (; i<4 && cnt>0; ++i) {
-                       data = (data << 8) | *src++;
-                       --cnt;
-                       ++cp;
-               }
-               for (; cnt==0 && i<4; ++i, ++cp) {
-                       data = (data << 8) | (*(uchar *)cp);
-               }
-
-               if ((rc = write_word(info, wp, data)) != 0) {
-                       return (rc);
-               }
-               wp += 4;
-       }
-
-       /*
-        * handle word aligned part
-        */
-       while (cnt >= 4) {
-               data = 0;
-               for (i=0; i<4; ++i) {
-                       data = (data << 8) | *src++;
-               }
-               if ((rc = write_word(info, wp, data)) != 0) {
-                       return (rc);
-               }
-               wp  += 4;
-               cnt -= 4;
-       }
-
-       if (cnt == 0) {
-               return (0);
-       }
-
-       /*
-        * handle unaligned tail bytes
-        */
-       data = 0;
-       for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
-               data = (data << 8) | *src++;
-               --cnt;
-       }
-       for (; i<4; ++i, ++cp) {
-               data = (data << 8) | (*(uchar *)cp);
-       }
-
-       return (write_word(info, wp, data));
-}
-
-/*
- * Write a word to Flash, returns:
- * 0 - OK
- * 1 - write timeout
- * 2 - Flash not erased
- */
-static int write_word (flash_info_t *info, ulong dest, ulong data)
-{
-       volatile ulong addr = info->start[0];
-       ulong start;
-       int i;
-
-       /* Check if Flash is (sufficiently) erased */
-       if ((in32(dest) & data) != data) {
-               return (2);
-       }
-
-       /* write each byte out */
-       for (i = 0; i < 4; i++) {
-               char *data_ch = (char *)&data;
-               int flag = disable_interrupts();
-
-               out8(addr + 0x555, 0xAA);
-               iobarrier_rw();
-               out8(addr + 0x2AA, 0x55);
-               iobarrier_rw();
-               out8(addr + 0x555, 0xA0);
-               iobarrier_rw();
-               out8(dest+i, data_ch[i]);
-               iobarrier_rw();
-
-               /* re-enable interrupts if necessary */
-               if (flag)
-                       enable_interrupts();
-
-               /* data polling for D7 */
-               start = get_timer (0);
-               while ((in8(dest+i) & 0x80) != (data_ch[i] & 0x80)) {
-                       if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
-                               flash_reset (addr);
-                               return (1);
-                       }
-                       iobarrier_rw();
-               }
-       }
-
-       flash_reset (addr);
-       return (0);
-}
-
-/*
- * Reset bank to read mode
- */
-static void flash_reset (ulong addr)
-{
-       out8(addr, 0xF0);       /* reset bank */
-       iobarrier_rw();
-}
-
-void flash_print_info (flash_info_t *info)
-{
-       int i;
-
-       if (info->flash_id == FLASH_UNKNOWN) {
-               printf ("missing or unknown FLASH type\n");
-               return;
-       }
-
-       switch (info->flash_id & FLASH_VENDMASK) {
-       case FLASH_MAN_AMD:     printf ("AMD ");                break;
-       case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
-       case FLASH_MAN_BM:      printf ("BRIGHT MICRO ");       break;
-       case FLASH_MAN_STM:     printf ("SGS THOMSON ");        break;
-       default:                printf ("Unknown Vendor ");     break;
-       }
-
-       switch (info->flash_id & FLASH_TYPEMASK) {
-       case FLASH_AM040:       printf ("29F040 or 29LV040 (4 Mbit, uniform sectors)\n");
-                               break;
-       case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
-                               break;
-       case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit, top boot sector)\n");
-                               break;
-       case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
-                               break;
-       case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit, top boot sector)\n");
-                               break;
-       case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
-                               break;
-       case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
-                               break;
-       case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
-                               break;
-       case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit, top boot sector)\n");
-                               break;
-       default:                printf ("Unknown Chip Type\n");
-                               break;
-       }
-
-       if (info->size % 0x100000 == 0) {
-               printf ("  Size: %ld MB in %d Sectors\n",
-                       info->size / 0x100000, info->sector_count);
-       } else if (info->size % 0x400 == 0) {
-               printf ("  Size: %ld KB in %d Sectors\n",
-                       info->size / 0x400, info->sector_count);
-       } else {
-               printf ("  Size: %ld B in %d Sectors\n",
-                       info->size, info->sector_count);
-       }
-
-       printf ("  Sector Start Addresses:");
-       for (i=0; i<info->sector_count; ++i) {
-               if ((i % 5) == 0)
-                       printf ("\n   ");
-               printf (" %08lX%s",
-                       info->start[i],
-                       info->protect[i] ? " (RO)" : "     "
-               );
-       }
-       printf ("\n");
-}
diff --git a/board/pcippc2/fpga_serial.c b/board/pcippc2/fpga_serial.c
deleted file mode 100644 (file)
index de61ca0..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 <config.h>
-#include <common.h>
-#include <asm/io.h>
-
-#include "fpga_serial.h"
-#include "hardware.h"
-#include "pcippc2.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-  /* 8 data, 1 stop, no parity
-   */
-#define LCRVAL         0x03
-  /* RTS/DTR
-   */
-#define MCRVAL         0x03
-  /* Clear & enable FIFOs
-   */
-#define FCRVAL         0x07
-
-static void fpga_serial_wait (void);
-static void fpga_serial_print (char c);
-
-void fpga_serial_init (int baudrate)
-{
-       int clock_divisor = 115200 / baudrate;
-
-       out8 (FPGA (INT, SERIAL_CONFIG), 0x24);
-       iobarrier_rw ();
-
-       fpga_serial_wait ();
-
-       out8 (UART (IER), 0);
-       out8 (UART (LCR), LCRVAL | 0x80);
-       iobarrier_rw ();
-       out8 (UART (DLL), clock_divisor & 0xff);
-       out8 (UART (DLM), clock_divisor >> 8);
-       iobarrier_rw ();
-       out8 (UART (LCR), LCRVAL);
-       iobarrier_rw ();
-       out8 (UART (MCR), MCRVAL);
-       out8 (UART (FCR), FCRVAL);
-       iobarrier_rw ();
-}
-
-void fpga_serial_putc (char c)
-{
-       if (c) {
-               fpga_serial_print (c);
-       }
-}
-
-int fpga_serial_getc (void)
-{
-       while ((in8 (UART (LSR)) & 0x01) == 0);
-
-       return in8 (UART (RBR));
-}
-
-int fpga_serial_tstc (void)
-{
-       return (in8 (UART (LSR)) & 0x01) != 0;
-}
-
-void fpga_serial_setbrg (void)
-{
-       int clock_divisor = 115200 / gd->baudrate;
-
-       fpga_serial_wait ();
-
-       out8 (UART (LCR), LCRVAL | 0x80);
-       iobarrier_rw ();
-       out8 (UART (DLL), clock_divisor & 0xff);
-       out8 (UART (DLM), clock_divisor >> 8);
-       iobarrier_rw ();
-       out8 (UART (LCR), LCRVAL);
-       iobarrier_rw ();
-}
-
-static void fpga_serial_wait (void)
-{
-       while ((in8 (UART (LSR)) & 0x40) == 0);
-}
-
-static void fpga_serial_print (char c)
-{
-       if (c == '\n') {
-               while ((in8 (UART (LSR)) & 0x20) == 0);
-
-               out8 (UART (THR), '\r');
-               iobarrier_rw ();
-       }
-
-       while ((in8 (UART (LSR)) & 0x20) == 0);
-
-       out8 (UART (THR), c);
-       iobarrier_rw ();
-
-       if (c == '\n') {
-               fpga_serial_wait ();
-       }
-}
diff --git a/board/pcippc2/hardware.h b/board/pcippc2/hardware.h
deleted file mode 100644 (file)
index 489929d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 _HARDWARE_H_
-#define _HARDWARE_H_
-
-#include "cpc710.h"
-#include "cpc710_pci.h"
-#include "pcippc2_fpga.h"
-#include "ns16550.h"
-
-#define REG(r, x)      (HW_PHYS_##r + HW_##r##_##x)
-
-  /* Address map:
-   *
-   * 0x00000000-0x20000000     SDRAM
-   * 0x40000000-0x00008000     Init RAM in the CPU DCache
-   * 0xf0000000-0xf8000000     CPCI MEM
-   * 0xf8000000-0xfc000000     Local PCI MEM
-   * 0xfc000000-0xfe000000     CPCI I/O
-   * 0xfe000000-0xff000000     Local PCI I/O
-   * 0xff000000-0xff201000     System configuration space
-   * 0xff400000-0xff500000     Local PCI bridge space
-   * 0xff500000-0xff600000     CPCI bridge space
-   * 0xfff00000-0xfff80000     Boot Flash
-   */
-
-#endif
diff --git a/board/pcippc2/i2c.c b/board/pcippc2/i2c.c
deleted file mode 100644 (file)
index ab52562..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 <config.h>
-#include <common.h>
-#include <asm/io.h>
-
-#include "hardware.h"
-#include "i2c.h"
-
-static void            i2c_start       (void);
-static void            i2c_stop        (void);
-static int             i2c_write       (u8             data);
-static void            i2c_read        (u8 *           data);
-
-static inline void     i2c_port_start  (void);
-static inline void     i2c_clock       (unsigned int   val);
-static inline void     i2c_data        (unsigned int   val);
-static inline unsigned int
-                       i2c_in          (void);
-static inline void     i2c_write_bit   (unsigned int   val);
-static inline unsigned int
-                       i2c_read_bit    (void);
-
-static inline void     i2c_udelay      (unsigned int   time);
-
-int i2c_read_byte (
-  u8 *                 data,
-  u8                   dev,
-  u8                   offset)
-{
-  int                  err = 0;
-
-  i2c_start();
-
-  err = ! i2c_write(dev);
-
-  if (! err)
-  {
-    err = ! i2c_write(offset);
-  }
-
-  if (! err)
-  {
-    i2c_start();
-  }
-
-  if (! err)
-  {
-    err = ! i2c_write(dev | 0x01);
-  }
-
-  if (! err)
-  {
-    i2c_read(data);
-  }
-
-  i2c_stop();
-
-  return ! err;
-}
-
-static inline void i2c_udelay (
-  unsigned int         time)
-{
-  int                  v;
-
-  asm volatile("mtdec %0" : : "r" (time * ((CONFIG_SYS_BUS_CLK / 4) / 1000000)));
-
-  do
-  {
-    asm volatile("isync; mfdec %0" : "=r" (v));
-  } while (v >= 0);
-}
-
-  /* Low-level hardware access
-   */
-
-#define BIT_GPDATA             0x80000000
-#define BIT_GPCLK              0x40000000
-
-static inline void i2c_port_start (void)
-{
-  out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~(BIT_GPCLK | BIT_GPDATA));
-  out32(REG(CPC0, GPOUT), in32(REG(CPC0, GPOUT)) & ~(BIT_GPCLK | BIT_GPDATA));
-  iobarrier_rw();
-
-  i2c_udelay(1);
-}
-
-static inline void i2c_clock (
-  unsigned int         val)
-{
-  if (val)
-  {
-    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPCLK);
-  }
-  else
-  {
-    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPCLK);
-  }
-
-  iobarrier_rw();
-
-  i2c_udelay(1);
-}
-
-static inline void i2c_data (
-  unsigned int         val)
-{
-  if (val)
-  {
-    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) & ~BIT_GPDATA);
-  }
-  else
-  {
-    out32(REG(CPC0, GPDIR), in32(REG(CPC0, GPDIR)) | BIT_GPDATA);
-  }
-
-  iobarrier_rw();
-
-  i2c_udelay(1);
-}
-
-static inline unsigned int i2c_in (void)
-{
-  unsigned int         val = ((in32(REG(CPC0, GPIN)) & BIT_GPDATA) != 0)?1:0;
-
-  iobarrier_rw();
-
-  return val;
-}
-
-
-  /* Protocol implementation
-   */
-
-static inline void i2c_write_bit (
-  unsigned int         val)
-{
-  i2c_data(val);
-  i2c_udelay(10);
-  i2c_clock(1);
-  i2c_udelay(10);
-  i2c_clock(0);
-  i2c_udelay(10);
-}
-
-static inline unsigned int i2c_read_bit (void)
-{
-  unsigned int         val;
-
-  i2c_data(1);
-  i2c_udelay(10);
-
-  i2c_clock(1);
-  i2c_udelay(10);
-
-  val = i2c_in();
-
-  i2c_clock(0);
-  i2c_udelay(10);
-
-  return val;
-}
-
-unsigned int i2c_reset (void)
-{
-  unsigned int         val;
-  int i;
-
-  i2c_port_start();
-
-  i=0;
-  do {
-    i2c_udelay(10);
-    i2c_clock(0);
-    i2c_udelay(10);
-    i2c_clock(1);
-    i2c_udelay(10);
-    val = i2c_in();
-    i++;
-  }  while ((i<9)&&(val==0));
-  return (val);
-}
-
-
-static void i2c_start (void)
-{
-  i2c_data(1);
-  i2c_clock(1);
-  i2c_udelay(10);
-  i2c_data(0);
-  i2c_udelay(10);
-  i2c_clock(0);
-  i2c_udelay(10);
-}
-
-static void i2c_stop (void)
-{
-  i2c_data(0);
-  i2c_udelay(10);
-  i2c_clock(1);
-  i2c_udelay(10);
-  i2c_data(1);
-  i2c_udelay(10);
-}
-
-static int i2c_write (
-  u8                   data)
-{
-  unsigned int         i;
-
-  for (i = 0; i < 8; i++)
-  {
-    i2c_write_bit(data >> 7);
-    data <<= 1;
-  }
-
-  return i2c_read_bit() == 0;
-}
-
-static void i2c_read (
-  u8 *                 data)
-{
-  unsigned int         i;
-  u8                   val = 0;
-
-  for (i = 0; i < 8; i++)
-  {
-    val <<= 1;
-    val |= i2c_read_bit();
-  }
-
-  *data = val;
-  i2c_write_bit(1); /* NoAck */
-}
diff --git a/board/pcippc2/pcippc2.c b/board/pcippc2/pcippc2.c
deleted file mode 100644 (file)
index 5e6fc58..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 <config.h>
-#include <common.h>
-#include <command.h>
-#include <asm/io.h>
-#include <linux/mtd/doc2000.h>
-#include <watchdog.h>
-#include <pci.h>
-#include <netdev.h>
-#include <serial.h>
-
-#include "hardware.h"
-#include "pcippc2.h"
-#include "sconsole.h"
-#include "fpga_serial.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#if defined(CONFIG_WATCHDOG)
-
-static int pcippc2_wdt_init_done = 0;
-
-void pcippc2_wdt_init (void);
-
-#endif
-
-  /* Check board identity
-   */
-int checkboard (void)
-{
-#ifdef CONFIG_PCIPPC2
-       puts ("Board: Gespac PCIPPC-2\n");
-#else
-       puts ("Board: Gespac PCIPPC-6\n");
-#endif
-       return 0;
-}
-
-  /* RAM size is stored in CPC0_RGBAN1
-   */
-u32 pcippc2_sdram_size (void)
-{
-       return in32 (REG (CPC0, RGBAN1));
-}
-
-phys_size_t initdram (int board_type)
-{
-       return cpc710_ram_init ();
-}
-
-int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       out32 (REG (CPC0, SPOR), 0);
-       iobarrier_rw ();
-       while (1);
-       /* notreached */
-       return (-1);
-}
-
-int board_early_init_f (void)
-{
-       out32 (REG (CPC0, RSTR), 0xC0000000);
-       iobarrier_rw ();
-
-       out32 (REG (CPC0, RSTR), 0xF0000000);
-       iobarrier_rw ();
-
-       out32 (REG (CPC0, UCTL), 0x00F80000);
-
-       out32 (REG (CPC0, SIOC0), 0x30000000);
-
-       out32 (REG (CPC0, ABCNTL), 0x00000000);
-
-       out32 (REG (CPC0, SESR), 0x00000000);
-       out32 (REG (CPC0, SEAR), 0x00000000);
-
-       /* Detect IBM Avignon CPC710 Revision */
-       if ((in32 (REG (CPC0, UCTL)) & 0x000000F0) == CPC710_TYPE_100P)
-               out32 (REG (CPC0, PGCHP), 0xA0000040);
-       else
-               out32 (REG (CPC0, PGCHP), 0x80800040);
-
-
-       out32 (REG (CPC0, ATAS), 0x709C2508);
-
-       iobarrier_rw ();
-
-       return 0;
-}
-
-void after_reloc (ulong dest_addr)
-{
-       /* Jump to the main U-Boot board init code
-        */
-       board_init_r ((gd_t *)gd, dest_addr);
-}
-
-int misc_init_r (void)
-{
-       pcippc2_fpga_init ();
-
-       pcippc2_cpci3264_init ();
-
-#if defined(CONFIG_WATCHDOG)
-       pcippc2_wdt_init ();
-#endif
-
-       fpga_serial_init (sconsole_get_baudrate ());
-
-       sconsole_putc   = fpga_serial_putc;
-       sconsole_puts   = default_serial_puts;
-       sconsole_getc   = fpga_serial_getc;
-       sconsole_tstc   = fpga_serial_tstc;
-       sconsole_setbrg = fpga_serial_setbrg;
-
-       sconsole_flush ();
-       return (0);
-}
-
-void pci_init_board (void)
-{
-       cpc710_pci_init ();
-
-       /* FPGA requires no retry timeouts to be enabled
-        */
-       cpc710_pci_enable_timeout ();
-}
-
-#ifdef CONFIG_CMD_DOC
-void doc_init (void)
-{
-       doc_probe (pcippc2_fpga1_phys + HW_FPGA1_DOC);
-}
-#endif
-
-void pcippc2_cpci3264_init (void)
-{
-  pci_dev_t            bdf = pci_find_device(FPGA_VENDOR_ID, FPGA_DEVICE_ID, 0);
-
-  if (bdf == -1)
-  {
-    puts("Unable to find FPGA !\n");
-    hang();
-  }
-
-       if((in32(pcippc2_fpga0_phys + HW_FPGA0_BOARD) & 0x01000000) == 0x01000000)
-       /* 32-bits Compact PCI bus - LSB bit */
-       {
-               iobarrier_rw();
-               out32(BRIDGE(CPCI, PCIDG), 0x40000000); /* 32-bits bridge, Pipeline */
-               iobarrier_rw();
-       }
-}
-
-#if defined(CONFIG_WATCHDOG)
-
-void pcippc2_wdt_init (void)
-{
-       out16r (FPGA (WDT, PROG), 0xffff);
-       out8 (FPGA (WDT, CTRL), 0x1);
-
-       pcippc2_wdt_init_done = 1;
-}
-
-void pcippc2_wdt_done (void)
-{
-       out8 (FPGA (WDT, CTRL), 0x0);
-
-       pcippc2_wdt_init_done = 0;
-}
-
-void pcippc2_wdt_reset (void)
-{
-       if (pcippc2_wdt_init_done == 1)
-               out8 (FPGA (WDT, REFRESH), 0x56);
-}
-
-void watchdog_reset (void)
-{
-       int re_enable = disable_interrupts ();
-
-       pcippc2_wdt_reset ();
-       if (re_enable)
-               enable_interrupts ();
-}
-
-#if defined(CONFIG_CMD_BSP)
-int do_wd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       switch (argc) {
-       case 1:
-               printf ("Watchdog timer status is %s\n",
-                       pcippc2_wdt_init_done == 1 ? "on" : "off");
-
-               return 0;
-       case 2:
-               if (!strcmp(argv[1],"on")) {
-                       pcippc2_wdt_init();
-                       printf("Watchdog timer now is on\n");
-
-                       return 0;
-
-               } else if (!strcmp(argv[1],"off")) {
-                       pcippc2_wdt_done();
-                       printf("Watchdog timer now is off\n");
-
-                       return 0;
-
-               } else
-                       break;
-       default:
-               break;
-       }
-       return cmd_usage(cmdtp);
-}
-
-U_BOOT_CMD(
-       wd,     2,      1,      do_wd,
-       "check and set watchdog",
-       "on   - switch watchDog on\n"
-       "wd off  - switch watchdog off\n"
-       "wd      - print current status"
-);
-
-#endif
-#endif /* CONFIG_WATCHDOG */
-
-int board_eth_init(bd_t *bis)
-{
-       return pci_eth_init(bis);
-}
diff --git a/board/pcippc2/pcippc2.h b/board/pcippc2/pcippc2.h
deleted file mode 100644 (file)
index a1366ef..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 _PCIPPC2_H_
-#define _PCIPPC2_H_
-
-#include <config.h>
-#include <common.h>
-
-#include "hardware.h"
-
-#define FPGA(r, p)     (pcippc2_fpga0_phys + HW_FPGA0_##r##_##p)
-#define UART(r)                (pcippc2_fpga0_phys + HW_FPGA0_UART1 + NS16550_##r * 4)
-#define RTC(r)         (pcippc2_fpga1_phys + HW_FPGA1_RTC + r)
-
-extern u32             pcippc2_fpga0_phys;
-extern u32             pcippc2_fpga1_phys;
-
-extern u32     pcippc2_sdram_size              (void);
-
-extern void    pcippc2_fpga_init               (void);
-
-extern void    pcippc2_cpci3264_init   (void);
-
-extern void    cpc710_pci_init                 (void);
-extern void    cpc710_pci_enable_timeout       (void);
-
-extern unsigned long
-               cpc710_ram_init                 (void);
-
-#endif
diff --git a/board/pcippc2/pcippc2_fpga.c b/board/pcippc2/pcippc2_fpga.c
deleted file mode 100644 (file)
index 7f6739d..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 <config.h>
-#include <common.h>
-#include <asm/io.h>
-
-#include "pci.h"
-
-#include "hardware.h"
-#include "pcippc2.h"
-
-u32            pcippc2_fpga0_phys;
-u32            pcippc2_fpga1_phys;
-
-void pcippc2_fpga_init (void)
-{
-  pci_dev_t            bdf = pci_find_device(FPGA_VENDOR_ID, FPGA_DEVICE_ID, 0);
-  unsigned int         addr;
-  u16                  cmd;
-
-  if (bdf == -1)
-  {
-    puts("Unable to find FPGA !\n");
-    hang();
-  }
-
-  pci_read_config_word(bdf, PCI_COMMAND, &cmd);
-  if ((cmd & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)) != (PCI_COMMAND_MEMORY | PCI_COMMAND_IO))
-  {
-    puts("FPGA is not configured !\n");
-    hang();
-  }
-
-  pci_read_config_dword(bdf, PCI_BASE_ADDRESS_0, &addr);
-  if (addr & 0x1)
-  {
-      /* IO space
-       */
-    pcippc2_fpga0_phys = pci_io_to_phys(bdf, addr & 0xfffffffc);
-  }
-  else
-  {
-      /* Memory space
-       */
-    pcippc2_fpga0_phys = pci_mem_to_phys(bdf, addr & 0xfffffff0);
-  }
-
-  pci_read_config_dword(bdf, PCI_BASE_ADDRESS_1, &addr);
-  if (addr & 0x1)
-  {
-      /* IO space
-       */
-    pcippc2_fpga1_phys = pci_io_to_phys(bdf, addr & 0xfffffffc);
-  }
-  else
-  {
-      /* Memory space
-       */
-    pcippc2_fpga1_phys = pci_mem_to_phys(bdf, addr & 0xfffffff0);
-  }
-
-    /* Interrupts are not used
-     */
-  out32(FPGA(INT, INTR_MASK), 0xffffffff);
-  iobarrier_rw();
-}
diff --git a/board/pcippc2/pcippc2_fpga.h b/board/pcippc2/pcippc2_fpga.h
deleted file mode 100644 (file)
index 850c331..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 _PCIPPC2_FPGA_H_
-#define _PCIPPC2_FPGA_H_
-
-#define FPGA_VENDOR_ID                 0x1310
-#define FPGA_DEVICE_ID                 0x000d
-
-#define HW_FPGA0_INT                   0x0000
-#define HW_FPGA0_BOARD         0x0060
-#define HW_FPGA0_UART1                 0x0080
-#define HW_FPGA0_UART2                 0x0100
-#define HW_FPGA0_RTC                   0x2000
-#define HW_FPGA0_DOC                   0x4000
-#define HW_FPGA1_RTC                   0x0000
-#define HW_FPGA1_DOC                   0x4000
-
-#define HW_FPGA0_INT_INTR_MASK         0x30
-#define HW_FPGA0_INT_INTR_STATUS       0x34
-#define HW_FPGA0_INT_INTR_EOI          0x40
-#define HW_FPGA0_INT_SERIAL_CONFIG     0x5c
-
-#define HW_FPGA0_WDT_CTRL              0x44
-#define HW_FPGA0_WDT_PROG              0x48
-#define HW_FPGA0_WDT_VAL               0x4c
-#define HW_FPGA0_WDT_REFRESH           0x50
-
-#endif
diff --git a/board/pcippc2/sconsole.c b/board/pcippc2/sconsole.c
deleted file mode 100644 (file)
index aa3c908..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 <config.h>
-#include <common.h>
-#include <serial.h>
-#include <linux/compiler.h>
-
-#include "sconsole.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-void   (*sconsole_putc) (char) = 0;
-void   (*sconsole_puts) (const char *) = 0;
-int    (*sconsole_getc) (void) = 0;
-int    (*sconsole_tstc) (void) = 0;
-void   (*sconsole_setbrg) (void) = 0;
-
-static int sconsole_serial_init(void)
-{
-       sconsole_buffer_t *sb = SCONSOLE_BUFFER;
-
-       sb->pos  = 0;
-       sb->size = 0;
-       sb->baud = gd->baudrate;
-       sb->max_size = CONFIG_SYS_SCONSOLE_SIZE - sizeof (sconsole_buffer_t);
-
-       return (0);
-}
-
-static void sconsole_serial_putc(char c)
-{
-       if (sconsole_putc) {
-               (*sconsole_putc) (c);
-       } else {
-               sconsole_buffer_t *sb = SCONSOLE_BUFFER;
-
-               if (c) {
-                       sb->data[sb->pos++] = c;
-                       if (sb->pos == sb->max_size) {
-                               sb->pos = 0;
-                       }
-                       if (sb->size < sb->max_size) {
-                               sb->size++;
-                       }
-               }
-       }
-}
-
-static void sconsole_serial_puts(const char *s)
-{
-       if (sconsole_puts) {
-               (*sconsole_puts) (s);
-       } else {
-               sconsole_buffer_t *sb = SCONSOLE_BUFFER;
-
-               while (*s) {
-                       sb->data[sb->pos++] = *s++;
-                       if (sb->pos == sb->max_size) {
-                               sb->pos = 0;
-                       }
-                       if (sb->size < sb->max_size) {
-                               sb->size++;
-                       }
-               }
-       }
-}
-
-static int sconsole_serial_getc(void)
-{
-       if (sconsole_getc) {
-               return (*sconsole_getc) ();
-       } else {
-               return 0;
-       }
-}
-
-static int sconsole_serial_tstc(void)
-{
-       if (sconsole_tstc) {
-               return (*sconsole_tstc) ();
-       } else {
-               return 0;
-       }
-}
-
-static void sconsole_serial_setbrg(void)
-{
-       if (sconsole_setbrg) {
-               (*sconsole_setbrg) ();
-       } else {
-               sconsole_buffer_t *sb = SCONSOLE_BUFFER;
-
-               sb->baud = gd->baudrate;
-       }
-}
-
-static struct serial_device sconsole_serial_drv = {
-       .name   = "sconsole_serial",
-       .start  = sconsole_serial_init,
-       .stop   = NULL,
-       .setbrg = sconsole_serial_setbrg,
-       .putc   = sconsole_serial_putc,
-       .puts   = sconsole_serial_puts,
-       .getc   = sconsole_serial_getc,
-       .tstc   = sconsole_serial_tstc,
-};
-
-void sconsole_serial_initialize(void)
-{
-       serial_register(&sconsole_serial_drv);
-}
-
-__weak struct serial_device *default_serial_console(void)
-{
-       return &sconsole_serial_drv;
-}
-
-int sconsole_get_baudrate (void)
-{
-       sconsole_buffer_t *sb = SCONSOLE_BUFFER;
-
-       return sb->baud;
-}
-
-void sconsole_flush (void)
-{
-       if (sconsole_putc) {
-               sconsole_buffer_t *sb = SCONSOLE_BUFFER;
-               unsigned int end = sb->pos < sb->size
-                               ? sb->pos + sb->max_size - sb->size
-                               : sb->pos - sb->size;
-
-               while (sb->size) {
-                       (*sconsole_putc) (sb->data[end++]);
-                       if (end == sb->max_size) {
-                               end = 0;
-                       }
-                       sb->size--;
-               }
-       }
-}
index a2a132344f5771f70a9a51c87e87358bababdbd8..3048acd117678635c952d27df86078917db99353 100644 (file)
@@ -44,63 +44,6 @@ DECLARE_GLOBAL_DATA_PTR;
 extern flash_info_t flash_info[];
 ulong flash_get_size (phys_addr_t base, int banknum);
 
-/* Clocks in use */
-#define SCCR1_CLOCKS_EN        (CLOCK_SCCR1_CFG_EN |                           \
-                        CLOCK_SCCR1_LPC_EN |                           \
-                        CLOCK_SCCR1_NFC_EN |                           \
-                        CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) |       \
-                        CLOCK_SCCR1_PSCFIFO_EN |                       \
-                        CLOCK_SCCR1_DDR_EN |                           \
-                        CLOCK_SCCR1_FEC_EN |                           \
-                        CLOCK_SCCR1_TPR_EN)
-
-#define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_MEM_EN |           \
-                        CLOCK_SCCR2_SPDIF_EN |         \
-                        CLOCK_SCCR2_DIU_EN |           \
-                        CLOCK_SCCR2_I2C_EN)
-
-int board_early_init_f(void)
-{
-       volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
-
-       /*
-        * Initialize Local Window for FLASH-Bank1 access (CS1)
-        */
-       out_be32(&im->sysconf.lpcs1aw,
-               CSAW_START(CONFIG_SYS_FLASH1_BASE) |
-               CSAW_STOP(CONFIG_SYS_FLASH1_BASE, CONFIG_SYS_FLASH_SIZE)
-       );
-       out_be32(&im->lpc.cs_cfg[1], CONFIG_SYS_CS1_CFG);
-
-       /*
-        * Local Window for MRAM access (CS2)
-        */
-       out_be32(&im->sysconf.lpcs2aw,
-               CSAW_START(CONFIG_SYS_MRAM_BASE) |
-               CSAW_STOP(CONFIG_SYS_MRAM_BASE, CONFIG_SYS_MRAM_SIZE)
-       );
-       out_be32(&im->lpc.cs_cfg[2], CONFIG_SYS_CS2_CFG);
-
-       sync_law(&im->sysconf.lpcs2aw);
-
-       /*
-        * Configure Flash Speed
-        */
-       out_be32(&im->lpc.cs_cfg[0], CONFIG_SYS_CS0_CFG);
-       out_be32(&im->lpc.altr, CONFIG_SYS_CS_ALETIMING);
-
-       /*
-        * Enable clocks
-        */
-       out_be32(&im->clk.sccr[0], SCCR1_CLOCKS_EN);
-       out_be32(&im->clk.sccr[1], SCCR2_CLOCKS_EN);
-#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE)
-       setbits_be32(&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN);
-#endif
-
-       return 0;
-}
-
 sdram_conf_t mddrc_config[] = {
        {
                (512 << 20),    /* 512 MB RAM configuration */
@@ -557,7 +500,6 @@ void ft_board_setup(void *blob, bd_t *bd)
        int rc, i = 0;
 
        ft_cpu_setup(blob, bd);
-       fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
 #ifdef CONFIG_FDT_FIXUP_PARTITIONS
        fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
 #endif
index 55bc01871457a716afe152e6d1a85128e1a6423c..1708ac2acdbd290bb1f485b2785dab3f56dea594 100644 (file)
@@ -61,7 +61,7 @@ static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
 
 static void rtc32k_enable(void)
 {
-       struct rtc_regs *rtc = (struct rtc_regs *)AM335X_RTC_BASE;
+       struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE;
 
        /*
         * Unlock the RTC's registers.  For more details please see the
@@ -159,7 +159,7 @@ void s_init(void)
        enable_board_pin_mux();
 
        config_ddr(DDR_CLK_MHZ, MT41J256M8HX15E_IOCTRL_VALUE, &ddr3_data,
-                       &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data);
+                       &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
 #endif
 }
 
@@ -199,8 +199,8 @@ static struct cpsw_slave_data cpsw_slaves[] = {
 };
 
 static struct cpsw_platform_data cpsw_data = {
-       .mdio_base              = AM335X_CPSW_MDIO_BASE,
-       .cpsw_base              = AM335X_CPSW_BASE,
+       .mdio_base              = CPSW_MDIO_BASE,
+       .cpsw_base              = CPSW_BASE,
        .mdio_div               = 0xff,
        .channels               = 8,
        .cpdma_reg_ofs          = 0x800,
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 9262aa55fb05da272d7bf2f953e80b531b13f72f..ef3a17fbbe61b3a6c253219cfc4e20782b88830a 100644 (file)
@@ -95,7 +95,7 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
   . = ALIGN(128 * 1024);
   .ppcenv      :
index 688b0aade137213948a8b3ba1a21de64abb5af7c..6b3e095ba89bcb96ae5c7b8e3708ca7b92787bd2 100644 (file)
  */
 
 #include <common.h>
+#include <asm/arch/mbox.h>
+#include <asm/arch/sdhci.h>
 #include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+struct msg_get_arm_mem {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
+       u32 end_tag;
+};
+
+struct msg_get_clock_rate {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_get_clock_rate get_clock_rate;
+       u32 end_tag;
+};
+
 int dram_init(void)
 {
-       gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+       ALLOC_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1, 16);
+       int ret;
+
+       BCM2835_MBOX_INIT_HDR(msg);
+       BCM2835_MBOX_INIT_TAG(&msg->get_arm_mem, GET_ARM_MEMORY);
+
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
+       if (ret) {
+               printf("bcm2835: Could not query ARM memory size\n");
+               return -1;
+       }
+
+       gd->ram_size = msg->get_arm_mem.body.resp.mem_size;
 
        return 0;
 }
@@ -32,3 +58,22 @@ int board_init(void)
 
        return 0;
 }
+
+int board_mmc_init(void)
+{
+       ALLOC_ALIGN_BUFFER(struct msg_get_clock_rate, msg_clk, 1, 16);
+       int ret;
+
+       BCM2835_MBOX_INIT_HDR(msg_clk);
+       BCM2835_MBOX_INIT_TAG(&msg_clk->get_clock_rate, GET_CLOCK_RATE);
+       msg_clk->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC;
+
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_clk->hdr);
+       if (ret) {
+               printf("bcm2835: Could not query eMMC clock rate\n");
+               return -1;
+       }
+
+       return bcm2835_sdhci_init(BCM2835_SDHCI_BASE,
+                                 msg_clk->get_clock_rate.body.resp.rate_hz);
+}
index c6560c60da4145e080466b3df0d6214d4a1803b8..b35440958cdfaebba8579c8ea04fe0ef0c74caae 100644 (file)
@@ -103,6 +103,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 5bbb63f853c921a3b424e9d0598139ef69c8a018..276f525eb7e8db90fbd0ec26ffb8670d594a41b6 100644 (file)
@@ -93,5 +93,5 @@ SECTIONS
        }
        PROVIDE (bss_end = .);
 
-       PROVIDE (__bss_end__ = .);
+       PROVIDE (__bss_end = .);
 }
index 0717d041ca8e576222c4a64ef5cacdb906dbfae7..58824271cb04799934bc3230c451c0b7204b88af 100644 (file)
@@ -94,5 +94,5 @@ SECTIONS
        }
        PROVIDE (bss_end = .);
 
-       PROVIDE (__bss_end__ = .);
+       PROVIDE (__bss_end = .);
 }
index 46625462b45f632f0b2ee195cb4bd3aeb7636169..240b9363c8db14e4b6dad2ce55988d18e2bbc05e 100644 (file)
@@ -125,6 +125,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index cbfab6f97fbbc9c76fd633ebedc4f80672dbbdde..1c2d52d622db9823f414dcc7186383352e6ff92f 100644 (file)
                        compatible = "maxim,max77686_pmic";
                };
        };
+
+       tmu@10060000 {
+               samsung,min-temp        = <25>;
+               samsung,max-temp        = <125>;
+               samsung,start-warning   = <95>;
+               samsung,start-tripping  = <105>;
+               samsung,hw-tripping     = <110>;
+               samsung,efuse-min-value = <40>;
+               samsung,efuse-value     = <55>;
+               samsung,efuse-max-value = <100>;
+               samsung,slope           = <274761730>;
+               samsung,dc-value        = <25>;
+       };
 };
diff --git a/board/samsung/dts/exynos5250-snow.dts b/board/samsung/dts/exynos5250-snow.dts
new file mode 100644 (file)
index 0000000..8b303bf
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * SAMSUNG Snow board device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * 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
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+/include/ ARCH_CPU_DTS
+
+/ {
+       model = "Google Snow";
+       compatible = "google,snow", "samsung,exynos5250";
+
+       aliases {
+               i2c0 = "/i2c@12c60000";
+               i2c1 = "/i2c@12c70000";
+               i2c2 = "/i2c@12c80000";
+               i2c3 = "/i2c@12c90000";
+               i2c4 = "/i2c@12ca0000";
+               i2c5 = "/i2c@12cb0000";
+               i2c6 = "/i2c@12cc0000";
+               i2c7 = "/i2c@12cd0000";
+               spi0 = "/spi@12d20000";
+               spi1 = "/spi@12d30000";
+               spi2 = "/spi@12d40000";
+               spi3 = "/spi@131a0000";
+               spi4 = "/spi@131b0000";
+       };
+
+       sound@12d60000 {
+               samsung,i2s-epll-clock-frequency = <192000000>;
+               samsung,i2s-sampling-rate = <48000>;
+               samsung,i2s-bits-per-sample = <16>;
+               samsung,i2s-channels = <2>;
+               samsung,i2s-lr-clk-framesize = <256>;
+               samsung,i2s-bit-clk-framesize = <32>;
+               samsung,codec-type = "max98095";
+       };
+
+       i2c@12cd0000 {
+               soundcodec@22 {
+                       reg = <0x22>;
+                       compatible = "maxim,max98095-codec";
+               };
+       };
+
+       i2c@12c60000 {
+               pmic@9 {
+                       reg = <0x9>;
+                       compatible = "maxim,max77686_pmic";
+               };
+       };
+};
index 4ef6a5197665eb28c888c185263c066911d19dce..4c8baaa9db36992168e85a38ceb2869ebf604f5b 100644 (file)
@@ -66,6 +66,6 @@ SECTIONS
                __bss_start = .;
                *(.bss*)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        } >.sram
 }
index 7a5f132ebb753a8519834b1e995f9810d414daf9..217c6df30185f14d6ba4797e65f3300fd6f3b4eb 100644 (file)
@@ -23,6 +23,7 @@
 #include <common.h>
 #include <fdtdec.h>
 #include <asm/io.h>
+#include <errno.h>
 #include <i2c.h>
 #include <lcd.h>
 #include <netdev.h>
 #include <asm/arch/sromc.h>
 #include <asm/arch/dp_info.h>
 #include <power/pmic.h>
+#include <power/max77686_pmic.h>
+#include <tmu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if defined CONFIG_EXYNOS_TMU
+/*
+ * Boot Time Thermal Analysis for SoC temperature threshold breach
+ */
+static void boot_temp_check(void)
+{
+       int temp;
+
+       switch (tmu_monitor(&temp)) {
+       /* Status TRIPPED ans WARNING means corresponding threshold breach */
+       case TMU_STATUS_TRIPPED:
+               puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n");
+               set_ps_hold_ctrl();
+               hang();
+               break;
+       case TMU_STATUS_WARNING:
+               puts("EXYNOS_TMU: WARNING! Temperature very high\n");
+               break;
+       /*
+        * TMU_STATUS_INIT means something is wrong with temperature sensing
+        * and TMU status was changed back from NORMAL to INIT.
+        */
+       case TMU_STATUS_INIT:
+       default:
+               debug("EXYNOS_TMU: Unknown TMU state\n");
+       }
+}
+#endif
+
 #ifdef CONFIG_USB_EHCI_EXYNOS
 int board_usb_vbus_init(void)
 {
@@ -54,14 +86,38 @@ int board_usb_vbus_init(void)
 }
 #endif
 
+#ifdef CONFIG_SOUND_MAX98095
+static void  board_enable_audio_codec(void)
+{
+       struct exynos5_gpio_part1 *gpio1 = (struct exynos5_gpio_part1 *)
+                                               samsung_get_base_gpio_part1();
+
+       /* Enable MAX98095 Codec */
+       s5p_gpio_direction_output(&gpio1->x1, 7, 1);
+       s5p_gpio_set_pull(&gpio1->x1, 7, GPIO_PULL_NONE);
+}
+#endif
+
 int board_init(void)
 {
        gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
+
+#if defined CONFIG_EXYNOS_TMU
+       if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) {
+               debug("%s: Failed to init TMU\n", __func__);
+               return -1;
+       }
+       boot_temp_check();
+#endif
+
 #ifdef CONFIG_EXYNOS_SPI
        spi_init();
 #endif
 #ifdef CONFIG_USB_EHCI_EXYNOS
        board_usb_vbus_init();
+#endif
+#ifdef CONFIG_SOUND_MAX98095
+       board_enable_audio_codec();
 #endif
        return 0;
 }
@@ -80,12 +136,119 @@ int dram_init(void)
 }
 
 #if defined(CONFIG_POWER)
+static int pmic_reg_update(struct pmic *p, int reg, uint regval)
+{
+       u32 val;
+       int ret = 0;
+
+       ret = pmic_reg_read(p, reg, &val);
+       if (ret) {
+               debug("%s: PMIC %d register read failed\n", __func__, reg);
+               return -1;
+       }
+       val |= regval;
+       ret = pmic_reg_write(p, reg, val);
+       if (ret) {
+               debug("%s: PMIC %d register write failed\n", __func__, reg);
+               return -1;
+       }
+       return 0;
+}
+
 int power_init_board(void)
 {
+       struct pmic *p;
+
+       set_ps_hold_ctrl();
+
+       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
        if (pmic_init(I2C_PMIC))
                return -1;
-       else
-               return 0;
+
+       p = pmic_get("MAX77686_PMIC");
+       if (!p)
+               return -ENODEV;
+
+       if (pmic_probe(p))
+               return -1;
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN))
+               return -1;
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT,
+                               MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V))
+               return -1;
+
+       /* VDD_MIF */
+       if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT,
+                                               MAX77686_BUCK1OUT_1V)) {
+               debug("%s: PMIC %d register write failed\n", __func__,
+                                               MAX77686_REG_PMIC_BUCK1OUT);
+               return -1;
+       }
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL,
+                                               MAX77686_BUCK1CTRL_EN))
+               return -1;
+
+       /* VDD_ARM */
+       if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1,
+                                       MAX77686_BUCK2DVS1_1_3V)) {
+               debug("%s: PMIC %d register write failed\n", __func__,
+                                               MAX77686_REG_PMIC_BUCK2DVS1);
+               return -1;
+       }
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1,
+                                       MAX77686_BUCK2CTRL_ON))
+               return -1;
+
+       /* VDD_INT */
+       if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1,
+                                       MAX77686_BUCK3DVS1_1_0125V)) {
+               debug("%s: PMIC %d register write failed\n", __func__,
+                                               MAX77686_REG_PMIC_BUCK3DVS1);
+               return -1;
+       }
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL,
+                                       MAX77686_BUCK3CTRL_ON))
+               return -1;
+
+       /* VDD_G3D */
+       if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1,
+                                       MAX77686_BUCK4DVS1_1_2V)) {
+               debug("%s: PMIC %d register write failed\n", __func__,
+                                               MAX77686_REG_PMIC_BUCK4DVS1);
+               return -1;
+       }
+
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1,
+                                       MAX77686_BUCK3CTRL_ON))
+               return -1;
+
+       /* VDD_LDO2 */
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1,
+                               MAX77686_LD02CTRL1_1_5V | EN_LDO))
+               return -1;
+
+       /* VDD_LDO3 */
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1,
+                               MAX77686_LD03CTRL1_1_8V | EN_LDO))
+               return -1;
+
+       /* VDD_LDO5 */
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1,
+                               MAX77686_LD05CTRL1_1_8V | EN_LDO))
+               return -1;
+
+       /* VDD_LDO10 */
+       if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1,
+                               MAX77686_LD10CTRL1_1_8V | EN_LDO))
+               return -1;
+
+       return 0;
 }
 #endif
 
@@ -212,8 +375,17 @@ int board_eth_init(bd_t *bis)
 #ifdef CONFIG_DISPLAY_BOARDINFO
 int checkboard(void)
 {
-       printf("\nBoard: SMDK5250\n");
+#ifdef CONFIG_OF_CONTROL
+       const char *board_name;
 
+       board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+       if (board_name == NULL)
+               printf("\nUnknown Board\n");
+       else
+               printf("\nBoard: %s\n", board_name);
+#else
+       printf("\nBoard: SMDK5250\n");
+#endif
        return 0;
 }
 #endif
index ae32b1625e2dcb1dbf6fe6f204f22ff3b8dde2e5..64c650d2e9c39ee964ef9917e349717bb9078473 100644 (file)
@@ -75,7 +75,7 @@ SECTIONS
                __bss_start = .;
                *(.bss)
                . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        }
 
        /DISCARD/ : { *(.dynstr*) }
index 88d193de280437a0f566a2e27be21e3a7c930109..920764664cc0ca69c0bf65dbd4359645eb44a5a4 100644 (file)
@@ -42,6 +42,7 @@
 #include <power/max8997_muic.h>
 #include <power/battery.h>
 #include <power/max17042_fg.h>
+#include <usb_mass_storage.h>
 
 #include "setup.h"
 
@@ -791,3 +792,65 @@ void init_panel_info(vidinfo_t *vid)
 
        setenv("lcdinfo", "lcd=s6e8ax0");
 }
+
+#ifdef CONFIG_USB_GADGET_MASS_STORAGE
+static int ums_read_sector(struct ums_device *ums_dev,
+                          ulong start, lbaint_t blkcnt, void *buf)
+{
+       if (ums_dev->mmc->block_dev.block_read(ums_dev->dev_num,
+                       start + ums_dev->offset, blkcnt, buf) != blkcnt)
+               return -1;
+
+       return 0;
+}
+
+static int ums_write_sector(struct ums_device *ums_dev,
+                           ulong start, lbaint_t blkcnt, const void *buf)
+{
+       if (ums_dev->mmc->block_dev.block_write(ums_dev->dev_num,
+                       start + ums_dev->offset, blkcnt, buf) != blkcnt)
+               return -1;
+
+       return 0;
+}
+
+static void ums_get_capacity(struct ums_device *ums_dev,
+                            long long int *capacity)
+{
+       long long int tmp_capacity;
+
+       tmp_capacity = (long long int) ((ums_dev->offset + ums_dev->part_size)
+                                       * SECTOR_SIZE);
+       *capacity = ums_dev->mmc->capacity - tmp_capacity;
+}
+
+static struct ums_board_info ums_board = {
+       .read_sector = ums_read_sector,
+       .write_sector = ums_write_sector,
+       .get_capacity = ums_get_capacity,
+       .name = "TRATS UMS disk",
+       .ums_dev = {
+               .mmc = NULL,
+               .dev_num = 0,
+               .offset = 0,
+               .part_size = 0.
+       },
+};
+
+struct ums_board_info *board_ums_init(unsigned int dev_num, unsigned int offset,
+                                     unsigned int part_size)
+{
+       struct mmc *mmc;
+
+       mmc = find_mmc_device(dev_num);
+       if (!mmc)
+               return NULL;
+
+       ums_board.ums_dev.mmc = mmc;
+       ums_board.ums_dev.dev_num = dev_num;
+       ums_board.ums_dev.offset = offset;
+       ums_board.ums_dev.part_size = part_size;
+
+       return &ums_board;
+}
+#endif
index ca13619659dd0b0c85b643b9668db4d83fb63006..95e13c46df0554e5955eca039a5947d1db1b5ef0 100644 (file)
@@ -95,6 +95,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index fa4de9d9c5c7c82850a3c843bbd6ab5e8907eda4..66c5fba210ee1c70aaff01130b8d0b8046acc9db 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 5929335bf527df0b5396198253e9a4a8bcb57cc7..285e8971ff4ca0bd6cbff003178b3d6ee655e85c 100644 (file)
@@ -96,6 +96,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index c2ec827dc78c34b4c1d3218cf81fe63fe9f30a2d..3334a44f618abbd4339ba541da2d3951547f5d9d 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index b2ad3434fdc028a0e8a624ca1fad80619e5646aa..58f2565f7fa9353251b2e1bbf471a51f663822ba 100644 (file)
@@ -102,6 +102,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ddb5a72b2ba8a77c5eede85e4313b5e41c707a9f..03891e937f1123349d8576860f1aa9bc2d6c37df 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index ebfa890211ba550a9d3d46872e28be611b982524..99b8bfa5bfeda02ea2560fe7658bf8750c9be001 100644 (file)
@@ -110,6 +110,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index f4b972b3e995c3dfcd833d7e99f8e7038212ebe7..12620bb69cd051b357957bd92d9a1d4582e426d8 100644 (file)
@@ -134,7 +134,7 @@ static int read_eeprom(void)
 
 static void rtc32k_enable(void)
 {
-       struct rtc_regs *rtc = (struct rtc_regs *)AM335X_RTC_BASE;
+       struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE;
 
        /*
         * Unlock the RTC's registers.  For more details please see the
@@ -208,6 +208,14 @@ static const struct ddr_data ddr3_data = {
        .datadldiff0 = PHY_DLL_LOCK_DIFF,
 };
 
+static const struct ddr_data ddr3_beagleblack_data = {
+       .datardsratio0 = MT41K256M16HA125E_RD_DQS,
+       .datawdsratio0 = MT41K256M16HA125E_WR_DQS,
+       .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
+       .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
+       .datadldiff0 = PHY_DLL_LOCK_DIFF,
+};
+
 static const struct ddr_data ddr3_evm_data = {
        .datardsratio0 = MT41J512M8RH125_RD_DQS,
        .datawdsratio0 = MT41J512M8RH125_WR_DQS,
@@ -230,6 +238,20 @@ static const struct cmd_control ddr3_cmd_ctrl_data = {
        .cmd2iclkout = MT41J128MJT125_INVERT_CLKOUT,
 };
 
+static const struct cmd_control ddr3_beagleblack_cmd_ctrl_data = {
+       .cmd0csratio = MT41K256M16HA125E_RATIO,
+       .cmd0dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
+       .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
+
+       .cmd1csratio = MT41K256M16HA125E_RATIO,
+       .cmd1dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
+       .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
+
+       .cmd2csratio = MT41K256M16HA125E_RATIO,
+       .cmd2dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
+       .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
+};
+
 static const struct cmd_control ddr3_evm_cmd_ctrl_data = {
        .cmd0csratio = MT41J512M8RH125_RATIO,
        .cmd0dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
@@ -251,7 +273,18 @@ static struct emif_regs ddr3_emif_reg_data = {
        .sdram_tim2 = MT41J128MJT125_EMIF_TIM2,
        .sdram_tim3 = MT41J128MJT125_EMIF_TIM3,
        .zq_config = MT41J128MJT125_ZQ_CFG,
-       .emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY,
+       .emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY |
+                               PHY_EN_DYN_PWRDN,
+};
+
+static struct emif_regs ddr3_beagleblack_emif_reg_data = {
+       .sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
+       .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
+       .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
+       .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
+       .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
+       .zq_config = MT41K256M16HA125E_ZQ_CFG,
+       .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY,
 };
 
 static struct emif_regs ddr3_evm_emif_reg_data = {
@@ -261,7 +294,8 @@ static struct emif_regs ddr3_evm_emif_reg_data = {
        .sdram_tim2 = MT41J512M8RH125_EMIF_TIM2,
        .sdram_tim3 = MT41J512M8RH125_EMIF_TIM3,
        .zq_config = MT41J512M8RH125_ZQ_CFG,
-       .emif_ddr_phy_ctlr_1 = MT41J512M8RH125_EMIF_READ_LATENCY,
+       .emif_ddr_phy_ctlr_1 = MT41J512M8RH125_EMIF_READ_LATENCY |
+                               PHY_EN_DYN_PWRDN,
 };
 #endif
 
@@ -341,15 +375,20 @@ void s_init(void)
                gpio_direction_output(GPIO_DDR_VTT_EN, 1);
        }
 
-       if (board_is_evm_sk() || board_is_bone_lt())
+       if (board_is_evm_sk())
                config_ddr(303, MT41J128MJT125_IOCTRL_VALUE, &ddr3_data,
-                          &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data);
+                          &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
+       else if (board_is_bone_lt())
+               config_ddr(303, MT41K256M16HA125E_IOCTRL_VALUE,
+                          &ddr3_beagleblack_data,
+                          &ddr3_beagleblack_cmd_ctrl_data,
+                          &ddr3_beagleblack_emif_reg_data, 0);
        else if (board_is_evm_15_or_later())
                config_ddr(303, MT41J512M8RH125_IOCTRL_VALUE, &ddr3_evm_data,
-                          &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data);
+                          &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data, 0);
        else
                config_ddr(266, MT47H128M16RT25E_IOCTRL_VALUE, &ddr2_data,
-                          &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data);
+                          &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0);
 #endif
 }
 
@@ -412,8 +451,8 @@ static struct cpsw_slave_data cpsw_slaves[] = {
 };
 
 static struct cpsw_platform_data cpsw_data = {
-       .mdio_base              = AM335X_CPSW_MDIO_BASE,
-       .cpsw_base              = AM335X_CPSW_BASE,
+       .mdio_base              = CPSW_MDIO_BASE,
+       .cpsw_base              = CPSW_BASE,
        .mdio_div               = 0xff,
        .channels               = 8,
        .cpdma_reg_ofs          = 0x800,
similarity index 54%
rename from board/pcippc2/Makefile
rename to board/ti/ti814x/Makefile
index 6f0a928805eca1dae29cd28ba897e7e90cc79614..09d24222f362d52490bb80ad8be52fa6c70227b7 100644 (file)
@@ -1,35 +1,28 @@
 #
-# (C) Copyright 2002-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+# Makefile
 #
-# See file CREDITS for list of people who contributed to this
-# project.
+# Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
 # published by the Free Software Foundation; either version 2 of
 # the License, or (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# This program is distributed "as is" WITHOUT ANY WARRANTY of any
+# kind, whether express or implied; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
 
 include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
-COBJS  = $(BOARD).o cpc710_pci.o flash.o sconsole.o \
-         fpga_serial.o pcippc2_fpga.o cpc710_init_ram.o i2c.o
-
-SOBJS  =
+ifdef CONFIG_SPL_BUILD
+COBJS  := mux.o
+endif
 
+COBJS  += evm.o
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
 SOBJS  := $(addprefix $(obj),$(SOBJS))
@@ -37,6 +30,12 @@ SOBJS        := $(addprefix $(obj),$(SOBJS))
 $(LIB):        $(obj).depend $(OBJS) $(SOBJS)
        $(call cmd_link_o_target, $(OBJS) $(SOBJS))
 
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak $(obj).depend
+
 #########################################################################
 
 # defines $(obj).depend target
diff --git a/board/ti/ti814x/evm.c b/board/ti/ti814x/evm.c
new file mode 100644 (file)
index 0000000..446e36b
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * evm.c
+ *
+ * Board functions for TI814x EVM
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <spl.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include "evm.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SPL_BUILD
+static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
+#endif
+
+/* UART Defines */
+#ifdef CONFIG_SPL_BUILD
+#define UART_RESET             (0x1 << 1)
+#define UART_CLK_RUNNING_MASK  0x1
+#define UART_SMART_IDLE_EN     (0x1 << 0x3)
+
+static void rtc32k_enable(void)
+{
+       struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE;
+
+       /*
+        * Unlock the RTC's registers.  For more details please see the
+        * RTC_SS section of the TRM.  In order to unlock we need to
+        * write these specific values (keys) in this order.
+        */
+       writel(0x83e70b13, &rtc->kick0r);
+       writel(0x95a4f1e0, &rtc->kick1r);
+
+       /* Enable the RTC 32K OSC by setting bits 3 and 6. */
+       writel((1 << 3) | (1 << 6), &rtc->osc);
+}
+
+static void uart_enable(void)
+{
+       u32 regVal;
+
+       /* UART softreset */
+       regVal = readl(&uart_base->uartsyscfg);
+       regVal |= UART_RESET;
+       writel(regVal, &uart_base->uartsyscfg);
+       while ((readl(&uart_base->uartsyssts) &
+               UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK)
+               ;
+
+       /* Disable smart idle */
+       regVal = readl(&uart_base->uartsyscfg);
+       regVal |= UART_SMART_IDLE_EN;
+       writel(regVal, &uart_base->uartsyscfg);
+}
+
+static void wdt_disable(void)
+{
+       writel(0xAAAA, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) != 0x0)
+               ;
+       writel(0x5555, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) != 0x0)
+               ;
+}
+
+static const struct cmd_control evm_ddr2_cctrl_data = {
+       .cmd0csratio    = 0x80,
+       .cmd0dldiff     = 0x04,
+       .cmd0iclkout    = 0x00,
+
+       .cmd1csratio    = 0x80,
+       .cmd1dldiff     = 0x04,
+       .cmd1iclkout    = 0x00,
+
+       .cmd2csratio    = 0x80,
+       .cmd2dldiff     = 0x04,
+       .cmd2iclkout    = 0x00,
+};
+
+static const struct emif_regs evm_ddr2_emif0_regs = {
+       .sdram_config                   = 0x40801ab2,
+       .ref_ctrl                       = 0x10000c30,
+       .sdram_tim1                     = 0x0aaaf552,
+       .sdram_tim2                     = 0x043631d2,
+       .sdram_tim3                     = 0x00000327,
+       .emif_ddr_phy_ctlr_1            = 0x00000007
+};
+
+static const struct emif_regs evm_ddr2_emif1_regs = {
+       .sdram_config                   = 0x40801ab2,
+       .ref_ctrl                       = 0x10000c30,
+       .sdram_tim1                     = 0x0aaaf552,
+       .sdram_tim2                     = 0x043631d2,
+       .sdram_tim3                     = 0x00000327,
+       .emif_ddr_phy_ctlr_1            = 0x00000007
+};
+
+const struct dmm_lisa_map_regs evm_lisa_map_regs = {
+       .dmm_lisa_map_0                 = 0x00000000,
+       .dmm_lisa_map_1                 = 0x00000000,
+       .dmm_lisa_map_2                 = 0x806c0300,
+       .dmm_lisa_map_3                 = 0x806c0300,
+};
+
+static const struct ddr_data evm_ddr2_data = {
+       .datardsratio0          = ((0x35<<10) | (0x35<<0)),
+       .datawdsratio0          = ((0x20<<10) | (0x20<<0)),
+       .datawiratio0           = ((0<<10) | (0<<0)),
+       .datagiratio0           = ((0<<10) | (0<<0)),
+       .datafwsratio0          = ((0x90<<10) | (0x90<<0)),
+       .datawrsratio0          = ((0x50<<10) | (0x50<<0)),
+       .datauserank0delay      = 1,
+       .datadldiff0            = 0x4,
+};
+#endif
+
+/*
+ * early system init of muxing and clocks.
+ */
+void s_init(void)
+{
+#ifdef CONFIG_SPL_BUILD
+       /* WDT1 is already running when the bootloader gets control
+        * Disable it to avoid "random" resets
+        */
+       wdt_disable();
+
+       /* Setup the PLLs and the clocks for the peripherals */
+       pll_init();
+
+       /* Enable RTC32K clock */
+       rtc32k_enable();
+
+       /* Set UART pins */
+       enable_uart0_pin_mux();
+
+       /* Set MMC pins */
+       enable_mmc1_pin_mux();
+
+       /* Enable UART */
+       uart_enable();
+
+       gd = &gdata;
+
+       preloader_console_init();
+
+       config_dmm(&evm_lisa_map_regs);
+
+       config_ddr(0, 0, &evm_ddr2_data, &evm_ddr2_cctrl_data,
+                  &evm_ddr2_emif0_regs, 0);
+       config_ddr(0, 0, &evm_ddr2_data, &evm_ddr2_cctrl_data,
+                  &evm_ddr2_emif1_regs, 1);
+#endif
+}
+
+/*
+ * Basic board specific setup.  Pinmux has been handled already.
+ */
+int board_init(void)
+{
+       gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
+       return 0;
+}
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC)
+int board_mmc_init(bd_t *bis)
+{
+       omap_mmc_init(1, 0, 0, -1, -1);
+
+       return 0;
+}
+#endif
diff --git a/board/ti/ti814x/evm.h b/board/ti/ti814x/evm.h
new file mode 100644 (file)
index 0000000..40f8710
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _EVM_H
+#define _EVM_H
+
+void enable_uart0_pin_mux(void);
+void enable_mmc1_pin_mux(void);
+
+#endif /* _EVM_H */
diff --git a/board/ti/ti814x/mux.c b/board/ti/ti814x/mux.c
new file mode 100644 (file)
index 0000000..137acb4
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * mux.c
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mux.h>
+#include <asm/io.h>
+#include <i2c.h>
+#include "evm.h"
+
+static struct module_pin_mux uart0_pin_mux[] = {
+       {OFFSET(pincntl70), PULLUP_EN | MODE(0x01)},    /* UART0_RXD */
+       {OFFSET(pincntl71), PULLUP_EN | MODE(0x01)},    /* UART0_TXD */
+       {-1},
+};
+
+static struct module_pin_mux mmc1_pin_mux[] = {
+       {OFFSET(pincntl1), PULLUP_EN | MODE(0x01)},     /* SD1_CLK */
+       {OFFSET(pincntl2), PULLUP_EN | MODE(0x01)},     /* SD1_CMD */
+       {OFFSET(pincntl3), PULLUP_EN | MODE(0x01)},     /* SD1_DAT[0] */
+       {OFFSET(pincntl4), PULLUP_EN | MODE(0x01)},     /* SD1_DAT[1] */
+       {OFFSET(pincntl5), PULLUP_EN | MODE(0x01)},     /* SD1_DAT[2] */
+       {OFFSET(pincntl6), PULLUP_EN | MODE(0x01)},     /* SD1_DAT[3] */
+       {OFFSET(pincntl74), PULLUP_EN | MODE(0x40)},    /* SD1_POW */
+       {OFFSET(pincntl75), MODE(0x40)},                /* SD1_SDWP */
+       {OFFSET(pincntl80), PULLUP_EN | MODE(0x02)},    /* SD1_SDCD */
+       {-1},
+};
+
+void enable_uart0_pin_mux(void)
+{
+       configure_module_pin_mux(uart0_pin_mux);
+}
+
+void enable_mmc1_pin_mux(void)
+{
+       configure_module_pin_mux(mmc1_pin_mux);
+}
index bab452cc69f933da80959f358dbc6691076638df..fbf321da5435d4d2d8e78d5919fb3b7abe44f4ac 100644 (file)
@@ -106,6 +106,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 9504fcd9f4b0f452c2019a33eead5bebc1f8e46e..f25a01b3d5a35a09eefd6d4cb00bd78e4c9a02c5 100644 (file)
@@ -93,6 +93,6 @@ SECTIONS
    *(COMMON)
    . = ALIGN(4);
   }
-  __bss_end__ = . ;
+  __bss_end = . ;
   PROVIDE (end = .);
 }
index 1958c2fb9031b2c252b48247062003f44e36484a..dc437d1f2329232320da07e3899d32895544a8d2 100644 (file)
@@ -78,7 +78,7 @@ SECTIONS
                __bss_start = .;
                *(.bss)
                 . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        }
 
        /DISCARD/ : { *(.bss*) }
index 5b044a95c00e11a3bd1319f2b538faff1a11857e..7c36af080e8a53405fc0476510295f2092390473 100644 (file)
@@ -148,7 +148,7 @@ void board_init_f(ulong dummy)
        woodburn_init();
 
        /* Clear the BSS. */
-       memset(__bss_start, 0, __bss_end__ - __bss_start);
+       memset(__bss_start, 0, __bss_end - __bss_start);
 
        /* Set global data pointer. */
        gd = &gdata;
index 7725a1534d4dec6dbbec7acd5168cddc1426b4c6..d7bda3663c61367577e589a6c129fe6bad3d2eb8 100644 (file)
@@ -242,6 +242,7 @@ am335x_evm_uart3             arm         armv7       am335x              ti
 am335x_evm_uart4             arm         armv7       am335x              ti             am33xx      am335x_evm:SERIAL5,CONS_INDEX=5
 am335x_evm_uart5             arm         armv7       am335x              ti             am33xx      am335x_evm:SERIAL6,CONS_INDEX=6
 am335x_evm_usbspl            arm         armv7       am335x              ti             am33xx      am335x_evm:SERIAL1,CONS_INDEX=1,SPL_USBETH_SUPPORT
+ti814x_evm                   arm         armv7       ti814x              ti             am33xx
 pcm051                       arm         armv7       pcm051              phytec         am33xx      pcm051
 highbank                     arm         armv7       highbank            -              highbank
 mx51_efikamx                 arm         armv7       mx51_efikamx        genesi         mx5            mx51_efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/genesi/mx51_efikamx/imximage_mx.cfg
@@ -300,6 +301,7 @@ s5p_goni                     arm         armv7       goni                samsung
 smdkc100                     arm         armv7       smdkc100            samsung        s5pc1xx
 origen                      arm         armv7       origen              samsung        exynos
 s5pc210_universal            arm         armv7       universal_c210      samsung        exynos
+snow                        arm         armv7       smdk5250            samsung        exynos
 smdk5250                    arm         armv7       smdk5250            samsung        exynos
 smdkv310                    arm         armv7       smdkv310            samsung        exynos
 trats                        arm         armv7       trats               samsung        exynos
@@ -480,8 +482,6 @@ openrisc-generic             openrisc    or1200      openrisc-generic    openris
 EVB64260                     powerpc     74xx_7xx    evb64260            -              -           EVB64260
 EVB64260_750CX               powerpc     74xx_7xx    evb64260            -              -           EVB64260
 P3G4                         powerpc     74xx_7xx    evb64260
-PCIPPC2                      powerpc     74xx_7xx    pcippc2
-PCIPPC6                      powerpc     74xx_7xx    pcippc2
 ppmc7xx                      powerpc     74xx_7xx
 ZUMA                         powerpc     74xx_7xx    evb64260
 ELPPC                        powerpc     74xx_7xx    elppc               eltec
@@ -496,10 +496,12 @@ aria                         powerpc     mpc512x     -                   daveden
 mecp5123                     powerpc     mpc512x     -                   esd
 mpc5121ads                   powerpc     mpc512x     mpc5121ads          freescale
 mpc5121ads_rev2              powerpc     mpc512x     mpc5121ads          freescale      -           mpc5121ads:MPC5121ADS_REV2
+ac14xx                       powerpc     mpc512x     ac14xx              ifm
 cmi_mpc5xx                   powerpc     mpc5xx      cmi
 PATI                         powerpc     mpc5xx      pati                mpl
 a3m071                       powerpc     mpc5xxx     a3m071
 a4m072                       powerpc     mpc5xxx     a4m072
+a4m2k                        powerpc     mpc5xxx     a3m071              -              -           a3m071:A4M2K
 BC3450                       powerpc     mpc5xxx     bc3450
 canmb                        powerpc     mpc5xxx
 cm5200                       powerpc     mpc5xxx
index 719fc231b885e067a6165c3f2bbb771b6a4c8da1..1abf4ea794e56686c420faeab5024aa885ac7304 100644 (file)
@@ -36,6 +36,10 @@ COBJS-y += s_record.o
 COBJS-y += xyzModem.o
 COBJS-y += cmd_disk.o
 
+# boards
+COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o
+COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
+
 # core command
 COBJS-y += cmd_boot.o
 COBJS-$(CONFIG_CMD_BOOTM) += cmd_bootm.o
@@ -175,6 +179,7 @@ COBJS-y += cmd_usb.o
 COBJS-y += usb.o usb_hub.o
 COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
 endif
+COBJS-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o
 COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
 COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
 COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
diff --git a/common/board_f.c b/common/board_f.c
new file mode 100644 (file)
index 0000000..29b49c3
--- /dev/null
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2002-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * 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 <linux/compiler.h>
+#include <version.h>
+#include <environment.h>
+#include <fdtdec.h>
+#if defined(CONFIG_CMD_IDE)
+#include <ide.h>
+#endif
+#include <i2c.h>
+#include <initcall.h>
+#include <logbuff.h>
+
+/* TODO: Can we move these into arch/ headers? */
+#ifdef CONFIG_8xx
+#include <mpc8xx.h>
+#endif
+#ifdef CONFIG_5xx
+#include <mpc5xx.h>
+#endif
+#ifdef CONFIG_MPC5xxx
+#include <mpc5xxx.h>
+#endif
+
+#include <post.h>
+#include <spi.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#ifdef CONFIG_MP
+#include <asm/mp.h>
+#endif
+#include <asm/sections.h>
+#ifdef CONFIG_X86
+#include <asm/init_helpers.h>
+#include <asm/relocate.h>
+#endif
+#include <linux/compiler.h>
+
+/*
+ * Pointer to initial global data area
+ *
+ * Here we initialize it if needed.
+ */
+#ifdef XTRN_DECLARE_GLOBAL_DATA_PTR
+#undef XTRN_DECLARE_GLOBAL_DATA_PTR
+#define XTRN_DECLARE_GLOBAL_DATA_PTR   /* empty = allocate here */
+DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CONFIG_SYS_INIT_GD_ADDR);
+#else
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+/*
+ * sjg: IMO this code should be
+ * refactored to a single function, something like:
+ *
+ * void led_set_state(enum led_colour_t colour, int on);
+ */
+/************************************************************************
+ * Coloured LED functionality
+ ************************************************************************
+ * May be supplied by boards if desired
+ */
+inline void __coloured_LED_init(void) {}
+void coloured_LED_init(void)
+       __attribute__((weak, alias("__coloured_LED_init")));
+inline void __red_led_on(void) {}
+void red_led_on(void) __attribute__((weak, alias("__red_led_on")));
+inline void __red_led_off(void) {}
+void red_led_off(void) __attribute__((weak, alias("__red_led_off")));
+inline void __green_led_on(void) {}
+void green_led_on(void) __attribute__((weak, alias("__green_led_on")));
+inline void __green_led_off(void) {}
+void green_led_off(void) __attribute__((weak, alias("__green_led_off")));
+inline void __yellow_led_on(void) {}
+void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on")));
+inline void __yellow_led_off(void) {}
+void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off")));
+inline void __blue_led_on(void) {}
+void blue_led_on(void) __attribute__((weak, alias("__blue_led_on")));
+inline void __blue_led_off(void) {}
+void blue_led_off(void) __attribute__((weak, alias("__blue_led_off")));
+
+/*
+ * Why is gd allocated a register? Prior to reloc it might be better to
+ * just pass it around to each function in this file?
+ *
+ * After reloc one could argue that it is hardly used and doesn't need
+ * to be in a register. Or if it is it should perhaps hold pointers to all
+ * global data for all modules, so that post-reloc we can avoid the massive
+ * literal pool we get on ARM. Or perhaps just encourage each module to use
+ * a structure...
+ */
+
+/*
+ * Could the CONFIG_SPL_BUILD infection become a flag in gd?
+ */
+
+#if defined(CONFIG_WATCHDOG)
+static int init_func_watchdog_init(void)
+{
+       puts("       Watchdog enabled\n");
+       WATCHDOG_RESET();
+
+       return 0;
+}
+
+int init_func_watchdog_reset(void)
+{
+       WATCHDOG_RESET();
+
+       return 0;
+}
+#endif /* CONFIG_WATCHDOG */
+
+void __board_add_ram_info(int use_default)
+{
+       /* please define platform specific board_add_ram_info() */
+}
+
+void board_add_ram_info(int)
+       __attribute__ ((weak, alias("__board_add_ram_info")));
+
+static int init_baud_rate(void)
+{
+       gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
+       return 0;
+}
+
+static int display_text_info(void)
+{
+       ulong bss_start, bss_end;
+
+#ifdef CONFIG_SYS_SYM_OFFSETS
+       bss_start = _bss_start_ofs + _TEXT_BASE;
+       bss_end = _bss_end_ofs + _TEXT_BASE;
+#else
+       bss_start = (ulong)&__bss_start;
+       bss_end = (ulong)&__bss_end;
+#endif
+       debug("U-Boot code: %08X -> %08lX  BSS: -> %08lX\n",
+             CONFIG_SYS_TEXT_BASE, bss_start, bss_end);
+
+#ifdef CONFIG_MODEM_SUPPORT
+       debug("Modem Support enabled\n");
+#endif
+#ifdef CONFIG_USE_IRQ
+       debug("IRQ Stack: %08lx\n", IRQ_STACK_START);
+       debug("FIQ Stack: %08lx\n", FIQ_STACK_START);
+#endif
+
+       return 0;
+}
+
+static int announce_dram_init(void)
+{
+       puts("DRAM:  ");
+       return 0;
+}
+
+#ifdef CONFIG_PPC
+static int init_func_ram(void)
+{
+#ifdef CONFIG_BOARD_TYPES
+       int board_type = gd->board_type;
+#else
+       int board_type = 0;     /* use dummy arg */
+#endif
+
+       gd->ram_size = initdram(board_type);
+
+       if (gd->ram_size > 0)
+               return 0;
+
+       puts("*** failed ***\n");
+       return 1;
+}
+#endif
+
+static int show_dram_config(void)
+{
+       ulong size;
+
+#ifdef CONFIG_NR_DRAM_BANKS
+       int i;
+
+       debug("\nRAM Configuration:\n");
+       for (i = size = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+               size += gd->bd->bi_dram[i].size;
+               debug("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
+#ifdef DEBUG
+               print_size(gd->bd->bi_dram[i].size, "\n");
+#endif
+       }
+       debug("\nDRAM:  ");
+#else
+       size = gd->ram_size;
+#endif
+
+       print_size(size, "");
+       board_add_ram_info(0);
+       putc('\n');
+
+       return 0;
+}
+
+ulong get_effective_memsize(void)
+{
+#ifndef        CONFIG_VERY_BIG_RAM
+       return gd->ram_size;
+#else
+       /* limit stack to what we can reasonable map */
+       return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
+               CONFIG_MAX_MEM_MAPPED : gd->ram_size);
+#endif
+}
+
+void __dram_init_banksize(void)
+{
+#if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE)
+       gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+       gd->bd->bi_dram[0].size = get_effective_memsize();
+#endif
+}
+
+void dram_init_banksize(void)
+       __attribute__((weak, alias("__dram_init_banksize")));
+
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+static int init_func_i2c(void)
+{
+       puts("I2C:   ");
+       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+       puts("ready\n");
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_HARD_SPI)
+static int init_func_spi(void)
+{
+       puts("SPI:   ");
+       spi_init();
+       puts("ready\n");
+       return 0;
+}
+#endif
+
+__maybe_unused
+static int zero_global_data(void)
+{
+       memset((void *)gd, '\0', sizeof(gd_t));
+
+       return 0;
+}
+
+static int setup_mon_len(void)
+{
+#ifdef CONFIG_SYS_SYM_OFFSETS
+       gd->mon_len = _bss_end_ofs;
+#else
+       /* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */
+       gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
+#endif
+       return 0;
+}
+
+__weak int arch_cpu_init(void)
+{
+       return 0;
+}
+
+static int setup_fdt(void)
+{
+#ifdef CONFIG_OF_EMBED
+       /* Get a pointer to the FDT */
+       gd->fdt_blob = _binary_dt_dtb_start;
+#elif defined CONFIG_OF_SEPARATE
+       /* FDT is at end of image */
+# ifdef CONFIG_SYS_SYM_OFFSETS
+       gd->fdt_blob = (void *)(_end_ofs + CONFIG_SYS_TEXT_BASE);
+# else
+       gd->fdt_blob = (ulong *)&_end;
+# endif
+#endif
+       /* Allow the early environment to override the fdt address */
+       gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
+                                               (uintptr_t)gd->fdt_blob);
+       return 0;
+}
+
+/* Get the top of usable RAM */
+__weak ulong board_get_usable_ram_top(ulong total_size)
+{
+       return gd->ram_top;
+}
+
+static int setup_dest_addr(void)
+{
+       debug("Monitor len: %08lX\n", gd->mon_len);
+       /*
+        * Ram is setup, size stored in gd !!
+        */
+       debug("Ram size: %08lX\n", (ulong)gd->ram_size);
+#if defined(CONFIG_SYS_MEM_TOP_HIDE)
+       /*
+        * Subtract specified amount of memory to hide so that it won't
+        * get "touched" at all by U-Boot. By fixing up gd->ram_size
+        * the Linux kernel should now get passed the now "corrected"
+        * memory size and won't touch it either. This should work
+        * for arch/ppc and arch/powerpc. Only Linux board ports in
+        * arch/powerpc with bootwrapper support, that recalculate the
+        * memory size from the SDRAM controller setup will have to
+        * get fixed.
+        */
+       gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
+#endif
+#ifdef CONFIG_SYS_SDRAM_BASE
+       gd->ram_top = CONFIG_SYS_SDRAM_BASE;
+#endif
+       gd->ram_top += get_effective_memsize();
+       gd->ram_top = board_get_usable_ram_top(gd->mon_len);
+       gd->dest_addr = 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);
+       }
+#endif
+       gd->dest_addr_sp = gd->dest_addr;
+       return 0;
+}
+
+#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
+static int reserve_logbuffer(void)
+{
+       /* reserve kernel log buffer */
+       gd->dest_addr -= LOGBUFF_RESERVE;
+       debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN,
+               gd->dest_addr);
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_PRAM
+/* reserve protected RAM */
+static int reserve_pram(void)
+{
+       ulong reg;
+
+       reg = getenv_ulong("pram", 10, CONFIG_PRAM);
+       gd->dest_addr -= (reg << 10);           /* size is in kB */
+       debug("Reserving %ldk for protected RAM at %08lx\n", reg,
+             gd->dest_addr);
+       return 0;
+}
+#endif /* CONFIG_PRAM */
+
+/* Round memory pointer down to next 4 kB limit */
+static int reserve_round_4k(void)
+{
+       gd->dest_addr &= ~(4096 - 1);
+       return 0;
+}
+
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
+               defined(CONFIG_ARM)
+static int reserve_mmu(void)
+{
+       /* reserve TLB table */
+       gd->arch.tlb_size = 4096 * 4;
+       gd->dest_addr -= gd->arch.tlb_size;
+
+       /* round down to next 64 kB limit */
+       gd->dest_addr &= ~(0x10000 - 1);
+
+       gd->arch.tlb_addr = gd->dest_addr;
+       debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr,
+             gd->arch.tlb_addr + gd->arch.tlb_size);
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_LCD
+static int reserve_lcd(void)
+{
+#ifdef CONFIG_FB_ADDR
+       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;
+#endif /* CONFIG_FB_ADDR */
+       return 0;
+}
+#endif /* CONFIG_LCD */
+
+#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) \
+               && !defined(CONFIG_ARM) && !defined(CONFIG_X86)
+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;
+
+       return 0;
+}
+#endif
+
+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);
+#ifdef CONFIG_E500
+       /* round down to next 64 kB limit so that IVPR stays aligned */
+       gd->dest_addr &= ~(65536 - 1);
+#endif
+
+       debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10,
+             gd->dest_addr);
+       return 0;
+}
+
+#ifndef CONFIG_SPL_BUILD
+/* reserve memory for malloc() area */
+static int reserve_malloc(void)
+{
+       gd->dest_addr_sp = gd->dest_addr - TOTAL_MALLOC_LEN;
+       debug("Reserving %dk for malloc() at: %08lx\n",
+                       TOTAL_MALLOC_LEN >> 10, gd->dest_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 *)gd->dest_addr_sp;
+       memset(gd->bd, '\0', sizeof(bd_t));
+       debug("Reserving %zu Bytes for Board Info at: %08lx\n",
+                       sizeof(bd_t), gd->dest_addr_sp);
+       return 0;
+}
+#endif
+
+static int setup_machine(void)
+{
+#ifdef CONFIG_MACH_TYPE
+       gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
+#endif
+       return 0;
+}
+
+static int reserve_global_data(void)
+{
+       gd->dest_addr_sp -= sizeof(gd_t);
+       gd->new_gd = (gd_t *)gd->dest_addr_sp;
+       debug("Reserving %zu Bytes for Global Data at: %08lx\n",
+                       sizeof(gd_t), gd->dest_addr_sp);
+       return 0;
+}
+
+static int reserve_fdt(void)
+{
+       /*
+        * If the device tree is sitting immediate above our image then we
+        * must relocate it. If it is embedded in the data section, then it
+        * will be relocated with other data.
+        */
+       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 = (void *)gd->dest_addr_sp;
+               debug("Reserving %lu Bytes for FDT at: %p\n",
+                     gd->fdt_size, gd->new_fdt);
+       }
+
+       return 0;
+}
+
+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;
+# endif
+#else
+# ifdef CONFIG_PPC
+       ulong *s;
+# endif
+
+       /* setup stack pointer for exceptions */
+       gd->dest_addr_sp -= 16;
+       gd->dest_addr_sp &= ~0xf;
+       gd->irq_sp = gd->dest_addr_sp;
+
+       /*
+        * Handle architecture-specific things here
+        * TODO(sjg@chromium.org): Perhaps create arch_reserve_stack()
+        * to handle this and put in arch/xxx/lib/stack.c
+        */
+# ifdef CONFIG_ARM
+#  ifdef CONFIG_USE_IRQ
+       gd->dest_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);
+
+       /* 8-byte alignment for ARM ABI compliance */
+       gd->dest_addr_sp &= ~0x07;
+#  endif
+       /* leave 3 words for abort-stack, plus 1 for alignment */
+       gd->dest_addr_sp -= 16;
+# elif defined(CONFIG_PPC)
+       /* Clear initial stack frame */
+       s = (ulong *) gd->dest_addr_sp;
+       *s = 0; /* Terminate back chain */
+       *++s = 0; /* NULL return address */
+# endif /* Architecture specific code */
+
+       return 0;
+#endif
+}
+
+static int display_new_sp(void)
+{
+       debug("New Stack Pointer is: %08lx\n", gd->dest_addr_sp);
+
+       return 0;
+}
+
+#ifdef CONFIG_PPC
+static int setup_board_part1(void)
+{
+       bd_t *bd = gd->bd;
+
+       /*
+        * Save local variables to board info struct
+        */
+
+       bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;        /* start of memory */
+       bd->bi_memsize = gd->ram_size;                  /* size in bytes */
+
+#ifdef CONFIG_SYS_SRAM_BASE
+       bd->bi_sramstart = CONFIG_SYS_SRAM_BASE;        /* start of SRAM */
+       bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE;         /* size  of SRAM */
+#endif
+
+#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx) || \
+               defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
+       bd->bi_immr_base = CONFIG_SYS_IMMR;     /* base  of IMMR register     */
+#endif
+#if defined(CONFIG_MPC5xxx)
+       bd->bi_mbar_base = CONFIG_SYS_MBAR;     /* base of internal registers */
+#endif
+#if defined(CONFIG_MPC83xx)
+       bd->bi_immrbar = CONFIG_SYS_IMMR;
+#endif
+#if defined(CONFIG_MPC8220)
+       bd->bi_mbar_base = CONFIG_SYS_MBAR;     /* base of internal registers */
+       bd->bi_inpfreq = gd->arch.inp_clk;
+       bd->bi_pcifreq = gd->pci_clk;
+       bd->bi_vcofreq = gd->arch.vco_clk;
+       bd->bi_pevfreq = gd->arch.pev_clk;
+       bd->bi_flbfreq = gd->arch.flb_clk;
+
+       /* store bootparam to sram (backward compatible), here? */
+       {
+               u32 *sram = (u32 *) CONFIG_SYS_SRAM_BASE;
+
+               *sram++ = gd->ram_size;
+               *sram++ = gd->bus_clk;
+               *sram++ = gd->arch.inp_clk;
+               *sram++ = gd->cpu_clk;
+               *sram++ = gd->arch.vco_clk;
+               *sram++ = gd->arch.flb_clk;
+               *sram++ = 0xb8c3ba11;   /* boot signature */
+       }
+#endif
+
+       return 0;
+}
+
+static int setup_board_part2(void)
+{
+       bd_t *bd = gd->bd;
+
+       bd->bi_intfreq = gd->cpu_clk;   /* Internal Freq, in Hz */
+       bd->bi_busfreq = gd->bus_clk;   /* Bus Freq,      in Hz */
+#if defined(CONFIG_CPM2)
+       bd->bi_cpmfreq = gd->arch.cpm_clk;
+       bd->bi_brgfreq = gd->arch.brg_clk;
+       bd->bi_sccfreq = gd->arch.scc_clk;
+       bd->bi_vco = gd->arch.vco_out;
+#endif /* CONFIG_CPM2 */
+#if defined(CONFIG_MPC512X)
+       bd->bi_ipsfreq = gd->arch.ips_clk;
+#endif /* CONFIG_MPC512X */
+#if defined(CONFIG_MPC5xxx)
+       bd->bi_ipbfreq = gd->arch.ipb_clk;
+       bd->bi_pcifreq = gd->pci_clk;
+#endif /* CONFIG_MPC5xxx */
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_EXTBDINFO
+static int setup_board_extra(void)
+{
+       bd_t *bd = gd->bd;
+
+       strncpy((char *) bd->bi_s_version, "1.2", sizeof(bd->bi_s_version));
+       strncpy((char *) bd->bi_r_version, U_BOOT_VERSION,
+               sizeof(bd->bi_r_version));
+
+       bd->bi_procfreq = gd->cpu_clk;  /* Processor Speed, In Hz */
+       bd->bi_plb_busfreq = gd->bus_clk;
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || \
+               defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+               defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+       bd->bi_pci_busfreq = get_PCI_freq();
+       bd->bi_opbfreq = get_OPB_freq();
+#elif defined(CONFIG_XILINX_405)
+       bd->bi_pci_busfreq = get_PCI_freq();
+#endif
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_POST
+static int init_post(void)
+{
+       post_bootmode_init();
+       post_run(NULL, POST_ROM | post_bootmode_get(0));
+
+       return 0;
+}
+#endif
+
+static int setup_baud_rate(void)
+{
+       /* Ick, can we get rid of this line? */
+       gd->bd->bi_baudrate = gd->baudrate;
+
+       return 0;
+}
+
+static int setup_dram_config(void)
+{
+       /* Ram is board specific, so move it to board code ... */
+       dram_init_banksize();
+
+       return 0;
+}
+
+static int reloc_fdt(void)
+{
+       if (gd->new_fdt) {
+               memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size);
+               gd->fdt_blob = gd->new_fdt;
+       }
+
+       return 0;
+}
+
+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;
+       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 %p, sp at %08lx\n",
+             gd->dest_addr, gd->new_gd, gd->dest_addr_sp);
+
+       return 0;
+}
+
+/* ARM calls relocate_code from its crt0.S */
+#if !defined(CONFIG_ARM)
+
+static int jump_to_copy(void)
+{
+       /*
+        * x86 is special, but in a nice way. It uses a trampoline which
+        * enables the dcache if possible.
+        *
+        * For now, other archs use relocate_code(), which is implemented
+        * similarly for all archs. When we do generic relocation, hopefully
+        * we can make all archs enable the dcache prior to relocation.
+        */
+#ifdef CONFIG_X86
+       /*
+        * SDRAM and console are now initialised. The final stack can now
+        * be setup in SDRAM. Code execution will continue in Flash, but
+        * with the stack in SDRAM and Global Data in temporary memory
+        * (CPU cache)
+        */
+       board_init_f_r_trampoline(gd->start_addr_sp);
+#else
+       relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr);
+#endif
+
+       return 0;
+}
+#endif
+
+/* Record the board_init_f() bootstage (after arch_cpu_init()) */
+static int mark_bootstage(void)
+{
+       bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f");
+
+       return 0;
+}
+
+static init_fnc_t init_sequence_f[] = {
+#if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC512X) && \
+               !defined(CONFIG_MPC83xx) && !defined(CONFIG_MPC85xx) && \
+               !defined(CONFIG_MPC86xx)
+       zero_global_data,
+#endif
+       setup_fdt,
+       setup_mon_len,
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
+       /* TODO: can this go into arch_cpu_init()? */
+       probecpu,
+#endif
+       arch_cpu_init,          /* basic arch cpu dependent setup */
+#ifdef CONFIG_X86
+       cpu_init_f,             /* TODO(sjg@chromium.org): remove */
+# ifdef CONFIG_OF_CONTROL
+       find_fdt,               /* TODO(sjg@chromium.org): remove */
+# endif
+#endif
+       mark_bootstage,
+#ifdef CONFIG_OF_CONTROL
+       fdtdec_check_fdt,
+#endif
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+       board_early_init_f,
+#endif
+       /* TODO: can any of this go into arch_cpu_init()? */
+#if defined(CONFIG_PPC) && !defined(CONFIG_8xx_CPUCLK_DEFAULT)
+       get_clocks,             /* get CPU and bus clocks (etc.) */
+#if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \
+               && !defined(CONFIG_TQM885D)
+       adjust_sdram_tbs_8xx,
+#endif
+       /* TODO: can we rename this to timer_init()? */
+       init_timebase,
+#endif
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+       board_early_init_f,
+#endif
+#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,
+#endif
+#endif
+#if defined(CONFIG_BOARD_POSTCLK_INIT)
+       board_postclk_init,
+#endif
+       env_init,               /* initialize environment */
+#if defined(CONFIG_8xx_CPUCLK_DEFAULT)
+       /* get CPU and bus clocks according to the environment variable */
+       get_clocks_866,
+       /* adjust sdram refresh rate according to the new clock */
+       sdram_adjust_866,
+       init_timebase,
+#endif
+       init_baud_rate,         /* initialze baudrate settings */
+       serial_init,            /* serial communications setup */
+       console_init_f,         /* stage 1 init of console */
+#if defined(CONFIG_X86) && defined(CONFIG_OF_CONTROL)
+       prepare_fdt,            /* TODO(sjg@chromium.org): remove */
+#endif
+       display_options,        /* say that we are here */
+       display_text_info,      /* show debugging info if required */
+#if defined(CONFIG_8260)
+       prt_8260_rsr,
+       prt_8260_clks,
+#endif /* CONFIG_8260 */
+#if defined(CONFIG_MPC83xx)
+       prt_83xx_rsr,
+#endif
+#ifdef CONFIG_PPC
+       checkcpu,
+#endif
+#if defined(CONFIG_DISPLAY_CPUINFO)
+       print_cpuinfo,          /* display cpu info (and speed) */
+#endif
+#if defined(CONFIG_MPC5xxx)
+       prt_mpc5xxx_clks,
+#endif /* CONFIG_MPC5xxx */
+#if defined(CONFIG_MPC8220)
+       prt_mpc8220_clks,
+#endif
+#if defined(CONFIG_DISPLAY_BOARDINFO)
+       checkboard,             /* display board info */
+#endif
+       INIT_FUNC_WATCHDOG_INIT
+#if defined(CONFIG_MISC_INIT_F)
+       misc_init_f,
+#endif
+       INIT_FUNC_WATCHDOG_RESET
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+       init_func_i2c,
+#endif
+#if defined(CONFIG_HARD_SPI)
+       init_func_spi,
+#endif
+#ifdef CONFIG_X86
+       dram_init_f,            /* configure available RAM banks */
+       /* x86 would prefer that this happens after relocation */
+       dram_init,
+#endif
+       announce_dram_init,
+       /* TODO: unify all these dram functions? */
+#ifdef CONFIG_ARM
+       dram_init,              /* configure available RAM banks */
+#endif
+#ifdef CONFIG_PPC
+       init_func_ram,
+#endif
+#ifdef CONFIG_POST
+       post_init_f,
+#endif
+       INIT_FUNC_WATCHDOG_RESET
+#if defined(CONFIG_SYS_DRAM_TEST)
+       testdram,
+#endif /* CONFIG_SYS_DRAM_TEST */
+       INIT_FUNC_WATCHDOG_RESET
+
+#ifdef CONFIG_POST
+       init_post,
+#endif
+       INIT_FUNC_WATCHDOG_RESET
+       /*
+        * Now that we have DRAM mapped and working, we can
+        * relocate the code and continue running from DRAM.
+        *
+        * Reserve memory at end of RAM for (top down in that order):
+        *  - area that won't get touched by U-Boot and Linux (optional)
+        *  - kernel log buffer
+        *  - protected RAM
+        *  - LCD framebuffer
+        *  - monitor code
+        *  - board info struct
+        */
+       setup_dest_addr,
+#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
+       reserve_logbuffer,
+#endif
+#ifdef CONFIG_PRAM
+       reserve_pram,
+#endif
+       reserve_round_4k,
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
+               defined(CONFIG_ARM)
+       reserve_mmu,
+#endif
+#ifdef CONFIG_LCD
+       reserve_lcd,
+#endif
+       /* TODO: Why the dependency on CONFIG_8xx? */
+#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) \
+               && !defined(CONFIG_ARM) && !defined(CONFIG_X86)
+       reserve_video,
+#endif
+       reserve_uboot,
+#ifndef CONFIG_SPL_BUILD
+       reserve_malloc,
+       reserve_board,
+#endif
+       setup_machine,
+       reserve_global_data,
+       reserve_fdt,
+       reserve_stacks,
+       setup_dram_config,
+       show_dram_config,
+#ifdef CONFIG_PPC
+       setup_board_part1,
+       INIT_FUNC_WATCHDOG_RESET
+       setup_board_part2,
+#endif
+       setup_baud_rate,
+       display_new_sp,
+#ifdef CONFIG_SYS_EXTBDINFO
+       setup_board_extra,
+#endif
+       INIT_FUNC_WATCHDOG_RESET
+       reloc_fdt,
+       setup_reloc,
+#ifndef CONFIG_ARM
+       jump_to_copy,
+#endif
+       NULL,
+};
+
+void board_init_f(ulong boot_flags)
+{
+#ifndef CONFIG_X86
+       gd_t data;
+
+       gd = &data;
+#endif
+
+       gd->flags = boot_flags;
+
+       if (initcall_run_list(init_sequence_f))
+               hang();
+
+#ifndef CONFIG_ARM
+       /* NOTREACHED - jump_to_copy() does not return */
+       hang();
+#endif
+}
+
+#ifdef CONFIG_X86
+/*
+ * For now this code is only used on x86.
+ *
+ * init_sequence_f_r is the list of init functions which are run when
+ * U-Boot is executing from Flash with a semi-limited 'C' environment.
+ * The following limitations must be considered when implementing an
+ * '_f_r' function:
+ *  - 'static' variables are read-only
+ *  - Global Data (gd->xxx) is read/write
+ *
+ * The '_f_r' sequence must, as a minimum, copy U-Boot to RAM (if
+ * supported).  It _should_, if possible, copy global data to RAM and
+ * initialise the CPU caches (to speed up the relocation process)
+ *
+ * NOTE: At present only x86 uses this route, but it is intended that
+ * all archs will move to this when generic relocation is implemented.
+ */
+static init_fnc_t init_sequence_f_r[] = {
+       init_cache_f_r,
+       copy_uboot_to_ram,
+       clear_bss,
+       do_elf_reloc_fixups,
+
+       NULL,
+};
+
+void board_init_f_r(void)
+{
+       if (initcall_run_list(init_sequence_f_r))
+               hang();
+
+       /*
+        * U-Boot has been copied into SDRAM, the BSS has been cleared etc.
+        * Transfer execution from Flash to RAM by calculating the address
+        * of the in-RAM copy of board_init_r() and calling it
+        */
+       (board_init_r + gd->reloc_off)(gd, gd->relocaddr);
+
+       /* NOTREACHED - board_init_r() does not return */
+       hang();
+}
+#endif /* CONFIG_X86 */
+
+void hang(void)
+{
+       puts("### ERROR ### Please RESET the board ###\n");
+       for (;;);
+}
diff --git a/common/board_r.c b/common/board_r.c
new file mode 100644 (file)
index 0000000..9605f80
--- /dev/null
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2002-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * 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>
+/* TODO: can we just include all these headers whether needed or not? */
+#if defined(CONFIG_CMD_BEDBUG)
+#include <bedbug/type.h>
+#endif
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
+#include <environment.h>
+#include <fdtdec.h>
+#if defined(CONFIG_CMD_IDE)
+#include <ide.h>
+#endif
+#include <initcall.h>
+#ifdef CONFIG_PS2KBD
+#include <keyboard.h>
+#endif
+#if defined(CONFIG_CMD_KGDB)
+#include <kgdb.h>
+#endif
+#include <logbuff.h>
+#include <malloc.h>
+#ifdef CONFIG_BITBANGMII
+#include <miiphy.h>
+#endif
+#include <mmc.h>
+#include <nand.h>
+#include <onenand_uboot.h>
+#include <scsi.h>
+#include <serial.h>
+#include <spi.h>
+#include <stdio_dev.h>
+#include <watchdog.h>
+#ifdef CONFIG_ADDR_MAP
+#include <asm/mmu.h>
+#endif
+#include <asm/sections.h>
+#ifdef CONFIG_X86
+#include <asm/init_helpers.h>
+#endif
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+ulong monitor_flash_len;
+
+int __board_flash_wp_on(void)
+{
+       /*
+        * Most flashes can't be detected when write protection is enabled,
+        * so provide a way to let U-Boot gracefully ignore write protected
+        * devices.
+        */
+       return 0;
+}
+
+int board_flash_wp_on(void)
+       __attribute__ ((weak, alias("__board_flash_wp_on")));
+
+void __cpu_secondary_init_r(void)
+{
+}
+
+void cpu_secondary_init_r(void)
+       __attribute__ ((weak, alias("__cpu_secondary_init_r")));
+
+static int initr_secondary_cpu(void)
+{
+       /*
+        * after non-volatile devices & environment is setup and cpu code have
+        * another round to deal with any initialization that might require
+        * full access to the environment or loading of some image (firmware)
+        * from a non-volatile device
+        */
+       /* TODO: maybe define this for all archs? */
+       cpu_secondary_init_r();
+
+       return 0;
+}
+
+static int initr_reloc(void)
+{
+       gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
+       bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
+
+       return 0;
+}
+
+#ifdef CONFIG_ARM
+/*
+ * Some of these functions are needed purely because the functions they
+ * call return void. If we change them to return 0, these stubs can go away.
+ */
+static int initr_caches(void)
+{
+       /* Enable caches */
+       enable_caches();
+       return 0;
+}
+#endif
+
+__weak int fixup_cpu(void)
+{
+       return 0;
+}
+
+static int initr_reloc_global_data(void)
+{
+#ifdef CONFIG_SYS_SYM_OFFSETS
+       monitor_flash_len = _end_ofs;
+#else
+       monitor_flash_len = (ulong)&__init_end - gd->dest_addr;
+#endif
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
+       /*
+        * The gd->cpu pointer is set to an address in flash before relocation.
+        * 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;
+
+       /*
+        * If we didn't know the cpu mask & # cores, we can save them of
+        * now rather than 'computing' them constantly
+        */
+       fixup_cpu();
+#endif
+#ifdef CONFIG_SYS_EXTRA_ENV_RELOC
+       /*
+        * Some systems need to relocate the env_addr pointer early because the
+        * location it points to will get invalidated before env_relocate is
+        * called.  One example is on systems that might use a L2 or L3 cache
+        * 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;
+#endif
+       return 0;
+}
+
+static int initr_serial(void)
+{
+       serial_initialize();
+       return 0;
+}
+
+#ifdef CONFIG_PPC
+static int initr_trap(void)
+{
+       /*
+        * Setup trap handlers
+        */
+       trap_init(gd->dest_addr);
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_ADDR_MAP
+static int initr_addr_map(void)
+{
+       init_addr_map();
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_LOGBUFFER
+unsigned long logbuffer_base(void)
+{
+       return gd->ram_top - LOGBUFF_LEN;
+}
+
+static int initr_logbuffer(void)
+{
+       logbuff_init_ptrs();
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_POST
+static int initr_post_backlog(void)
+{
+       post_output_backlog();
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_DELAYED_ICACHE
+static int initr_icache_enable(void)
+{
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
+static int initr_unlock_ram_in_cache(void)
+{
+       unlock_ram_in_cache();  /* it's time to unlock D-cache in e500 */
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_PCI
+static int initr_pci(void)
+{
+       pci_init();
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_WINBOND_83C553
+static int initr_w83c553f(void)
+{
+       /*
+        * Initialise the ISA bridge
+        */
+       initialise_w83c553f();
+       return 0;
+}
+#endif
+
+static int initr_barrier(void)
+{
+#ifdef CONFIG_PPC
+       /* TODO: Can we not use dmb() macros for this? */
+       asm("sync ; isync");
+#endif
+       return 0;
+}
+
+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;
+       mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN);
+       return 0;
+}
+
+__weak int power_init_board(void)
+{
+       return 0;
+}
+
+static int initr_announce(void)
+{
+       debug("Now running in RAM - U-Boot at: %08lx\n", gd->dest_addr);
+       return 0;
+}
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+static int initr_flash(void)
+{
+       ulong flash_size = 0;
+       bd_t *bd = gd->bd;
+       int ok;
+
+       puts("Flash: ");
+
+       if (board_flash_wp_on()) {
+               printf("Uninitialized - Write Protect On\n");
+               /* Since WP is on, we can't find real size.  Set to 0 */
+               ok = 1;
+       } else {
+               flash_size = flash_init();
+               ok = flash_size > 0;
+       }
+       if (!ok) {
+               puts("*** failed ***\n");
+#ifdef CONFIG_PPC
+               /* Why does PPC do this? */
+               hang();
+#endif
+               return -1;
+       }
+       print_size(flash_size, "");
+#ifdef CONFIG_SYS_FLASH_CHECKSUM
+       /*
+       * Compute and print flash CRC if flashchecksum is set to 'y'
+       *
+       * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
+       */
+       if (getenv_yesno("flashchecksum") == 1) {
+               printf("  CRC: %08X", crc32(0,
+                       (const unsigned char *) CONFIG_SYS_FLASH_BASE,
+                       flash_size));
+       }
+#endif /* CONFIG_SYS_FLASH_CHECKSUM */
+       putc('\n');
+
+       /* update start of FLASH memory    */
+#ifdef CONFIG_SYS_FLASH_BASE
+       bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
+#endif
+       /* size of FLASH memory (final value) */
+       bd->bi_flashsize = flash_size;
+
+#if defined(CONFIG_SYS_UPDATE_FLASH_SIZE)
+       /* Make a update of the Memctrl. */
+       update_flash_size(flash_size);
+#endif
+
+
+#if defined(CONFIG_OXC) || defined(CONFIG_RMU)
+       /* flash mapped at end of memory map */
+       bd->bi_flashoffset = CONFIG_SYS_TEXT_BASE + flash_size;
+#elif CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE
+       bd->bi_flashoffset = monitor_flash_len; /* reserved area for monitor */
+#endif
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_PPC
+static int initr_spi(void)
+{
+       /* PPC does this here */
+#ifdef CONFIG_SPI
+#if !defined(CONFIG_ENV_IS_IN_EEPROM)
+       spi_init_f();
+#endif
+       spi_init_r();
+#endif
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_NAND
+/* go init the NAND */
+int initr_nand(void)
+{
+       puts("NAND:  ");
+       nand_init();
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_ONENAND)
+/* go init the NAND */
+int initr_onenand(void)
+{
+       puts("NAND:  ");
+       onenand_init();
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_GENERIC_MMC
+int initr_mmc(void)
+{
+       puts("MMC:   ");
+       mmc_initialize(gd->bd);
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_HAS_DATAFLASH
+int initr_dataflash(void)
+{
+       AT91F_DataflashInit();
+       dataflash_print_info();
+       return 0;
+}
+#endif
+
+/*
+ * Tell if it's OK to load the environment early in boot.
+ *
+ * If CONFIG_OF_CONFIG is defined, we'll check with the FDT to see
+ * if this is OK (defaulting to saying it's OK).
+ *
+ * NOTE: Loading the environment early can be a bad idea if security is
+ *       important, since no verification is done on the environment.
+ *
+ * @return 0 if environment should not be loaded, !=0 if it is ok to load
+ */
+static int should_load_env(void)
+{
+#ifdef CONFIG_OF_CONTROL
+       return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 1);
+#elif defined CONFIG_DELAY_ENVIRONMENT
+       return 0;
+#else
+       return 1;
+#endif
+}
+
+static int initr_env(void)
+{
+       /* initialize environment */
+       if (should_load_env())
+               env_relocate();
+       else
+               set_default_env(NULL);
+
+       /* Initialize from environment */
+       load_addr = getenv_ulong("loadaddr", 16, load_addr);
+#if defined(CONFIG_SYS_EXTBDINFO)
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
+#if defined(CONFIG_I2CFAST)
+       /*
+        * set bi_iic_fast for linux taking environment variable
+        * "i2cfast" into account
+        */
+       {
+               char *s = getenv("i2cfast");
+
+               if (s && ((*s == 'y') || (*s == 'Y'))) {
+                       gd->bd->bi_iic_fast[0] = 1;
+                       gd->bd->bi_iic_fast[1] = 1;
+               }
+       }
+#endif /* CONFIG_I2CFAST */
+#endif /* CONFIG_405GP, CONFIG_405EP */
+#endif /* CONFIG_SYS_EXTBDINFO */
+       return 0;
+}
+
+#ifdef CONFIG_HERMES
+static int initr_hermes(void)
+{
+       if ((gd->board_type >> 16) == 2)
+               gd->bd->bi_ethspeed = gd->board_type & 0xFFFF;
+       else
+               gd->bd->bi_ethspeed = 0xFFFF;
+       return 0;
+}
+
+static int initr_hermes_start(void)
+{
+       if (gd->bd->bi_ethspeed != 0xFFFF)
+               hermes_start_lxt980((int) gd->bd->bi_ethspeed);
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SC3
+/* TODO: with new initcalls, move this into the driver */
+extern void sc3_read_eeprom(void);
+
+static int initr_sc3_read_eeprom(void)
+{
+       sc3_read_eeprom();
+       return 0;
+}
+#endif
+
+static int initr_jumptable(void)
+{
+       jumptable_init();
+       return 0;
+}
+
+#if defined(CONFIG_API)
+static int initr_api(void)
+{
+       /* Initialize API */
+       api_init();
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
+static int show_model_r(void)
+{
+       /* Put this here so it appears on the LCD, now it is ready */
+# ifdef CONFIG_OF_CONTROL
+       const char *model;
+
+       model = (char *)fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+       printf("Model: %s\n", model ? model : "<unknown>");
+# else
+       checkboard();
+# endif
+}
+#endif
+
+/* enable exceptions */
+#ifdef CONFIG_ARM
+static int initr_enable_interrupts(void)
+{
+       enable_interrupts();
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_NET
+static int initr_ethaddr(void)
+{
+       bd_t *bd = gd->bd;
+
+       /* kept around for legacy kernels only ... ignore the next section */
+       eth_getenv_enetaddr("ethaddr", bd->bi_enetaddr);
+#ifdef CONFIG_HAS_ETH1
+       eth_getenv_enetaddr("eth1addr", bd->bi_enet1addr);
+#endif
+#ifdef CONFIG_HAS_ETH2
+       eth_getenv_enetaddr("eth2addr", bd->bi_enet2addr);
+#endif
+#ifdef CONFIG_HAS_ETH3
+       eth_getenv_enetaddr("eth3addr", bd->bi_enet3addr);
+#endif
+#ifdef CONFIG_HAS_ETH4
+       eth_getenv_enetaddr("eth4addr", bd->bi_enet4addr);
+#endif
+#ifdef CONFIG_HAS_ETH5
+       eth_getenv_enetaddr("eth5addr", bd->bi_enet5addr);
+#endif
+       return 0;
+}
+#endif /* CONFIG_CMD_NET */
+
+#ifdef CONFIG_CMD_KGDB
+static int initr_kgdb(void)
+{
+       puts("KGDB:  ");
+       kgdb_init();
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
+static int initr_status_led(void)
+{
+       status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
+
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_SCSI)
+static int initr_scsi(void)
+{
+       /* Not supported properly on ARM yet */
+#ifndef CONFIG_ARM
+       puts("SCSI:  ");
+       scsi_init();
+#endif
+
+       return 0;
+}
+#endif /* CONFIG_CMD_NET */
+
+#if defined(CONFIG_CMD_DOC)
+static int initr_doc(void)
+{
+       puts("DOC:   ");
+       doc_init();
+}
+#endif
+
+#ifdef CONFIG_BITBANGMII
+static int initr_bbmii(void)
+{
+       bb_miiphy_init();
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_NET
+static int initr_net(void)
+{
+       puts("Net:   ");
+       eth_initialize(gd->bd);
+#if defined(CONFIG_RESET_PHY_R)
+       debug("Reset Ethernet PHY\n");
+       reset_phy();
+#endif
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_POST
+static int initr_post(void)
+{
+       post_run(NULL, POST_RAM | post_bootmode_get(0));
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)
+static int initr_pcmcia(void)
+{
+       puts("PCMCIA:");
+       pcmcia_init();
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_IDE)
+static int initr_ide(void)
+{
+#ifdef CONFIG_IDE_8xx_PCCARD
+       puts("PCMCIA:");
+#else
+       puts("IDE:   ");
+#endif
+#if defined(CONFIG_START_IDE)
+       if (board_start_ide())
+               ide_init();
+#else
+       ide_init();
+#endif
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
+/*
+ * Export available size of memory for Linux, taking into account the
+ * protected RAM at top of memory
+ */
+int initr_mem(void)
+{
+       ulong pram = 0;
+       char memsz[32];
+
+# ifdef CONFIG_PRAM
+       pram = getenv_ulong("pram", 10, CONFIG_PRAM);
+# endif
+# if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
+       /* Also take the logbuffer into account (pram is in kB) */
+       pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;
+# endif
+       sprintf(memsz, "%ldk", (gd->ram_size / 1024) - pram);
+       setenv("mem", memsz);
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_BEDBUG
+static int initr_bedbug(void)
+{
+       bedbug_init();
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_PS2KBD
+static int initr_kbd(void)
+{
+       puts("PS/2:  ");
+       kbd_init();
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int initr_modem(void)
+{
+       /* TODO: with new initcalls, move this into the driver */
+       extern int do_mdm_init;
+
+       do_mdm_init = gd->do_mdm_init;
+       return 0;
+}
+#endif
+
+static int run_main_loop(void)
+{
+       /* main_loop() can return to retry autoboot, if so just run it again */
+       for (;;)
+               main_loop();
+       return 0;
+}
+
+/*
+ * Over time we hope to remove these functions with code fragments and
+ * stub funtcions, and instead call the relevant function directly.
+ *
+ * We also hope to remove most of the driver-related init and do it if/when
+ * the driver is later used.
+ *
+ * TODO: perhaps reset the watchdog in the initcall function after each call?
+ */
+init_fnc_t init_sequence_r[] = {
+       initr_reloc,
+       /* TODO: could x86/PPC have this also perhaps? */
+#ifdef CONFIG_ARM
+       initr_caches,
+       board_init,     /* Setup chipselects */
+#endif
+       /*
+        * TODO: printing of the clock inforamtion of the board is now
+        * implemented as part of bdinfo command. Currently only support for
+        * davinci SOC's is added. Remove this check once all the board
+        * implement this.
+        */
+#ifdef CONFIG_CLOCKS
+       set_cpu_clk_info, /* Setup clock information */
+#endif
+#ifdef CONFIG_X86
+       init_bd_struct_r,
+#endif
+       initr_reloc_global_data,
+       initr_serial,
+       initr_announce,
+       INIT_FUNC_WATCHDOG_RESET
+#ifdef CONFIG_PPC
+       initr_trap,
+#endif
+#ifdef CONFIG_ADDR_MAP
+       initr_addr_map,
+#endif
+#if defined(CONFIG_BOARD_EARLY_INIT_R)
+       board_early_init_r,
+#endif
+       INIT_FUNC_WATCHDOG_RESET
+#ifdef CONFIG_LOGBUFFER
+       initr_logbuffer,
+#endif
+#ifdef CONFIG_POST
+       initr_post_backlog,
+#endif
+       INIT_FUNC_WATCHDOG_RESET
+#ifdef CONFIG_SYS_DELAYED_ICACHE
+       initr_icache_enable,
+#endif
+#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
+       initr_unlock_ram_in_cache,
+#endif
+#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
+       /*
+        * Do early PCI configuration _before_ the flash gets initialised,
+        * because PCU ressources are crucial for flash access on some boards.
+        */
+       initr_pci,
+#endif
+#ifdef CONFIG_WINBOND_83C553
+       initr_w83c553f,
+#endif
+       initr_barrier,
+       initr_malloc,
+#ifdef CONFIG_ARCH_EARLY_INIT_R
+       arch_early_init_r,
+#endif
+       power_init_board,
+#ifndef CONFIG_SYS_NO_FLASH
+       initr_flash,
+#endif
+       INIT_FUNC_WATCHDOG_RESET
+#if defined(CONFIG_PPC) || defined(CONFIG_X86)
+       /* initialize higher level parts of CPU like time base and timers */
+       cpu_init_r,
+#endif
+#ifdef CONFIG_PPC
+       initr_spi,
+#endif
+#if defined(CONFIG_X86) && defined(CONFIG_SPI)
+       init_func_spi,
+#endif
+#ifdef CONFIG_CMD_NAND
+       initr_nand,
+#endif
+#ifdef CONFIG_CMD_ONENAND
+       initr_onenand,
+#endif
+#ifdef CONFIG_GENERIC_MMC
+       initr_mmc,
+#endif
+#ifdef CONFIG_HAS_DATAFLASH
+       initr_dataflash,
+#endif
+       initr_env,
+       INIT_FUNC_WATCHDOG_RESET
+       initr_secondary_cpu,
+#ifdef CONFIG_SC3
+       initr_sc3_read_eeprom,
+#endif
+#ifdef CONFIG_HERMES
+       initr_hermes,
+#endif
+#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
+       mac_read_from_eeprom,
+#endif
+       INIT_FUNC_WATCHDOG_RESET
+#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
+       /*
+        * Do pci configuration
+        */
+       initr_pci,
+#endif
+       stdio_init,
+       initr_jumptable,
+#ifdef CONFIG_API
+       initr_api,
+#endif
+       console_init_r,         /* fully init console as a device */
+#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
+       show_model_r,
+#endif
+#ifdef CONFIG_ARCH_MISC_INIT
+       arch_misc_init,         /* miscellaneous arch-dependent init */
+#endif
+#ifdef CONFIG_MISC_INIT_R
+       misc_init_r,            /* miscellaneous platform-dependent init */
+#endif
+#ifdef CONFIG_HERMES
+       initr_hermes_start,
+#endif
+       INIT_FUNC_WATCHDOG_RESET
+#ifdef CONFIG_CMD_KGDB
+       initr_kgdb,
+#endif
+#ifdef CONFIG_X86
+       board_early_init_r,
+#endif
+       interrupt_init,
+#if defined(CONFIG_ARM) || defined(CONFIG_x86)
+       initr_enable_interrupts,
+#endif
+#ifdef CONFIG_X86
+       timer_init,             /* initialize timer */
+#endif
+#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
+       initr_status_led,
+#endif
+       /* PPC has a udelay(20) here dating from 2002. Why? */
+#ifdef CONFIG_CMD_NET
+       initr_ethaddr,
+#endif
+#ifdef CONFIG_BOARD_LATE_INIT
+       board_late_init,
+#endif
+#ifdef CONFIG_CMD_SCSI
+       INIT_FUNC_WATCHDOG_RESET
+       initr_scsi,
+#endif
+#ifdef CONFIG_CMD_DOC
+       INIT_FUNC_WATCHDOG_RESET
+       initr_doc,
+#endif
+#ifdef CONFIG_BITBANGMII
+       initr_bbmii,
+#endif
+#ifdef CONFIG_CMD_NET
+       INIT_FUNC_WATCHDOG_RESET
+       initr_net,
+#endif
+#ifdef CONFIG_POST
+       initr_post,
+#endif
+#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)
+       initr_pcmcia,
+#endif
+#if defined(CONFIG_CMD_IDE)
+       initr_ide,
+#endif
+#ifdef CONFIG_LAST_STAGE_INIT
+       INIT_FUNC_WATCHDOG_RESET
+       /*
+        * Some parts can be only initialized if all others (like
+        * Interrupts) are up and running (i.e. the PC-style ISA
+        * keyboard).
+        */
+       last_stage_init,
+#endif
+#ifdef CONFIG_CMD_BEDBUG
+       INIT_FUNC_WATCHDOG_RESET
+       initr_bedbug,
+#endif
+#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
+       initr_mem,
+#endif
+#ifdef CONFIG_PS2KBD
+       initr_kbd,
+#endif
+#ifdef CONFIG_MODEM_SUPPORT
+       initr_modem,
+#endif
+       run_main_loop,
+};
+
+void board_init_r(gd_t *new_gd, ulong dest_addr)
+{
+#ifndef CONFIG_X86
+       gd = new_gd;
+#endif
+       if (initcall_run_list(init_sequence_r))
+               hang();
+
+       /* NOTREACHED - run_main_loop() does not return */
+       hang();
+}
index 2e9335207c5c11fb8d781c3ecf55b0d968c5b1b4..7438469d091721a6dcba15ec2263ef7b086dc743 100644 (file)
@@ -88,7 +88,7 @@ static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 #include <linux/err.h>
 #include <nand.h>
 
-#ifdef CONFIG_SILENT_CONSOLE
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
 static void fixup_silent_linux(void);
 #endif
 
@@ -128,6 +128,9 @@ static boot_os_fn do_bootm_rtems;
 #if defined(CONFIG_BOOTM_OSE)
 static boot_os_fn do_bootm_ose;
 #endif
+#if defined(CONFIG_BOOTM_PLAN9)
+static boot_os_fn do_bootm_plan9;
+#endif
 #if defined(CONFIG_CMD_ELF)
 static boot_os_fn do_bootm_vxworks;
 static boot_os_fn do_bootm_qnxelf;
@@ -154,6 +157,9 @@ static boot_os_fn *boot_os[] = {
 #if defined(CONFIG_BOOTM_OSE)
        [IH_OS_OSE] = do_bootm_ose,
 #endif
+#if defined(CONFIG_BOOTM_PLAN9)
+       [IH_OS_PLAN9] = do_bootm_plan9,
+#endif
 #if defined(CONFIG_CMD_ELF)
        [IH_OS_VXWORKS] = do_bootm_vxworks,
        [IH_OS_QNX] = do_bootm_qnxelf,
@@ -694,7 +700,7 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        bootstage_mark(BOOTSTAGE_ID_CHECK_BOOT_OS);
 
-#ifdef CONFIG_SILENT_CONSOLE
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
        if (images.os.os == IH_OS_LINUX)
                fixup_silent_linux();
 #endif
@@ -1413,7 +1419,7 @@ U_BOOT_CMD(
 /*******************************************************************/
 /* helper routines */
 /*******************************************************************/
-#ifdef CONFIG_SILENT_CONSOLE
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
 static void fixup_silent_linux(void)
 {
        char buf[256], *start, *end;
@@ -1628,6 +1634,39 @@ static int do_bootm_ose(int flag, int argc, char * const argv[],
 }
 #endif /* CONFIG_BOOTM_OSE */
 
+#if defined(CONFIG_BOOTM_PLAN9)
+static int do_bootm_plan9(int flag, int argc, char * const argv[],
+                          bootm_headers_t *images)
+{
+       void (*entry_point)(void);
+
+       if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
+               return 1;
+
+#if defined(CONFIG_FIT)
+       if (!images->legacy_hdr_valid) {
+               fit_unsupported_reset("Plan 9");
+               return 1;
+       }
+#endif
+
+       entry_point = (void (*)(void))images->ep;
+
+       printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
+               (ulong)entry_point);
+
+       bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+       /*
+        * Plan 9 Parameters:
+        *   None
+        */
+       (*entry_point)();
+
+       return 1;
+}
+#endif /* CONFIG_BOOTM_PLAN9 */
+
 #if defined(CONFIG_CMD_ELF)
 static int do_bootm_vxworks(int flag, int argc, char * const argv[],
                             bootm_headers_t *images)
@@ -1806,7 +1845,7 @@ static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        usb_stop();
 #endif
 
-#ifdef CONFIG_SILENT_CONSOLE
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
        fixup_silent_linux();
 #endif
        arch_preboot_os();
diff --git a/common/cmd_df.c b/common/cmd_df.c
deleted file mode 100644 (file)
index f7e5df3..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Command for accessing DataFlash.
- *
- * Copyright (C) 2008 Atmel Corporation
- */
-#include <common.h>
-#include <df.h>
-
-static int do_df(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       const char *cmd;
-
-       /* need at least two arguments */
-       if (argc < 2)
-               goto usage;
-
-       cmd = argv[1];
-
-       if (strcmp(cmd, "init") == 0) {
-               df_init(0, 0, 1000000);
-               return 0;
-       }
-
-       if (strcmp(cmd, "info") == 0) {
-               df_show_info();
-               return 0;
-       }
-
-usage:
-       return CMD_RET_USAGE;
-}
-
-U_BOOT_CMD(
-       sf,     2,      1,      do_serial_flash,
-       "Serial flash sub-system",
-       "probe [bus:]cs         - init flash device on given SPI bus and CS")
index 01d6b3a2d66b6a4780f8a479ff41ffd2a5bd601b..83ef32497a865bf63586d024c54de07bea62e515 100644 (file)
@@ -50,12 +50,15 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        if (ret)
                return CMD_RET_FAILURE;
 
-       if (strcmp(argv[3], "list") == 0) {
+       if (argc > 3 && strcmp(argv[3], "list") == 0) {
                dfu_show_entities();
                goto done;
        }
 
+#ifdef CONFIG_TRATS
        board_usb_init();
+#endif
+
        g_dnl_register(s);
        while (1) {
                if (ctrlc())
index cd94423d21910d61055bade1bc285dbed099b9f9..edbd4a83cabcbf6f0d7df3e9c8118cfb2311c3a5 100644 (file)
@@ -27,7 +27,9 @@
 
 #include <dtt.h>
 #include <i2c.h>
+#include <tmu.h>
 
+#if defined CONFIG_DTT_SENSORS
 static unsigned long sensor_initialized;
 
 static void _initialize_dtt(void)
@@ -59,9 +61,11 @@ void dtt_init(void)
        /* switch back to original I2C bus */
        I2C_SET_BUS(old_bus);
 }
+#endif
 
-int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+int dtt_i2c(void)
 {
+#if defined CONFIG_DTT_SENSORS
        int i;
        unsigned char sensors[] = CONFIG_DTT_SENSORS;
        int old_bus;
@@ -83,8 +87,34 @@ int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 
        /* switch back to original I2C bus */
        I2C_SET_BUS(old_bus);
+#endif
 
        return 0;
+}
+
+int dtt_tmu(void)
+{
+#if defined CONFIG_TMU_CMD_DTT
+       int cur_temp;
+
+       /* Sense and return latest thermal info */
+       if (tmu_monitor(&cur_temp) == TMU_STATUS_INIT) {
+               puts("TMU is in unknown state, temperature is invalid\n");
+               return -1;
+       }
+       printf("Current temperature: %u degrees Celsius\n", cur_temp);
+#endif
+       return 0;
+}
+
+int do_dtt(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int err = 0;
+
+       err |= dtt_i2c();
+       err |= dtt_tmu();
+
+       return err;
 }      /* do_dtt() */
 
 /***************************************************/
index dcf76a50cde54d103419b0533146dd3f8f96592f..706fd54a553b9fc394a18c3f4add6027838967c0 100644 (file)
@@ -88,10 +88,10 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
        dev = dev_desc->dev;
 
        /* get the filename */
-       filename = argv[3];
+       filename = argv[4];
 
        /* get the address in hexadecimal format (string to int) */
-       ram_address = simple_strtoul(argv[4], NULL, 16);
+       ram_address = simple_strtoul(argv[3], NULL, 16);
 
        /* get the filesize in base 10 format */
        file_size = simple_strtoul(argv[5], NULL, 10);
@@ -122,7 +122,7 @@ fail:
 
 U_BOOT_CMD(ext4write, 6, 1, do_ext4_write,
        "create a file in the root directory",
-       "<interface> <dev[:part]> [Absolute filename path] [Address] [sizebytes]\n"
+       "<interface> <dev[:part]> <addr> <absolute filename path> [sizebytes]\n"
        "    - create a file in / directory");
 
 #endif
index 86be044725c6504982a867fb55a485961e0badad..0487438faa028655b752689a21d023b38414812e 100644 (file)
@@ -49,6 +49,9 @@ U_BOOT_CMD(
        "      If 'pos' is omitted, 0 is used. 'pos' requires 'bytes'.\n"
        "      'bytes' gives the size to load. If 'bytes' is 0 or omitted,\n"
        "      the load stops on end of file.\n"
+       "      If either 'pos' or 'bytes' are not aligned to\n"
+       "      ARCH_DMA_MINALIGN then a misaligned buffer warning will\n"
+       "      be printed and performance will suffer for the load.\n"
        "      All numeric parameters are assumed to be hex."
 );
 
index 042c994a1bb53b7d535b5dd4a9c7e9951e6f3e1c..64dd76a0f5dfbb5a35b52a4cd14b1c8c80a5d5b3 100644 (file)
@@ -631,6 +631,7 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 }
 #endif /* CONFIG_LOOPW */
 
+#ifdef CONFIG_CMD_MEMTEST
 static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr,
                          vu_long *dummy)
 {
@@ -1002,7 +1003,7 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
 
        return ret;     /* not reached */
 }
-
+#endif /* CONFIG_CMD_MEMTEST */
 
 /* Modify memory.
  *
@@ -1240,11 +1241,13 @@ U_BOOT_CMD(
 );
 #endif /* CONFIG_LOOPW */
 
+#ifdef CONFIG_CMD_MEMTEST
 U_BOOT_CMD(
        mtest,  5,      1,      do_mem_mtest,
        "simple RAM read/write test",
        "[start [end [pattern [iterations]]]]"
 );
+#endif /* CONFIG_CMD_MEMTEST */
 
 #ifdef CONFIG_MX_CYCLIC
 U_BOOT_CMD(
index 0cfca0c46ba00e58ce094910bb6413c28e4bbc44..5192dee8ae23cf398a204e2dcb16c23fbb970113 100644 (file)
@@ -1420,7 +1420,7 @@ static int delete_partition(const char *id)
                        return 1;
 
                if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) {
-                       printf("generated mtdparts too long, reseting to null\n");
+                       printf("generated mtdparts too long, resetting to null\n");
                        return 1;
                }
                return 0;
@@ -1518,7 +1518,7 @@ static int spread_partitions(void)
        index_partitions();
 
        if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) {
-               printf("generated mtdparts too long, reseting to null\n");
+               printf("generated mtdparts too long, resetting to null\n");
                return 1;
        }
        return 0;
@@ -2016,7 +2016,7 @@ static int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc,
                }
 
                if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) {
-                       printf("generated mtdparts too long, reseting to null\n");
+                       printf("generated mtdparts too long, resetting to null\n");
                        return 1;
                }
 
index 3a05e6010306f6053624514c48843c375e43b9f6..947d6c4ed665ad156ae07e037d8010a1df805c97 100644 (file)
@@ -325,41 +325,50 @@ static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 int do_env_ask(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        char message[CONFIG_SYS_CBSIZE];
-       int size = CONFIG_SYS_CBSIZE - 1;
-       int i, len, pos;
+       int i, len, pos, size;
        char *local_args[4];
+       char *endptr;
 
        local_args[0] = argv[0];
        local_args[1] = argv[1];
        local_args[2] = NULL;
        local_args[3] = NULL;
 
-       /* Check the syntax */
-       switch (argc) {
-       case 1:
+       /*
+        * Check the syntax:
+        *
+        * env_ask envname [message1 ...] [size]
+        */
+       if (argc == 1)
                return CMD_RET_USAGE;
 
-       case 2:         /* env_ask envname */
-               sprintf(message, "Please enter '%s':", argv[1]);
-               break;
-
-       case 3:         /* env_ask envname size */
-               sprintf(message, "Please enter '%s':", argv[1]);
-               size = simple_strtoul(argv[2], NULL, 10);
-               break;
+       /*
+        * We test the last argument if it can be converted
+        * into a decimal number.  If yes, we assume it's
+        * the size.  Otherwise we echo it as part of the
+        * message.
+        */
+       i = simple_strtoul(argv[argc - 1], &endptr, 10);
+       if (*endptr != '\0') {                  /* no size */
+               size = CONFIG_SYS_CBSIZE - 1;
+       } else {                                /* size given */
+               size = i;
+               --argc;
+       }
 
-       default:        /* env_ask envname message1 ... messagen size */
-               for (i = 2, pos = 0; i < argc - 1; i++) {
+       if (argc <= 2) {
+               sprintf(message, "Please enter '%s': ", argv[1]);
+       } else {
+               /* env_ask envname message1 ... messagen [size] */
+               for (i = 2, pos = 0; i < argc; i++) {
                        if (pos)
                                message[pos++] = ' ';
 
                        strcpy(message + pos, argv[i]);
                        pos += strlen(argv[i]);
                }
-
+               message[pos++] = ' ';
                message[pos] = '\0';
-               size = simple_strtoul(argv[argc - 1], NULL, 10);
-               break;
        }
 
        if (size >= CONFIG_SYS_CBSIZE)
@@ -1168,14 +1177,7 @@ U_BOOT_CMD(
        askenv, CONFIG_SYS_MAXARGS,     1,      do_env_ask,
        "get environment variables from stdin",
        "name [message] [size]\n"
-       "    - get environment variable 'name' from stdin (max 'size' chars)\n"
-       "askenv name\n"
-       "    - get environment variable 'name' from stdin\n"
-       "askenv name size\n"
-       "    - get environment variable 'name' from stdin (max 'size' chars)\n"
-       "askenv name [message] size\n"
-       "    - display 'message' string and get environment variable 'name'"
-       "from stdin (max 'size' chars)"
+       "    - get environment variable 'name' from stdin (max 'size' chars)"
 );
 #endif
 
index d997597c1e1e7b0d0260135afa10ba779a9b6934..b79f074f841aa21c53ad53ccec61ef92a5510d93 100644 (file)
@@ -96,7 +96,7 @@ int do_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 U_BOOT_CMD(
        part,   5,      1,      do_part,
        "disk partition related commands",
-       "part uuid <interface> <dev>:<part>\n"
+       "uuid <interface> <dev>:<part>\n"
        "    - print partition UUID\n"
        "part uuid <interface> <dev>:<part> <varname>\n"
        "    - set environment variable to partition UUID\n"
index b1753587d3c92f1273e66acab040bad9efca5761..3f0d414954c3e317507b899ec61391d07b38a77b 100644 (file)
@@ -369,8 +369,8 @@ static void spi_test_next_stage(struct test_info *test)
  * @param vbuf         Verification buffer
  * @return 0 if ok, -1 on error
  */
-static int spi_flash_test(struct spi_flash *flash, char *buf, ulong len,
-                          ulong offset, char *vbuf)
+static int spi_flash_test(struct spi_flash *flash, uint8_t *buf, ulong len,
+                          ulong offset, uint8_t *vbuf)
 {
        struct test_info test;
        int i;
@@ -431,9 +431,9 @@ static int do_spi_flash_test(int argc, char * const argv[])
 {
        unsigned long offset;
        unsigned long len;
-       char *buf = (char *)CONFIG_SYS_TEXT_BASE;
+       uint8_t *buf = (uint8_t *)CONFIG_SYS_TEXT_BASE;
        char *endp;
-       char *vbuf;
+       uint8_t *vbuf;
        int ret;
 
        offset = simple_strtoul(argv[1], &endp, 16);
diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c
new file mode 100644 (file)
index 0000000..87a5f2f
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ * Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <errno.h>
+#include <common.h>
+#include <command.h>
+#include <g_dnl.h>
+#include <usb_mass_storage.h>
+
+int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
+                              int argc, char * const argv[])
+{
+       char *ep;
+       unsigned int dev_num = 0, offset = 0, part_size = 0;
+       int rc;
+
+       struct ums_board_info *ums_info;
+       static char *s = "ums";
+
+       if (argc < 2) {
+               printf("usage: ums <dev> - e.g. ums 0\n");
+               return 0;
+       }
+
+       dev_num = (int)simple_strtoul(argv[1], &ep, 16);
+
+       if (dev_num) {
+               puts("\nSet eMMC device to 0! - e.g. ums 0\n");
+               goto fail;
+       }
+
+       board_usb_init();
+       ums_info = board_ums_init(dev_num, offset, part_size);
+
+       if (!ums_info) {
+               printf("MMC: %d -> NOT available\n", dev_num);
+               goto fail;
+       }
+       rc = fsg_init(ums_info);
+       if (rc) {
+               printf("cmd ums: fsg_init failed\n");
+               goto fail;
+       }
+
+       g_dnl_register(s);
+
+       while (1) {
+               /* Handle control-c and timeouts */
+               if (ctrlc()) {
+                       printf("The remote end did not respond in time.\n");
+                       goto exit;
+               }
+               usb_gadget_handle_interrupts();
+               /* Check if USB cable has been detached */
+               if (fsg_main_thread(NULL) == EIO)
+                       goto exit;
+       }
+exit:
+       g_dnl_unregister();
+       return 0;
+
+fail:
+       return -1;
+}
+
+U_BOOT_CMD(ums, CONFIG_SYS_MAXARGS, 1, do_usb_mass_storage,
+       "Use the UMS [User Mass Storage]",
+       "ums - User Mass Storage Gadget"
+);
index 78ca3674f09a85d5834bae0e2bb4d3a1427b07d3..78aafb4f2c224ad6fa4665424f36bd158b7d67bb 100644 (file)
@@ -31,7 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /*
  * Look up a callback function pointer by name
  */
-struct env_clbk_tbl *find_env_callback(const char *name)
+static struct env_clbk_tbl *find_env_callback(const char *name)
 {
        struct env_clbk_tbl *clbkp;
        int i;
index 6afbb40a9871078abe99d48deba8a2b54b16dbc5..60c21270398e649c7bb77a8bd04445769e22d127 100644 (file)
@@ -108,6 +108,7 @@ static const table_entry_t uimage_os[] = {
 #endif
        {       IH_OS_NETBSD,   "netbsd",       "NetBSD",               },
        {       IH_OS_OSE,      "ose",          "Enea OSE",             },
+       {       IH_OS_PLAN9,    "plan9",        "Plan 9",               },
        {       IH_OS_RTEMS,    "rtems",        "RTEMS",                },
        {       IH_OS_U_BOOT,   "u-boot",       "U-Boot",               },
 #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
index 590bbb9301fd7c9e456dd355ab30af005da5ee6b..77914adbce558aca4a67607dcd3292519cf02275 100644 (file)
@@ -386,8 +386,6 @@ int drv_lcd_init (void)
 
        lcd_base = (void *)(gd->fb_base);
 
-       lcd_get_size(&lcd_line_length);
-
        lcd_init(lcd_base);             /* LCD initialization */
 
        /* Device initialization */
@@ -470,6 +468,8 @@ static int lcd_init(void *lcdbase)
        debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
 
        lcd_ctrl_init(lcdbase);
+       lcd_get_size(&lcd_line_length);
+       lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
        lcd_is_enabled = 1;
        lcd_clear();
        lcd_enable ();
index e2d2e09bf9f750bc278fa8d5f452c63ccc6ad1e2..a15f020830bb81a310f03bc9b262accf99cee42c 100644 (file)
@@ -95,7 +95,7 @@ extern void mdm_init(void); /* defined in board.c */
  * Watch for 'delay' seconds for autoboot stop or autoboot delay string.
  * returns: 0 -  no key string, allow autoboot 1 - got key string, abort
  */
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+#if defined(CONFIG_BOOTDELAY)
 # if defined(CONFIG_AUTOBOOT_KEYED)
 #ifndef CONFIG_MENU
 static inline
@@ -279,7 +279,7 @@ int abortboot(int bootdelay)
        return abort;
 }
 # endif        /* CONFIG_AUTOBOOT_KEYED */
-#endif /* CONFIG_BOOTDELAY >= 0  */
+#endif /* CONFIG_BOOTDELAY */
 
 /*
  * Runs the given boot command securely.  Specifically:
@@ -295,8 +295,7 @@ int abortboot(int bootdelay)
  * printing the error message to console.
  */
 
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \
-       defined(CONFIG_OF_CONTROL)
+#if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL)
 static void secure_boot_cmd(char *cmd)
 {
        cmd_tbl_t *cmdtp;
@@ -358,11 +357,10 @@ void main_loop (void)
        int rc = 1;
        int flag;
 #endif
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \
-               defined(CONFIG_OF_CONTROL)
+#if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL)
        char *env;
 #endif
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+#if defined(CONFIG_BOOTDELAY)
        char *s;
        int bootdelay;
 #endif
@@ -378,6 +376,10 @@ void main_loop (void)
 
        bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
 
+#if defined CONFIG_OF_CONTROL
+       set_working_fdt_addr((void *)gd->fdt_blob);
+#endif /* CONFIG_OF_CONTROL */
+
 #ifdef CONFIG_BOOTCOUNT_LIMIT
        bootcount = bootcount_load();
        bootcount++;
@@ -431,7 +433,7 @@ void main_loop (void)
        update_tftp (0UL);
 #endif /* CONFIG_UPDATE_TFTP */
 
-#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+#if defined(CONFIG_BOOTDELAY)
        s = getenv ("bootdelay");
        bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
 
@@ -500,10 +502,6 @@ void main_loop (void)
 #endif /* CONFIG_MENUKEY */
 #endif /* CONFIG_BOOTDELAY */
 
-#if defined CONFIG_OF_CONTROL
-       set_working_fdt_addr((void *)gd->fdt_blob);
-#endif /* CONFIG_OF_CONTROL */
-
        /*
         * Main Loop for Monitor Command Processing
         */
index bb5c69a15d9f67376ca58534b189707dc714db72..4e6a19bd8a60bc94137e49d17b2718de7a76d5bd 100644 (file)
--- a/config.mk
+++ b/config.mk
@@ -219,6 +219,14 @@ ifeq ($(CONFIG_SPL_BUILD),y)
 CPPFLAGS += -DCONFIG_SPL_BUILD
 endif
 
+# Does this architecture support generic board init?
+ifeq ($(__HAVE_ARCH_GENERIC_BOARD),)
+ifneq ($(CONFIG_SYS_GENERIC_BOARD),)
+$(error Your architecture does not support generic board. Please undefined \
+CONFIG_SYS_GENERIC_BOARD in your board config file)
+endif
+endif
+
 ifneq ($(RESET_VECTOR_ADDRESS),)
 CPPFLAGS += -DRESET_VECTOR_ADDRESS=$(RESET_VECTOR_ADDRESS)
 endif
diff --git a/doc/README.memory-test b/doc/README.memory-test
new file mode 100644 (file)
index 0000000..eb60e8d
--- /dev/null
@@ -0,0 +1,98 @@
+The most frequent cause of problems when porting U-Boot to new
+hardware, or when using a sloppy port on some board, is memory errors.
+In most cases these are not caused by failing hardware, but by
+incorrect initialization of the memory controller.  So it appears to
+be a good idea to always test if the memory is working correctly,
+before looking for any other potential causes of any problems.
+
+U-Boot implements 3 different approaches to perform memory tests:
+
+1. The get_ram_size() function (see "common/memsize.c").
+
+   This function is supposed to be used in each and every U-Boot port
+   determine the presence and actual size of each of the potential
+   memory banks on this piece of hardware.  The code is supposed to be
+   very fast, so running it for each reboot does not hurt.  It is a
+   little known and generally underrated fact that this code will also
+   catch 99% of hardware related (i. e. reliably reproducible) memory
+   errors.  It is strongly recommended to always use this function, in
+   each and every port of U-Boot.
+
+2. The "mtest" command.
+
+   This is probably the best known memory test utility in U-Boot.
+   Unfortunately, it is also the most problematic, and the most
+   useless one.
+
+   There are a number of serious problems with this command:
+
+   - It is terribly slow.  Running "mtest" on the whole system RAM
+     takes a _long_ time before there is any significance in the fact
+     that no errors have been found so far.
+
+   - It is difficult to configure, and to use.  And any errors here
+     will reliably crash or hang your system.  "mtest" is dumb and has
+     no knowledge about memory ranges that may be in use for other
+     purposes, like exception code, U-Boot code and data, stack,
+     malloc arena, video buffer, log buffer, etc.  If you let it, it
+     will happily "test" all such areas, which of course will cause
+     some problems.
+
+   - It is not easy to configure and use, and a large number of
+     systems are seriously misconfigured.  The original idea was to
+     test basically the whole system RAM, with only exempting the
+     areas used by U-Boot itself - on most systems these are the areas
+     used for the exception vectors (usually at the very lower end of
+     system memory) and for U-Boot (code, data, etc. - see above;
+     these are usually at the very upper end of system memory).  But
+     experience has shown that a very large number of ports use
+     pretty much bogus settings of CONFIG_SYS_MEMTEST_START and
+     CONFIG_SYS_MEMTEST_END; this results in useless tests (because
+     the ranges is too small and/or badly located) or in critical
+     failures (system crashes).
+
+   Because of these issues, the "mtest" command is considered depre-
+   cated.  It should not be enabled in most normal ports of U-Boot,
+   especially not in production.  If you really need a memory test,
+   then see 1. and 3. above resp. below.
+
+3. The most thorough memory test facility is available as part of the
+   POST (Power-On Self Test) sub-system, see "post/drivers/memory.c".
+
+   If you really need to perform memory tests (for example, because
+   it is mandatory part of your requirement specification), then
+   enable this test which is generic and should work on all archi-
+   tectures.
+
+WARNING:
+
+It should pointed out that _all_ these memory tests have one
+fundamental, unfixable design flaw:  they are based on the assumption
+that memory errors can be found by writing to and reading from memory.
+Unfortunately, this is only true for the relatively harmless, usually
+static errors like shorts between data or address lines, unconnected
+pins, etc.  All the really nasty errors which will first turn your
+hair gray, only to make you tear it out later, are dynamical errors,
+which usually happen not with simple read or write cycles on the bus,
+but when performing back-to-back data transfers in burst mode.  Such
+accesses usually happen only for certain DMA operations, or for heavy
+cache use (instruction fetching, cache flushing).  So far I am not
+aware of any freely available code that implements a generic, and
+efficient, memory test like that.  The best known test case to stress
+a system like that is to boot Linux with root file system mounted over
+NFS, and then build some larger software package natively (say,
+compile a Linux kernel on the system) - this will cause enough context
+switches, network traffic (and thus DMA transfers from the network
+controller), varying RAM use, etc. to trigger any weak spots in this
+area.
+
+Note: An attempt was made once to implement such a test to catch
+memory problems on a specific board.  The code is pretty much board
+specific (for example, it includes setting specific GPIO signals to
+provide triggers for an attached logic analyzer), but you can get an
+idea how it works: see "examples/standalone/test_burst*".
+
+Note 2: Ironically enough, the "test_burst" did not catch any RAM
+errors, not a single one ever.  The problems this code was supposed
+to catch did not happen when accessing the RAM, but when reading from
+NOR flash.
index e9ca96cba7c13a5614b060d5ede5664a28fe516c..189b8839d51452c507dd00b36c4b6d769c5ff34b 100644 (file)
@@ -90,3 +90,5 @@ MVS1             powerpc     MPC823         306620b     2008-08-26  Andre Schwar
 adsvix           ARM         PXA27x         7610db1     2008-07-30  Adrian Filipi <adrian.filipi@eurotech.com>
 R5200            ColdFire    -              48ead7a     2008-03-31  Zachary P. Landau <zachary.landau@labxtechnologies.com>
 CPCI440          powerpc     440GP          b568fd2     2007-12-27  Matthias Fuchs <matthias.fuchs@esd-electronics.com>
+PCIPPC2          powerpc     MPC740/MPC750  7c9e89b     2013-02-07  Wolfgang Denk <wd@denx.de>
+PCIPPC6        powerpc MPC740/MPC750 -   -             Wolfgang Denk <wd@denx.de>
index 70202cece97fe8a53b49251ca8f64a9cef26ee1e..6d90a0ec40376d87f87c2ed549bd26fc6b0d07e2 100644 (file)
@@ -23,4 +23,6 @@ The following actions are taken if "silent" is set at boot time:
 
  - When booting a linux kernel, the "bootargs" are fixed up so that
    the argument "console=" will be in the command line, no matter how
-   it was set in "bootargs" before.
+   it was set in "bootargs" before. If you don't want the linux command
+   line to be affected, define CONFIG_SILENT_U_BOOT_ONLY in your board
+   config file as well, and this part of the feature will be disabled.
diff --git a/doc/device-tree-bindings/exynos/tmu.txt b/doc/device-tree-bindings/exynos/tmu.txt
new file mode 100644 (file)
index 0000000..89d3bf0
--- /dev/null
@@ -0,0 +1,44 @@
+Exynos Thermal management Unit
+
+Required properties:
+
+ - compatible : Should be "samsung,exynos-tmu" for TMU
+ - samsung,min-temp : Minimum temperature value (25 degree celsius)
+       - Current temperature of SoC should be more than this value.
+ - samsung,max-temp : Maximum temperature value (125 degree celsius)
+       - Current temperature of SoC should be less than this value.
+ - samsung,start-warning : Temperature at which TMU starts giving warning (degree celsius)
+ - samsung,start-tripping : Temperature at which TMU shuts down the system (degree celsius)
+ - samsung,hw-tripping : Temperature at which hardware tripping should happen
+       in case TMU fails to power off (degree celsius)
+ - samsung,efuse-min-value : SOC efuse min value (Constant 40)
+       - efuse-value should be more than this value.
+ - samsung,efuse-value : SOC actual efuse value (Literal value)
+       - This is the data trimming info.
+       - This value is used to calculate measuring error.
+ - samsung,efuse-max-value : SoC max efuse value (Constant 100)
+       - efuse-value should be less than this value.
+ - samsung,slope : Default value 274761730 (Constant 0x1060_8802).
+       - This is the default value for TMU_CONTROL register.
+       - It sets the gain of amplifier to the positive-tc generator block.
+       - It selects thermal tripping mode and enables thermal tripping.
+ - samsung,dc-value : Measured data calibration value (Constant 25)
+       - Used for tempearture calculation.
+       - This is 25 because temperature measured is always above 25 degrees.
+
+
+Example:
+
+tmu@10060000 {
+       compatible = "samsung,exynos-tmu"
+       samsung,min-temp = <25>;
+       samsung,max-temp = <125>;
+       samsung,start-warning = <95>;
+       samsung,start-tripping = <105>;
+       samsung,hw-tripping = <110>;
+       samsung,efuse-min-value = <40>;
+       samsung,efuse-value = <55>;
+       samsung,efuse-max-value = <100>;
+       samsung,slope = <274761730>;
+       samsung,dc-value = <25>;
+};
index b65e9ea73e3369790c961b5c43c6ae8512aeacc7..c2cf2d5a626819063aa76a477334ccdde4c42b8e 100644 (file)
@@ -240,10 +240,6 @@ III) Analysis of in-tree drivers
     ----------------
       Standard driver, uses indirect functions.
 
-    8) pcippc2/cpc710_pci.c
-    -----------------------
-      Standard driver, uses indirect functions, has two busses.
-
     9) Marvell/db64360/pci.c
     ------------------------
       Standard driver, uses dword for read/write ops, has two busses.
index 271bd263355e5755a7b42c6884e4ea59d664eb85..7db328639fe63fd764519ab120002d0c31ee81d5 100644 (file)
@@ -292,11 +292,6 @@ III) Analysis of in-tree drivers
   Only function proxy call. Code cleanup needed.
 
 
-  45) board/pcippc2/pcippc2.c
-  ---------------------------
-  The driver is standard HW watchdog. Simple conversion is possible.
-
-
   46) board/pcs440ep/pcs440ep.c
   -----------------------------
   The driver is standard HW watchdog. Simple conversion is possible.
index e04ba2dda5a35f09479b26120ee18e63dbda66f4..d9a0cc267beaa1029b3403fb19654cc33cc3855e 100644 (file)
@@ -7,6 +7,23 @@ file.
 
 ---------------------------
 
+What:  Remove CONFIG_CMD_MEMTEST from default list
+When:  Release v2013.07
+
+Why:   The "mtest" command is of little practical use (if any), and
+       experience has shown that a large number of board configu-
+       rations define useless or even dangerous start and end
+       addresses.  If not even the board maintainers are able to
+       figure out which memory range can be reliably tested, how can
+       we expect such from the end users?  As this problem comes up
+       repeatedly, we rather do not enable this command by default,
+       so only people who know what they are doing will be confronted
+       with it.
+
+Who:   Wolfgang Denk <wd@denx.de>
+
+---------------------------
+
 What:  Users of the legacy miiphy_* code
 When:  undetermined
 
index a88d0f7f83995dd3465f8becf20869d6aa8051a4..42c177fe455b1976ecb13ca366549bfb51b11b4f 100644 (file)
@@ -56,8 +56,8 @@ struct mvsata_port_registers {
  * Sanity checks:
  * - to compile at all, we need CONFIG_SYS_ATA_BASE_ADDR.
  * - for ide_preinit to make sense, we need at least one of
- *   CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE0_OFFSET;
- * - for inde_preinit to be called, we need CONFIG_IDE_PREINIT.
+ *   CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE1_OFFSET;
+ * - for ide_preinit to be called, we need CONFIG_IDE_PREINIT.
  * Fail with an explanation message if these conditions are not met.
  * This is particularly important for CONFIG_IDE_PREINIT, because
  * its lack would not cause a build error.
index 5d504dffd11cb5df825556c679dd8c0f7a95d668..083d74591b0be80739281bd8bb5263e68c9abf3d 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <common.h>
 #include <malloc.h>
+#include <errno.h>
 #include <dfu.h>
 
 enum dfu_mmc_op {
@@ -153,6 +154,10 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, void *buf, long *len)
 
 int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
 {
+       int dev, part;
+       struct mmc *mmc;
+       block_dev_desc_t *blk_dev;
+       disk_partition_t partinfo;
        char *st;
 
        dfu->dev_type = DFU_DEV_MMC;
@@ -166,8 +171,34 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
                dfu->layout = DFU_FS_FAT;
        } else if (!strcmp(st, "ext4")) {
                dfu->layout = DFU_FS_EXT4;
+       } else if (!strcmp(st, "part")) {
+
+               dfu->layout = DFU_RAW_ADDR;
+
+               dev = simple_strtoul(s, &s, 10);
+               s++;
+               part = simple_strtoul(s, &s, 10);
+
+               mmc = find_mmc_device(dev);
+               if (mmc == NULL || mmc_init(mmc)) {
+                       printf("%s: could not find mmc device #%d!\n", __func__, dev);
+                       return -ENODEV;
+               }
+
+               blk_dev = &mmc->block_dev;
+               if (get_partition_info(blk_dev, part, &partinfo) != 0) {
+                       printf("%s: could not find partition #%d on mmc device #%d!\n",
+                                       __func__, part, dev);
+                       return -ENODEV;
+               }
+
+               dfu->data.mmc.lba_start = partinfo.start;
+               dfu->data.mmc.lba_size = partinfo.size;
+               dfu->data.mmc.lba_blk_size = partinfo.blksz;
+
        } else {
                printf("%s: Memory layout (%s) not supported!\n", __func__, st);
+               return -ENODEV;
        }
 
        if (dfu->layout == DFU_FS_EXT4 || dfu->layout == DFU_FS_FAT) {
index 769a2ba5ba32bd77a492647900bc86e5626f89d4..46d25061ee6456a02a2780f5c363788f407981d2 100644 (file)
@@ -86,13 +86,6 @@ static int GetI2CSDA(void)
 #endif
 }
 
-#if 0
-static void SetI2CSDA(int x)
-{
-       rGPEDAT = (rGPEDAT & ~0x8000) | (x & 1) << 15;
-}
-#endif
-
 static void SetI2CSCL(int x)
 {
        struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
@@ -331,7 +324,7 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c,
                        writel(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP,
                               &i2c->iicstat);
                        i = 0;
-                       while ((i < data_len) && (result = I2C_OK)) {
+                       while ((i < data_len) && (result == I2C_OK)) {
                                result = WaitForXfer(i2c);
                                writel(data[i], &i2c->iicds);
                                ReadWriteByte(i2c);
@@ -343,17 +336,16 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c,
                        result = WaitForXfer(i2c);
 
                /* send STOP */
-               writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
+               writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);
                ReadWriteByte(i2c);
                break;
 
        case I2C_READ:
                if (addr && addr_len) {
-                       writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);
                        writel(chip, &i2c->iicds);
                        /* send START */
-                       writel(readl(&i2c->iicstat) | I2C_START_STOP,
-                              &i2c->iicstat);
+                       writel(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP,
+                               &i2c->iicstat);
                        result = WaitForXfer(i2c);
                        if (IsACK(i2c)) {
                                i = 0;
@@ -387,11 +379,10 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c,
                        }
 
                } else {
-                       writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
                        writel(chip, &i2c->iicds);
                        /* send START */
-                       writel(readl(&i2c->iicstat) | I2C_START_STOP,
-                              &i2c->iicstat);
+                       writel(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP,
+                               &i2c->iicstat);
                        result = WaitForXfer(i2c);
 
                        if (IsACK(i2c)) {
index 65791aa218449039439faf578ca0d4e899680f7b..1d6faa2a9249b023e265681086804570855655fe 100644 (file)
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_MXS_MMC) += mxsmmc.o
 COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
 COBJS-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o
 COBJS-$(CONFIG_SDHCI) += sdhci.o
+COBJS-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o
 COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
 COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
new file mode 100644 (file)
index 0000000..54cfabf
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * This code was extracted from:
+ * git://github.com/gonzoua/u-boot-pi.git master
+ * and hence presumably (C) 2012 Oleksandr Tymoshenko
+ *
+ * Tweaks for U-Boot upstreaming
+ * (C) 2012 Stephen Warren
+ *
+ * Portions (e.g. read/write macros, concepts for back-to-back register write
+ * timing workarounds) obviously extracted from the Linux kernel at:
+ * https://github.com/raspberrypi/linux.git rpi-3.6.y
+ *
+ * The Linux kernel code has the following (c) and license, which is hence
+ * propagated to Oleksandr's tree and here:
+ *
+ * Support for SDHCI device on 2835
+ * Based on sdhci-bcm2708.c (c) 2010 Broadcom
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * SDHCI platform device - Arasan SD controller in BCM2708
+ *
+ * Inspired by sdhci-pci.c, by Pierre Ossman
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <sdhci.h>
+#include <asm/arch/timer.h>
+
+/* 400KHz is max freq for card ID etc. Use that as min */
+#define MIN_FREQ 400000
+
+struct bcm2835_sdhci_host {
+       struct sdhci_host host;
+       uint twoticks_delay;
+       ulong last_write;
+};
+
+static inline struct bcm2835_sdhci_host *to_bcm(struct sdhci_host *host)
+{
+       return (struct bcm2835_sdhci_host *)host;
+}
+
+static inline void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val,
+                                               int reg)
+{
+       struct bcm2835_sdhci_host *bcm_host = to_bcm(host);
+
+       /*
+        * The Arasan has a bugette whereby it may lose the content of
+        * successive writes to registers that are within two SD-card clock
+        * cycles of each other (a clock domain crossing problem).
+        * It seems, however, that the data register does not have this problem.
+        * (Which is just as well - otherwise we'd have to nobble the DMA engine
+        * too)
+        */
+       while (get_timer_us(bcm_host->last_write) < bcm_host->twoticks_delay)
+               ;
+
+       writel(val, host->ioaddr + reg);
+       bcm_host->last_write = get_timer_us(0);
+}
+
+static inline u32 bcm2835_sdhci_raw_readl(struct sdhci_host *host, int reg)
+{
+       return readl(host->ioaddr + reg);
+}
+
+static void bcm2835_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+       bcm2835_sdhci_raw_writel(host, val, reg);
+}
+
+static void bcm2835_sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+       static u32 shadow;
+       u32 oldval = (reg == SDHCI_COMMAND) ? shadow :
+               bcm2835_sdhci_raw_readl(host, reg & ~3);
+       u32 word_num = (reg >> 1) & 1;
+       u32 word_shift = word_num * 16;
+       u32 mask = 0xffff << word_shift;
+       u32 newval = (oldval & ~mask) | (val << word_shift);
+
+       if (reg == SDHCI_TRANSFER_MODE)
+               shadow = newval;
+       else
+               bcm2835_sdhci_raw_writel(host, newval, reg & ~3);
+}
+
+static void bcm2835_sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+       u32 oldval = bcm2835_sdhci_raw_readl(host, reg & ~3);
+       u32 byte_num = reg & 3;
+       u32 byte_shift = byte_num * 8;
+       u32 mask = 0xff << byte_shift;
+       u32 newval = (oldval & ~mask) | (val << byte_shift);
+
+       bcm2835_sdhci_raw_writel(host, newval, reg & ~3);
+}
+
+static u32 bcm2835_sdhci_readl(struct sdhci_host *host, int reg)
+{
+       u32 val = bcm2835_sdhci_raw_readl(host, reg);
+
+       return val;
+}
+
+static u16 bcm2835_sdhci_readw(struct sdhci_host *host, int reg)
+{
+       u32 val = bcm2835_sdhci_raw_readl(host, (reg & ~3));
+       u32 word_num = (reg >> 1) & 1;
+       u32 word_shift = word_num * 16;
+       u32 word = (val >> word_shift) & 0xffff;
+
+       return word;
+}
+
+static u8 bcm2835_sdhci_readb(struct sdhci_host *host, int reg)
+{
+       u32 val = bcm2835_sdhci_raw_readl(host, (reg & ~3));
+       u32 byte_num = reg & 3;
+       u32 byte_shift = byte_num * 8;
+       u32 byte = (val >> byte_shift) & 0xff;
+
+       return byte;
+}
+
+static const struct sdhci_ops bcm2835_ops = {
+       .write_l = bcm2835_sdhci_writel,
+       .write_w = bcm2835_sdhci_writew,
+       .write_b = bcm2835_sdhci_writeb,
+       .read_l = bcm2835_sdhci_readl,
+       .read_w = bcm2835_sdhci_readw,
+       .read_b = bcm2835_sdhci_readb,
+};
+
+int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq)
+{
+       struct bcm2835_sdhci_host *bcm_host;
+       struct sdhci_host *host;
+
+       bcm_host = malloc(sizeof(*bcm_host));
+       if (!bcm_host) {
+               printf("sdhci_host malloc fail!\n");
+               return 1;
+       }
+
+       /*
+        * See the comments in bcm2835_sdhci_raw_writel().
+        *
+        * This should probably be dynamically calculated based on the actual
+        * frequency. However, this is the longest we'll have to wait, and
+        * doesn't seem to slow access down too much, so the added complexity
+        * doesn't seem worth it for now.
+        *
+        * 1/MIN_FREQ is (max) time per tick of eMMC clock.
+        * 2/MIN_FREQ is time for two ticks.
+        * Multiply by 1000000 to get uS per two ticks.
+        * +1 for hack rounding.
+        */
+       bcm_host->twoticks_delay = ((2 * 1000000) / MIN_FREQ) + 1;
+       bcm_host->last_write = 0;
+
+       host = &bcm_host->host;
+       host->name = "bcm2835_sdhci";
+       host->ioaddr = (void *)regbase;
+       host->quirks = SDHCI_QUIRK_BROKEN_VOLTAGE | SDHCI_QUIRK_BROKEN_R1B |
+               SDHCI_QUIRK_WAIT_SEND_CMD;
+       host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+       host->ops = &bcm2835_ops;
+
+       host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
+       add_sdhci(host, emmc_freq, MIN_FREQ);
+
+       return 0;
+}
index 7b5fdd9f66ed51445c2588b33a1e6c4ad0961b6f..d732581eb8d9708d6c30019d5f376b9beaea29b2 100644 (file)
@@ -51,8 +51,12 @@ int mmc_getwp(struct mmc *mmc)
 
        wp = board_mmc_getwp(mmc);
 
-       if ((wp < 0) && mmc->getwp)
-               wp = mmc->getwp(mmc);
+       if (wp < 0) {
+               if (mmc->getwp)
+                       wp = mmc->getwp(mmc);
+               else
+                       wp = 0;
+       }
 
        return wp;
 }
@@ -692,8 +696,12 @@ int mmc_getcd(struct mmc *mmc)
 
        cd = board_mmc_getcd(mmc);
 
-       if ((cd < 0) && mmc->getcd)
-               cd = mmc->getcd(mmc);
+       if (cd < 0) {
+               if (mmc->getcd)
+                       cd = mmc->getcd(mmc);
+               else
+                       cd = 1;
+       }
 
        return cd;
 }
index 67cfcc24dc0bd946aae074e2852477e93ecfd13c..166744c3204ff4a8d1701fc37cae80f08f2f39f3 100644 (file)
@@ -593,8 +593,6 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
        mmc->send_cmd = mmc_send_cmd;
        mmc->set_ios = mmc_set_ios;
        mmc->init = mmc_init_setup;
-       mmc->getcd = omap_mmc_getcd;
-       mmc->getwp = omap_mmc_getwp;
        mmc->priv = priv_data;
 
        switch (dev_index) {
@@ -616,7 +614,13 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                return 1;
        }
        priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd");
+       if (priv_data->cd_gpio != -1)
+               mmc->getcd = omap_mmc_getcd;
+
        priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp");
+       if (priv_data->wp_gpio != -1)
+               mmc->getwp = omap_mmc_getwp;
+
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
        mmc->host_caps = (MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
                                MMC_MODE_HC) & ~host_caps_mask;
index daca0ea4f7021aa5138b3395ed3c7bca5e8834c0..1eaea04ad108ac27fe5e4c954eed7fb1221384d2 100644 (file)
@@ -412,9 +412,11 @@ int sdhci_init(struct mmc *mmc)
                        status = sdhci_readl(host, SDHCI_PRESENT_STATE);
        }
 
-       /* Eable all state */
-       sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE);
-       sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE);
+       /* Enable only interrupts served by the SD controller */
+       sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK
+                    , SDHCI_INT_ENABLE);
+       /* Mask all sdhci interrupt sources */
+       sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
 
        return 0;
 }
index cee394ece4b7699bc3932c367f436aeb2debc885..bbf5443ec8af0b7c0c0f4a517dea1a750e6a11e3 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/io.h>
 #include <asm/errno.h>
 #include <asm/arch/mem.h>
+#include <asm/arch/cpu.h>
 #include <asm/arch/omap_gpmc.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/compiler.h>
index 006f6d5d04fcb2258b3014fa41a32bdbadd8fb56..6a92c4b774b41ff85dbb834ccc206e12b8a7017d 100644 (file)
@@ -480,15 +480,13 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
                return NULL;
        }
 
-       asf = malloc(sizeof(struct atmel_spi_flash));
+       asf = spi_flash_alloc(struct atmel_spi_flash, spi, params->name);
        if (!asf) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
        }
 
        asf->params = params;
-       asf->flash.spi = spi;
-       asf->flash.name = params->name;
 
        /* Assuming power-of-two page size initially. */
        page_size = 1 << params->l2_page_size;
@@ -513,7 +511,6 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
                        asf->flash.erase = dataflash_erase_at45;
                        page_size += 1 << (params->l2_page_size - 5);
                } else {
-                       asf->flash.read = spi_flash_cmd_read_fast;
                        asf->flash.write = dataflash_write_p2;
                        asf->flash.erase = dataflash_erase_p2;
                }
@@ -524,9 +521,6 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
 
        case DF_FAMILY_AT26F:
        case DF_FAMILY_AT26DF:
-               asf->flash.read = spi_flash_cmd_read_fast;
-               asf->flash.write = spi_flash_cmd_write_multi;
-               asf->flash.erase = spi_flash_cmd_erase;
                asf->flash.page_size = page_size;
                asf->flash.sector_size = 4096;
                /* clear SPRL# bit for locked flash */
index 691ed4efc4f61096da88314dc202f9c6b9a3f82f..b16e7ab098ea36b7d1146ad7028fe3ec910e2e85 100644 (file)
@@ -46,18 +46,12 @@ struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
                return NULL;
        }
 
-       flash = malloc(sizeof(*flash));
+       flash = spi_flash_alloc_base(spi, params->name);
        if (!flash) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
        }
 
-       flash->spi = spi;
-       flash->name = params->name;
-
-       flash->write = spi_flash_cmd_write_multi;
-       flash->erase = spi_flash_cmd_erase;
-       flash->read = spi_flash_cmd_read_fast;
        flash->page_size = 256;
        flash->sector_size = 256 * 16 * 16;
        flash->size = 256 * 16
index c97a39d49981201aa66178716b1cd457b55b7edc..036c30d3beee54488de1b20b4cedd8b93b2a7d75 100644 (file)
@@ -97,18 +97,12 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
                return NULL;
        }
 
-       flash = malloc(sizeof(*flash));
+       flash = spi_flash_alloc_base(spi, params->name);
        if (!flash) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
        }
 
-       flash->spi = spi;
-       flash->name = params->name;
-
-       flash->write = spi_flash_cmd_write_multi;
-       flash->erase = spi_flash_cmd_erase;
-       flash->read = spi_flash_cmd_read_fast;
        flash->page_size = 256;
        flash->sector_size = 256 * 16 * 16;
        flash->size = flash->sector_size * params->nr_blocks;
index 099978149696968452e2851530687f6b358d2c4f..5299a6dbde09882e1e76ca232442d68dba698237 100644 (file)
@@ -284,15 +284,13 @@ struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
        return NULL;
 
 found:
-       sn = malloc(sizeof(*sn));
+       sn = spi_flash_alloc(struct ramtron_spi_fram, spi, params->name);
        if (!sn) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
        }
 
        sn->params = params;
-       sn->flash.spi = spi;
-       sn->flash.name = params->name;
 
        sn->flash.write = ramtron_write;
        sn->flash.read = ramtron_read;
index 9288672c84cfbfb1ba8b076a03b2c58e54d63ffe..bc558c4c96ba317bffac1a66730bc28c2f49be32 100644 (file)
@@ -128,18 +128,12 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
                return NULL;
        }
 
-       flash = malloc(sizeof(*flash));
+       flash = spi_flash_alloc_base(spi, params->name);
        if (!flash) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
        }
 
-       flash->spi = spi;
-       flash->name = params->name;
-
-       flash->write = spi_flash_cmd_write_multi;
-       flash->erase = spi_flash_cmd_erase;
-       flash->read = spi_flash_cmd_read_fast;
        flash->page_size = 256;
        flash->sector_size = 256 * params->pages_per_sector;
        flash->size = flash->sector_size * params->nr_sectors;
index 00aece9291c398f44ec4db007d7048ac8727b5a3..111185af17586900b7ff447ead1e0ea9d131ecc4 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <fdtdec.h>
 #include <malloc.h>
 #include <spi.h>
 #include <spi_flash.h>
@@ -15,6 +16,8 @@
 
 #include "spi_flash_internal.h"
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static void spi_flash_addr(u32 addr, u8 *cmd)
 {
        /* cmd[0] is actual command */
@@ -87,6 +90,9 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
        for (actual = 0; actual < len; actual += chunk_len) {
                chunk_len = min(len - actual, page_size - byte_addr);
 
+               if (flash->spi->max_write_size)
+                       chunk_len = min(chunk_len, flash->spi->max_write_size);
+
                cmd[1] = page_addr >> 8;
                cmd[2] = page_addr;
                cmd[3] = byte_addr;
@@ -111,8 +117,11 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
                if (ret)
                        break;
 
-               page_addr++;
-               byte_addr = 0;
+               byte_addr += chunk_len;
+               if (byte_addr == page_size) {
+                       page_addr++;
+                       byte_addr = 0;
+               }
        }
 
        debug("SF: program %s %zu bytes @ %#x\n",
@@ -140,6 +149,10 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
 {
        u8 cmd[5];
 
+       /* Handle memory-mapped SPI */
+       if (flash->memory_map)
+               memcpy(data, flash->memory_map + offset, len);
+
        cmd[0] = CMD_READ_ARRAY_FAST;
        spi_flash_addr(offset, cmd);
        cmd[4] = 0x00;
@@ -269,6 +282,34 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr)
        return 0;
 }
 
+#ifdef CONFIG_OF_CONTROL
+int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
+{
+       fdt_addr_t addr;
+       fdt_size_t size;
+       int node;
+
+       /* If there is no node, do nothing */
+       node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
+       if (node < 0)
+               return 0;
+
+       addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
+       if (addr == FDT_ADDR_T_NONE) {
+               debug("%s: Cannot decode address\n", __func__);
+               return 0;
+       }
+
+       if (flash->size != size) {
+               debug("%s: Memory map must cover entire device\n", __func__);
+               return -1;
+       }
+       flash->memory_map = (void *)addr;
+
+       return 0;
+}
+#endif /* CONFIG_OF_CONTROL */
+
 /*
  * The following table holds all device probe functions
  *
@@ -385,9 +426,18 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
                goto err_manufacturer_probe;
        }
 
+#ifdef CONFIG_OF_CONTROL
+       if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
+               debug("SF: FDT decode error\n");
+               goto err_manufacturer_probe;
+       }
+#endif
        printf("SF: Detected %s with page size ", flash->name);
        print_size(flash->sector_size, ", total ");
-       print_size(flash->size, "\n");
+       print_size(flash->size, "");
+       if (flash->memory_map)
+               printf(", mapped at %p", flash->memory_map);
+       puts("\n");
 
        spi_release_bus(spi);
 
@@ -401,6 +451,31 @@ err_claim_bus:
        return NULL;
 }
 
+void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi,
+                        const char *name)
+{
+       struct spi_flash *flash;
+       void *ptr;
+
+       ptr = malloc(size);
+       if (!ptr) {
+               debug("SF: Failed to allocate memory\n");
+               return NULL;
+       }
+       memset(ptr, '\0', size);
+       flash = (struct spi_flash *)(ptr + offset);
+
+       /* Set up some basic fields - caller will sort out sizes */
+       flash->spi = spi;
+       flash->name = name;
+
+       flash->read = spi_flash_cmd_read_fast;
+       flash->write = spi_flash_cmd_write_multi;
+       flash->erase = spi_flash_cmd_erase;
+
+       return flash;
+}
+
 void spi_flash_free(struct spi_flash *flash)
 {
        spi_free_slave(flash->spi);
index ced4f2473f47189c45169638df6b20cb5a500485..95f5490c350ac0f85287b518f1b2427286c30ee3 100644 (file)
@@ -203,22 +203,16 @@ spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode)
                return NULL;
        }
 
-       stm = malloc(sizeof(*stm));
+       stm = spi_flash_alloc(struct sst_spi_flash, spi, params->name);
        if (!stm) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
        }
 
        stm->params = params;
-       stm->flash.spi = spi;
-       stm->flash.name = params->name;
 
        if (stm->params->flags & SST_FEAT_WP)
                stm->flash.write = sst_write_wp;
-       else
-               stm->flash.write = spi_flash_cmd_write_multi;
-       stm->flash.erase = spi_flash_cmd_erase;
-       stm->flash.read = spi_flash_cmd_read_fast;
        stm->flash.page_size = 256;
        stm->flash.sector_size = 4096;
        stm->flash.size = stm->flash.sector_size * params->nr_sectors;
index 8a193449d0cda34b983feed97b4fa4b481321569..2a9972bd4ee519f97c67c7df3e6c0c4ac49fa49d 100644 (file)
@@ -176,18 +176,12 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
                return NULL;
        }
 
-       flash = malloc(sizeof(*flash));
+       flash = spi_flash_alloc_base(spi, params->name);
        if (!flash) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
        }
 
-       flash->spi = spi;
-       flash->name = params->name;
-
-       flash->write = spi_flash_cmd_write_multi;
-       flash->erase = spi_flash_cmd_erase;
-       flash->read = spi_flash_cmd_read_fast;
        flash->page_size = 256;
        flash->sector_size = 256 * params->pages_per_sector;
        flash->size = flash->sector_size * params->nr_sectors;
index 441830216944ef035d233ee72afd8e13b4662e50..27162091c5ac69e4cfe8af4fc7d4f4944391c0a5 100644 (file)
@@ -67,6 +67,11 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
                .nr_blocks              = 128,
                .name                   = "W25Q80",
        },
+       {
+               .id                     = 0x6016,
+               .nr_blocks              = 512,
+               .name                   = "W25Q32DW",
+       },
        {
                .id                     = 0x6017,
                .nr_blocks              = 128,
@@ -92,18 +97,12 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
                return NULL;
        }
 
-       flash = malloc(sizeof(*flash));
+       flash = spi_flash_alloc_base(spi, params->name);
        if (!flash) {
                debug("SF: Failed to allocate memory\n");
                return NULL;
        }
 
-       flash->spi = spi;
-       flash->name = params->name;
-
-       flash->write = spi_flash_cmd_write_multi;
-       flash->erase = spi_flash_cmd_erase;
-       flash->read = spi_flash_cmd_read_fast;
        flash->page_size = 256;
        flash->sector_size = 4096;
        flash->size = 4096 * 16 * params->nr_blocks;
index 93f8417a4ce8efe2e70953a4505cf80131181404..7a36850198f40020ebc33765084f36f734e68b08 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <phy.h>
+#include <asm/arch/cpu.h>
 
 #define BITMASK(bits)          (BIT(bits) - 1)
 #define PHY_REG_MASK           0x1f
index 8c7190156c302b60b9f5b8601bc7e4e7a0594b73..1dac16a9f7da05fc25b19df326f04fe82bb4cd68 100644 (file)
@@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
 
 LIB    := $(obj)libpower.o
 
+COBJS-$(CONFIG_EXYNOS_TMU)     += exynos-tmu.o
 COBJS-$(CONFIG_FTPMU010_POWER) += ftpmu010.o
 COBJS-$(CONFIG_TPS6586X_POWER) += tps6586x.o
 COBJS-$(CONFIG_TWL4030_POWER)  += twl4030.o
diff --git a/drivers/power/exynos-tmu.c b/drivers/power/exynos-tmu.c
new file mode 100644 (file)
index 0000000..d4b3e65
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *      http://www.samsung.com
+ * Akshay Saraswat <akshay.s@samsung.com>
+ *
+ * EXYNOS - Thermal Management Unit
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ * 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 <errno.h>
+#include <fdtdec.h>
+#include <tmu.h>
+#include <asm/arch/tmu.h>
+#include <asm/arch/power.h>
+
+#define TRIMINFO_RELOAD                1
+#define CORE_EN                        1
+#define THERM_TRIP_EN          (1 << 12)
+
+#define INTEN_RISE0            1
+#define INTEN_RISE1            (1 << 4)
+#define INTEN_RISE2            (1 << 8)
+#define INTEN_FALL0            (1 << 16)
+#define INTEN_FALL1            (1 << 20)
+#define INTEN_FALL2            (1 << 24)
+
+#define TRIM_INFO_MASK         0xff
+
+#define INTCLEAR_RISE0         1
+#define INTCLEAR_RISE1         (1 << 4)
+#define INTCLEAR_RISE2         (1 << 8)
+#define INTCLEAR_FALL0         (1 << 16)
+#define INTCLEAR_FALL1         (1 << 20)
+#define INTCLEAR_FALL2         (1 << 24)
+#define INTCLEARALL            (INTCLEAR_RISE0 | INTCLEAR_RISE1 | \
+                                INTCLEAR_RISE2 | INTCLEAR_FALL0 | \
+                                INTCLEAR_FALL1 | INTCLEAR_FALL2)
+
+/* Tmeperature threshold values for various thermal events */
+struct temperature_params {
+       /* minimum value in temperature code range */
+       unsigned int min_val;
+       /* maximum value in temperature code range */
+       unsigned int max_val;
+       /* temperature threshold to start warning */
+       unsigned int start_warning;
+       /* temperature threshold CPU tripping */
+       unsigned int start_tripping;
+       /* temperature threshold for HW tripping */
+       unsigned int hardware_tripping;
+};
+
+/* Pre-defined values and thresholds for calibration of current temperature */
+struct tmu_data {
+       /* pre-defined temperature thresholds */
+       struct temperature_params ts;
+       /* pre-defined efuse range minimum value */
+       unsigned int efuse_min_value;
+       /* pre-defined efuse value for temperature calibration */
+       unsigned int efuse_value;
+       /* pre-defined efuse range maximum value */
+       unsigned int efuse_max_value;
+       /* current temperature sensing slope */
+       unsigned int slope;
+};
+
+/* TMU device specific details and status */
+struct tmu_info {
+       /* base Address for the TMU */
+       unsigned tmu_base;
+       /* pre-defined values for calibration and thresholds */
+       struct tmu_data data;
+       /* value required for triminfo_25 calibration */
+       unsigned int te1;
+       /* value required for triminfo_85 calibration */
+       unsigned int te2;
+       /* Value for measured data calibration */
+       int dc_value;
+       /* enum value indicating status of the TMU */
+       int tmu_state;
+};
+
+/* Global struct tmu_info variable to store init values */
+static struct tmu_info gbl_info;
+
+/*
+ * Get current temperature code from register,
+ * then calculate and calibrate it's value
+ * in degree celsius.
+ *
+ * @return     current temperature of the chip as sensed by TMU
+ */
+static int get_cur_temp(struct tmu_info *info)
+{
+       int cur_temp;
+       struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base;
+
+       /*
+        * Temperature code range between min 25 and max 125.
+        * May run more than once for first call as initial sensing
+        * has not yet happened.
+        */
+       do {
+               cur_temp = readl(&reg->current_temp) & 0xff;
+       } while (cur_temp == 0 && info->tmu_state == TMU_STATUS_NORMAL);
+
+       /* Calibrate current temperature */
+       cur_temp = cur_temp - info->te1 + info->dc_value;
+
+       return cur_temp;
+}
+
+/*
+ * Monitors status of the TMU device and exynos temperature
+ *
+ * @param temp pointer to the current temperature value
+ * @return     enum tmu_status_t value, code indicating event to execute
+ */
+enum tmu_status_t tmu_monitor(int *temp)
+{
+       int cur_temp;
+       struct tmu_data *data = &gbl_info.data;
+
+       if (gbl_info.tmu_state == TMU_STATUS_INIT)
+               return TMU_STATUS_INIT;
+
+       /* Read current temperature of the SOC */
+       cur_temp = get_cur_temp(&gbl_info);
+       *temp = cur_temp;
+
+       /* Temperature code lies between min 25 and max 125 */
+       if (cur_temp >= data->ts.start_tripping &&
+                       cur_temp <= data->ts.max_val) {
+               return TMU_STATUS_TRIPPED;
+       } else if (cur_temp >= data->ts.start_warning) {
+               return TMU_STATUS_WARNING;
+       } else if (cur_temp < data->ts.start_warning &&
+                       cur_temp >= data->ts.min_val) {
+               return TMU_STATUS_NORMAL;
+       } else {
+               /* Temperature code does not lie between min 25 and max 125 */
+               gbl_info.tmu_state = TMU_STATUS_INIT;
+               debug("EXYNOS_TMU: Thermal reading failed\n");
+               return TMU_STATUS_INIT;
+       }
+}
+
+/*
+ * Get TMU specific pre-defined values from FDT
+ *
+ * @param info pointer to the tmu_info struct
+ * @param blob  FDT blob
+ * @return     int value, 0 for success
+ */
+static int get_tmu_fdt_values(struct tmu_info *info, const void *blob)
+{
+#ifdef CONFIG_OF_CONTROL
+       int node;
+       int error = 0;
+
+       /* Get the node from FDT for TMU */
+       node = fdtdec_next_compatible(blob, 0,
+                                     COMPAT_SAMSUNG_EXYNOS_TMU);
+       if (node < 0) {
+               debug("EXYNOS_TMU: No node for tmu in device tree\n");
+               return -1;
+       }
+
+       /*
+        * Get the pre-defined TMU specific values from FDT.
+        * All of these are expected to be correct otherwise
+        * miscalculation of register values in tmu_setup_parameters
+        * may result in misleading current temperature.
+        */
+       info->tmu_base = fdtdec_get_addr(blob, node, "reg");
+       if (info->tmu_base == FDT_ADDR_T_NONE) {
+               debug("%s: Missing tmu-base\n", __func__);
+               return -1;
+       }
+       info->data.ts.min_val = fdtdec_get_int(blob,
+                               node, "samsung,min-temp", -1);
+       error |= info->data.ts.min_val;
+       info->data.ts.max_val = fdtdec_get_int(blob,
+                               node, "samsung,max-temp", -1);
+       error |= info->data.ts.max_val;
+       info->data.ts.start_warning = fdtdec_get_int(blob,
+                               node, "samsung,start-warning", -1);
+       error |= info->data.ts.start_warning;
+       info->data.ts.start_tripping = fdtdec_get_int(blob,
+                               node, "samsung,start-tripping", -1);
+       error |= info->data.ts.start_tripping;
+       info->data.ts.hardware_tripping = fdtdec_get_int(blob,
+                               node, "samsung,hw-tripping", -1);
+       error |= info->data.ts.hardware_tripping;
+       info->data.efuse_min_value = fdtdec_get_int(blob,
+                               node, "samsung,efuse-min-value", -1);
+       error |= info->data.efuse_min_value;
+       info->data.efuse_value = fdtdec_get_int(blob,
+                               node, "samsung,efuse-value", -1);
+       error |= info->data.efuse_value;
+       info->data.efuse_max_value = fdtdec_get_int(blob,
+                               node, "samsung,efuse-max-value", -1);
+       error |= info->data.efuse_max_value;
+       info->data.slope = fdtdec_get_int(blob,
+                               node, "samsung,slope", -1);
+       error |= info->data.slope;
+       info->dc_value = fdtdec_get_int(blob,
+                               node, "samsung,dc-value", -1);
+       error |= info->dc_value;
+
+       if (error == -1) {
+               debug("fail to get tmu node properties\n");
+               return -1;
+       }
+#endif
+
+       return 0;
+}
+
+/*
+ * Calibrate and calculate threshold values and
+ * enable interrupt levels
+ *
+ * @param      info pointer to the tmu_info struct
+ */
+static void tmu_setup_parameters(struct tmu_info *info)
+{
+       unsigned int te_code, con;
+       unsigned int warning_code, trip_code, hwtrip_code;
+       unsigned int cooling_temp;
+       unsigned int rising_value;
+       struct tmu_data *data = &info->data;
+       struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base;
+
+       /* Must reload for reading efuse value from triminfo register */
+       writel(TRIMINFO_RELOAD, &reg->triminfo_control);
+
+       /* Get the compensation parameter */
+       te_code = readl(&reg->triminfo);
+       info->te1 = te_code & TRIM_INFO_MASK;
+       info->te2 = ((te_code >> 8) & TRIM_INFO_MASK);
+
+       if ((data->efuse_min_value > info->te1) ||
+                       (info->te1 > data->efuse_max_value)
+                       ||  (info->te2 != 0))
+               info->te1 = data->efuse_value;
+
+       /* Get RISING & FALLING Threshold value */
+       warning_code = data->ts.start_warning
+                       + info->te1 - info->dc_value;
+       trip_code = data->ts.start_tripping
+                       + info->te1 - info->dc_value;
+       hwtrip_code = data->ts.hardware_tripping
+                       + info->te1 - info->dc_value;
+
+       cooling_temp = 0;
+
+       rising_value = ((warning_code << 8) |
+                       (trip_code << 16) |
+                       (hwtrip_code << 24));
+
+       /* Set interrupt level */
+       writel(rising_value, &reg->threshold_temp_rise);
+       writel(cooling_temp, &reg->threshold_temp_fall);
+
+       /*
+        * Init TMU control tuning parameters
+        * [28:24] VREF - Voltage reference
+        * [15:13] THERM_TRIP_MODE - Tripping mode
+        * [12] THERM_TRIP_EN - Thermal tripping enable
+        * [11:8] BUF_SLOPE_SEL - Gain of amplifier
+        * [6] THERM_TRIP_BY_TQ_EN - Tripping by TQ pin
+        */
+       writel(data->slope, &reg->tmu_control);
+
+       writel(INTCLEARALL, &reg->intclear);
+
+       /* TMU core enable */
+       con = readl(&reg->tmu_control);
+       con |= THERM_TRIP_EN | CORE_EN;
+
+       writel(con, &reg->tmu_control);
+
+       /* Enable HW thermal trip */
+       set_hw_thermal_trip();
+
+       /* LEV1 LEV2 interrupt enable */
+       writel(INTEN_RISE1 | INTEN_RISE2, &reg->inten);
+}
+
+/*
+ * Initialize TMU device
+ *
+ * @param blob  FDT blob
+ * @return     int value, 0 for success
+ */
+int tmu_init(const void *blob)
+{
+       gbl_info.tmu_state = TMU_STATUS_INIT;
+       if (get_tmu_fdt_values(&gbl_info, blob) < 0)
+               goto ret;
+
+       tmu_setup_parameters(&gbl_info);
+       gbl_info.tmu_state = TMU_STATUS_NORMAL;
+ret:
+
+       return gbl_info.tmu_state;
+}
index e2858232d0528bce144a192cf7865291f5dcfb89..3af2623eb8b17e7406a0f2b7c20cb41669ab885b 100644 (file)
@@ -49,20 +49,6 @@ static void rtc_write (short reg, uchar val)
        out8(RTC_PORT_DATA, val);
 }
 
-#elif defined(CONFIG_PCIPPC2)
-
-#include "../board/pcippc2/pcippc2.h"
-
-static uchar rtc_read (short reg)
-{
-       return in8(RTC(reg));
-}
-
-static void rtc_write (short reg, uchar val)
-{
-       out8(RTC(reg),val);
-}
-
 #elif defined(CONFIG_EVAL5200)
 
 static uchar rtc_read (short reg)
index 87a09170864242b262c338dc72670cc46b9e9d97..ed4e6b3a1fdc6822491b1b2a7b641afe5967d36d 100644 (file)
@@ -43,10 +43,10 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
 
        serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
 #if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
-                                       defined(CONFIG_AM33XX)
+                       defined(CONFIG_AM33XX) || defined(CONFIG_TI814X)
        serial_out(0x7, &com_port->mdr1);       /* mode select reset TL16C750*/
 #endif
-       serial_out(UART_LCR_BKSE | UART_LCRVAL, (ulong)&com_port->lcr);
+       serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
        serial_out(0, &com_port->dll);
        serial_out(0, &com_port->dlm);
        serial_out(UART_LCRVAL, &com_port->lcr);
@@ -57,7 +57,8 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
        serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
        serial_out(UART_LCRVAL, &com_port->lcr);
 #if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
-       defined(CONFIG_AM33XX) || defined(CONFIG_SOC_DA8XX)
+       defined(CONFIG_AM33XX) || defined(CONFIG_SOC_DA8XX) || \
+       defined(CONFIG_TI814X)
 
 #if defined(CONFIG_APTIX)
        /* /13 mode so Aptix 6MHz can hit 115200 */
index e47cb9a9e724bbb560a3b0f42f0c844dd0bcb867..148d1a6ddd3b17cac525ec7ed48d053b2d0329ae 100644 (file)
@@ -63,7 +63,7 @@
 /*
  * Buffers to hold input and output data
  */
-#define USBTTY_BUFFER_SIZE 256
+#define USBTTY_BUFFER_SIZE 2048
 static circbuf_t usbtty_input;
 static circbuf_t usbtty_output;
 
index 8fdffb10effd76782703716aab176119e39dc9af..1987ca1a05b4831dfb02660552c41e3bb49a143b 100644 (file)
@@ -28,6 +28,7 @@ LIB   := $(obj)libsound.o
 COBJS-$(CONFIG_SOUND)  += sound.o
 COBJS-$(CONFIG_I2S)    += samsung-i2s.o
 COBJS-$(CONFIG_SOUND_WM8994)   += wm8994.o
+COBJS-$(CONFIG_SOUND_MAX98095) += max98095.o
 
 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/sound/max98095.c b/drivers/sound/max98095.c
new file mode 100644 (file)
index 0000000..d69db58
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+ * max98095.c -- MAX98095 ALSA SoC Audio driver
+ *
+ * Copyright 2011 Maxim Integrated Products
+ *
+ * Modified for uboot by R. Chandrasekar (rcsekar@samsung.com)
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+#include <asm/arch/clk.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/power.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <common.h>
+#include <div64.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <sound.h>
+#include "i2s.h"
+#include "max98095.h"
+
+enum max98095_type {
+       MAX98095,
+};
+
+struct max98095_priv {
+       enum max98095_type devtype;
+       unsigned int sysclk;
+       unsigned int rate;
+       unsigned int fmt;
+};
+
+static struct sound_codec_info g_codec_info;
+struct max98095_priv g_max98095_info;
+unsigned int g_max98095_i2c_dev_addr;
+
+/* Index 0 is reserved. */
+int rate_table[] = {0, 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
+               88200, 96000};
+
+/*
+ * Writes value to a device register through i2c
+ *
+ * @param reg  reg number to be write
+ * @param data data to be writen to the above registor
+ *
+ * @return     int value 1 for change, 0 for no change or negative error code.
+ */
+static int max98095_i2c_write(unsigned int reg, unsigned char data)
+{
+       debug("%s: Write Addr : 0x%02X, Data :  0x%02X\n",
+               __func__, reg, data);
+       return i2c_write(g_max98095_i2c_dev_addr, reg, 1, &data, 1);
+}
+
+/*
+ * Read a value from a device register through i2c
+ *
+ * @param reg  reg number to be read
+ * @param data address of read data to be stored
+ *
+ * @return     int value 0 for success, -1 in case of error.
+ */
+static unsigned int max98095_i2c_read(unsigned int reg, unsigned char *data)
+{
+       int ret;
+
+       ret = i2c_read(g_max98095_i2c_dev_addr, reg, 1, data, 1);
+       if (ret != 0) {
+               debug("%s: Error while reading register %#04x\n",
+                       __func__, reg);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+ * update device register bits through i2c
+ *
+ * @param reg  codec register
+ * @param mask register mask
+ * @param value        new value
+ *
+ * @return int value 0 for success, non-zero error code.
+ */
+static int max98095_update_bits(unsigned int reg, unsigned char mask,
+                               unsigned char value)
+{
+       int change, ret = 0;
+       unsigned char old, new;
+
+       if (max98095_i2c_read(reg, &old) != 0)
+               return -1;
+       new = (old & ~mask) | (value & mask);
+       change  = (old != new) ? 1 : 0;
+       if (change)
+               ret = max98095_i2c_write(reg, new);
+       if (ret < 0)
+               return ret;
+
+       return change;
+}
+
+/*
+ * codec mclk clock divider coefficients based on sampling rate
+ *
+ * @param rate sampling rate
+ * @param value address of indexvalue to be stored
+ *
+ * @return     0 for success or negative error code.
+ */
+static int rate_value(int rate, u8 *value)
+{
+       int i;
+
+       for (i = 1; i < ARRAY_SIZE(rate_table); i++) {
+               if (rate_table[i] >= rate) {
+                       *value = i;
+                       return 0;
+               }
+       }
+       *value = 1;
+
+       return -1;
+}
+
+/*
+ * Sets hw params for max98095
+ *
+ * @param max98095     max98095 information pointer
+ * @param rate         Sampling rate
+ * @param bits_per_sample      Bits per sample
+ *
+ * @return -1 for error  and 0  Success.
+ */
+static int max98095_hw_params(struct max98095_priv *max98095,
+               unsigned int rate, unsigned int bits_per_sample)
+{
+       u8 regval;
+       int error;
+
+       switch (bits_per_sample) {
+       case 16:
+               error = max98095_update_bits(M98095_034_DAI2_FORMAT,
+                       M98095_DAI_WS, 0);
+               break;
+       case 24:
+               error = max98095_update_bits(M98095_034_DAI2_FORMAT,
+                       M98095_DAI_WS, M98095_DAI_WS);
+               break;
+       default:
+               debug("%s: Illegal bits per sample %d.\n",
+                       __func__, bits_per_sample);
+               return -1;
+       }
+
+       if (rate_value(rate, &regval)) {
+               debug("%s: Failed to set sample rate to %d.\n",
+                       __func__, rate);
+               return -1;
+       }
+       max98095->rate = rate;
+
+       error |= max98095_update_bits(M98095_031_DAI2_CLKMODE,
+               M98095_CLKMODE_MASK, regval);
+
+       /* Update sample rate mode */
+       if (rate < 50000)
+               error |= max98095_update_bits(M98095_038_DAI2_FILTERS,
+                       M98095_DAI_DHF, 0);
+       else
+               error |= max98095_update_bits(M98095_038_DAI2_FILTERS,
+                       M98095_DAI_DHF, M98095_DAI_DHF);
+
+       if (error < 0) {
+               debug("%s: Error setting hardware params.\n", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+ * Configures Audio interface system clock for the given frequency
+ *
+ * @param max98095     max98095 information
+ * @param freq         Sampling frequency in Hz
+ *
+ * @return -1 for error and 0 success.
+ */
+static int max98095_set_sysclk(struct max98095_priv *max98095,
+                               unsigned int freq)
+{
+       int error = 0;
+
+       /* Requested clock frequency is already setup */
+       if (freq == max98095->sysclk)
+               return 0;
+
+       /* Setup clocks for slave mode, and using the PLL
+        * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
+        *      0x02 (when master clk is 20MHz to 40MHz)..
+        *      0x03 (when master clk is 40MHz to 60MHz)..
+        */
+       if ((freq >= 10000000) && (freq < 20000000)) {
+               error = max98095_i2c_write(M98095_026_SYS_CLK, 0x10);
+       } else if ((freq >= 20000000) && (freq < 40000000)) {
+               error = max98095_i2c_write(M98095_026_SYS_CLK, 0x20);
+       } else if ((freq >= 40000000) && (freq < 60000000)) {
+               error = max98095_i2c_write(M98095_026_SYS_CLK, 0x30);
+       } else {
+               debug("%s: Invalid master clock frequency\n", __func__);
+               return -1;
+       }
+
+       debug("%s: Clock at %uHz\n", __func__, freq);
+
+       if (error < 0)
+               return -1;
+
+       max98095->sysclk = freq;
+       return 0;
+}
+
+/*
+ * Sets Max98095 I2S format
+ *
+ * @param max98095     max98095 information
+ * @param fmt          i2S format - supports a subset of the options defined
+ *                     in i2s.h.
+ *
+ * @return -1 for error and 0  Success.
+ */
+static int max98095_set_fmt(struct max98095_priv *max98095, int fmt)
+{
+       u8 regval = 0;
+       int error = 0;
+
+       if (fmt == max98095->fmt)
+               return 0;
+
+       max98095->fmt = fmt;
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               /* Slave mode PLL */
+               error |= max98095_i2c_write(M98095_032_DAI2_CLKCFG_HI,
+                                       0x80);
+               error |= max98095_i2c_write(M98095_033_DAI2_CLKCFG_LO,
+                                       0x00);
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM:
+               /* Set to master mode */
+               regval |= M98095_DAI_MAS;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFM:
+       case SND_SOC_DAIFMT_CBM_CFS:
+       default:
+               debug("%s: Clock mode unsupported\n", __func__);
+               return -1;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               regval |= M98095_DAI_DLY;
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               break;
+       default:
+               debug("%s: Unrecognized format.\n", __func__);
+               return -1;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               regval |= M98095_DAI_WCI;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               regval |= M98095_DAI_BCI;
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               regval |= M98095_DAI_BCI | M98095_DAI_WCI;
+               break;
+       default:
+               debug("%s: Unrecognized inversion settings.\n", __func__);
+               return -1;
+       }
+
+       error |= max98095_update_bits(M98095_034_DAI2_FORMAT,
+               M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
+               M98095_DAI_WCI, regval);
+
+       error |= max98095_i2c_write(M98095_035_DAI2_CLOCK,
+               M98095_DAI_BSEL64);
+
+       if (error < 0) {
+               debug("%s: Error setting i2s format.\n", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+ * resets the audio codec
+ *
+ * @return -1 for error and 0 success.
+ */
+static int max98095_reset(void)
+{
+       int i, ret;
+
+       /*
+        * Gracefully reset the DSP core and the codec hardware in a proper
+        * sequence.
+        */
+       ret = max98095_i2c_write(M98095_00F_HOST_CFG, 0);
+       if (ret != 0) {
+               debug("%s: Failed to reset DSP: %d\n", __func__, ret);
+               return ret;
+       }
+
+       ret = max98095_i2c_write(M98095_097_PWR_SYS, 0);
+       if (ret != 0) {
+               debug("%s: Failed to reset codec: %d\n", __func__, ret);
+               return ret;
+       }
+
+       /*
+        * Reset to hardware default for registers, as there is not a soft
+        * reset hardware control register.
+        */
+       for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
+               ret = max98095_i2c_write(i, 0);
+               if (ret < 0) {
+                       debug("%s: Failed to reset: %d\n", __func__, ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Intialise max98095 codec device
+ *
+ * @param max98095     max98095 information
+ *
+ * @returns -1 for error  and 0 Success.
+ */
+static int max98095_device_init(struct max98095_priv *max98095)
+{
+       unsigned char id;
+       int error = 0;
+
+       /* reset the codec, the DSP core, and disable all interrupts */
+       error = max98095_reset();
+       if (error != 0) {
+               debug("Reset\n");
+               return error;
+       }
+
+       /* initialize private data */
+       max98095->sysclk = -1U;
+       max98095->rate = -1U;
+       max98095->fmt = -1U;
+
+       error = max98095_i2c_read(M98095_0FF_REV_ID, &id);
+       if (error < 0) {
+               debug("%s: Failure reading hardware revision: %d\n",
+                       __func__, id);
+               goto err_access;
+       }
+       debug("%s: Hardware revision: %c\n", __func__, (id - 0x40) + 'A');
+
+       error |= max98095_i2c_write(M98095_097_PWR_SYS, M98095_PWRSV);
+
+       /*
+        * initialize registers to hardware default configuring audio
+        * interface2 to DAC
+        */
+       error |= max98095_i2c_write(M98095_048_MIX_DAC_LR,
+               M98095_DAI2M_TO_DACL|M98095_DAI2M_TO_DACR);
+
+       error |= max98095_i2c_write(M98095_092_PWR_EN_OUT,
+                       M98095_SPK_SPREADSPECTRUM);
+       error |= max98095_i2c_write(M98095_045_CFG_DSP, M98095_DSPNORMAL);
+       error |= max98095_i2c_write(M98095_04E_CFG_HP, M98095_HPNORMAL);
+
+       error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG,
+                       M98095_S1NORMAL|M98095_SDATA);
+
+       error |= max98095_i2c_write(M98095_036_DAI2_IOCFG,
+                       M98095_S2NORMAL|M98095_SDATA);
+
+       error |= max98095_i2c_write(M98095_040_DAI3_IOCFG,
+                       M98095_S3NORMAL|M98095_SDATA);
+
+       /* take the codec out of the shut down */
+       error |= max98095_update_bits(M98095_097_PWR_SYS, M98095_SHDNRUN,
+                       M98095_SHDNRUN);
+       /* route DACL and DACR output to HO and Spekers */
+       error |= max98095_i2c_write(M98095_050_MIX_SPK_LEFT, 0x01); /* DACL */
+       error |= max98095_i2c_write(M98095_051_MIX_SPK_RIGHT, 0x01);/* DACR */
+       error |= max98095_i2c_write(M98095_04C_MIX_HP_LEFT, 0x01);  /* DACL */
+       error |= max98095_i2c_write(M98095_04D_MIX_HP_RIGHT, 0x01); /* DACR */
+
+       /* power Enable */
+       error |= max98095_i2c_write(M98095_091_PWR_EN_OUT, 0xF3);
+
+       /* set Volume */
+       error |= max98095_i2c_write(M98095_064_LVL_HP_L, 15);
+       error |= max98095_i2c_write(M98095_065_LVL_HP_R, 15);
+       error |= max98095_i2c_write(M98095_067_LVL_SPK_L, 16);
+       error |= max98095_i2c_write(M98095_068_LVL_SPK_R, 16);
+
+       /* Enable DAIs */
+       error |= max98095_i2c_write(M98095_093_BIAS_CTRL, 0x30);
+       error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07);
+
+err_access:
+       if (error < 0)
+               return -1;
+
+       return 0;
+}
+
+static int max98095_do_init(struct sound_codec_info *pcodec_info,
+                       int sampling_rate, int mclk_freq,
+                       int bits_per_sample)
+{
+       int ret = 0;
+
+       /* Enable codec clock */
+       set_xclkout();
+
+       /* shift the device address by 1 for 7 bit addressing */
+       g_max98095_i2c_dev_addr = pcodec_info->i2c_dev_addr >> 1;
+
+       if (pcodec_info->codec_type == CODEC_MAX_98095)
+               g_max98095_info.devtype = MAX98095;
+       else {
+               debug("%s: Codec id [%d] not defined\n", __func__,
+                               pcodec_info->codec_type);
+               return -1;
+       }
+
+       ret = max98095_device_init(&g_max98095_info);
+       if (ret < 0) {
+               debug("%s: max98095 codec chip init failed\n", __func__);
+               return ret;
+       }
+
+       ret = max98095_set_sysclk(&g_max98095_info, mclk_freq);
+       if (ret < 0) {
+               debug("%s: max98095 codec set sys clock failed\n", __func__);
+               return ret;
+       }
+
+       ret = max98095_hw_params(&g_max98095_info, sampling_rate,
+                               bits_per_sample);
+
+       if (ret == 0) {
+               ret = max98095_set_fmt(&g_max98095_info,
+                                       SND_SOC_DAIFMT_I2S |
+                                       SND_SOC_DAIFMT_NB_NF |
+                                       SND_SOC_DAIFMT_CBS_CFS);
+       }
+
+       return ret;
+}
+
+static int get_max98095_codec_values(struct sound_codec_info *pcodec_info,
+                               const void *blob)
+{
+       int error = 0;
+#ifdef CONFIG_OF_CONTROL
+       enum fdt_compat_id compat;
+       int node;
+       int parent;
+
+       /* Get the node from FDT for codec */
+       node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_98095_CODEC);
+       if (node <= 0) {
+               debug("EXYNOS_SOUND: No node for codec in device tree\n");
+               debug("node = %d\n", node);
+               return -1;
+       }
+
+       parent = fdt_parent_offset(blob, node);
+       if (parent < 0) {
+               debug("%s: Cannot find node parent\n", __func__);
+               return -1;
+       }
+
+       compat = fdtdec_lookup(blob, parent);
+       switch (compat) {
+       case COMPAT_SAMSUNG_S3C2440_I2C:
+               pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent);
+               error |= pcodec_info->i2c_bus;
+               debug("i2c bus = %d\n", pcodec_info->i2c_bus);
+               pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node,
+                                                       "reg", 0);
+               error |= pcodec_info->i2c_dev_addr;
+               debug("i2c dev addr = %x\n", pcodec_info->i2c_dev_addr);
+               break;
+       default:
+               debug("%s: Unknown compat id %d\n", __func__, compat);
+               return -1;
+       }
+#else
+       pcodec_info->i2c_bus = AUDIO_I2C_BUS;
+       pcodec_info->i2c_dev_addr = AUDIO_I2C_REG;
+       debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr);
+#endif
+       pcodec_info->codec_type = CODEC_MAX_98095;
+       if (error == -1) {
+               debug("fail to get max98095 codec node properties\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+/* max98095 Device Initialisation */
+int max98095_init(const void *blob, int sampling_rate, int mclk_freq,
+                       int bits_per_sample)
+{
+       int ret;
+       int old_bus = i2c_get_bus_num();
+       struct sound_codec_info *pcodec_info = &g_codec_info;
+
+       if (get_max98095_codec_values(pcodec_info, blob) < 0) {
+               debug("FDT Codec values failed\n");
+                return -1;
+       }
+
+       i2c_set_bus_num(pcodec_info->i2c_bus);
+       ret = max98095_do_init(pcodec_info, sampling_rate, mclk_freq,
+                               bits_per_sample);
+       i2c_set_bus_num(old_bus);
+
+       return ret;
+}
diff --git a/drivers/sound/max98095.h b/drivers/sound/max98095.h
new file mode 100644 (file)
index 0000000..ae5eb14
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * max98095.h -- MAX98095 ALSA SoC Audio driver
+ *
+ * Copyright 2011 Maxim Integrated Products
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _MAX98095_H
+#define _MAX98095_H
+
+/*
+ * MAX98095 Registers Definition
+ */
+
+#define M98095_000_HOST_DATA           0x00
+#define M98095_001_HOST_INT_STS                0x01
+#define M98095_002_HOST_RSP_STS                0x02
+#define M98095_003_HOST_CMD_STS                0x03
+#define M98095_004_CODEC_STS           0x04
+#define M98095_005_DAI1_ALC_STS                0x05
+#define M98095_006_DAI2_ALC_STS                0x06
+#define M98095_007_JACK_AUTO_STS       0x07
+#define M98095_008_JACK_MANUAL_STS     0x08
+#define M98095_009_JACK_VBAT_STS       0x09
+#define M98095_00A_ACC_ADC_STS         0x0A
+#define M98095_00B_MIC_NG_AGC_STS      0x0B
+#define M98095_00C_SPK_L_VOLT_STS      0x0C
+#define M98095_00D_SPK_R_VOLT_STS      0x0D
+#define M98095_00E_TEMP_SENSOR_STS     0x0E
+#define M98095_00F_HOST_CFG            0x0F
+#define M98095_010_HOST_INT_CFG                0x10
+#define M98095_011_HOST_INT_EN         0x11
+#define M98095_012_CODEC_INT_EN                0x12
+#define M98095_013_JACK_INT_EN         0x13
+#define M98095_014_JACK_INT_EN         0x14
+#define M98095_015_DEC                 0x15
+#define M98095_016_RESERVED            0x16
+#define M98095_017_RESERVED            0x17
+#define M98095_018_KEYCODE3            0x18
+#define M98095_019_KEYCODE2            0x19
+#define M98095_01A_KEYCODE1            0x1A
+#define M98095_01B_KEYCODE0            0x1B
+#define M98095_01C_OEMCODE1            0x1C
+#define M98095_01D_OEMCODE0            0x1D
+#define M98095_01E_XCFG1               0x1E
+#define M98095_01F_XCFG2               0x1F
+#define M98095_020_XCFG3               0x20
+#define M98095_021_XCFG4               0x21
+#define M98095_022_XCFG5               0x22
+#define M98095_023_XCFG6               0x23
+#define M98095_024_XGPIO               0x24
+#define M98095_025_XCLKCFG             0x25
+#define M98095_026_SYS_CLK             0x26
+#define M98095_027_DAI1_CLKMODE                0x27
+#define M98095_028_DAI1_CLKCFG_HI      0x28
+#define M98095_029_DAI1_CLKCFG_LO      0x29
+#define M98095_02A_DAI1_FORMAT         0x2A
+#define M98095_02B_DAI1_CLOCK          0x2B
+#define M98095_02C_DAI1_IOCFG          0x2C
+#define M98095_02D_DAI1_TDM            0x2D
+#define M98095_02E_DAI1_FILTERS                0x2E
+#define M98095_02F_DAI1_LVL1           0x2F
+#define M98095_030_DAI1_LVL2           0x30
+#define M98095_031_DAI2_CLKMODE                0x31
+#define M98095_032_DAI2_CLKCFG_HI      0x32
+#define M98095_033_DAI2_CLKCFG_LO      0x33
+#define M98095_034_DAI2_FORMAT         0x34
+#define M98095_035_DAI2_CLOCK          0x35
+#define M98095_036_DAI2_IOCFG          0x36
+#define M98095_037_DAI2_TDM            0x37
+#define M98095_038_DAI2_FILTERS                0x38
+#define M98095_039_DAI2_LVL1           0x39
+#define M98095_03A_DAI2_LVL2           0x3A
+#define M98095_03B_DAI3_CLKMODE                0x3B
+#define M98095_03C_DAI3_CLKCFG_HI      0x3C
+#define M98095_03D_DAI3_CLKCFG_LO      0x3D
+#define M98095_03E_DAI3_FORMAT         0x3E
+#define M98095_03F_DAI3_CLOCK          0x3F
+#define M98095_040_DAI3_IOCFG          0x40
+#define M98095_041_DAI3_TDM            0x41
+#define M98095_042_DAI3_FILTERS                0x42
+#define M98095_043_DAI3_LVL1           0x43
+#define M98095_044_DAI3_LVL2           0x44
+#define M98095_045_CFG_DSP             0x45
+#define M98095_046_DAC_CTRL1           0x46
+#define M98095_047_DAC_CTRL2           0x47
+#define M98095_048_MIX_DAC_LR          0x48
+#define M98095_049_MIX_DAC_M           0x49
+#define M98095_04A_MIX_ADC_LEFT                0x4A
+#define M98095_04B_MIX_ADC_RIGHT       0x4B
+#define M98095_04C_MIX_HP_LEFT         0x4C
+#define M98095_04D_MIX_HP_RIGHT                0x4D
+#define M98095_04E_CFG_HP              0x4E
+#define M98095_04F_MIX_RCV             0x4F
+#define M98095_050_MIX_SPK_LEFT                0x50
+#define M98095_051_MIX_SPK_RIGHT       0x51
+#define M98095_052_MIX_SPK_CFG         0x52
+#define M98095_053_MIX_LINEOUT1                0x53
+#define M98095_054_MIX_LINEOUT2                0x54
+#define M98095_055_MIX_LINEOUT_CFG     0x55
+#define M98095_056_LVL_SIDETONE_DAI12  0x56
+#define M98095_057_LVL_SIDETONE_DAI3   0x57
+#define M98095_058_LVL_DAI1_PLAY       0x58
+#define M98095_059_LVL_DAI1_EQ         0x59
+#define M98095_05A_LVL_DAI2_PLAY       0x5A
+#define M98095_05B_LVL_DAI2_EQ         0x5B
+#define M98095_05C_LVL_DAI3_PLAY       0x5C
+#define M98095_05D_LVL_ADC_L           0x5D
+#define M98095_05E_LVL_ADC_R           0x5E
+#define M98095_05F_LVL_MIC1            0x5F
+#define M98095_060_LVL_MIC2            0x60
+#define M98095_061_LVL_LINEIN          0x61
+#define M98095_062_LVL_LINEOUT1                0x62
+#define M98095_063_LVL_LINEOUT2                0x63
+#define M98095_064_LVL_HP_L            0x64
+#define M98095_065_LVL_HP_R            0x65
+#define M98095_066_LVL_RCV             0x66
+#define M98095_067_LVL_SPK_L           0x67
+#define M98095_068_LVL_SPK_R           0x68
+#define M98095_069_MICAGC_CFG          0x69
+#define M98095_06A_MICAGC_THRESH       0x6A
+#define M98095_06B_SPK_NOISEGATE       0x6B
+#define M98095_06C_DAI1_ALC1_TIME      0x6C
+#define M98095_06D_DAI1_ALC1_COMP      0x6D
+#define M98095_06E_DAI1_ALC1_EXPN      0x6E
+#define M98095_06F_DAI1_ALC1_GAIN      0x6F
+#define M98095_070_DAI1_ALC2_TIME      0x70
+#define M98095_071_DAI1_ALC2_COMP      0x71
+#define M98095_072_DAI1_ALC2_EXPN      0x72
+#define M98095_073_DAI1_ALC2_GAIN      0x73
+#define M98095_074_DAI1_ALC3_TIME      0x74
+#define M98095_075_DAI1_ALC3_COMP      0x75
+#define M98095_076_DAI1_ALC3_EXPN      0x76
+#define M98095_077_DAI1_ALC3_GAIN      0x77
+#define M98095_078_DAI2_ALC1_TIME      0x78
+#define M98095_079_DAI2_ALC1_COMP      0x79
+#define M98095_07A_DAI2_ALC1_EXPN      0x7A
+#define M98095_07B_DAI2_ALC1_GAIN      0x7B
+#define M98095_07C_DAI2_ALC2_TIME      0x7C
+#define M98095_07D_DAI2_ALC2_COMP      0x7D
+#define M98095_07E_DAI2_ALC2_EXPN      0x7E
+#define M98095_07F_DAI2_ALC2_GAIN      0x7F
+#define M98095_080_DAI2_ALC3_TIME      0x80
+#define M98095_081_DAI2_ALC3_COMP      0x81
+#define M98095_082_DAI2_ALC3_EXPN      0x82
+#define M98095_083_DAI2_ALC3_GAIN      0x83
+#define M98095_084_HP_NOISE_GATE       0x84
+#define M98095_085_AUX_ADC             0x85
+#define M98095_086_CFG_LINE            0x86
+#define M98095_087_CFG_MIC             0x87
+#define M98095_088_CFG_LEVEL           0x88
+#define M98095_089_JACK_DET_AUTO       0x89
+#define M98095_08A_JACK_DET_MANUAL     0x8A
+#define M98095_08B_JACK_KEYSCAN_DBC    0x8B
+#define M98095_08C_JACK_KEYSCAN_DLY    0x8C
+#define M98095_08D_JACK_KEY_THRESH     0x8D
+#define M98095_08E_JACK_DC_SLEW                0x8E
+#define M98095_08F_JACK_TEST_CFG       0x8F
+#define M98095_090_PWR_EN_IN           0x90
+#define M98095_091_PWR_EN_OUT          0x91
+#define M98095_092_PWR_EN_OUT          0x92
+#define M98095_093_BIAS_CTRL           0x93
+#define M98095_094_PWR_DAC_21          0x94
+#define M98095_095_PWR_DAC_03          0x95
+#define M98095_096_PWR_DAC_CK          0x96
+#define M98095_097_PWR_SYS             0x97
+
+#define M98095_0FF_REV_ID              0xFF
+
+#define M98095_REG_CNT                 (0xFF+1)
+#define M98095_REG_MAX_CACHED          0X97
+
+/* MAX98095 Registers Bit Fields */
+
+/* M98095_00F_HOST_CFG */
+#define M98095_SEG                     (1<<0)
+#define M98095_XTEN                    (1<<1)
+#define M98095_MDLLEN                  (1<<2)
+
+/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
+#define M98095_CLKMODE_MASK            0xFF
+
+/* M98095_02A_DAI1_FORMAT, M98095_034_DAI2_FORMAT, M98095_03E_DAI3_FORMAT */
+#define M98095_DAI_MAS                 (1<<7)
+#define M98095_DAI_WCI                 (1<<6)
+#define M98095_DAI_BCI                 (1<<5)
+#define M98095_DAI_DLY                 (1<<4)
+#define M98095_DAI_TDM                 (1<<2)
+#define M98095_DAI_FSW                 (1<<1)
+#define M98095_DAI_WS                  (1<<0)
+
+/* M98095_02B_DAI1_CLOCK, M98095_035_DAI2_CLOCK, M98095_03F_DAI3_CLOCK */
+#define M98095_DAI_BSEL64              (1<<0)
+#define M98095_DAI_DOSR_DIV2           (0<<5)
+#define M98095_DAI_DOSR_DIV4           (1<<5)
+
+/* M98095_02C_DAI1_IOCFG, M98095_036_DAI2_IOCFG, M98095_040_DAI3_IOCFG */
+#define M98095_S1NORMAL                        (1<<6)
+#define M98095_S2NORMAL                        (2<<6)
+#define M98095_S3NORMAL                        (3<<6)
+#define M98095_SDATA                   (3<<0)
+
+/* M98095_02E_DAI1_FILTERS, M98095_038_DAI2_FILTERS, M98095_042_DAI3_FILTERS */
+#define M98095_DAI_DHF                 (1<<3)
+
+/* M98095_045_DSP_CFG */
+#define M98095_DSPNORMAL               (5<<4)
+
+/* M98095_048_MIX_DAC_LR */
+#define M98095_DAI1L_TO_DACR           (1<<7)
+#define M98095_DAI1R_TO_DACR           (1<<6)
+#define M98095_DAI2M_TO_DACR           (1<<5)
+#define M98095_DAI1L_TO_DACL           (1<<3)
+#define M98095_DAI1R_TO_DACL           (1<<2)
+#define M98095_DAI2M_TO_DACL           (1<<1)
+#define M98095_DAI3M_TO_DACL           (1<<0)
+
+/* M98095_049_MIX_DAC_M */
+#define M98095_DAI1L_TO_DACM           (1<<3)
+#define M98095_DAI1R_TO_DACM           (1<<2)
+#define M98095_DAI2M_TO_DACM           (1<<1)
+#define M98095_DAI3M_TO_DACM           (1<<0)
+
+/* M98095_04E_MIX_HP_CFG */
+#define M98095_HPNORMAL                        (3<<4)
+
+/* M98095_05F_LVL_MIC1, M98095_060_LVL_MIC2 */
+#define M98095_MICPRE_MASK             (3<<5)
+#define M98095_MICPRE_SHIFT            5
+
+/* M98095_064_LVL_HP_L, M98095_065_LVL_HP_R */
+#define M98095_HP_MUTE                 (1<<7)
+
+/* M98095_066_LVL_RCV */
+#define M98095_REC_MUTE                        (1<<7)
+
+/* M98095_067_LVL_SPK_L, M98095_068_LVL_SPK_R */
+#define M98095_SP_MUTE                 (1<<7)
+
+/* M98095_087_CFG_MIC */
+#define M98095_MICSEL_MASK             (3<<0)
+#define M98095_DIGMIC_L                        (1<<2)
+#define M98095_DIGMIC_R                        (1<<3)
+#define M98095_DIGMIC2L                        (1<<4)
+#define M98095_DIGMIC2R                        (1<<5)
+
+/* M98095_088_CFG_LEVEL */
+#define M98095_VSEN                    (1<<6)
+#define M98095_ZDEN                    (1<<5)
+#define M98095_BQ2EN                   (1<<3)
+#define M98095_BQ1EN                   (1<<2)
+#define M98095_EQ2EN                   (1<<1)
+#define M98095_EQ1EN                   (1<<0)
+
+/* M98095_090_PWR_EN_IN */
+#define M98095_INEN                    (1<<7)
+#define M98095_MB2EN                   (1<<3)
+#define M98095_MB1EN                   (1<<2)
+#define M98095_MBEN                    (3<<2)
+#define M98095_ADREN                   (1<<1)
+#define M98095_ADLEN                   (1<<0)
+
+/* M98095_091_PWR_EN_OUT */
+#define M98095_HPLEN                   (1<<7)
+#define M98095_HPREN                   (1<<6)
+#define M98095_SPLEN                   (1<<5)
+#define M98095_SPREN                   (1<<4)
+#define M98095_RECEN                   (1<<3)
+#define M98095_DALEN                   (1<<1)
+#define M98095_DAREN                   (1<<0)
+
+/* M98095_092_PWR_EN_OUT */
+#define M98095_SPK_FIXEDSPECTRUM       (0<<4)
+#define M98095_SPK_SPREADSPECTRUM      (1<<4)
+
+/* M98095_097_PWR_SYS */
+#define M98095_SHDNRUN                 (1<<7)
+#define M98095_PERFMODE                        (1<<3)
+#define M98095_HPPLYBACK               (1<<2)
+#define M98095_PWRSV8K                 (1<<1)
+#define M98095_PWRSV                   (1<<0)
+
+#define M98095_COEFS_PER_BAND          5
+
+/* Equalizer filter coefficients */
+#define M98095_110_DAI1_EQ_BASE                0x10
+#define M98095_142_DAI2_EQ_BASE                0x42
+
+/* Biquad filter coefficients */
+#define M98095_174_DAI1_BQ_BASE                0x74
+#define M98095_17E_DAI2_BQ_BASE                0x7E
+
+/* function prototype */
+
+/*
+ * intialise max98095 sound codec device for the given configuration
+ *
+ * @param blob                 FDT node for codec values
+ * @param sampling_rate                Sampling rate (Hz)
+ * @param mclk_freq            MCLK Frequency (Hz)
+ * @param bits_per_sample      bits per Sample (must be 16 or 24)
+ *
+ * @returns -1 for error and 0 Success.
+ */
+int max98095_init(const void *blob, int sampling_rate, int mclk_freq,
+                       int bits_per_sample);
+
+#endif
index fa8432d48acedc2acc0fc341b90fee62eb9e980c..a4bf4adcb38bf744d379f84613006483e22e7119 100644 (file)
@@ -31,6 +31,7 @@
 #include <sound.h>
 #include <asm/arch/sound.h>
 #include "wm8994.h"
+#include "max98095.h"
 
 /* defines */
 #define SOUND_400_HZ 400
@@ -149,11 +150,15 @@ static int codec_init(const void *blob, struct i2stx_info *pi2s_tx)
                        pi2s_tx->samplingrate,
                        (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
                        pi2s_tx->bitspersample, pi2s_tx->channels);
+       } else if (!strcmp(codectype, "max98095")) {
+               ret = max98095_init(blob, pi2s_tx->samplingrate,
+                               (pi2s_tx->samplingrate * (pi2s_tx->rfs)),
+                               pi2s_tx->bitspersample);
        } else {
-               debug("%s: Unknown code type %s\n", __func__,
-                     codectype);
+               debug("%s: Unknown codec type %s\n", __func__, codectype);
                return -1;
        }
+
        if (ret) {
                debug("%s: Codec init failed\n", __func__);
                return -1;
index b8264df3a9b34cac227461d6563c4dadcfc0cdb8..d08609effe1ace437a87c06a9dd66744d7a3a642 100644 (file)
@@ -25,6 +25,9 @@ include $(TOPDIR)/config.mk
 
 LIB    := $(obj)libspi.o
 
+# There are many options which enable SPI, so make this library available
+COBJS-y += spi.o
+
 COBJS-$(CONFIG_ALTERA_SPI) += altera_spi.o
 COBJS-$(CONFIG_ANDES_SPI) += andes_spi.o
 COBJS-$(CONFIG_ARMADA100_SPI) += armada100_spi.o
@@ -36,6 +39,7 @@ COBJS-$(CONFIG_CF_SPI) += cf_spi.o
 COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
 COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
 COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
+COBJS-$(CONFIG_ICH_SPI) +=  ich.o
 COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
 COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
 COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
@@ -46,8 +50,10 @@ COBJS-$(CONFIG_OMAP3_SPI) += omap3_spi.o
 COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
 COBJS-$(CONFIG_SH_SPI) += sh_spi.o
 COBJS-$(CONFIG_FSL_ESPI) += fsl_espi.o
-COBJS-$(CONFIG_TEGRA_SPI) += tegra_spi.o
-COBJS-$(CONFIG_TEGRA_SLINK) += tegra_slink.o
+COBJS-$(CONFIG_FDT_SPI) += fdt_spi.o
+COBJS-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
+COBJS-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
+COBJS-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
 COBJS-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 
 COBJS  := $(COBJS-y)
index 138d6f4b45c523e239d57c62638110ae6fa08e11..b53607a4ec0264b654d93d52cee9e2fea48dad50 100644 (file)
@@ -83,12 +83,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       altspi = malloc(sizeof(*altspi));
+       altspi = spi_alloc_slave(struct altera_spi_slave, bus, cs);
        if (!altspi)
                return NULL;
 
-       altspi->slave.bus = bus;
-       altspi->slave.cs = cs;
        altspi->base = altera_spi_base_list[bus];
        debug("%s: bus:%i cs:%i base:%lx\n", __func__,
                bus, cs, altspi->base);
index fdde13954b18a0aac466f5e9852637fa65e4c033..c56377b63501ecf6e7a75f84b0c3c2db47082fc1 100644 (file)
@@ -53,12 +53,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       ds = malloc(sizeof(*ds));
+       ds = spi_alloc_slave(struct andes_spi_slave, bus, cs);
        if (!ds)
                return NULL;
 
-       ds->slave.bus = bus;
-       ds->slave.cs = cs;
        ds->regs = (struct andes_spi_regs *)CONFIG_SYS_SPI_BASE;
 
        /*
index 7384c9cd2c14671231e80f41ba889ec3b3736cdd..afdbe0508ca1c0db7cc88237e45288c626f8e304 100644 (file)
@@ -120,12 +120,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 {
        struct armd_spi_slave *pss;
 
-       pss = malloc(sizeof(*pss));
+       pss = spi_alloc_slave(struct armd_spi_slave, bus, cs);
        if (!pss)
                return NULL;
 
-       pss->slave.bus = bus;
-       pss->slave.cs = cs;
        pss->spi_reg = (struct ssp_reg *)SSP_REG_BASE(CONFIG_SYS_SSP_PORT);
 
        pss->cr0 = SSCR0_MOTO | SSCR0_DATASIZE(DEFAULT_WORD_LEN) | SSCR0_SSE;
index ce7d46085543330cf1721b7585557e5a797af2fe..f4b1bad22e85f787212194ff265908139946254e 100644 (file)
@@ -84,12 +84,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (mode & SPI_CPOL)
                csrx |= ATMEL_SPI_CSRx_CPOL;
 
-       as = malloc(sizeof(struct atmel_spi_slave));
+       as = spi_alloc_slave(struct atmel_spi_slave, bus, cs);
        if (!as)
                return NULL;
 
-       as->slave.bus = bus;
-       as->slave.cs = cs;
        as->regs = regs;
        as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS
 #if defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9M10G45)
index e080bec7052e523fd7c72dccfda5d5ec97ebb9bb..ab2e8b998bbf0ff1e089abf6e4f5aa740fa39593 100644 (file)
@@ -182,12 +182,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                default: return NULL;
        }
 
-       bss = malloc(sizeof(*bss));
+       bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs);
        if (!bss)
                return NULL;
 
-       bss->slave.bus = bus;
-       bss->slave.cs = cs;
        bss->mmr_base = (void *)mmr_base;
        bss->ctl = SPE | MSTR | TDBR_CORE;
        if (mode & SPI_CPHA) bss->ctl |= CPHA;
index fde3447426770eb78f549d3d5484e1c2f04fbd92..c25c4a9aeab5550d34b9b544a22b9d64bfc185ad 100644 (file)
@@ -178,12 +178,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                return NULL;
        }
 
-       bss = malloc(sizeof(*bss));
+       bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs);
        if (!bss)
                return NULL;
 
-       bss->slave.bus = bus;
-       bss->slave.cs = cs;
        bss->regs = (struct bfin_spi_regs *)reg_base;
        bss->control = SPI_CTL_EN | SPI_CTL_MSTR;
        if (mode & SPI_CPHA)
index 72dd1a520db822ca7a936e111fe4e84311d75dd1..a37ac4e5264b04db3dd3a558f82c428f1de88b6a 100644 (file)
@@ -120,13 +120,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       dev = malloc(sizeof(struct cf_qspi_slave));
+       dev = spi_alloc_slave(struct cf_qspi_slave, bus, cs);
        if (!dev)
                return NULL;
 
        /* Initialize to known value */
-       dev->slave.bus = bus;
-       dev->slave.cs  = cs;
        dev->regs      = (qspi_t *)MMAP_QSPI;
        dev->qmr       = 0;
        dev->qwr       = 0;
index a883da93688a1bc056b569ab859bdb6dae263dfa..afe791737c81ec5e35e5437240acbb09e4979dfc 100644 (file)
@@ -330,12 +330,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       cfslave = malloc(sizeof(struct cf_spi_slave));
+       cfslave = spi_alloc_slave(struct cf_spi_slave, bus, cs);
        if (!cfslave)
                return NULL;
 
-       cfslave->slave.bus = bus;
-       cfslave->slave.cs = cs;
        cfslave->baudrate = max_hz;
 
        /* specific setup */
index 13aca52c7e2add329fb2c4334f9d3bb4d1752684..74792af0359b90bc25e602d69eda0aedcc52f258 100644 (file)
@@ -44,12 +44,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       ds = malloc(sizeof(*ds));
+       ds = spi_alloc_slave(struct davinci_spi_slave, bus, cs);
        if (!ds)
                return NULL;
 
-       ds->slave.bus = bus;
-       ds->slave.cs = cs;
        ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
        ds->freq = max_hz;
 
index be60ada2ba43a17ecda4a8b968b08b791f0af73f..51b3d30538aefccda2860ec92f49beb45b3e864d 100644 (file)
@@ -89,15 +89,13 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
                return NULL;
        }
 
-       spi_slave = malloc(sizeof(*spi_slave));
+       spi_slave = spi_alloc_slave(struct exynos_spi_slave, busnum, cs);
        if (!spi_slave) {
                debug("%s: Could not allocate spi_slave\n", __func__);
                return NULL;
        }
 
        bus = &spi_bus[busnum];
-       spi_slave->slave.bus = busnum;
-       spi_slave->slave.cs = cs;
        spi_slave->regs = bus->regs;
        spi_slave->mode = mode;
        spi_slave->periph_id = bus->periph_id;
diff --git a/drivers/spi/fdt_spi.c b/drivers/spi/fdt_spi.c
new file mode 100644 (file)
index 0000000..58f139a
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Common fdt based SPI driver front end
+ *
+ * Copyright (c) 2013 NVIDIA Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra20/tegra20_sflash.h>
+#include <asm/arch-tegra20/tegra20_slink.h>
+#include <asm/arch-tegra114/tegra114_spi.h>
+#include <spi.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct fdt_spi_driver {
+       int compat;
+       int max_ctrls;
+       int (*init)(int *node_list, int count);
+       int (*claim_bus)(struct spi_slave *slave);
+       int (*release_bus)(struct spi_slave *slave);
+       int (*cs_is_valid)(unsigned int bus, unsigned int cs);
+       struct spi_slave *(*setup_slave)(unsigned int bus, unsigned int cs,
+                                       unsigned int max_hz, unsigned int mode);
+       void (*free_slave)(struct spi_slave *slave);
+       void (*cs_activate)(struct spi_slave *slave);
+       void (*cs_deactivate)(struct spi_slave *slave);
+       int (*xfer)(struct spi_slave *slave, unsigned int bitlen,
+                   const void *data_out, void *data_in, unsigned long flags);
+};
+
+static struct fdt_spi_driver fdt_spi_drivers[] = {
+#ifdef CONFIG_TEGRA20_SFLASH
+       {
+               .compat         = COMPAT_NVIDIA_TEGRA20_SFLASH,
+               .max_ctrls      = 1,
+               .init           = tegra20_spi_init,
+               .claim_bus      = tegra20_spi_claim_bus,
+               .cs_is_valid    = tegra20_spi_cs_is_valid,
+               .setup_slave    = tegra20_spi_setup_slave,
+               .free_slave     = tegra20_spi_free_slave,
+               .cs_activate    = tegra20_spi_cs_activate,
+               .cs_deactivate  = tegra20_spi_cs_deactivate,
+               .xfer           = tegra20_spi_xfer,
+       },
+#endif
+#ifdef CONFIG_TEGRA20_SLINK
+       {
+               .compat         = COMPAT_NVIDIA_TEGRA20_SLINK,
+               .max_ctrls      = CONFIG_TEGRA_SLINK_CTRLS,
+               .init           = tegra30_spi_init,
+               .claim_bus      = tegra30_spi_claim_bus,
+               .cs_is_valid    = tegra30_spi_cs_is_valid,
+               .setup_slave    = tegra30_spi_setup_slave,
+               .free_slave     = tegra30_spi_free_slave,
+               .cs_activate    = tegra30_spi_cs_activate,
+               .cs_deactivate  = tegra30_spi_cs_deactivate,
+               .xfer           = tegra30_spi_xfer,
+       },
+#endif
+#ifdef CONFIG_TEGRA114_SPI
+       {
+               .compat         = COMPAT_NVIDIA_TEGRA114_SPI,
+               .max_ctrls      = CONFIG_TEGRA114_SPI_CTRLS,
+               .init           = tegra114_spi_init,
+               .claim_bus      = tegra114_spi_claim_bus,
+               .cs_is_valid    = tegra114_spi_cs_is_valid,
+               .setup_slave    = tegra114_spi_setup_slave,
+               .free_slave     = tegra114_spi_free_slave,
+               .cs_activate    = tegra114_spi_cs_activate,
+               .cs_deactivate  = tegra114_spi_cs_deactivate,
+               .xfer           = tegra114_spi_xfer,
+       },
+#endif
+};
+
+static struct fdt_spi_driver *driver;
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+       if (!driver)
+               return 0;
+       else if (!driver->cs_is_valid)
+               return 1;
+       else
+               return driver->cs_is_valid(bus, cs);
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int mode)
+{
+       if (!driver || !driver->setup_slave)
+               return NULL;
+
+       return driver->setup_slave(bus, cs, max_hz, mode);
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+       if (driver && driver->free_slave)
+               return driver->free_slave(slave);
+}
+
+static int spi_init_driver(struct fdt_spi_driver *driver)
+{
+       int count;
+       int node_list[driver->max_ctrls];
+
+       count = fdtdec_find_aliases_for_id(gd->fdt_blob, "spi",
+                                          driver->compat,
+                                          node_list,
+                                          driver->max_ctrls);
+       return driver->init(node_list, count);
+}
+
+void spi_init(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(fdt_spi_drivers); i++) {
+               driver = &fdt_spi_drivers[i];
+               if (!spi_init_driver(driver))
+                       break;
+       }
+       if (i == ARRAY_SIZE(fdt_spi_drivers))
+               driver = NULL;
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+       if (!driver)
+               return 1;
+       if (!driver->claim_bus)
+               return 0;
+
+       return driver->claim_bus(slave);
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       if (driver && driver->release_bus)
+               driver->release_bus(slave);
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+       if (driver && driver->cs_activate)
+               driver->cs_activate(slave);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+       if (driver && driver->cs_deactivate)
+               driver->cs_deactivate(slave);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+            const void *data_out, void *data_in, unsigned long flags)
+{
+       if (!driver || !driver->xfer)
+               return -1;
+
+       return driver->xfer(slave, bitlen, data_out, data_in, flags);
+}
index eb99e90becc9e27eb140e5b6f2ab9841ec63377b..28609eefebfde2ffe2b00a1fcbee08a9c28a63cc 100644 (file)
@@ -79,12 +79,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       fsl = malloc(sizeof(struct fsl_spi_slave));
+       fsl = spi_alloc_slave(struct fsl_spi_slave, bus, cs);
        if (!fsl)
                return NULL;
 
-       fsl->slave.bus = bus;
-       fsl->slave.cs = cs;
        fsl->mode = mode;
        fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN;
 
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
new file mode 100644 (file)
index 0000000..8865df5
--- /dev/null
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 2011-12 The Chromium OS Authors.
+ *
+ * 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
+ *
+ * This file is derived from the flashrom project.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+#include <pci.h>
+#include <pci_ids.h>
+#include <asm/io.h>
+
+#include "ich.h"
+
+#define SPI_OPCODE_WREN      0x06
+#define SPI_OPCODE_FAST_READ 0x0b
+
+struct ich_ctlr {
+       pci_dev_t dev;          /* PCI device number */
+       int ich_version;        /* Controller version, 7 or 9 */
+       int ichspi_lock;
+       int locked;
+       uint8_t *opmenu;
+       int menubytes;
+       void *base;             /* Base of register set */
+       uint16_t *preop;
+       uint16_t *optype;
+       uint32_t *addr;
+       uint8_t *data;
+       unsigned databytes;
+       uint8_t *status;
+       uint16_t *control;
+       uint32_t *bbar;
+       uint32_t *pr;           /* only for ich9 */
+       uint8_t *speed;         /* pointer to speed control */
+       ulong max_speed;        /* Maximum bus speed in MHz */
+};
+
+struct ich_ctlr ctlr;
+
+static inline struct ich_spi_slave *to_ich_spi(struct spi_slave *slave)
+{
+       return container_of(slave, struct ich_spi_slave, slave);
+}
+
+static unsigned int ich_reg(const void *addr)
+{
+       return (unsigned)(addr - ctlr.base) & 0xffff;
+}
+
+static u8 ich_readb(const void *addr)
+{
+       u8 value = readb(addr);
+
+       debug("read %2.2x from %4.4x\n", value, ich_reg(addr));
+
+       return value;
+}
+
+static u16 ich_readw(const void *addr)
+{
+       u16 value = readw(addr);
+
+       debug("read %4.4x from %4.4x\n", value, ich_reg(addr));
+
+       return value;
+}
+
+static u32 ich_readl(const void *addr)
+{
+       u32 value = readl(addr);
+
+       debug("read %8.8x from %4.4x\n", value, ich_reg(addr));
+
+       return value;
+}
+
+static void ich_writeb(u8 value, void *addr)
+{
+       writeb(value, addr);
+       debug("wrote %2.2x to %4.4x\n", value, ich_reg(addr));
+}
+
+static void ich_writew(u16 value, void *addr)
+{
+       writew(value, addr);
+       debug("wrote %4.4x to %4.4x\n", value, ich_reg(addr));
+}
+
+static void ich_writel(u32 value, void *addr)
+{
+       writel(value, addr);
+       debug("wrote %8.8x to %4.4x\n", value, ich_reg(addr));
+}
+
+static void write_reg(const void *value, void *dest, uint32_t size)
+{
+       memcpy_toio(dest, value, size);
+}
+
+static void read_reg(const void *src, void *value, uint32_t size)
+{
+       memcpy_fromio(value, src, size);
+}
+
+static void ich_set_bbar(struct ich_ctlr *ctlr, uint32_t minaddr)
+{
+       const uint32_t bbar_mask = 0x00ffff00;
+       uint32_t ichspi_bbar;
+
+       minaddr &= bbar_mask;
+       ichspi_bbar = ich_readl(ctlr->bbar) & ~bbar_mask;
+       ichspi_bbar |= minaddr;
+       ich_writel(ichspi_bbar, ctlr->bbar);
+}
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+       puts("spi_cs_is_valid used but not implemented\n");
+       return 0;
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int mode)
+{
+       struct ich_spi_slave *ich;
+
+       ich = spi_alloc_slave(struct ich_spi_slave, bus, cs);
+       if (!ich) {
+               puts("ICH SPI: Out of memory\n");
+               return NULL;
+       }
+
+       /*
+        * Yes this controller can only write a small number of bytes at
+        * once! The limit is typically 64 bytes.
+        */
+       ich->slave.max_write_size = ctlr.databytes;
+       ich->speed = max_hz;
+
+       return &ich->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+       struct ich_spi_slave *ich = to_ich_spi(slave);
+
+       free(ich);
+}
+
+/*
+ * Check if this device ID matches one of supported Intel PCH devices.
+ *
+ * Return the ICH version if there is a match, or zero otherwise.
+ */
+static int get_ich_version(uint16_t device_id)
+{
+       if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC)
+               return 7;
+
+       if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN &&
+            device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) ||
+           (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN &&
+            device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX))
+               return 9;
+
+       return 0;
+}
+
+/* @return 1 if the SPI flash supports the 33MHz speed */
+static int ich9_can_do_33mhz(pci_dev_t dev)
+{
+       u32 fdod, speed;
+
+       /* Observe SPI Descriptor Component Section 0 */
+       pci_write_config_dword(dev, 0xb0, 0x1000);
+
+       /* Extract the Write/Erase SPI Frequency from descriptor */
+       pci_read_config_dword(dev, 0xb4, &fdod);
+
+       /* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */
+       speed = (fdod >> 21) & 7;
+
+       return speed == 1;
+}
+
+static int ich_find_spi_controller(pci_dev_t *devp, int *ich_versionp)
+{
+       int last_bus = pci_last_busno();
+       int bus;
+
+       if (last_bus == -1) {
+               debug("No PCI busses?\n");
+               return -1;
+       }
+
+       for (bus = 0; bus <= last_bus; bus++) {
+               uint16_t vendor_id, device_id;
+               uint32_t ids;
+               pci_dev_t dev;
+
+               dev = PCI_BDF(bus, 31, 0);
+               pci_read_config_dword(dev, 0, &ids);
+               vendor_id = ids;
+               device_id = ids >> 16;
+
+               if (vendor_id == PCI_VENDOR_ID_INTEL) {
+                       *devp = dev;
+                       *ich_versionp = get_ich_version(device_id);
+                       return 0;
+               }
+       }
+
+       debug("ICH SPI: No ICH found.\n");
+       return -1;
+}
+
+static int ich_init_controller(struct ich_ctlr *ctlr)
+{
+       uint8_t *rcrb; /* Root Complex Register Block */
+       uint32_t rcba; /* Root Complex Base Address */
+
+       pci_read_config_dword(ctlr->dev, 0xf0, &rcba);
+       /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */
+       rcrb = (uint8_t *)(rcba & 0xffffc000);
+       if (ctlr->ich_version == 7) {
+               struct ich7_spi_regs *ich7_spi;
+
+               ich7_spi = (struct ich7_spi_regs *)(rcrb + 0x3020);
+               ctlr->ichspi_lock = ich_readw(&ich7_spi->spis) & SPIS_LOCK;
+               ctlr->opmenu = ich7_spi->opmenu;
+               ctlr->menubytes = sizeof(ich7_spi->opmenu);
+               ctlr->optype = &ich7_spi->optype;
+               ctlr->addr = &ich7_spi->spia;
+               ctlr->data = (uint8_t *)ich7_spi->spid;
+               ctlr->databytes = sizeof(ich7_spi->spid);
+               ctlr->status = (uint8_t *)&ich7_spi->spis;
+               ctlr->control = &ich7_spi->spic;
+               ctlr->bbar = &ich7_spi->bbar;
+               ctlr->preop = &ich7_spi->preop;
+               ctlr->base = ich7_spi;
+       } else if (ctlr->ich_version == 9) {
+               struct ich9_spi_regs *ich9_spi;
+
+               ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800);
+               ctlr->ichspi_lock = ich_readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
+               ctlr->opmenu = ich9_spi->opmenu;
+               ctlr->menubytes = sizeof(ich9_spi->opmenu);
+               ctlr->optype = &ich9_spi->optype;
+               ctlr->addr = &ich9_spi->faddr;
+               ctlr->data = (uint8_t *)ich9_spi->fdata;
+               ctlr->databytes = sizeof(ich9_spi->fdata);
+               ctlr->status = &ich9_spi->ssfs;
+               ctlr->control = (uint16_t *)ich9_spi->ssfc;
+               ctlr->speed = ich9_spi->ssfc + 2;
+               ctlr->bbar = &ich9_spi->bbar;
+               ctlr->preop = &ich9_spi->preop;
+               ctlr->pr = &ich9_spi->pr[0];
+               ctlr->base = ich9_spi;
+       } else {
+               debug("ICH SPI: Unrecognized ICH version %d.\n",
+                     ctlr->ich_version);
+               return -1;
+       }
+       debug("ICH SPI: Version %d detected\n", ctlr->ich_version);
+
+       /* Work out the maximum speed we can support */
+       ctlr->max_speed = 20000000;
+       if (ctlr->ich_version == 9 && ich9_can_do_33mhz(ctlr->dev))
+               ctlr->max_speed = 33000000;
+
+       ich_set_bbar(ctlr, 0);
+
+       return 0;
+}
+
+void spi_init(void)
+{
+       uint8_t bios_cntl;
+
+       if (ich_find_spi_controller(&ctlr.dev, &ctlr.ich_version)) {
+               printf("ICH SPI: Cannot find device\n");
+               return;
+       }
+
+       if (ich_init_controller(&ctlr)) {
+               printf("ICH SPI: Cannot setup controller\n");
+               return;
+       }
+
+       /*
+        * Disable the BIOS write protect so write commands are allowed.  On
+        * v9, deassert SMM BIOS Write Protect Disable.
+        */
+       pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl);
+       if (ctlr.ich_version == 9)
+               bios_cntl &= ~(1 << 5);
+       pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+       /* Handled by ICH automatically. */
+       return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       /* Handled by ICH automatically. */
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+       /* Handled by ICH automatically. */
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+       /* Handled by ICH automatically. */
+}
+
+static inline void spi_use_out(struct spi_trans *trans, unsigned bytes)
+{
+       trans->out += bytes;
+       trans->bytesout -= bytes;
+}
+
+static inline void spi_use_in(struct spi_trans *trans, unsigned bytes)
+{
+       trans->in += bytes;
+       trans->bytesin -= bytes;
+}
+
+static void spi_setup_type(struct spi_trans *trans, int data_bytes)
+{
+       trans->type = 0xFF;
+
+       /* Try to guess spi type from read/write sizes. */
+       if (trans->bytesin == 0) {
+               if (trans->bytesout + data_bytes > 4)
+                       /*
+                        * If bytesin = 0 and bytesout > 4, we presume this is
+                        * a write data operation, which is accompanied by an
+                        * address.
+                        */
+                       trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
+               else
+                       trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
+               return;
+       }
+
+       if (trans->bytesout == 1) {     /* and bytesin is > 0 */
+               trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
+               return;
+       }
+
+       if (trans->bytesout == 4)       /* and bytesin is > 0 */
+               trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
+
+       /* Fast read command is called with 5 bytes instead of 4 */
+       if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
+               trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
+               --trans->bytesout;
+       }
+}
+
+static int spi_setup_opcode(struct spi_trans *trans)
+{
+       uint16_t optypes;
+       uint8_t opmenu[ctlr.menubytes];
+
+       trans->opcode = trans->out[0];
+       spi_use_out(trans, 1);
+       if (!ctlr.ichspi_lock) {
+               /* The lock is off, so just use index 0. */
+               ich_writeb(trans->opcode, ctlr.opmenu);
+               optypes = ich_readw(ctlr.optype);
+               optypes = (optypes & 0xfffc) | (trans->type & 0x3);
+               ich_writew(optypes, ctlr.optype);
+               return 0;
+       } else {
+               /* The lock is on. See if what we need is on the menu. */
+               uint8_t optype;
+               uint16_t opcode_index;
+
+               /* Write Enable is handled as atomic prefix */
+               if (trans->opcode == SPI_OPCODE_WREN)
+                       return 0;
+
+               read_reg(ctlr.opmenu, opmenu, sizeof(opmenu));
+               for (opcode_index = 0; opcode_index < ctlr.menubytes;
+                               opcode_index++) {
+                       if (opmenu[opcode_index] == trans->opcode)
+                               break;
+               }
+
+               if (opcode_index == ctlr.menubytes) {
+                       printf("ICH SPI: Opcode %x not found\n",
+                              trans->opcode);
+                       return -1;
+               }
+
+               optypes = ich_readw(ctlr.optype);
+               optype = (optypes >> (opcode_index * 2)) & 0x3;
+               if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
+                   optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
+                   trans->bytesout >= 3) {
+                       /* We guessed wrong earlier. Fix it up. */
+                       trans->type = optype;
+               }
+               if (optype != trans->type) {
+                       printf("ICH SPI: Transaction doesn't fit type %d\n",
+                              optype);
+                       return -1;
+               }
+               return opcode_index;
+       }
+}
+
+static int spi_setup_offset(struct spi_trans *trans)
+{
+       /* Separate the SPI address and data. */
+       switch (trans->type) {
+       case SPI_OPCODE_TYPE_READ_NO_ADDRESS:
+       case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS:
+               return 0;
+       case SPI_OPCODE_TYPE_READ_WITH_ADDRESS:
+       case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS:
+               trans->offset = ((uint32_t)trans->out[0] << 16) |
+                               ((uint32_t)trans->out[1] << 8) |
+                               ((uint32_t)trans->out[2] << 0);
+               spi_use_out(trans, 3);
+               return 1;
+       default:
+               printf("Unrecognized SPI transaction type %#x\n", trans->type);
+               return -1;
+       }
+}
+
+/*
+ * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set
+ * below is True) or 0. In case the wait was for the bit(s) to set - write
+ * those bits back, which would cause resetting them.
+ *
+ * Return the last read status value on success or -1 on failure.
+ */
+static int ich_status_poll(u16 bitmask, int wait_til_set)
+{
+       int timeout = 600000; /* This will result in 6s */
+       u16 status = 0;
+
+       while (timeout--) {
+               status = ich_readw(ctlr.status);
+               if (wait_til_set ^ ((status & bitmask) == 0)) {
+                       if (wait_til_set)
+                               ich_writew((status & bitmask), ctlr.status);
+                       return status;
+               }
+               udelay(10);
+       }
+
+       printf("ICH SPI: SCIP timeout, read %x, expected %x\n",
+              status, bitmask);
+       return -1;
+}
+
+/*
+int spi_xfer(struct spi_slave *slave, const void *dout,
+               unsigned int bitsout, void *din, unsigned int bitsin)
+*/
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+               void *din, unsigned long flags)
+{
+       struct ich_spi_slave *ich = to_ich_spi(slave);
+       uint16_t control;
+       int16_t opcode_index;
+       int with_address;
+       int status;
+       int bytes = bitlen / 8;
+       struct spi_trans *trans = &ich->trans;
+       unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END);
+       int using_cmd = 0;
+       /* Align read transactions to 64-byte boundaries */
+       char buff[ctlr.databytes];
+
+       /* Ee don't support writing partial bytes. */
+       if (bitlen % 8) {
+               debug("ICH SPI: Accessing partial bytes not supported\n");
+               return -1;
+       }
+
+       /* An empty end transaction can be ignored */
+       if (type == SPI_XFER_END && !dout && !din)
+               return 0;
+
+       if (type & SPI_XFER_BEGIN)
+               memset(trans, '\0', sizeof(*trans));
+
+       /* Dp we need to come back later to finish it? */
+       if (dout && type == SPI_XFER_BEGIN) {
+               if (bytes > ICH_MAX_CMD_LEN) {
+                       debug("ICH SPI: Command length limit exceeded\n");
+                       return -1;
+               }
+               memcpy(trans->cmd, dout, bytes);
+               trans->cmd_len = bytes;
+               debug("ICH SPI: Saved %d bytes\n", bytes);
+               return 0;
+       }
+
+       /*
+        * We process a 'middle' spi_xfer() call, which has no
+        * SPI_XFER_BEGIN/END, as an independent transaction as if it had
+        * an end. We therefore repeat the command. This is because ICH
+        * seems to have no support for this, or because interest (in digging
+        * out the details and creating a special case in the code) is low.
+        */
+       if (trans->cmd_len) {
+               trans->out = trans->cmd;
+               trans->bytesout = trans->cmd_len;
+               using_cmd = 1;
+               debug("ICH SPI: Using %d bytes\n", trans->cmd_len);
+       } else {
+               trans->out = dout;
+               trans->bytesout = dout ? bytes : 0;
+       }
+
+       trans->in = din;
+       trans->bytesin = din ? bytes : 0;
+
+       /* There has to always at least be an opcode. */
+       if (!trans->bytesout) {
+               debug("ICH SPI: No opcode for transfer\n");
+               return -1;
+       }
+
+       if (ich_status_poll(SPIS_SCIP, 0) == -1)
+               return -1;
+
+       ich_writew(SPIS_CDS | SPIS_FCERR, ctlr.status);
+
+       spi_setup_type(trans, using_cmd ? bytes : 0);
+       opcode_index = spi_setup_opcode(trans);
+       if (opcode_index < 0)
+               return -1;
+       with_address = spi_setup_offset(trans);
+       if (with_address < 0)
+               return -1;
+
+       if (trans->opcode == SPI_OPCODE_WREN) {
+               /*
+                * Treat Write Enable as Atomic Pre-Op if possible
+                * in order to prevent the Management Engine from
+                * issuing a transaction between WREN and DATA.
+                */
+               if (!ctlr.ichspi_lock)
+                       ich_writew(trans->opcode, ctlr.preop);
+               return 0;
+       }
+
+       if (ctlr.speed && ctlr.max_speed >= 33000000) {
+               int byte;
+
+               byte = ich_readb(ctlr.speed);
+               if (ich->speed >= 33000000)
+                       byte |= SSFC_SCF_33MHZ;
+               else
+                       byte &= ~SSFC_SCF_33MHZ;
+               ich_writeb(byte, ctlr.speed);
+       }
+
+       /* See if we have used up the command data */
+       if (using_cmd && dout && bytes) {
+               trans->out = dout;
+               trans->bytesout = bytes;
+               debug("ICH SPI: Moving to data, %d bytes\n", bytes);
+       }
+
+       /* Preset control fields */
+       control = ich_readw(ctlr.control);
+       control &= ~SSFC_RESERVED;
+       control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
+
+       /* Issue atomic preop cycle if needed */
+       if (ich_readw(ctlr.preop))
+               control |= SPIC_ACS;
+
+       if (!trans->bytesout && !trans->bytesin) {
+               /* SPI addresses are 24 bit only */
+               if (with_address)
+                       ich_writel(trans->offset & 0x00FFFFFF, ctlr.addr);
+
+               /*
+                * This is a 'no data' command (like Write Enable), its
+                * bitesout size was 1, decremented to zero while executing
+                * spi_setup_opcode() above. Tell the chip to send the
+                * command.
+                */
+               ich_writew(control, ctlr.control);
+
+               /* wait for the result */
+               status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
+               if (status == -1)
+                       return -1;
+
+               if (status & SPIS_FCERR) {
+                       debug("ICH SPI: Command transaction error\n");
+                       return -1;
+               }
+
+               return 0;
+       }
+
+       /*
+        * Check if this is a write command atempting to transfer more bytes
+        * than the controller can handle. Iterations for writes are not
+        * supported here because each SPI write command needs to be preceded
+        * and followed by other SPI commands, and this sequence is controlled
+        * by the SPI chip driver.
+        */
+       if (trans->bytesout > ctlr.databytes) {
+               debug("ICH SPI: Too much to write. This should be prevented by the driver's max_write_size?\n");
+               return -1;
+       }
+
+       /*
+        * Read or write up to databytes bytes at a time until everything has
+        * been sent.
+        */
+       while (trans->bytesout || trans->bytesin) {
+               uint32_t data_length;
+               uint32_t aligned_offset;
+               uint32_t diff;
+
+               aligned_offset = trans->offset & ~(ctlr.databytes - 1);
+               diff = trans->offset - aligned_offset;
+
+               /* SPI addresses are 24 bit only */
+               ich_writel(aligned_offset & 0x00FFFFFF, ctlr.addr);
+
+               if (trans->bytesout)
+                       data_length = min(trans->bytesout, ctlr.databytes);
+               else
+                       data_length = min(trans->bytesin, ctlr.databytes);
+
+               /* Program data into FDATA0 to N */
+               if (trans->bytesout) {
+                       write_reg(trans->out, ctlr.data, data_length);
+                       spi_use_out(trans, data_length);
+                       if (with_address)
+                               trans->offset += data_length;
+               }
+
+               /* Add proper control fields' values */
+               control &= ~((ctlr.databytes - 1) << 8);
+               control |= SPIC_DS;
+               control |= (data_length - 1) << 8;
+
+               /* write it */
+               ich_writew(control, ctlr.control);
+
+               /* Wait for Cycle Done Status or Flash Cycle Error. */
+               status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
+               if (status == -1)
+                       return -1;
+
+               if (status & SPIS_FCERR) {
+                       debug("ICH SPI: Data transaction error\n");
+                       return -1;
+               }
+
+               if (trans->bytesin) {
+                       if (diff) {
+                               data_length -= diff;
+                               read_reg(ctlr.data, buff, ctlr.databytes);
+                               memcpy(trans->in, buff + diff, data_length);
+                       } else {
+                               read_reg(ctlr.data, trans->in, data_length);
+                       }
+                       spi_use_in(trans, data_length);
+                       if (with_address)
+                               trans->offset += data_length;
+               }
+       }
+
+       /* Clear atomic preop now that xfer is done */
+       ich_writew(0, ctlr.preop);
+
+       return 0;
+}
+
+
+/*
+ * This uses the SPI controller from the Intel Cougar Point and Panther Point
+ * PCH to write-protect portions of the SPI flash until reboot. The changes
+ * don't actually take effect until the HSFS[FLOCKDN] bit is set, but that's
+ * done elsewhere.
+ */
+int spi_write_protect_region(uint32_t lower_limit, uint32_t length, int hint)
+{
+       uint32_t tmplong;
+       uint32_t upper_limit;
+
+       if (!ctlr.pr) {
+               printf("%s: operation not supported on this chipset\n",
+                      __func__);
+               return -1;
+       }
+
+       if (length == 0 ||
+           lower_limit > (0xFFFFFFFFUL - length) + 1 ||
+           hint < 0 || hint > 4) {
+               printf("%s(0x%x, 0x%x, %d): invalid args\n", __func__,
+                      lower_limit, length, hint);
+               return -1;
+       }
+
+       upper_limit = lower_limit + length - 1;
+
+       /*
+        * Determine bits to write, as follows:
+        *  31     Write-protection enable (includes erase operation)
+        *  30:29  reserved
+        *  28:16  Upper Limit (FLA address bits 24:12, with 11:0 == 0xfff)
+        *  15     Read-protection enable
+        *  14:13  reserved
+        *  12:0   Lower Limit (FLA address bits 24:12, with 11:0 == 0x000)
+        */
+       tmplong = 0x80000000 |
+               ((upper_limit & 0x01fff000) << 4) |
+               ((lower_limit & 0x01fff000) >> 12);
+
+       printf("%s: writing 0x%08x to %p\n", __func__, tmplong,
+              &ctlr.pr[hint]);
+       ctlr.pr[hint] = tmplong;
+
+       return 0;
+}
diff --git a/drivers/spi/ich.h b/drivers/spi/ich.h
new file mode 100644 (file)
index 0000000..bd7bc12
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * 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
+ *
+ * This file is derived from the flashrom project.
+ */
+
+struct ich7_spi_regs {
+       uint16_t spis;
+       uint16_t spic;
+       uint32_t spia;
+       uint64_t spid[8];
+       uint64_t _pad;
+       uint32_t bbar;
+       uint16_t preop;
+       uint16_t optype;
+       uint8_t opmenu[8];
+} __packed;
+
+struct ich9_spi_regs {
+       uint32_t bfpr;                  /* 0x00 */
+       uint16_t hsfs;
+       uint16_t hsfc;
+       uint32_t faddr;
+       uint32_t _reserved0;
+       uint32_t fdata[16];             /* 0x10 */
+       uint32_t frap;                  /* 0x50 */
+       uint32_t freg[5];
+       uint32_t _reserved1[3];
+       uint32_t pr[5];                 /* 0x74 */
+       uint32_t _reserved2[2];
+       uint8_t ssfs;                   /* 0x90 */
+       uint8_t ssfc[3];
+       uint16_t preop;                 /* 0x94 */
+       uint16_t optype;
+       uint8_t opmenu[8];              /* 0x98 */
+       uint32_t bbar;
+       uint8_t _reserved3[12];
+       uint32_t fdoc;
+       uint32_t fdod;
+       uint8_t _reserved4[8];
+       uint32_t afc;
+       uint32_t lvscc;
+       uint32_t uvscc;
+       uint8_t _reserved5[4];
+       uint32_t fpb;
+       uint8_t _reserved6[28];
+       uint32_t srdl;
+       uint32_t srdc;
+       uint32_t srd;
+} __packed;
+
+enum {
+       SPIS_SCIP =             0x0001,
+       SPIS_GRANT =            0x0002,
+       SPIS_CDS =              0x0004,
+       SPIS_FCERR =            0x0008,
+       SSFS_AEL =              0x0010,
+       SPIS_LOCK =             0x8000,
+       SPIS_RESERVED_MASK =    0x7ff0,
+       SSFS_RESERVED_MASK =    0x7fe2
+};
+
+enum {
+       SPIC_SCGO =             0x000002,
+       SPIC_ACS =              0x000004,
+       SPIC_SPOP =             0x000008,
+       SPIC_DBC =              0x003f00,
+       SPIC_DS =               0x004000,
+       SPIC_SME =              0x008000,
+       SSFC_SCF_MASK =         0x070000,
+       SSFC_RESERVED =         0xf80000,
+
+       /* Mask for speed byte, biuts 23:16 of SSFC */
+       SSFC_SCF_33MHZ  =       0x01,
+};
+
+enum {
+       HSFS_FDONE =            0x0001,
+       HSFS_FCERR =            0x0002,
+       HSFS_AEL =              0x0004,
+       HSFS_BERASE_MASK =      0x0018,
+       HSFS_BERASE_SHIFT =     3,
+       HSFS_SCIP =             0x0020,
+       HSFS_FDOPSS =           0x2000,
+       HSFS_FDV =              0x4000,
+       HSFS_FLOCKDN =          0x8000
+};
+
+enum {
+       HSFC_FGO =              0x0001,
+       HSFC_FCYCLE_MASK =      0x0006,
+       HSFC_FCYCLE_SHIFT =     1,
+       HSFC_FDBC_MASK =        0x3f00,
+       HSFC_FDBC_SHIFT =       8,
+       HSFC_FSMIE =            0x8000
+};
+
+enum {
+       SPI_OPCODE_TYPE_READ_NO_ADDRESS =       0,
+       SPI_OPCODE_TYPE_WRITE_NO_ADDRESS =      1,
+       SPI_OPCODE_TYPE_READ_WITH_ADDRESS =     2,
+       SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS =    3
+};
+
+enum {
+       ICH_MAX_CMD_LEN         = 5,
+};
+
+struct spi_trans {
+       uint8_t cmd[ICH_MAX_CMD_LEN];
+       int cmd_len;
+       const uint8_t *out;
+       uint32_t bytesout;
+       uint8_t *in;
+       uint32_t bytesin;
+       uint8_t type;
+       uint8_t opcode;
+       uint32_t offset;
+};
+
+struct ich_spi_slave {
+       struct spi_slave slave;
+       struct spi_trans trans; /* current transaction in progress */
+       int speed;              /* SPI speed in Hz */
+};
index de81064b9defbff63f15b2975f5271d976e2a1ee..caa91e3e81718c8c4626fbb819a121f14e28e3e8 100644 (file)
@@ -49,13 +49,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       slave = malloc(sizeof(struct spi_slave));
+       slave = spi_alloc_slave_base(bus, cs);
        if (!slave)
                return NULL;
 
-       slave->bus = bus;
-       slave->cs = cs;
-
        writel(~KWSPI_CSN_ACT | KWSPI_SMEMRDY, &spireg->ctrl);
 
        /* calculate spi clock prescaller using max_hz */
index 3e96b3f9f3b88fa997667a931650d76d8bdf9667..4b50bca880a8bdc9420d4163b0913bfe9f1a019d 100644 (file)
@@ -48,13 +48,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 {
        struct spi_slave *slave;
 
-       slave = malloc(sizeof(struct spi_slave));
+       slave = spi_alloc_slave_base(bus, cs);
        if (!slave)
                return NULL;
 
-       slave->bus = bus;
-       slave->cs = cs;
-
        return slave;
 }
 
index 4e46041dfff5df76c98561d161daa4a13790acd5..6b0e3b46ec8fead7db89daf64e67422dc9fe50bd 100644 (file)
@@ -45,13 +45,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       slave = malloc(sizeof(struct spi_slave));
+       slave = spi_alloc_slave_base(bus, cs);
        if (!slave)
                return NULL;
 
-       slave->bus = bus;
-       slave->cs = cs;
-
        /*
         * TODO: Some of the code in spi_init() should probably move
         * here, or into spi_claim_bus() below.
index 4c19e0bf18b65cdb08faab5141c79be759080dea..cb48019a42b409acb8195ea3bd3cfa97f005de5d 100644 (file)
@@ -408,7 +408,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (bus >= ARRAY_SIZE(spi_bases))
                return NULL;
 
-       mxcs = calloc(sizeof(struct mxc_spi_slave), 1);
+       mxcs = spi_alloc_slave(struct mxc_spi_slave, bus, cs);
        if (!mxcs) {
                puts("mxc_spi: SPI Slave not allocated !\n");
                return NULL;
@@ -424,8 +424,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 
        cs = ret;
 
-       mxcs->slave.bus = bus;
-       mxcs->slave.cs = cs;
        mxcs->base = spi_bases[bus];
 
        ret = spi_cfg_mxc(mxcs, cs, max_hz, mode);
index ffa3c1d693bbab56381bd8789aafc6b53ff392f3..aa999f9a945583a740e75af2e831b56d7406dab4 100644 (file)
@@ -77,15 +77,13 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                return NULL;
        }
 
-       mxs_slave = calloc(sizeof(struct mxs_spi_slave), 1);
+       mxs_slave = spi_alloc_slave(struct mxs_spi_slave, bus, cs);
        if (!mxs_slave)
                return NULL;
 
        if (mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + bus))
                goto err_init;
 
-       mxs_slave->slave.bus = bus;
-       mxs_slave->slave.cs = cs;
        mxs_slave->max_khz = max_hz / 1000;
        mxs_slave->mode = mode;
        mxs_slave->regs = mxs_ssp_regs_by_bus(bus);
index fc01fb83a21b64b9e06d2d77d5954e97414590a2..6f7b1edd602c7a145375b32a42158b861b691628 100644 (file)
@@ -90,13 +90,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs) || gpio_request(cs, "tiny_spi"))
                return NULL;
 
-       tiny_spi = malloc(sizeof(*tiny_spi));
+       tiny_spi = spi_alloc_slave(struct tiny_spi_slave, bus, cs);
        if (!tiny_spi)
                return NULL;
-       memset(tiny_spi, 0, sizeof(*tiny_spi));
 
-       tiny_spi->slave.bus = bus;
-       tiny_spi->slave.cs = cs;
        tiny_spi->host = &tiny_spi_host_list[bus];
        tiny_spi->mode = mode & (SPI_CPOL | SPI_CPHA);
        tiny_spi->flg = mode & SPI_CS_HIGH ? 1 : 0;
index 344d5b8a7e2dc5d9006793e00d40343dec18be44..80a4e4776c83d17314b54060e758d980d91975b8 100644 (file)
@@ -80,12 +80,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                                  unsigned int max_hz, unsigned int mode)
 {
        struct omap3_spi_slave  *ds;
-
-       ds = malloc(sizeof(struct omap3_spi_slave));
-       if (!ds) {
-               printf("SPI error: malloc of SPI structure failed\n");
-               return NULL;
-       }
+       struct mcspi *regs;
 
        /*
         * OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules)
@@ -98,21 +93,21 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 
        switch (bus) {
        case 0:
-               ds->regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
+               regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
                break;
 #ifdef OMAP3_MCSPI2_BASE
        case 1:
-               ds->regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
+               regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
                break;
 #endif
 #ifdef OMAP3_MCSPI3_BASE 
        case 2:
-               ds->regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
+               regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
                break;
 #endif
 #ifdef OMAP3_MCSPI4_BASE
        case 3:
-               ds->regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
+               regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
                break;
 #endif
        default:
@@ -120,7 +115,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                        Supported busses 0 - 3\n", bus);
                return NULL;
        }
-       ds->slave.bus = bus;
 
        if (((bus == 0) && (cs > 3)) ||
                        ((bus == 1) && (cs > 1)) ||
@@ -130,19 +124,26 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                        on bus %i\n", cs, bus);
                return NULL;
        }
-       ds->slave.cs = cs;
 
        if (max_hz > OMAP3_MCSPI_MAX_FREQ) {
                printf("SPI error: unsupported frequency %i Hz. \
                        Max frequency is 48 Mhz\n", max_hz);
                return NULL;
        }
-       ds->freq = max_hz;
 
        if (mode > SPI_MODE_3) {
                printf("SPI error: unsupported SPI mode %i\n", mode);
                return NULL;
        }
+
+       ds = spi_alloc_slave(struct omap3_spi_slave, bus, cs);
+       if (!ds) {
+               printf("SPI error: malloc of SPI structure failed\n");
+               return NULL;
+       }
+
+       ds->regs = regs;
+       ds->freq = max_hz;
        ds->mode = mode;
 
        return &ds->slave;
index e944b23c2df355936e724d4013bb217f185ad13a..744afe3295aebeca01ad9e1921ce387c0c823dbb 100644 (file)
@@ -103,12 +103,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       ss = malloc(sizeof(struct spi_slave));
+       ss = spi_alloc_slave(struct sh_spi, bus, cs);
        if (!ss)
                return NULL;
 
-       ss->slave.bus = bus;
-       ss->slave.cs = cs;
        ss->regs = (struct sh_spi_regs *)CONFIG_SH_SPI_BASE;
 
        /* SPI sycle stop */
index 13df8cb7de167aece971549f0cddf5696cbb8c17..a1b84b6e37b921d39a68aac0d55bc28a60fde41c 100644 (file)
@@ -73,12 +73,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
-       ss = malloc(sizeof(struct soft_spi_slave));
+       ss = spi_alloc_slave(struct soft_spi_slave, bus, cs);
        if (!ss)
                return NULL;
 
-       ss->slave.bus = bus;
-       ss->slave.cs = cs;
        ss->mode = mode;
 
        /* TODO: Use max_hz to limit the SCK rate */
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
new file mode 100644 (file)
index 0000000..cb36c5e
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+
+void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
+                        unsigned int cs)
+{
+       struct spi_slave *slave;
+       void *ptr;
+
+       ptr = malloc(size);
+       if (ptr) {
+               memset(ptr, '\0', size);
+               slave = (struct spi_slave *)(ptr + offset);
+               slave->bus = bus;
+               slave->cs = cs;
+       }
+
+       return ptr;
+}
diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c
new file mode 100644 (file)
index 0000000..b11a0a1
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * NVIDIA Tegra SPI controller (T114 and later)
+ *
+ * Copyright (c) 2010-2013 NVIDIA Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra114/tegra114_spi.h>
+#include <spi.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* COMMAND1 */
+#define SPI_CMD1_GO                    (1 << 31)
+#define SPI_CMD1_M_S                   (1 << 30)
+#define SPI_CMD1_MODE_MASK             0x3
+#define SPI_CMD1_MODE_SHIFT            28
+#define SPI_CMD1_CS_SEL_MASK           0x3
+#define SPI_CMD1_CS_SEL_SHIFT          26
+#define SPI_CMD1_CS_POL_INACTIVE3      (1 << 25)
+#define SPI_CMD1_CS_POL_INACTIVE2      (1 << 24)
+#define SPI_CMD1_CS_POL_INACTIVE1      (1 << 23)
+#define SPI_CMD1_CS_POL_INACTIVE0      (1 << 22)
+#define SPI_CMD1_CS_SW_HW              (1 << 21)
+#define SPI_CMD1_CS_SW_VAL             (1 << 20)
+#define SPI_CMD1_IDLE_SDA_MASK         0x3
+#define SPI_CMD1_IDLE_SDA_SHIFT                18
+#define SPI_CMD1_BIDIR                 (1 << 17)
+#define SPI_CMD1_LSBI_FE               (1 << 16)
+#define SPI_CMD1_LSBY_FE               (1 << 15)
+#define SPI_CMD1_BOTH_EN_BIT           (1 << 14)
+#define SPI_CMD1_BOTH_EN_BYTE          (1 << 13)
+#define SPI_CMD1_RX_EN                 (1 << 12)
+#define SPI_CMD1_TX_EN                 (1 << 11)
+#define SPI_CMD1_PACKED                        (1 << 5)
+#define SPI_CMD1_BIT_LEN_MASK          0x1F
+#define SPI_CMD1_BIT_LEN_SHIFT         0
+
+/* COMMAND2 */
+#define SPI_CMD2_TX_CLK_TAP_DELAY      (1 << 6)
+#define SPI_CMD2_TX_CLK_TAP_DELAY_MASK (0x3F << 6)
+#define SPI_CMD2_RX_CLK_TAP_DELAY      (1 << 0)
+#define SPI_CMD2_RX_CLK_TAP_DELAY_MASK (0x3F << 0)
+
+/* TRANSFER STATUS */
+#define SPI_XFER_STS_RDY               (1 << 30)
+
+/* FIFO STATUS */
+#define SPI_FIFO_STS_CS_INACTIVE       (1 << 31)
+#define SPI_FIFO_STS_FRAME_END         (1 << 30)
+#define SPI_FIFO_STS_RX_FIFO_FLUSH     (1 << 15)
+#define SPI_FIFO_STS_TX_FIFO_FLUSH     (1 << 14)
+#define SPI_FIFO_STS_ERR               (1 << 8)
+#define SPI_FIFO_STS_TX_FIFO_OVF       (1 << 7)
+#define SPI_FIFO_STS_TX_FIFO_UNR       (1 << 6)
+#define SPI_FIFO_STS_RX_FIFO_OVF       (1 << 5)
+#define SPI_FIFO_STS_RX_FIFO_UNR       (1 << 4)
+#define SPI_FIFO_STS_TX_FIFO_FULL      (1 << 3)
+#define SPI_FIFO_STS_TX_FIFO_EMPTY     (1 << 2)
+#define SPI_FIFO_STS_RX_FIFO_FULL      (1 << 1)
+#define SPI_FIFO_STS_RX_FIFO_EMPTY     (1 << 0)
+
+#define SPI_TIMEOUT            1000
+#define TEGRA_SPI_MAX_FREQ     52000000
+
+struct spi_regs {
+       u32 command1;   /* 000:SPI_COMMAND1 register */
+       u32 command2;   /* 004:SPI_COMMAND2 register */
+       u32 timing1;    /* 008:SPI_CS_TIM1 register */
+       u32 timing2;    /* 00c:SPI_CS_TIM2 register */
+       u32 xfer_status;/* 010:SPI_TRANS_STATUS register */
+       u32 fifo_status;/* 014:SPI_FIFO_STATUS register */
+       u32 tx_data;    /* 018:SPI_TX_DATA register */
+       u32 rx_data;    /* 01c:SPI_RX_DATA register */
+       u32 dma_ctl;    /* 020:SPI_DMA_CTL register */
+       u32 dma_blk;    /* 024:SPI_DMA_BLK register */
+       u32 rsvd[56];   /* 028-107 reserved */
+       u32 tx_fifo;    /* 108:SPI_FIFO1 register */
+       u32 rsvd2[31];  /* 10c-187 reserved */
+       u32 rx_fifo;    /* 188:SPI_FIFO2 register */
+       u32 spare_ctl;  /* 18c:SPI_SPARE_CTRL register */
+};
+
+struct tegra_spi_ctrl {
+       struct spi_regs *regs;
+       unsigned int freq;
+       unsigned int mode;
+       int periph_id;
+       int valid;
+};
+
+struct tegra_spi_slave {
+       struct spi_slave slave;
+       struct tegra_spi_ctrl *ctrl;
+};
+
+static struct tegra_spi_ctrl spi_ctrls[CONFIG_TEGRA114_SPI_CTRLS];
+
+static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
+{
+       return container_of(slave, struct tegra_spi_slave, slave);
+}
+
+int tegra114_spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+       if (bus >= CONFIG_TEGRA114_SPI_CTRLS || cs > 3 || !spi_ctrls[bus].valid)
+               return 0;
+       else
+               return 1;
+}
+
+struct spi_slave *tegra114_spi_setup_slave(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int mode)
+{
+       struct tegra_spi_slave *spi;
+
+       debug("%s: bus: %u, cs: %u, max_hz: %u, mode: %u\n", __func__,
+               bus, cs, max_hz, mode);
+
+       if (!spi_cs_is_valid(bus, cs)) {
+               printf("SPI error: unsupported bus %d / chip select %d\n",
+                      bus, cs);
+               return NULL;
+       }
+
+       if (max_hz > TEGRA_SPI_MAX_FREQ) {
+               printf("SPI error: unsupported frequency %d Hz. Max frequency"
+                       " is %d Hz\n", max_hz, TEGRA_SPI_MAX_FREQ);
+               return NULL;
+       }
+
+       spi = malloc(sizeof(struct tegra_spi_slave));
+       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",
+                      bus);
+               return NULL;
+       }
+
+       if (max_hz < spi->ctrl->freq) {
+               debug("%s: limiting frequency from %u to %u\n", __func__,
+                     spi->ctrl->freq, max_hz);
+               spi->ctrl->freq = max_hz;
+       }
+       spi->ctrl->mode = mode;
+
+       return &spi->slave;
+}
+
+void tegra114_spi_free_slave(struct spi_slave *slave)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+
+       free(spi);
+}
+
+int tegra114_spi_init(int *node_list, int count)
+{
+       struct tegra_spi_ctrl *ctrl;
+       int i;
+       int node = 0;
+       int found = 0;
+
+       for (i = 0; i < count; i++) {
+               ctrl = &spi_ctrls[i];
+               node = node_list[i];
+
+               ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
+                                                                node, "reg");
+               if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
+                       debug("%s: no spi register found\n", __func__);
+                       continue;
+               }
+               ctrl->freq = fdtdec_get_int(gd->fdt_blob, node,
+                                           "spi-max-frequency", 0);
+               if (!ctrl->freq) {
+                       debug("%s: no spi max frequency found\n", __func__);
+                       continue;
+               }
+
+               ctrl->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
+               if (ctrl->periph_id == PERIPH_ID_NONE) {
+                       debug("%s: could not decode periph id\n", __func__);
+                       continue;
+               }
+               ctrl->valid = 1;
+               found = 1;
+
+               debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
+                     __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
+       }
+
+       return !found;
+}
+
+int tegra114_spi_claim_bus(struct spi_slave *slave)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+       struct spi_regs *regs = spi->ctrl->regs;
+
+       /* Change SPI clock to correct frequency, PLLP_OUT0 source */
+       clock_start_periph_pll(spi->ctrl->periph_id, CLOCK_ID_PERIPH,
+                              spi->ctrl->freq);
+
+       /* Clear stale status here */
+       setbits_le32(&regs->fifo_status,
+                    SPI_FIFO_STS_ERR           |
+                    SPI_FIFO_STS_TX_FIFO_OVF   |
+                    SPI_FIFO_STS_TX_FIFO_UNR   |
+                    SPI_FIFO_STS_RX_FIFO_OVF   |
+                    SPI_FIFO_STS_RX_FIFO_UNR   |
+                    SPI_FIFO_STS_TX_FIFO_FULL  |
+                    SPI_FIFO_STS_TX_FIFO_EMPTY |
+                    SPI_FIFO_STS_RX_FIFO_FULL  |
+                    SPI_FIFO_STS_RX_FIFO_EMPTY);
+       debug("%s: FIFO STATUS = %08x\n", __func__, readl(&regs->fifo_status));
+
+       /* Set master mode and sw controlled CS */
+       setbits_le32(&regs->command1, SPI_CMD1_M_S | SPI_CMD1_CS_SW_HW |
+                    (spi->ctrl->mode << SPI_CMD1_MODE_SHIFT));
+       debug("%s: COMMAND1 = %08x\n", __func__, readl(&regs->command1));
+
+       return 0;
+}
+
+void tegra114_spi_cs_activate(struct spi_slave *slave)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+       struct spi_regs *regs = spi->ctrl->regs;
+
+       clrbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL);
+}
+
+void tegra114_spi_cs_deactivate(struct spi_slave *slave)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+       struct spi_regs *regs = spi->ctrl->regs;
+
+       setbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL);
+}
+
+int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+               const void *data_out, void *data_in, unsigned long flags)
+{
+       struct tegra_spi_slave *spi = to_tegra_spi(slave);
+       struct spi_regs *regs = spi->ctrl->regs;
+       u32 reg, tmpdout, tmpdin = 0;
+       const u8 *dout = data_out;
+       u8 *din = data_in;
+       int num_bytes;
+       int ret;
+
+       debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
+             __func__, slave->bus, slave->cs, dout, din, bitlen);
+       if (bitlen % 8)
+               return -1;
+       num_bytes = bitlen / 8;
+
+       ret = 0;
+
+       /* clear all error status bits */
+       reg = readl(&regs->fifo_status);
+       writel(reg, &regs->fifo_status);
+
+       /* clear ready bit */
+       setbits_le32(&regs->xfer_status, SPI_XFER_STS_RDY);
+
+       clrsetbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL,
+                       SPI_CMD1_RX_EN | SPI_CMD1_TX_EN | SPI_CMD1_LSBY_FE |
+                       (slave->cs << SPI_CMD1_CS_SEL_SHIFT));
+
+       /* set xfer size to 1 block (32 bits) */
+       writel(0, &regs->dma_blk);
+
+       if (flags & SPI_XFER_BEGIN)
+               spi_cs_activate(slave);
+
+       /* handle data in 32-bit chunks */
+       while (num_bytes > 0) {
+               int bytes;
+               int is_read = 0;
+               int tm, i;
+
+               tmpdout = 0;
+               bytes = (num_bytes > 4) ?  4 : num_bytes;
+
+               if (dout != NULL) {
+                       for (i = 0; i < bytes; ++i)
+                               tmpdout = (tmpdout << 8) | dout[i];
+                       dout += bytes;
+               }
+
+               num_bytes -= bytes;
+
+               clrsetbits_le32(&regs->command1,
+                               SPI_CMD1_BIT_LEN_MASK << SPI_CMD1_BIT_LEN_SHIFT,
+                               (bytes * 8 - 1) << SPI_CMD1_BIT_LEN_SHIFT);
+               writel(tmpdout, &regs->tx_fifo);
+               setbits_le32(&regs->command1, SPI_CMD1_GO);
+
+               /*
+                * Wait for SPI transmit FIFO to empty, or to time out.
+                * The RX FIFO status will be read and cleared last
+                */
+               for (tm = 0, is_read = 0; tm < SPI_TIMEOUT; ++tm) {
+                       u32 fifo_status, xfer_status;
+
+                       fifo_status = readl(&regs->fifo_status);
+
+                       /* We can exit when we've had both RX and TX activity */
+                       if (is_read &&
+                           (fifo_status & SPI_FIFO_STS_TX_FIFO_EMPTY))
+                               break;
+
+                       xfer_status = readl(&regs->xfer_status);
+                       if (!(xfer_status & SPI_XFER_STS_RDY))
+                               continue;
+
+                       if (fifo_status & SPI_FIFO_STS_ERR) {
+                               debug("%s: got a fifo error: ", __func__);
+                               if (fifo_status & SPI_FIFO_STS_TX_FIFO_OVF)
+                                       debug("tx FIFO overflow ");
+                               if (fifo_status & SPI_FIFO_STS_TX_FIFO_UNR)
+                                       debug("tx FIFO underrun ");
+                               if (fifo_status & SPI_FIFO_STS_RX_FIFO_OVF)
+                                       debug("rx FIFO overflow ");
+                               if (fifo_status & SPI_FIFO_STS_RX_FIFO_UNR)
+                                       debug("rx FIFO underrun ");
+                               if (fifo_status & SPI_FIFO_STS_TX_FIFO_FULL)
+                                       debug("tx FIFO full ");
+                               if (fifo_status & SPI_FIFO_STS_TX_FIFO_EMPTY)
+                                       debug("tx FIFO empty ");
+                               if (fifo_status & SPI_FIFO_STS_RX_FIFO_FULL)
+                                       debug("rx FIFO full ");
+                               if (fifo_status & SPI_FIFO_STS_RX_FIFO_EMPTY)
+                                       debug("rx FIFO empty ");
+                               debug("\n");
+                               break;
+                       }
+
+                       if (!(fifo_status & SPI_FIFO_STS_RX_FIFO_EMPTY)) {
+                               tmpdin = readl(&regs->rx_fifo);
+                               is_read = 1;
+
+                               /* swap bytes read in */
+                               if (din != NULL) {
+                                       for (i = bytes - 1; i >= 0; --i) {
+                                               din[i] = tmpdin & 0xff;
+                                               tmpdin >>= 8;
+                                       }
+                                       din += bytes;
+                               }
+                       }
+               }
+
+               if (tm >= SPI_TIMEOUT)
+                       ret = tm;
+
+               /* clear ACK RDY, etc. bits */
+               writel(readl(&regs->fifo_status), &regs->fifo_status);
+       }
+
+       if (flags & SPI_XFER_END)
+               spi_cs_deactivate(slave);
+
+       debug("%s: transfer ended. Value=%08x, fifo_status = %08x\n",
+             __func__, tmpdin, readl(&regs->fifo_status));
+
+       if (ret) {
+               printf("%s: timeout during SPI transfer, tm %d\n",
+                      __func__, ret);
+               return -1;
+       }
+
+       return 0;
+}
similarity index 56%
rename from drivers/spi/tegra_spi.c
rename to drivers/spi/tegra20_sflash.c
index ce19095af03d931f5db46094289a48d79f464ebf..9322ce7f64102b61100039feb071716f243ab65e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 NVIDIA Corporation
+ * Copyright (c) 2010-2013 NVIDIA Corporation
  * With help from the mpc8xxx SPI driver
  * With more help from omap3_spi SPI driver
  *
 #include <asm/gpio.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/pinmux.h>
-#include <asm/arch/uart-spi-switch.h>
 #include <asm/arch-tegra/clk_rst.h>
-#include <asm/arch-tegra/tegra_spi.h>
+#include <asm/arch-tegra20/tegra20_sflash.h>
 #include <spi.h>
 #include <fdtdec.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_SPI_CORRUPTS_UART)
- #define corrupt_delay()       udelay(CONFIG_SPI_CORRUPTS_UART_DLY);
-#else
- #define corrupt_delay()
-#endif
+#define SPI_CMD_GO                     (1 << 30)
+#define SPI_CMD_ACTIVE_SCLK_SHIFT      26
+#define SPI_CMD_ACTIVE_SCLK_MASK       (3 << SPI_CMD_ACTIVE_SCLK_SHIFT)
+#define SPI_CMD_CK_SDA                 (1 << 21)
+#define SPI_CMD_ACTIVE_SDA_SHIFT       18
+#define SPI_CMD_ACTIVE_SDA_MASK                (3 << SPI_CMD_ACTIVE_SDA_SHIFT)
+#define SPI_CMD_CS_POL                 (1 << 16)
+#define SPI_CMD_TXEN                   (1 << 15)
+#define SPI_CMD_RXEN                   (1 << 14)
+#define SPI_CMD_CS_VAL                 (1 << 13)
+#define SPI_CMD_CS_SOFT                        (1 << 12)
+#define SPI_CMD_CS_DELAY               (1 << 9)
+#define SPI_CMD_CS3_EN                 (1 << 8)
+#define SPI_CMD_CS2_EN                 (1 << 7)
+#define SPI_CMD_CS1_EN                 (1 << 6)
+#define SPI_CMD_CS0_EN                 (1 << 5)
+#define SPI_CMD_BIT_LENGTH             (1 << 4)
+#define SPI_CMD_BIT_LENGTH_MASK                0x0000001F
+
+#define SPI_STAT_BSY                   (1 << 31)
+#define SPI_STAT_RDY                   (1 << 30)
+#define SPI_STAT_RXF_FLUSH             (1 << 29)
+#define SPI_STAT_TXF_FLUSH             (1 << 28)
+#define SPI_STAT_RXF_UNR               (1 << 27)
+#define SPI_STAT_TXF_OVF               (1 << 26)
+#define SPI_STAT_RXF_EMPTY             (1 << 25)
+#define SPI_STAT_RXF_FULL              (1 << 24)
+#define SPI_STAT_TXF_EMPTY             (1 << 23)
+#define SPI_STAT_TXF_FULL              (1 << 22)
+#define SPI_STAT_SEL_TXRX_N            (1 << 16)
+#define SPI_STAT_CUR_BLKCNT            (1 << 15)
+
+#define SPI_TIMEOUT            1000
+#define TEGRA_SPI_MAX_FREQ     52000000
+
+struct spi_regs {
+       u32 command;    /* SPI_COMMAND_0 register  */
+       u32 status;     /* SPI_STATUS_0 register */
+       u32 rx_cmp;     /* SPI_RX_CMP_0 register  */
+       u32 dma_ctl;    /* SPI_DMA_CTL_0 register */
+       u32 tx_fifo;    /* SPI_TX_FIFO_0 register */
+       u32 rsvd[3];    /* offsets 0x14 to 0x1F reserved */
+       u32 rx_fifo;    /* SPI_RX_FIFO_0 register */
+};
 
-struct tegra_spi_slave {
-       struct spi_slave slave;
-       struct spi_tegra *regs;
+struct tegra_spi_ctrl {
+       struct spi_regs *regs;
        unsigned int freq;
        unsigned int mode;
        int periph_id;
+       int valid;
 };
 
+struct tegra_spi_slave {
+       struct spi_slave slave;
+       struct tegra_spi_ctrl *ctrl;
+};
+
+/* tegra20 only supports one SFLASH controller */
+static struct tegra_spi_ctrl spi_ctrls[1];
+
 static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
 {
        return container_of(slave, struct tegra_spi_slave, slave);
 }
 
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+int tegra20_spi_cs_is_valid(unsigned int bus, unsigned int cs)
 {
        /* Tegra20 SPI-Flash - only 1 device ('bus/cs') */
        if (bus != 0 || cs != 0)
@@ -64,8 +110,8 @@ int spi_cs_is_valid(unsigned int bus, unsigned int cs)
                return 1;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int mode)
+struct spi_slave *tegra20_spi_setup_slave(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int mode)
 {
        struct tegra_spi_slave *spi;
 
@@ -81,93 +127,100 @@ struct spi_slave *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;
-#ifdef CONFIG_OF_CONTROL
-       int node = fdtdec_next_compatible(gd->fdt_blob, 0,
-                                         COMPAT_NVIDIA_TEGRA20_SFLASH);
-       if (node < 0) {
-               debug("%s: cannot locate sflash node\n", __func__);
+       spi->ctrl = &spi_ctrls[bus];
+       if (!spi->ctrl) {
+               printf("SPI error: could not find controller for bus %d\n",
+                      bus);
                return NULL;
        }
-       if (!fdtdec_get_is_enabled(gd->fdt_blob, node)) {
-               debug("%s: sflash is disabled\n", __func__);
-               return NULL;
-       }
-       spi->regs = (struct spi_tegra *)fdtdec_get_addr(gd->fdt_blob,
-                                                       node, "reg");
-       if ((fdt_addr_t)spi->regs == FDT_ADDR_T_NONE) {
-               debug("%s: no sflash register found\n", __func__);
-               return NULL;
-       }
-       spi->freq = fdtdec_get_int(gd->fdt_blob, node, "spi-max-frequency", 0);
-       if (!spi->freq) {
-               debug("%s: no sflash max frequency found\n", __func__);
-               return NULL;
-       }
-       spi->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
-       if (spi->periph_id == PERIPH_ID_NONE) {
-               debug("%s: could not decode periph id\n", __func__);
-               return NULL;
-       }
-#else
-       spi->regs = (struct spi_tegra *)NV_PA_SPI_BASE;
-       spi->freq = TEGRA_SPI_MAX_FREQ;
-       spi->periph_id = PERIPH_ID_SPI1;
-#endif
-       if (max_hz < spi->freq) {
+
+       if (max_hz < spi->ctrl->freq) {
                debug("%s: limiting frequency from %u to %u\n", __func__,
-                     spi->freq, max_hz);
-               spi->freq = max_hz;
+                     spi->ctrl->freq, max_hz);
+               spi->ctrl->freq = max_hz;
        }
-       debug("%s: controller initialized at %p, freq = %u, periph_id = %d\n",
-             __func__, spi->regs, spi->freq, spi->periph_id);
-       spi->mode = mode;
+       spi->ctrl->mode = mode;
 
        return &spi->slave;
 }
 
-void spi_free_slave(struct spi_slave *slave)
+void tegra20_spi_free_slave(struct spi_slave *slave)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
 
        free(spi);
 }
 
-void spi_init(void)
+int tegra20_spi_init(int *node_list, int count)
 {
-       /* do nothing */
+       struct tegra_spi_ctrl *ctrl;
+       int i;
+       int node = 0;
+       int found = 0;
+
+       for (i = 0; i < count; i++) {
+               ctrl = &spi_ctrls[i];
+               node = node_list[i];
+
+               ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
+                                                               node, "reg");
+               if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
+                       debug("%s: no slink register found\n", __func__);
+                       continue;
+               }
+               ctrl->freq = fdtdec_get_int(gd->fdt_blob, node,
+                                           "spi-max-frequency", 0);
+               if (!ctrl->freq) {
+                       debug("%s: no slink max frequency found\n", __func__);
+                       continue;
+               }
+
+               ctrl->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
+               if (ctrl->periph_id == PERIPH_ID_NONE) {
+                       debug("%s: could not decode periph id\n", __func__);
+                       continue;
+               }
+               ctrl->valid = 1;
+               found = 1;
+
+               debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
+                     __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
+       }
+       return !found;
 }
 
-int spi_claim_bus(struct spi_slave *slave)
+int tegra20_spi_claim_bus(struct spi_slave *slave)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_tegra *regs = spi->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
        u32 reg;
 
        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
-       clock_start_periph_pll(spi->periph_id, CLOCK_ID_PERIPH, spi->freq);
+       clock_start_periph_pll(spi->ctrl->periph_id, CLOCK_ID_PERIPH,
+                              spi->ctrl->freq);
 
        /* Clear stale status here */
        reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \
                SPI_STAT_RXF_UNR | SPI_STAT_TXF_OVF;
        writel(reg, &regs->status);
-       debug("spi_init: STATUS = %08x\n", readl(&regs->status));
+       debug("%s: STATUS = %08x\n", __func__, readl(&regs->status));
 
        /*
         * Use sw-controlled CS, so we can clock in data after ReadID, etc.
         */
-       reg = (spi->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT;
-       if (spi->mode & 2)
+       reg = (spi->ctrl->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT;
+       if (spi->ctrl->mode & 2)
                reg |= 1 << SPI_CMD_ACTIVE_SCLK_SHIFT;
        clrsetbits_le32(&regs->command, SPI_CMD_ACTIVE_SCLK_MASK |
                SPI_CMD_ACTIVE_SDA_MASK, SPI_CMD_CS_SOFT | reg);
-       debug("spi_init: COMMAND = %08x\n", readl(&regs->command));
+       debug("%s: COMMAND = %08x\n", __func__, readl(&regs->command));
 
        /*
         * SPI pins on Tegra20 are muxed - change pinmux later due to UART
@@ -175,58 +228,34 @@ int spi_claim_bus(struct spi_slave *slave)
         */
        pinmux_set_func(PINGRP_GMD, PMUX_FUNC_SFLASH);
        pinmux_tristate_disable(PINGRP_LSPI);
+       pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH);
 
-#ifndef CONFIG_SPI_UART_SWITCH
-       /*
-        * NOTE:
-        * Only set PinMux bits 3:2 to SPI here on boards that don't have the
-        * SPI UART switch or subsequent UART data won't go out!  See
-        * spi_uart_switch().
-        */
-       /* TODO: pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH); */
-#endif
        return 0;
 }
 
-void spi_release_bus(struct spi_slave *slave)
-{
-       /*
-        * We can't release UART_DISABLE and set pinmux to UART4 here since
-        * some code (e,g, spi_flash_probe) uses printf() while the SPI
-        * bus is held. That is arguably bad, but it has the advantage of
-        * already being in the source tree.
-        */
-}
-
-void spi_cs_activate(struct spi_slave *slave)
+void tegra20_spi_cs_activate(struct spi_slave *slave)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-
-       pinmux_select_spi();
+       struct spi_regs *regs = spi->ctrl->regs;
 
        /* CS is negated on Tegra, so drive a 1 to get a 0 */
-       setbits_le32(&spi->regs->command, SPI_CMD_CS_VAL);
-
-       corrupt_delay();                /* Let UART settle */
+       setbits_le32(&regs->command, SPI_CMD_CS_VAL);
 }
 
-void spi_cs_deactivate(struct spi_slave *slave)
+void tegra20_spi_cs_deactivate(struct spi_slave *slave)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-
-       pinmux_select_uart();
+       struct spi_regs *regs = spi->ctrl->regs;
 
        /* CS is negated on Tegra, so drive a 0 to get a 1 */
-       clrbits_le32(&spi->regs->command, SPI_CMD_CS_VAL);
-
-       corrupt_delay();                /* Let SPI settle */
+       clrbits_le32(&regs->command, SPI_CMD_CS_VAL);
 }
 
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+int tegra20_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                const void *data_out, void *data_in, unsigned long flags)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_tegra *regs = spi->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
        u32 reg, tmpdout, tmpdin = 0;
        const u8 *dout = data_out;
        u8 *din = data_in;
similarity index 71%
rename from drivers/spi/tegra_slink.c
rename to drivers/spi/tegra20_slink.c
index 2c41fabe286ea55ad2aaab4343142cd627fde35e..664de6e916613f4571fadb9fbd46497a32131fce 100644 (file)
 #include <asm/gpio.h>
 #include <asm/arch/clock.h>
 #include <asm/arch-tegra/clk_rst.h>
-#include <asm/arch-tegra/tegra_slink.h>
+#include <asm/arch-tegra20/tegra20_slink.h>
 #include <spi.h>
 #include <fdtdec.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* COMMAND */
+#define SLINK_CMD_ENB                  (1 << 31)
+#define SLINK_CMD_GO                   (1 << 30)
+#define SLINK_CMD_M_S                  (1 << 28)
+#define SLINK_CMD_CK_SDA               (1 << 21)
+#define SLINK_CMD_CS_POL               (1 << 13)
+#define SLINK_CMD_CS_VAL               (1 << 12)
+#define SLINK_CMD_CS_SOFT              (1 << 11)
+#define SLINK_CMD_BIT_LENGTH           (1 << 4)
+#define SLINK_CMD_BIT_LENGTH_MASK      0x0000001F
+/* COMMAND2 */
+#define SLINK_CMD2_TXEN                        (1 << 30)
+#define SLINK_CMD2_RXEN                        (1 << 31)
+#define SLINK_CMD2_SS_EN               (1 << 18)
+#define SLINK_CMD2_SS_EN_SHIFT         18
+#define SLINK_CMD2_SS_EN_MASK          0x000C0000
+#define SLINK_CMD2_CS_ACTIVE_BETWEEN   (1 << 17)
+/* STATUS */
+#define SLINK_STAT_BSY                 (1 << 31)
+#define SLINK_STAT_RDY                 (1 << 30)
+#define SLINK_STAT_ERR                 (1 << 29)
+#define SLINK_STAT_RXF_FLUSH           (1 << 27)
+#define SLINK_STAT_TXF_FLUSH           (1 << 26)
+#define SLINK_STAT_RXF_OVF             (1 << 25)
+#define SLINK_STAT_TXF_UNR             (1 << 24)
+#define SLINK_STAT_RXF_EMPTY           (1 << 23)
+#define SLINK_STAT_RXF_FULL            (1 << 22)
+#define SLINK_STAT_TXF_EMPTY           (1 << 21)
+#define SLINK_STAT_TXF_FULL            (1 << 20)
+#define SLINK_STAT_TXF_OVF             (1 << 19)
+#define SLINK_STAT_RXF_UNR             (1 << 18)
+#define SLINK_STAT_CUR_BLKCNT          (1 << 15)
+/* STATUS2 */
+#define SLINK_STAT2_RXF_FULL_CNT       (1 << 16)
+#define SLINK_STAT2_TXF_FULL_CNT       (1 << 0)
+
+#define SPI_TIMEOUT            1000
+#define TEGRA_SPI_MAX_FREQ     52000000
+
+struct spi_regs {
+       u32 command;    /* SLINK_COMMAND_0 register  */
+       u32 command2;   /* SLINK_COMMAND2_0 reg */
+       u32 status;     /* SLINK_STATUS_0 register */
+       u32 reserved;   /* Reserved offset 0C */
+       u32 mas_data;   /* SLINK_MAS_DATA_0 reg */
+       u32 slav_data;  /* SLINK_SLAVE_DATA_0 reg */
+       u32 dma_ctl;    /* SLINK_DMA_CTL_0 register */
+       u32 status2;    /* SLINK_STATUS2_0 reg */
+       u32 rsvd[56];   /* 0x20 to 0xFF reserved */
+       u32 tx_fifo;    /* SLINK_TX_FIFO_0 reg off 100h */
+       u32 rsvd2[31];  /* 0x104 to 0x17F reserved */
+       u32 rx_fifo;    /* SLINK_RX_FIFO_0 reg off 180h */
+};
+
 struct tegra_spi_ctrl {
-       struct slink_tegra *regs;
+       struct spi_regs *regs;
        unsigned int freq;
        unsigned int mode;
        int periph_id;
@@ -53,7 +107,7 @@ static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
        return container_of(slave, struct tegra_spi_slave, slave);
 }
 
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+int tegra30_spi_cs_is_valid(unsigned int bus, unsigned int cs)
 {
        if (bus >= CONFIG_TEGRA_SLINK_CTRLS || cs > 3 || !spi_ctrls[bus].valid)
                return 0;
@@ -61,7 +115,7 @@ int spi_cs_is_valid(unsigned int bus, unsigned int cs)
                return 1;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+struct spi_slave *tegra30_spi_setup_slave(unsigned int bus, unsigned int cs,
                unsigned int max_hz, unsigned int mode)
 {
        struct tegra_spi_slave *spi;
@@ -81,13 +135,11 @@ struct spi_slave *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",
@@ -105,32 +157,26 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        return &spi->slave;
 }
 
-void spi_free_slave(struct spi_slave *slave)
+void tegra30_spi_free_slave(struct spi_slave *slave)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
 
        free(spi);
 }
 
-void spi_init(void)
+int tegra30_spi_init(int *node_list, int count)
 {
        struct tegra_spi_ctrl *ctrl;
        int i;
-#ifdef CONFIG_OF_CONTROL
        int node = 0;
-       int count;
-       int node_list[CONFIG_TEGRA_SLINK_CTRLS];
+       int found = 0;
 
-       count = fdtdec_find_aliases_for_id(gd->fdt_blob, "spi",
-                                          COMPAT_NVIDIA_TEGRA20_SLINK,
-                                          node_list,
-                                          CONFIG_TEGRA_SLINK_CTRLS);
        for (i = 0; i < count; i++) {
                ctrl = &spi_ctrls[i];
                node = node_list[i];
 
-               ctrl->regs = (struct slink_tegra *)fdtdec_get_addr(gd->fdt_blob,
-                                                                  node, "reg");
+               ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
+                                                               node, "reg");
                if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
                        debug("%s: no slink register found\n", __func__);
                        continue;
@@ -148,44 +194,18 @@ void spi_init(void)
                        continue;
                }
                ctrl->valid = 1;
+               found = 1;
 
                debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
                      __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
        }
-#else
-       for (i = 0; i < CONFIG_TEGRA_SLINK_CTRLS; i++) {
-               ctrl = &spi_ctrls[i];
-               u32 base_regs[] = {
-                       NV_PA_SLINK1_BASE,
-                       NV_PA_SLINK2_BASE,
-                       NV_PA_SLINK3_BASE,
-                       NV_PA_SLINK4_BASE,
-                       NV_PA_SLINK5_BASE,
-                       NV_PA_SLINK6_BASE,
-               };
-               int periph_ids[] = {
-                       PERIPH_ID_SBC1,
-                       PERIPH_ID_SBC2,
-                       PERIPH_ID_SBC3,
-                       PERIPH_ID_SBC4,
-                       PERIPH_ID_SBC5,
-                       PERIPH_ID_SBC6,
-               };
-               ctrl->regs = (struct slink_tegra *)base_regs[i];
-               ctrl->freq = TEGRA_SPI_MAX_FREQ;
-               ctrl->periph_id = periph_ids[i];
-               ctrl->valid = 1;
-
-               debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
-                     __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
-       }
-#endif
+       return !found;
 }
 
-int spi_claim_bus(struct spi_slave *slave)
+int tegra30_spi_claim_bus(struct spi_slave *slave)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct slink_tegra *regs = spi->ctrl->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
        u32 reg;
 
        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
@@ -207,33 +227,29 @@ int spi_claim_bus(struct spi_slave *slave)
        return 0;
 }
 
-void spi_release_bus(struct spi_slave *slave)
-{
-}
-
-void spi_cs_activate(struct spi_slave *slave)
+void tegra30_spi_cs_activate(struct spi_slave *slave)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct slink_tegra *regs = spi->ctrl->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
 
        /* CS is negated on Tegra, so drive a 1 to get a 0 */
        setbits_le32(&regs->command, SLINK_CMD_CS_VAL);
 }
 
-void spi_cs_deactivate(struct spi_slave *slave)
+void tegra30_spi_cs_deactivate(struct spi_slave *slave)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct slink_tegra *regs = spi->ctrl->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
 
        /* CS is negated on Tegra, so drive a 0 to get a 1 */
        clrbits_le32(&regs->command, SLINK_CMD_CS_VAL);
 }
 
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                const void *data_out, void *data_in, unsigned long flags)
 {
        struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct slink_tegra *regs = spi->ctrl->regs;
+       struct spi_regs *regs = spi->ctrl->regs;
        u32 reg, tmpdout, tmpdin = 0;
        const u8 *dout = data_out;
        u8 *din = data_in;
index db01cc25f71ae37a9ba54c10c87b019becfa885e..a82b056948a4cecd716a776f6d7eae1e63b89423 100644 (file)
@@ -85,14 +85,12 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                return NULL;
        }
 
-       xilspi = malloc(sizeof(*xilspi));
+       xilspi = spi_alloc_slave(struct xilinx_spi_slave, bus, cs);
        if (!xilspi) {
                printf("XILSPI error: %s: malloc of SPI structure failed\n",
                                __func__);
                return NULL;
        }
-       xilspi->slave.bus = bus;
-       xilspi->slave.cs = cs;
        xilspi->regs = (struct xilinx_spi_reg *)xilinx_spi_base_list[bus];
        xilspi->freq = max_hz;
        xilspi->mode = mode;
index dc5ca65463800e27bdad6cfa496f583f9b002858..fd8f8a760670f80872fe73cabcb2c35700748489 100644 (file)
@@ -265,10 +265,6 @@ static int smsc95xx_eeprom_confirm_not_busy(struct ueth_data *dev)
 
        do {
                smsc95xx_read_reg(dev, E2P_CMD, &val);
-               if (!(val & E2P_CMD_LOADED_)) {
-                       debug("No EEPROM present\n");
-                       return -1;
-               }
                if (!(val & E2P_CMD_BUSY_))
                        return 0;
                udelay(40);
index 040eaba3bc9008514782755075f32b28f906c11b..e545b6be6b33030bd42cf27d9a8a2cdde8027bb1 100644 (file)
@@ -25,15 +25,21 @@ include $(TOPDIR)/config.mk
 
 LIB    := $(obj)libusb_gadget.o
 
+# if defined(CONFIG_USB_GADGET) || defined(CONFIG_USB_ETHER)
+#   Everytime you forget how crufty makefiles can get things like
+#   this remind you...
+ifneq (,$(CONFIG_USB_GADGET)$(CONFIG_USB_ETHER))
+COBJS-y += epautoconf.o config.o usbstring.o
+endif
+
 # new USB gadget layer dependencies
 ifdef CONFIG_USB_GADGET
-COBJS-y += epautoconf.o config.o usbstring.o
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
 endif
 ifdef CONFIG_USB_ETHER
-COBJS-y += ether.o epautoconf.o config.o usbstring.o
+COBJS-y += ether.o
 COBJS-$(CONFIG_USB_ETH_RNDIS) += rndis.o
 COBJS-$(CONFIG_MV_UDC) += mv_udc.o
 COBJS-$(CONFIG_CPU_PXA25X) += pxa25x_udc.o
index ebb5131a9cbd2786244184d05aa6fa4a77aade75..2c5600ed5210c9da2e2450132d11d1c65a41578e 100644 (file)
@@ -859,6 +859,25 @@ unknown:
                        if (&f->list == &cdev->config->functions)
                                f = NULL;
                        break;
+               /*
+                * dfu-util (version 0.5) sets bmRequestType.Receipent = Device
+                * for non-standard request (w_value = 0x21,
+                * bRequest = GET_DESCRIPTOR in this case).
+                * When only one interface is registered (as it is done now),
+                * then this request shall be handled as it was requested for
+                * interface.
+                *
+                * In the below code it is checked if only one interface is
+                * present and proper function for it is extracted. Due to that
+                * function's setup (f->setup) is called to handle this
+                * special non-standard request.
+                */
+               case USB_RECIP_DEVICE:
+                       debug("cdev->config->next_interface_id: %d intf: %d\n",
+                              cdev->config->next_interface_id, intf);
+                       if (cdev->config->next_interface_id == 1)
+                               f = cdev->config->interface[intf];
+                       break;
                }
 
                if (f && f->setup)
index 10547e3279b6aadac2cc376ea2d5efd281147ad2..a322ae5eb8720751a7178984e1422fa67b80cd5d 100644 (file)
@@ -164,6 +164,9 @@ static void handle_getstatus(struct usb_request *req)
 
        /* send status response */
        dstat->bStatus = f_dfu->dfu_status;
+       dstat->bwPollTimeout[0] = 0;
+       dstat->bwPollTimeout[1] = 0;
+       dstat->bwPollTimeout[2] = 0;
        dstat->bState = f_dfu->dfu_state;
        dstat->iString = 0;
 }
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
new file mode 100644 (file)
index 0000000..c28866f
--- /dev/null
@@ -0,0 +1,2793 @@
+/*
+ * f_mass_storage.c -- Mass Storage USB Composite Function
+ *
+ * Copyright (C) 2003-2008 Alan Stern
+ * Copyright (C) 2009 Samsung Electronics
+ *                    Author: Michal Nazarewicz <m.nazarewicz@samsung.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+ * The Mass Storage Function acts as a USB Mass Storage device,
+ * appearing to the host as a disk drive or as a CD-ROM drive.  In
+ * addition to providing an example of a genuinely useful composite
+ * function for a USB device, it also illustrates a technique of
+ * double-buffering for increased throughput.
+ *
+ * Function supports multiple logical units (LUNs).  Backing storage
+ * for each LUN is provided by a regular file or a block device.
+ * Access for each LUN can be limited to read-only.  Moreover, the
+ * function can indicate that LUN is removable and/or CD-ROM.  (The
+ * later implies read-only access.)
+ *
+ * MSF is configured by specifying a fsg_config structure.  It has the
+ * following fields:
+ *
+ *     nluns           Number of LUNs function have (anywhere from 1
+ *                             to FSG_MAX_LUNS which is 8).
+ *     luns            An array of LUN configuration values.  This
+ *                             should be filled for each LUN that
+ *                             function will include (ie. for "nluns"
+ *                             LUNs).  Each element of the array has
+ *                             the following fields:
+ *     ->filename      The path to the backing file for the LUN.
+ *                             Required if LUN is not marked as
+ *                             removable.
+ *     ->ro            Flag specifying access to the LUN shall be
+ *                             read-only.  This is implied if CD-ROM
+ *                             emulation is enabled as well as when
+ *                             it was impossible to open "filename"
+ *                             in R/W mode.
+ *     ->removable     Flag specifying that LUN shall be indicated as
+ *                             being removable.
+ *     ->cdrom         Flag specifying that LUN shall be reported as
+ *                             being a CD-ROM.
+ *
+ *     lun_name_format A printf-like format for names of the LUN
+ *                             devices.  This determines how the
+ *                             directory in sysfs will be named.
+ *                             Unless you are using several MSFs in
+ *                             a single gadget (as opposed to single
+ *                             MSF in many configurations) you may
+ *                             leave it as NULL (in which case
+ *                             "lun%d" will be used).  In the format
+ *                             you can use "%d" to index LUNs for
+ *                             MSF's with more than one LUN.  (Beware
+ *                             that there is only one integer given
+ *                             as an argument for the format and
+ *                             specifying invalid format may cause
+ *                             unspecified behaviour.)
+ *     thread_name     Name of the kernel thread process used by the
+ *                             MSF.  You can safely set it to NULL
+ *                             (in which case default "file-storage"
+ *                             will be used).
+ *
+ *     vendor_name
+ *     product_name
+ *     release         Information used as a reply to INQUIRY
+ *                             request.  To use default set to NULL,
+ *                             NULL, 0xffff respectively.  The first
+ *                             field should be 8 and the second 16
+ *                             characters or less.
+ *
+ *     can_stall       Set to permit function to halt bulk endpoints.
+ *                             Disabled on some USB devices known not
+ *                             to work correctly.  You should set it
+ *                             to true.
+ *
+ * If "removable" is not set for a LUN then a backing file must be
+ * specified.  If it is set, then NULL filename means the LUN's medium
+ * is not loaded (an empty string as "filename" in the fsg_config
+ * structure causes error).  The CD-ROM emulation includes a single
+ * data track and no audio tracks; hence there need be only one
+ * backing file per LUN.  Note also that the CD-ROM block length is
+ * set to 512 rather than the more common value 2048.
+ *
+ *
+ * MSF includes support for module parameters.  If gadget using it
+ * decides to use it, the following module parameters will be
+ * available:
+ *
+ *     file=filename[,filename...]
+ *                     Names of the files or block devices used for
+ *                             backing storage.
+ *     ro=b[,b...]     Default false, boolean for read-only access.
+ *     removable=b[,b...]
+ *                     Default true, boolean for removable media.
+ *     cdrom=b[,b...]  Default false, boolean for whether to emulate
+ *                             a CD-ROM drive.
+ *     luns=N          Default N = number of filenames, number of
+ *                             LUNs to support.
+ *     stall           Default determined according to the type of
+ *                             USB device controller (usually true),
+ *                             boolean to permit the driver to halt
+ *                             bulk endpoints.
+ *
+ * The module parameters may be prefixed with some string.  You need
+ * to consult gadget's documentation or source to verify whether it is
+ * using those module parameters and if it does what are the prefixes
+ * (look for FSG_MODULE_PARAMETERS() macro usage, what's inside it is
+ * the prefix).
+ *
+ *
+ * Requirements are modest; only a bulk-in and a bulk-out endpoint are
+ * needed.  The memory requirement amounts to two 16K buffers, size
+ * configurable by a parameter.  Support is included for both
+ * full-speed and high-speed operation.
+ *
+ * Note that the driver is slightly non-portable in that it assumes a
+ * single memory/DMA buffer will be useable for bulk-in, bulk-out, and
+ * interrupt-in endpoints.  With most device controllers this isn't an
+ * issue, but there may be some with hardware restrictions that prevent
+ * a buffer from being used by more than one endpoint.
+ *
+ *
+ * The pathnames of the backing files and the ro settings are
+ * available in the attribute files "file" and "ro" in the lun<n> (or
+ * to be more precise in a directory which name comes from
+ * "lun_name_format" option!) subdirectory of the gadget's sysfs
+ * directory.  If the "removable" option is set, writing to these
+ * files will simulate ejecting/loading the medium (writing an empty
+ * line means eject) and adjusting a write-enable tab.  Changes to the
+ * ro setting are not allowed when the medium is loaded or if CD-ROM
+ * emulation is being used.
+ *
+ * When a LUN receive an "eject" SCSI request (Start/Stop Unit),
+ * if the LUN is removable, the backing file is released to simulate
+ * ejection.
+ *
+ *
+ * This function is heavily based on "File-backed Storage Gadget" by
+ * Alan Stern which in turn is heavily based on "Gadget Zero" by David
+ * Brownell.  The driver's SCSI command interface was based on the
+ * "Information technology - Small Computer System Interface - 2"
+ * document from X3T9.2 Project 375D, Revision 10L, 7-SEP-93,
+ * available at <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>.
+ * The single exception is opcode 0x23 (READ FORMAT CAPACITIES), which
+ * was based on the "Universal Serial Bus Mass Storage Class UFI
+ * Command Specification" document, Revision 1.0, December 14, 1998,
+ * available at
+ * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>.
+ */
+
+
+/*
+ *                             Driver Design
+ *
+ * The MSF is fairly straightforward.  There is a main kernel
+ * thread that handles most of the work.  Interrupt routines field
+ * callbacks from the controller driver: bulk- and interrupt-request
+ * completion notifications, endpoint-0 events, and disconnect events.
+ * Completion events are passed to the main thread by wakeup calls.  Many
+ * ep0 requests are handled at interrupt time, but SetInterface,
+ * SetConfiguration, and device reset requests are forwarded to the
+ * thread in the form of "exceptions" using SIGUSR1 signals (since they
+ * should interrupt any ongoing file I/O operations).
+ *
+ * The thread's main routine implements the standard command/data/status
+ * parts of a SCSI interaction.  It and its subroutines are full of tests
+ * for pending signals/exceptions -- all this polling is necessary since
+ * the kernel has no setjmp/longjmp equivalents.  (Maybe this is an
+ * indication that the driver really wants to be running in userspace.)
+ * An important point is that so long as the thread is alive it keeps an
+ * open reference to the backing file.  This will prevent unmounting
+ * the backing file's underlying filesystem and could cause problems
+ * during system shutdown, for example.  To prevent such problems, the
+ * thread catches INT, TERM, and KILL signals and converts them into
+ * an EXIT exception.
+ *
+ * In normal operation the main thread is started during the gadget's
+ * fsg_bind() callback and stopped during fsg_unbind().  But it can
+ * also exit when it receives a signal, and there's no point leaving
+ * the gadget running when the thread is dead.  At of this moment, MSF
+ * provides no way to deregister the gadget when thread dies -- maybe
+ * a callback functions is needed.
+ *
+ * To provide maximum throughput, the driver uses a circular pipeline of
+ * buffer heads (struct fsg_buffhd).  In principle the pipeline can be
+ * arbitrarily long; in practice the benefits don't justify having more
+ * than 2 stages (i.e., double buffering).  But it helps to think of the
+ * pipeline as being a long one.  Each buffer head contains a bulk-in and
+ * a bulk-out request pointer (since the buffer can be used for both
+ * output and input -- directions always are given from the host's
+ * point of view) as well as a pointer to the buffer and various state
+ * variables.
+ *
+ * Use of the pipeline follows a simple protocol.  There is a variable
+ * (fsg->next_buffhd_to_fill) that points to the next buffer head to use.
+ * At any time that buffer head may still be in use from an earlier
+ * request, so each buffer head has a state variable indicating whether
+ * it is EMPTY, FULL, or BUSY.  Typical use involves waiting for the
+ * buffer head to be EMPTY, filling the buffer either by file I/O or by
+ * USB I/O (during which the buffer head is BUSY), and marking the buffer
+ * head FULL when the I/O is complete.  Then the buffer will be emptied
+ * (again possibly by USB I/O, during which it is marked BUSY) and
+ * finally marked EMPTY again (possibly by a completion routine).
+ *
+ * A module parameter tells the driver to avoid stalling the bulk
+ * endpoints wherever the transport specification allows.  This is
+ * necessary for some UDCs like the SuperH, which cannot reliably clear a
+ * halt on a bulk endpoint.  However, under certain circumstances the
+ * Bulk-only specification requires a stall.  In such cases the driver
+ * will halt the endpoint and set a flag indicating that it should clear
+ * the halt in software during the next device reset.  Hopefully this
+ * will permit everything to work correctly.  Furthermore, although the
+ * specification allows the bulk-out endpoint to halt when the host sends
+ * too much data, implementing this would cause an unavoidable race.
+ * The driver will always use the "no-stall" approach for OUT transfers.
+ *
+ * One subtle point concerns sending status-stage responses for ep0
+ * requests.  Some of these requests, such as device reset, can involve
+ * interrupting an ongoing file I/O operation, which might take an
+ * arbitrarily long time.  During that delay the host might give up on
+ * the original ep0 request and issue a new one.  When that happens the
+ * driver should not notify the host about completion of the original
+ * request, as the host will no longer be waiting for it.  So the driver
+ * assigns to each ep0 request a unique tag, and it keeps track of the
+ * tag value of the request associated with a long-running exception
+ * (device-reset, interface-change, or configuration-change).  When the
+ * exception handler is finished, the status-stage response is submitted
+ * only if the current ep0 request tag is equal to the exception request
+ * tag.  Thus only the most recently received ep0 request will get a
+ * status-stage response.
+ *
+ * Warning: This driver source file is too long.  It ought to be split up
+ * into a header file plus about 3 separate .c files, to handle the details
+ * of the Gadget, USB Mass Storage, and SCSI protocols.
+ */
+
+/* #define VERBOSE_DEBUG */
+/* #define DUMP_MSGS */
+
+#include <config.h>
+#include <malloc.h>
+#include <common.h>
+
+#include <linux/err.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <usb_mass_storage.h>
+
+#include <asm/unaligned.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/composite.h>
+#include <usb/lin_gadget_compat.h>
+
+/*------------------------------------------------------------------------*/
+
+#define FSG_DRIVER_DESC        "Mass Storage Function"
+#define FSG_DRIVER_VERSION     "2012/06/5"
+
+static const char fsg_string_interface[] = "Mass Storage";
+
+
+#define FSG_NO_INTR_EP 1
+#define FSG_NO_DEVICE_STRINGS    1
+#define FSG_NO_OTG               1
+#define FSG_NO_INTR_EP           1
+
+#include "storage_common.c"
+
+/*-------------------------------------------------------------------------*/
+
+#define GFP_ATOMIC ((gfp_t) 0)
+#define PAGE_CACHE_SHIFT       12
+#define PAGE_CACHE_SIZE                (1 << PAGE_CACHE_SHIFT)
+#define kthread_create(...)    __builtin_return_address(0)
+#define wait_for_completion(...) do {} while (0)
+
+struct kref {int x; };
+struct completion {int x; };
+
+inline void set_bit(int nr, volatile void *addr)
+{
+       int     mask;
+       unsigned int *a = (unsigned int *) addr;
+
+       a += nr >> 5;
+       mask = 1 << (nr & 0x1f);
+       *a |= mask;
+}
+
+inline void clear_bit(int nr, volatile void *addr)
+{
+       int     mask;
+       unsigned int *a = (unsigned int *) addr;
+
+       a += nr >> 5;
+       mask = 1 << (nr & 0x1f);
+       *a &= ~mask;
+}
+
+struct fsg_dev;
+struct fsg_common;
+
+/* Data shared by all the FSG instances. */
+struct fsg_common {
+       struct usb_gadget       *gadget;
+       struct fsg_dev          *fsg, *new_fsg;
+
+       struct usb_ep           *ep0;           /* Copy of gadget->ep0 */
+       struct usb_request      *ep0req;        /* Copy of cdev->req */
+       unsigned int            ep0_req_tag;
+
+       struct fsg_buffhd       *next_buffhd_to_fill;
+       struct fsg_buffhd       *next_buffhd_to_drain;
+       struct fsg_buffhd       buffhds[FSG_NUM_BUFFERS];
+
+       int                     cmnd_size;
+       u8                      cmnd[MAX_COMMAND_SIZE];
+
+       unsigned int            nluns;
+       unsigned int            lun;
+       struct fsg_lun          luns[FSG_MAX_LUNS];
+
+       unsigned int            bulk_out_maxpacket;
+       enum fsg_state          state;          /* For exception handling */
+       unsigned int            exception_req_tag;
+
+       enum data_direction     data_dir;
+       u32                     data_size;
+       u32                     data_size_from_cmnd;
+       u32                     tag;
+       u32                     residue;
+       u32                     usb_amount_left;
+
+       unsigned int            can_stall:1;
+       unsigned int            free_storage_on_release:1;
+       unsigned int            phase_error:1;
+       unsigned int            short_packet_received:1;
+       unsigned int            bad_lun_okay:1;
+       unsigned int            running:1;
+
+       int                     thread_wakeup_needed;
+       struct completion       thread_notifier;
+       struct task_struct      *thread_task;
+
+       /* Callback functions. */
+       const struct fsg_operations     *ops;
+       /* Gadget's private data. */
+       void                    *private_data;
+
+       const char *vendor_name;                /*  8 characters or less */
+       const char *product_name;               /* 16 characters or less */
+       u16 release;
+
+       /* Vendor (8 chars), product (16 chars), release (4
+        * hexadecimal digits) and NUL byte */
+       char inquiry_string[8 + 16 + 4 + 1];
+
+       struct kref             ref;
+};
+
+struct fsg_config {
+       unsigned nluns;
+       struct fsg_lun_config {
+               const char *filename;
+               char ro;
+               char removable;
+               char cdrom;
+               char nofua;
+       } luns[FSG_MAX_LUNS];
+
+       /* Callback functions. */
+       const struct fsg_operations     *ops;
+       /* Gadget's private data. */
+       void                    *private_data;
+
+       const char *vendor_name;                /*  8 characters or less */
+       const char *product_name;               /* 16 characters or less */
+
+       char                    can_stall;
+};
+
+struct fsg_dev {
+       struct usb_function     function;
+       struct usb_gadget       *gadget;        /* Copy of cdev->gadget */
+       struct fsg_common       *common;
+
+       u16                     interface_number;
+
+       unsigned int            bulk_in_enabled:1;
+       unsigned int            bulk_out_enabled:1;
+
+       unsigned long           atomic_bitflags;
+#define IGNORE_BULK_OUT                0
+
+       struct usb_ep           *bulk_in;
+       struct usb_ep           *bulk_out;
+};
+
+
+static inline int __fsg_is_set(struct fsg_common *common,
+                              const char *func, unsigned line)
+{
+       if (common->fsg)
+               return 1;
+       ERROR(common, "common->fsg is NULL in %s at %u\n", func, line);
+       WARN_ON(1);
+       return 0;
+}
+
+#define fsg_is_set(common) likely(__fsg_is_set(common, __func__, __LINE__))
+
+
+static inline struct fsg_dev *fsg_from_func(struct usb_function *f)
+{
+       return container_of(f, struct fsg_dev, function);
+}
+
+
+typedef void (*fsg_routine_t)(struct fsg_dev *);
+
+static int exception_in_progress(struct fsg_common *common)
+{
+       return common->state > FSG_STATE_IDLE;
+}
+
+/* Make bulk-out requests be divisible by the maxpacket size */
+static void set_bulk_out_req_length(struct fsg_common *common,
+               struct fsg_buffhd *bh, unsigned int length)
+{
+       unsigned int    rem;
+
+       bh->bulk_out_intended_length = length;
+       rem = length % common->bulk_out_maxpacket;
+       if (rem > 0)
+               length += common->bulk_out_maxpacket - rem;
+       bh->outreq->length = length;
+}
+
+/*-------------------------------------------------------------------------*/
+
+struct ums_board_info                  *ums_info;
+struct fsg_common *the_fsg_common;
+
+static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
+{
+       const char      *name;
+
+       if (ep == fsg->bulk_in)
+               name = "bulk-in";
+       else if (ep == fsg->bulk_out)
+               name = "bulk-out";
+       else
+               name = ep->name;
+       DBG(fsg, "%s set halt\n", name);
+       return usb_ep_set_halt(ep);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* These routines may be called in process context or in_irq */
+
+/* Caller must hold fsg->lock */
+static void wakeup_thread(struct fsg_common *common)
+{
+       common->thread_wakeup_needed = 1;
+}
+
+static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
+{
+       /* Do nothing if a higher-priority exception is already in progress.
+        * If a lower-or-equal priority exception is in progress, preempt it
+        * and notify the main thread by sending it a signal. */
+       if (common->state <= new_state) {
+               common->exception_req_tag = common->ep0_req_tag;
+               common->state = new_state;
+               common->thread_wakeup_needed = 1;
+       }
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int ep0_queue(struct fsg_common *common)
+{
+       int     rc;
+
+       rc = usb_ep_queue(common->ep0, common->ep0req, GFP_ATOMIC);
+       common->ep0->driver_data = common;
+       if (rc != 0 && rc != -ESHUTDOWN) {
+               /* We can't do much more than wait for a reset */
+               WARNING(common, "error in submission: %s --> %d\n",
+                       common->ep0->name, rc);
+       }
+       return rc;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Bulk and interrupt endpoint completion handlers.
+ * These always run in_irq. */
+
+static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct fsg_common       *common = ep->driver_data;
+       struct fsg_buffhd       *bh = req->context;
+
+       if (req->status || req->actual != req->length)
+               DBG(common, "%s --> %d, %u/%u\n", __func__,
+                               req->status, req->actual, req->length);
+       if (req->status == -ECONNRESET)         /* Request was cancelled */
+               usb_ep_fifo_flush(ep);
+
+       /* Hold the lock while we update the request and buffer states */
+       bh->inreq_busy = 0;
+       bh->state = BUF_STATE_EMPTY;
+       wakeup_thread(common);
+}
+
+static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct fsg_common       *common = ep->driver_data;
+       struct fsg_buffhd       *bh = req->context;
+
+       dump_msg(common, "bulk-out", req->buf, req->actual);
+       if (req->status || req->actual != bh->bulk_out_intended_length)
+               DBG(common, "%s --> %d, %u/%u\n", __func__,
+                               req->status, req->actual,
+                               bh->bulk_out_intended_length);
+       if (req->status == -ECONNRESET)         /* Request was cancelled */
+               usb_ep_fifo_flush(ep);
+
+       /* Hold the lock while we update the request and buffer states */
+       bh->outreq_busy = 0;
+       bh->state = BUF_STATE_FULL;
+       wakeup_thread(common);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Ep0 class-specific handlers.  These always run in_irq. */
+
+static int fsg_setup(struct usb_function *f,
+               const struct usb_ctrlrequest *ctrl)
+{
+       struct fsg_dev          *fsg = fsg_from_func(f);
+       struct usb_request      *req = fsg->common->ep0req;
+       u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
+       u16                     w_length = le16_to_cpu(ctrl->wLength);
+
+       if (!fsg_is_set(fsg->common))
+               return -EOPNOTSUPP;
+
+       switch (ctrl->bRequest) {
+
+       case USB_BULK_RESET_REQUEST:
+               if (ctrl->bRequestType !=
+                   (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+                       break;
+               if (w_index != fsg->interface_number || w_value != 0)
+                       return -EDOM;
+
+               /* Raise an exception to stop the current operation
+                * and reinitialize our state. */
+               DBG(fsg, "bulk reset request\n");
+               raise_exception(fsg->common, FSG_STATE_RESET);
+               return DELAYED_STATUS;
+
+       case USB_BULK_GET_MAX_LUN_REQUEST:
+               if (ctrl->bRequestType !=
+                   (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
+                       break;
+               if (w_index != fsg->interface_number || w_value != 0)
+                       return -EDOM;
+               VDBG(fsg, "get max LUN\n");
+               *(u8 *) req->buf = fsg->common->nluns - 1;
+
+               /* Respond with data/status */
+               req->length = min((u16)1, w_length);
+               return ep0_queue(fsg->common);
+       }
+
+       VDBG(fsg,
+            "unknown class-specific control req "
+            "%02x.%02x v%04x i%04x l%u\n",
+            ctrl->bRequestType, ctrl->bRequest,
+            le16_to_cpu(ctrl->wValue), w_index, w_length);
+       return -EOPNOTSUPP;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* All the following routines run in process context */
+
+/* Use this for bulk or interrupt transfers, not ep0 */
+static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
+               struct usb_request *req, int *pbusy,
+               enum fsg_buffer_state *state)
+{
+       int     rc;
+
+       if (ep == fsg->bulk_in)
+               dump_msg(fsg, "bulk-in", req->buf, req->length);
+
+       *pbusy = 1;
+       *state = BUF_STATE_BUSY;
+       rc = usb_ep_queue(ep, req, GFP_KERNEL);
+       if (rc != 0) {
+               *pbusy = 0;
+               *state = BUF_STATE_EMPTY;
+
+               /* We can't do much more than wait for a reset */
+
+               /* Note: currently the net2280 driver fails zero-length
+                * submissions if DMA is enabled. */
+               if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP &&
+                                               req->length == 0))
+                       WARNING(fsg, "error in submission: %s --> %d\n",
+                                       ep->name, rc);
+       }
+}
+
+#define START_TRANSFER_OR(common, ep_name, req, pbusy, state)          \
+       if (fsg_is_set(common))                                         \
+               start_transfer((common)->fsg, (common)->fsg->ep_name,   \
+                              req, pbusy, state);                      \
+       else
+
+#define START_TRANSFER(common, ep_name, req, pbusy, state)             \
+       START_TRANSFER_OR(common, ep_name, req, pbusy, state) (void)0
+
+static void busy_indicator(void)
+{
+       static int state;
+
+       switch (state) {
+       case 0:
+               puts("\r|"); break;
+       case 1:
+               puts("\r/"); break;
+       case 2:
+               puts("\r-"); break;
+       case 3:
+               puts("\r\\"); break;
+       case 4:
+               puts("\r|"); break;
+       case 5:
+               puts("\r/"); break;
+       case 6:
+               puts("\r-"); break;
+       case 7:
+               puts("\r\\"); break;
+       default:
+               state = 0;
+       }
+       if (state++ == 8)
+               state = 0;
+}
+
+static int sleep_thread(struct fsg_common *common)
+{
+       int     rc = 0;
+       int i = 0, k = 0;
+
+       /* Wait until a signal arrives or we are woken up */
+       for (;;) {
+               if (common->thread_wakeup_needed)
+                       break;
+
+               if (++i == 50000) {
+                       busy_indicator();
+                       i = 0;
+                       k++;
+               }
+
+               usb_gadget_handle_interrupts();
+       }
+       common->thread_wakeup_needed = 0;
+       return rc;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int do_read(struct fsg_common *common)
+{
+       struct fsg_lun          *curlun = &common->luns[common->lun];
+       u32                     lba;
+       struct fsg_buffhd       *bh;
+       int                     rc;
+       u32                     amount_left;
+       loff_t                  file_offset;
+       unsigned int            amount;
+       unsigned int            partial_page;
+       ssize_t                 nread;
+
+       /* Get the starting Logical Block Address and check that it's
+        * not too big */
+       if (common->cmnd[0] == SC_READ_6)
+               lba = get_unaligned_be24(&common->cmnd[1]);
+       else {
+               lba = get_unaligned_be32(&common->cmnd[2]);
+
+               /* We allow DPO (Disable Page Out = don't save data in the
+                * cache) and FUA (Force Unit Access = don't read from the
+                * cache), but we don't implement them. */
+               if ((common->cmnd[1] & ~0x18) != 0) {
+                       curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+                       return -EINVAL;
+               }
+       }
+       if (lba >= curlun->num_sectors) {
+               curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+               return -EINVAL;
+       }
+       file_offset = ((loff_t) lba) << 9;
+
+       /* Carry out the file reads */
+       amount_left = common->data_size_from_cmnd;
+       if (unlikely(amount_left == 0))
+               return -EIO;            /* No default reply */
+
+       for (;;) {
+
+               /* Figure out how much we need to read:
+                * Try to read the remaining amount.
+                * But don't read more than the buffer size.
+                * And don't try to read past the end of the file.
+                * Finally, if we're not at a page boundary, don't read past
+                *      the next page.
+                * If this means reading 0 then we were asked to read past
+                *      the end of file. */
+               amount = min(amount_left, FSG_BUFLEN);
+               partial_page = file_offset & (PAGE_CACHE_SIZE - 1);
+               if (partial_page > 0)
+                       amount = min(amount, (unsigned int) PAGE_CACHE_SIZE -
+                                       partial_page);
+
+               /* Wait for the next buffer to become available */
+               bh = common->next_buffhd_to_fill;
+               while (bh->state != BUF_STATE_EMPTY) {
+                       rc = sleep_thread(common);
+                       if (rc)
+                               return rc;
+               }
+
+               /* If we were asked to read past the end of file,
+                * end with an empty buffer. */
+               if (amount == 0) {
+                       curlun->sense_data =
+                                       SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+                       curlun->info_valid = 1;
+                       bh->inreq->length = 0;
+                       bh->state = BUF_STATE_FULL;
+                       break;
+               }
+
+               /* Perform the read */
+               nread = 0;
+               rc = ums_info->read_sector(&(ums_info->ums_dev),
+                                          file_offset / SECTOR_SIZE,
+                                          amount / SECTOR_SIZE,
+                                          (char __user *)bh->buf);
+               if (rc)
+                       return -EIO;
+               nread = amount;
+
+               VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
+                               (unsigned long long) file_offset,
+                               (int) nread);
+
+               if (nread < 0) {
+                       LDBG(curlun, "error in file read: %d\n",
+                                       (int) nread);
+                       nread = 0;
+               } else if (nread < amount) {
+                       LDBG(curlun, "partial file read: %d/%u\n",
+                                       (int) nread, amount);
+                       nread -= (nread & 511); /* Round down to a block */
+               }
+               file_offset  += nread;
+               amount_left  -= nread;
+               common->residue -= nread;
+               bh->inreq->length = nread;
+               bh->state = BUF_STATE_FULL;
+
+               /* If an error occurred, report it and its position */
+               if (nread < amount) {
+                       curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
+                       curlun->info_valid = 1;
+                       break;
+               }
+
+               if (amount_left == 0)
+                       break;          /* No more left to read */
+
+               /* Send this buffer and go read some more */
+               bh->inreq->zero = 0;
+               START_TRANSFER_OR(common, bulk_in, bh->inreq,
+                              &bh->inreq_busy, &bh->state)
+                       /* Don't know what to do if
+                        * common->fsg is NULL */
+                       return -EIO;
+               common->next_buffhd_to_fill = bh->next;
+       }
+
+       return -EIO;            /* No default reply */
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int do_write(struct fsg_common *common)
+{
+       struct fsg_lun          *curlun = &common->luns[common->lun];
+       u32                     lba;
+       struct fsg_buffhd       *bh;
+       int                     get_some_more;
+       u32                     amount_left_to_req, amount_left_to_write;
+       loff_t                  usb_offset, file_offset;
+       unsigned int            amount;
+       unsigned int            partial_page;
+       ssize_t                 nwritten;
+       int                     rc;
+
+       if (curlun->ro) {
+               curlun->sense_data = SS_WRITE_PROTECTED;
+               return -EINVAL;
+       }
+
+       /* Get the starting Logical Block Address and check that it's
+        * not too big */
+       if (common->cmnd[0] == SC_WRITE_6)
+               lba = get_unaligned_be24(&common->cmnd[1]);
+       else {
+               lba = get_unaligned_be32(&common->cmnd[2]);
+
+               /* We allow DPO (Disable Page Out = don't save data in the
+                * cache) and FUA (Force Unit Access = write directly to the
+                * medium).  We don't implement DPO; we implement FUA by
+                * performing synchronous output. */
+               if (common->cmnd[1] & ~0x18) {
+                       curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+                       return -EINVAL;
+               }
+       }
+       if (lba >= curlun->num_sectors) {
+               curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+               return -EINVAL;
+       }
+
+       /* Carry out the file writes */
+       get_some_more = 1;
+       file_offset = usb_offset = ((loff_t) lba) << 9;
+       amount_left_to_req = common->data_size_from_cmnd;
+       amount_left_to_write = common->data_size_from_cmnd;
+
+       while (amount_left_to_write > 0) {
+
+               /* Queue a request for more data from the host */
+               bh = common->next_buffhd_to_fill;
+               if (bh->state == BUF_STATE_EMPTY && get_some_more) {
+
+                       /* Figure out how much we want to get:
+                        * Try to get the remaining amount.
+                        * But don't get more than the buffer size.
+                        * And don't try to go past the end of the file.
+                        * If we're not at a page boundary,
+                        *      don't go past the next page.
+                        * If this means getting 0, then we were asked
+                        *      to write past the end of file.
+                        * Finally, round down to a block boundary. */
+                       amount = min(amount_left_to_req, FSG_BUFLEN);
+                       partial_page = usb_offset & (PAGE_CACHE_SIZE - 1);
+                       if (partial_page > 0)
+                               amount = min(amount,
+       (unsigned int) PAGE_CACHE_SIZE - partial_page);
+
+                       if (amount == 0) {
+                               get_some_more = 0;
+                               curlun->sense_data =
+                                       SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+                               curlun->info_valid = 1;
+                               continue;
+                       }
+                       amount -= (amount & 511);
+                       if (amount == 0) {
+
+                               /* Why were we were asked to transfer a
+                                * partial block? */
+                               get_some_more = 0;
+                               continue;
+                       }
+
+                       /* Get the next buffer */
+                       usb_offset += amount;
+                       common->usb_amount_left -= amount;
+                       amount_left_to_req -= amount;
+                       if (amount_left_to_req == 0)
+                               get_some_more = 0;
+
+                       /* amount is always divisible by 512, hence by
+                        * the bulk-out maxpacket size */
+                       bh->outreq->length = amount;
+                       bh->bulk_out_intended_length = amount;
+                       bh->outreq->short_not_ok = 1;
+                       START_TRANSFER_OR(common, bulk_out, bh->outreq,
+                                         &bh->outreq_busy, &bh->state)
+                               /* Don't know what to do if
+                                * common->fsg is NULL */
+                               return -EIO;
+                       common->next_buffhd_to_fill = bh->next;
+                       continue;
+               }
+
+               /* Write the received data to the backing file */
+               bh = common->next_buffhd_to_drain;
+               if (bh->state == BUF_STATE_EMPTY && !get_some_more)
+                       break;                  /* We stopped early */
+               if (bh->state == BUF_STATE_FULL) {
+                       common->next_buffhd_to_drain = bh->next;
+                       bh->state = BUF_STATE_EMPTY;
+
+                       /* Did something go wrong with the transfer? */
+                       if (bh->outreq->status != 0) {
+                               curlun->sense_data = SS_COMMUNICATION_FAILURE;
+                               curlun->info_valid = 1;
+                               break;
+                       }
+
+                       amount = bh->outreq->actual;
+
+                       /* Perform the write */
+                       rc = ums_info->write_sector(&(ums_info->ums_dev),
+                                              file_offset / SECTOR_SIZE,
+                                              amount / SECTOR_SIZE,
+                                              (char __user *)bh->buf);
+                       if (rc)
+                               return -EIO;
+                       nwritten = amount;
+
+                       VLDBG(curlun, "file write %u @ %llu -> %d\n", amount,
+                                       (unsigned long long) file_offset,
+                                       (int) nwritten);
+
+                       if (nwritten < 0) {
+                               LDBG(curlun, "error in file write: %d\n",
+                                               (int) nwritten);
+                               nwritten = 0;
+                       } else if (nwritten < amount) {
+                               LDBG(curlun, "partial file write: %d/%u\n",
+                                               (int) nwritten, amount);
+                               nwritten -= (nwritten & 511);
+                               /* Round down to a block */
+                       }
+                       file_offset += nwritten;
+                       amount_left_to_write -= nwritten;
+                       common->residue -= nwritten;
+
+                       /* If an error occurred, report it and its position */
+                       if (nwritten < amount) {
+                               curlun->sense_data = SS_WRITE_ERROR;
+                               curlun->info_valid = 1;
+                               break;
+                       }
+
+                       /* Did the host decide to stop early? */
+                       if (bh->outreq->actual != bh->outreq->length) {
+                               common->short_packet_received = 1;
+                               break;
+                       }
+                       continue;
+               }
+
+               /* Wait for something to happen */
+               rc = sleep_thread(common);
+               if (rc)
+                       return rc;
+       }
+
+       return -EIO;            /* No default reply */
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int do_synchronize_cache(struct fsg_common *common)
+{
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int do_verify(struct fsg_common *common)
+{
+       struct fsg_lun          *curlun = &common->luns[common->lun];
+       u32                     lba;
+       u32                     verification_length;
+       struct fsg_buffhd       *bh = common->next_buffhd_to_fill;
+       loff_t                  file_offset;
+       u32                     amount_left;
+       unsigned int            amount;
+       ssize_t                 nread;
+       int                     rc;
+
+       /* Get the starting Logical Block Address and check that it's
+        * not too big */
+       lba = get_unaligned_be32(&common->cmnd[2]);
+       if (lba >= curlun->num_sectors) {
+               curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+               return -EINVAL;
+       }
+
+       /* We allow DPO (Disable Page Out = don't save data in the
+        * cache) but we don't implement it. */
+       if (common->cmnd[1] & ~0x10) {
+               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+               return -EINVAL;
+       }
+
+       verification_length = get_unaligned_be16(&common->cmnd[7]);
+       if (unlikely(verification_length == 0))
+               return -EIO;            /* No default reply */
+
+       /* Prepare to carry out the file verify */
+       amount_left = verification_length << 9;
+       file_offset = ((loff_t) lba) << 9;
+
+       /* Write out all the dirty buffers before invalidating them */
+
+       /* Just try to read the requested blocks */
+       while (amount_left > 0) {
+
+               /* Figure out how much we need to read:
+                * Try to read the remaining amount, but not more than
+                * the buffer size.
+                * And don't try to read past the end of the file.
+                * If this means reading 0 then we were asked to read
+                * past the end of file. */
+               amount = min(amount_left, FSG_BUFLEN);
+               if (amount == 0) {
+                       curlun->sense_data =
+                                       SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+                       curlun->info_valid = 1;
+                       break;
+               }
+
+               /* Perform the read */
+               nread = 0;
+               rc = ums_info->read_sector(&(ums_info->ums_dev),
+                                          file_offset / SECTOR_SIZE,
+                                          amount / SECTOR_SIZE,
+                                          (char __user *)bh->buf);
+               if (rc)
+                       return -EIO;
+               nread = amount;
+
+               VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
+                               (unsigned long long) file_offset,
+                               (int) nread);
+               if (nread < 0) {
+                       LDBG(curlun, "error in file verify: %d\n",
+                                       (int) nread);
+                       nread = 0;
+               } else if (nread < amount) {
+                       LDBG(curlun, "partial file verify: %d/%u\n",
+                                       (int) nread, amount);
+                       nread -= (nread & 511); /* Round down to a sector */
+               }
+               if (nread == 0) {
+                       curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
+                       curlun->info_valid = 1;
+                       break;
+               }
+               file_offset += nread;
+               amount_left -= nread;
+       }
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+       struct fsg_lun *curlun = &common->luns[common->lun];
+       static const char vendor_id[] = "Linux   ";
+       u8      *buf = (u8 *) bh->buf;
+
+       if (!curlun) {          /* Unsupported LUNs are okay */
+               common->bad_lun_okay = 1;
+               memset(buf, 0, 36);
+               buf[0] = 0x7f;          /* Unsupported, no device-type */
+               buf[4] = 31;            /* Additional length */
+               return 36;
+       }
+
+       memset(buf, 0, 8);
+       buf[0] = TYPE_DISK;
+       buf[2] = 2;             /* ANSI SCSI level 2 */
+       buf[3] = 2;             /* SCSI-2 INQUIRY data format */
+       buf[4] = 31;            /* Additional length */
+                               /* No special options */
+       sprintf((char *) (buf + 8), "%-8s%-16s%04x", (char*) vendor_id ,
+                       ums_info->name, (u16) 0xffff);
+
+       return 36;
+}
+
+
+static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+       struct fsg_lun  *curlun = &common->luns[common->lun];
+       u8              *buf = (u8 *) bh->buf;
+       u32             sd, sdinfo;
+       int             valid;
+
+       /*
+        * From the SCSI-2 spec., section 7.9 (Unit attention condition):
+        *
+        * If a REQUEST SENSE command is received from an initiator
+        * with a pending unit attention condition (before the target
+        * generates the contingent allegiance condition), then the
+        * target shall either:
+        *   a) report any pending sense data and preserve the unit
+        *      attention condition on the logical unit, or,
+        *   b) report the unit attention condition, may discard any
+        *      pending sense data, and clear the unit attention
+        *      condition on the logical unit for that initiator.
+        *
+        * FSG normally uses option a); enable this code to use option b).
+        */
+#if 0
+       if (curlun && curlun->unit_attention_data != SS_NO_SENSE) {
+               curlun->sense_data = curlun->unit_attention_data;
+               curlun->unit_attention_data = SS_NO_SENSE;
+       }
+#endif
+
+       if (!curlun) {          /* Unsupported LUNs are okay */
+               common->bad_lun_okay = 1;
+               sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
+               sdinfo = 0;
+               valid = 0;
+       } else {
+               sd = curlun->sense_data;
+               valid = curlun->info_valid << 7;
+               curlun->sense_data = SS_NO_SENSE;
+               curlun->info_valid = 0;
+       }
+
+       memset(buf, 0, 18);
+       buf[0] = valid | 0x70;                  /* Valid, current error */
+       buf[2] = SK(sd);
+       put_unaligned_be32(sdinfo, &buf[3]);    /* Sense information */
+       buf[7] = 18 - 8;                        /* Additional sense length */
+       buf[12] = ASC(sd);
+       buf[13] = ASCQ(sd);
+       return 18;
+}
+
+static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+       struct fsg_lun  *curlun = &common->luns[common->lun];
+       u32             lba = get_unaligned_be32(&common->cmnd[2]);
+       int             pmi = common->cmnd[8];
+       u8              *buf = (u8 *) bh->buf;
+
+       /* Check the PMI and LBA fields */
+       if (pmi > 1 || (pmi == 0 && lba != 0)) {
+               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+               return -EINVAL;
+       }
+
+       put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
+                                               /* Max logical block */
+       put_unaligned_be32(512, &buf[4]);       /* Block length */
+       return 8;
+}
+
+static int do_read_header(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+       struct fsg_lun  *curlun = &common->luns[common->lun];
+       int             msf = common->cmnd[1] & 0x02;
+       u32             lba = get_unaligned_be32(&common->cmnd[2]);
+       u8              *buf = (u8 *) bh->buf;
+
+       if (common->cmnd[1] & ~0x02) {          /* Mask away MSF */
+               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+               return -EINVAL;
+       }
+       if (lba >= curlun->num_sectors) {
+               curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+               return -EINVAL;
+       }
+
+       memset(buf, 0, 8);
+       buf[0] = 0x01;          /* 2048 bytes of user data, rest is EC */
+       store_cdrom_address(&buf[4], msf, lba);
+       return 8;
+}
+
+
+static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+       struct fsg_lun  *curlun = &common->luns[common->lun];
+       int             msf = common->cmnd[1] & 0x02;
+       int             start_track = common->cmnd[6];
+       u8              *buf = (u8 *) bh->buf;
+
+       if ((common->cmnd[1] & ~0x02) != 0 ||   /* Mask away MSF */
+                       start_track > 1) {
+               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+               return -EINVAL;
+       }
+
+       memset(buf, 0, 20);
+       buf[1] = (20-2);                /* TOC data length */
+       buf[2] = 1;                     /* First track number */
+       buf[3] = 1;                     /* Last track number */
+       buf[5] = 0x16;                  /* Data track, copying allowed */
+       buf[6] = 0x01;                  /* Only track is number 1 */
+       store_cdrom_address(&buf[8], msf, 0);
+
+       buf[13] = 0x16;                 /* Lead-out track is data */
+       buf[14] = 0xAA;                 /* Lead-out track number */
+       store_cdrom_address(&buf[16], msf, curlun->num_sectors);
+
+       return 20;
+}
+
+static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+       struct fsg_lun  *curlun = &common->luns[common->lun];
+       int             mscmnd = common->cmnd[0];
+       u8              *buf = (u8 *) bh->buf;
+       u8              *buf0 = buf;
+       int             pc, page_code;
+       int             changeable_values, all_pages;
+       int             valid_page = 0;
+       int             len, limit;
+
+       if ((common->cmnd[1] & ~0x08) != 0) {   /* Mask away DBD */
+               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+               return -EINVAL;
+       }
+       pc = common->cmnd[2] >> 6;
+       page_code = common->cmnd[2] & 0x3f;
+       if (pc == 3) {
+               curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED;
+               return -EINVAL;
+       }
+       changeable_values = (pc == 1);
+       all_pages = (page_code == 0x3f);
+
+       /* Write the mode parameter header.  Fixed values are: default
+        * medium type, no cache control (DPOFUA), and no block descriptors.
+        * The only variable value is the WriteProtect bit.  We will fill in
+        * the mode data length later. */
+       memset(buf, 0, 8);
+       if (mscmnd == SC_MODE_SENSE_6) {
+               buf[2] = (curlun->ro ? 0x80 : 0x00);            /* WP, DPOFUA */
+               buf += 4;
+               limit = 255;
+       } else {                        /* SC_MODE_SENSE_10 */
+               buf[3] = (curlun->ro ? 0x80 : 0x00);            /* WP, DPOFUA */
+               buf += 8;
+               limit = 65535;          /* Should really be FSG_BUFLEN */
+       }
+
+       /* No block descriptors */
+
+       /* The mode pages, in numerical order.  The only page we support
+        * is the Caching page. */
+       if (page_code == 0x08 || all_pages) {
+               valid_page = 1;
+               buf[0] = 0x08;          /* Page code */
+               buf[1] = 10;            /* Page length */
+               memset(buf+2, 0, 10);   /* None of the fields are changeable */
+
+               if (!changeable_values) {
+                       buf[2] = 0x04;  /* Write cache enable, */
+                                       /* Read cache not disabled */
+                                       /* No cache retention priorities */
+                       put_unaligned_be16(0xffff, &buf[4]);
+                                       /* Don't disable prefetch */
+                                       /* Minimum prefetch = 0 */
+                       put_unaligned_be16(0xffff, &buf[8]);
+                                       /* Maximum prefetch */
+                       put_unaligned_be16(0xffff, &buf[10]);
+                                       /* Maximum prefetch ceiling */
+               }
+               buf += 12;
+       }
+
+       /* Check that a valid page was requested and the mode data length
+        * isn't too long. */
+       len = buf - buf0;
+       if (!valid_page || len > limit) {
+               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+               return -EINVAL;
+       }
+
+       /*  Store the mode data length */
+       if (mscmnd == SC_MODE_SENSE_6)
+               buf0[0] = len - 1;
+       else
+               put_unaligned_be16(len - 2, buf0);
+       return len;
+}
+
+
+static int do_start_stop(struct fsg_common *common)
+{
+       struct fsg_lun  *curlun = &common->luns[common->lun];
+
+       if (!curlun) {
+               return -EINVAL;
+       } else if (!curlun->removable) {
+               curlun->sense_data = SS_INVALID_COMMAND;
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int do_prevent_allow(struct fsg_common *common)
+{
+       struct fsg_lun  *curlun = &common->luns[common->lun];
+       int             prevent;
+
+       if (!curlun->removable) {
+               curlun->sense_data = SS_INVALID_COMMAND;
+               return -EINVAL;
+       }
+
+       prevent = common->cmnd[4] & 0x01;
+       if ((common->cmnd[4] & ~0x01) != 0) {   /* Mask away Prevent */
+               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+               return -EINVAL;
+       }
+
+       if (curlun->prevent_medium_removal && !prevent)
+               fsg_lun_fsync_sub(curlun);
+       curlun->prevent_medium_removal = prevent;
+       return 0;
+}
+
+
+static int do_read_format_capacities(struct fsg_common *common,
+                       struct fsg_buffhd *bh)
+{
+       struct fsg_lun  *curlun = &common->luns[common->lun];
+       u8              *buf = (u8 *) bh->buf;
+
+       buf[0] = buf[1] = buf[2] = 0;
+       buf[3] = 8;     /* Only the Current/Maximum Capacity Descriptor */
+       buf += 4;
+
+       put_unaligned_be32(curlun->num_sectors, &buf[0]);
+                                               /* Number of blocks */
+       put_unaligned_be32(512, &buf[4]);       /* Block length */
+       buf[4] = 0x02;                          /* Current capacity */
+       return 12;
+}
+
+
+static int do_mode_select(struct fsg_common *common, struct fsg_buffhd *bh)
+{
+       struct fsg_lun  *curlun = &common->luns[common->lun];
+
+       /* We don't support MODE SELECT */
+       if (curlun)
+               curlun->sense_data = SS_INVALID_COMMAND;
+       return -EINVAL;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
+{
+       int     rc;
+
+       rc = fsg_set_halt(fsg, fsg->bulk_in);
+       if (rc == -EAGAIN)
+               VDBG(fsg, "delayed bulk-in endpoint halt\n");
+       while (rc != 0) {
+               if (rc != -EAGAIN) {
+                       WARNING(fsg, "usb_ep_set_halt -> %d\n", rc);
+                       rc = 0;
+                       break;
+               }
+
+               rc = usb_ep_set_halt(fsg->bulk_in);
+       }
+       return rc;
+}
+
+static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
+{
+       int     rc;
+
+       DBG(fsg, "bulk-in set wedge\n");
+       rc = 0; /* usb_ep_set_wedge(fsg->bulk_in); */
+       if (rc == -EAGAIN)
+               VDBG(fsg, "delayed bulk-in endpoint wedge\n");
+       while (rc != 0) {
+               if (rc != -EAGAIN) {
+                       WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc);
+                       rc = 0;
+                       break;
+               }
+       }
+       return rc;
+}
+
+static int pad_with_zeros(struct fsg_dev *fsg)
+{
+       struct fsg_buffhd       *bh = fsg->common->next_buffhd_to_fill;
+       u32                     nkeep = bh->inreq->length;
+       u32                     nsend;
+       int                     rc;
+
+       bh->state = BUF_STATE_EMPTY;            /* For the first iteration */
+       fsg->common->usb_amount_left = nkeep + fsg->common->residue;
+       while (fsg->common->usb_amount_left > 0) {
+
+               /* Wait for the next buffer to be free */
+               while (bh->state != BUF_STATE_EMPTY) {
+                       rc = sleep_thread(fsg->common);
+                       if (rc)
+                               return rc;
+               }
+
+               nsend = min(fsg->common->usb_amount_left, FSG_BUFLEN);
+               memset(bh->buf + nkeep, 0, nsend - nkeep);
+               bh->inreq->length = nsend;
+               bh->inreq->zero = 0;
+               start_transfer(fsg, fsg->bulk_in, bh->inreq,
+                               &bh->inreq_busy, &bh->state);
+               bh = fsg->common->next_buffhd_to_fill = bh->next;
+               fsg->common->usb_amount_left -= nsend;
+               nkeep = 0;
+       }
+       return 0;
+}
+
+static int throw_away_data(struct fsg_common *common)
+{
+       struct fsg_buffhd       *bh;
+       u32                     amount;
+       int                     rc;
+
+       for (bh = common->next_buffhd_to_drain;
+            bh->state != BUF_STATE_EMPTY || common->usb_amount_left > 0;
+            bh = common->next_buffhd_to_drain) {
+
+               /* Throw away the data in a filled buffer */
+               if (bh->state == BUF_STATE_FULL) {
+                       bh->state = BUF_STATE_EMPTY;
+                       common->next_buffhd_to_drain = bh->next;
+
+                       /* A short packet or an error ends everything */
+                       if (bh->outreq->actual != bh->outreq->length ||
+                                       bh->outreq->status != 0) {
+                               raise_exception(common,
+                                               FSG_STATE_ABORT_BULK_OUT);
+                               return -EINTR;
+                       }
+                       continue;
+               }
+
+               /* Try to submit another request if we need one */
+               bh = common->next_buffhd_to_fill;
+               if (bh->state == BUF_STATE_EMPTY
+                && common->usb_amount_left > 0) {
+                       amount = min(common->usb_amount_left, FSG_BUFLEN);
+
+                       /* amount is always divisible by 512, hence by
+                        * the bulk-out maxpacket size */
+                       bh->outreq->length = amount;
+                       bh->bulk_out_intended_length = amount;
+                       bh->outreq->short_not_ok = 1;
+                       START_TRANSFER_OR(common, bulk_out, bh->outreq,
+                                         &bh->outreq_busy, &bh->state)
+                               /* Don't know what to do if
+                                * common->fsg is NULL */
+                               return -EIO;
+                       common->next_buffhd_to_fill = bh->next;
+                       common->usb_amount_left -= amount;
+                       continue;
+               }
+
+               /* Otherwise wait for something to happen */
+               rc = sleep_thread(common);
+               if (rc)
+                       return rc;
+       }
+       return 0;
+}
+
+
+static int finish_reply(struct fsg_common *common)
+{
+       struct fsg_buffhd       *bh = common->next_buffhd_to_fill;
+       int                     rc = 0;
+
+       switch (common->data_dir) {
+       case DATA_DIR_NONE:
+               break;                  /* Nothing to send */
+
+       /* If we don't know whether the host wants to read or write,
+        * this must be CB or CBI with an unknown command.  We mustn't
+        * try to send or receive any data.  So stall both bulk pipes
+        * if we can and wait for a reset. */
+       case DATA_DIR_UNKNOWN:
+               if (!common->can_stall) {
+                       /* Nothing */
+               } else if (fsg_is_set(common)) {
+                       fsg_set_halt(common->fsg, common->fsg->bulk_out);
+                       rc = halt_bulk_in_endpoint(common->fsg);
+               } else {
+                       /* Don't know what to do if common->fsg is NULL */
+                       rc = -EIO;
+               }
+               break;
+
+       /* All but the last buffer of data must have already been sent */
+       case DATA_DIR_TO_HOST:
+               if (common->data_size == 0) {
+                       /* Nothing to send */
+
+               /* If there's no residue, simply send the last buffer */
+               } else if (common->residue == 0) {
+                       bh->inreq->zero = 0;
+                       START_TRANSFER_OR(common, bulk_in, bh->inreq,
+                                         &bh->inreq_busy, &bh->state)
+                               return -EIO;
+                       common->next_buffhd_to_fill = bh->next;
+
+               /* For Bulk-only, if we're allowed to stall then send the
+                * short packet and halt the bulk-in endpoint.  If we can't
+                * stall, pad out the remaining data with 0's. */
+               } else if (common->can_stall) {
+                       bh->inreq->zero = 1;
+                       START_TRANSFER_OR(common, bulk_in, bh->inreq,
+                                         &bh->inreq_busy, &bh->state)
+                               /* Don't know what to do if
+                                * common->fsg is NULL */
+                               rc = -EIO;
+                       common->next_buffhd_to_fill = bh->next;
+                       if (common->fsg)
+                               rc = halt_bulk_in_endpoint(common->fsg);
+               } else if (fsg_is_set(common)) {
+                       rc = pad_with_zeros(common->fsg);
+               } else {
+                       /* Don't know what to do if common->fsg is NULL */
+                       rc = -EIO;
+               }
+               break;
+
+       /* We have processed all we want from the data the host has sent.
+        * There may still be outstanding bulk-out requests. */
+       case DATA_DIR_FROM_HOST:
+               if (common->residue == 0) {
+                       /* Nothing to receive */
+
+               /* Did the host stop sending unexpectedly early? */
+               } else if (common->short_packet_received) {
+                       raise_exception(common, FSG_STATE_ABORT_BULK_OUT);
+                       rc = -EINTR;
+
+               /* We haven't processed all the incoming data.  Even though
+                * we may be allowed to stall, doing so would cause a race.
+                * The controller may already have ACK'ed all the remaining
+                * bulk-out packets, in which case the host wouldn't see a
+                * STALL.  Not realizing the endpoint was halted, it wouldn't
+                * clear the halt -- leading to problems later on. */
+#if 0
+               } else if (common->can_stall) {
+                       if (fsg_is_set(common))
+                               fsg_set_halt(common->fsg,
+                                            common->fsg->bulk_out);
+                       raise_exception(common, FSG_STATE_ABORT_BULK_OUT);
+                       rc = -EINTR;
+#endif
+
+               /* We can't stall.  Read in the excess data and throw it
+                * all away. */
+               } else {
+                       rc = throw_away_data(common);
+               }
+               break;
+       }
+       return rc;
+}
+
+
+static int send_status(struct fsg_common *common)
+{
+       struct fsg_lun          *curlun = &common->luns[common->lun];
+       struct fsg_buffhd       *bh;
+       struct bulk_cs_wrap     *csw;
+       int                     rc;
+       u8                      status = USB_STATUS_PASS;
+       u32                     sd, sdinfo = 0;
+
+       /* Wait for the next buffer to become available */
+       bh = common->next_buffhd_to_fill;
+       while (bh->state != BUF_STATE_EMPTY) {
+               rc = sleep_thread(common);
+               if (rc)
+                       return rc;
+       }
+
+       if (curlun)
+               sd = curlun->sense_data;
+       else if (common->bad_lun_okay)
+               sd = SS_NO_SENSE;
+       else
+               sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
+
+       if (common->phase_error) {
+               DBG(common, "sending phase-error status\n");
+               status = USB_STATUS_PHASE_ERROR;
+               sd = SS_INVALID_COMMAND;
+       } else if (sd != SS_NO_SENSE) {
+               DBG(common, "sending command-failure status\n");
+               status = USB_STATUS_FAIL;
+               VDBG(common, "  sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
+                       "  info x%x\n",
+                       SK(sd), ASC(sd), ASCQ(sd), sdinfo);
+       }
+
+       /* Store and send the Bulk-only CSW */
+       csw = (void *)bh->buf;
+
+       csw->Signature = cpu_to_le32(USB_BULK_CS_SIG);
+       csw->Tag = common->tag;
+       csw->Residue = cpu_to_le32(common->residue);
+       csw->Status = status;
+
+       bh->inreq->length = USB_BULK_CS_WRAP_LEN;
+       bh->inreq->zero = 0;
+       START_TRANSFER_OR(common, bulk_in, bh->inreq,
+                         &bh->inreq_busy, &bh->state)
+               /* Don't know what to do if common->fsg is NULL */
+               return -EIO;
+
+       common->next_buffhd_to_fill = bh->next;
+       return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Check whether the command is properly formed and whether its data size
+ * and direction agree with the values we already have. */
+static int check_command(struct fsg_common *common, int cmnd_size,
+               enum data_direction data_dir, unsigned int mask,
+               int needs_medium, const char *name)
+{
+       int                     i;
+       int                     lun = common->cmnd[1] >> 5;
+       static const char       dirletter[4] = {'u', 'o', 'i', 'n'};
+       char                    hdlen[20];
+       struct fsg_lun          *curlun;
+
+       hdlen[0] = 0;
+       if (common->data_dir != DATA_DIR_UNKNOWN)
+               sprintf(hdlen, ", H%c=%u", dirletter[(int) common->data_dir],
+                               common->data_size);
+       VDBG(common, "SCSI command: %s;  Dc=%d, D%c=%u;  Hc=%d%s\n",
+            name, cmnd_size, dirletter[(int) data_dir],
+            common->data_size_from_cmnd, common->cmnd_size, hdlen);
+
+       /* We can't reply at all until we know the correct data direction
+        * and size. */
+       if (common->data_size_from_cmnd == 0)
+               data_dir = DATA_DIR_NONE;
+       if (common->data_size < common->data_size_from_cmnd) {
+               /* Host data size < Device data size is a phase error.
+                * Carry out the command, but only transfer as much as
+                * we are allowed. */
+               common->data_size_from_cmnd = common->data_size;
+               common->phase_error = 1;
+       }
+       common->residue = common->data_size;
+       common->usb_amount_left = common->data_size;
+
+       /* Conflicting data directions is a phase error */
+       if (common->data_dir != data_dir
+        && common->data_size_from_cmnd > 0) {
+               common->phase_error = 1;
+               return -EINVAL;
+       }
+
+       /* Verify the length of the command itself */
+       if (cmnd_size != common->cmnd_size) {
+
+               /* Special case workaround: There are plenty of buggy SCSI
+                * implementations. Many have issues with cbw->Length
+                * field passing a wrong command size. For those cases we
+                * always try to work around the problem by using the length
+                * sent by the host side provided it is at least as large
+                * as the correct command length.
+                * Examples of such cases would be MS-Windows, which issues
+                * REQUEST SENSE with cbw->Length == 12 where it should
+                * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and
+                * REQUEST SENSE with cbw->Length == 10 where it should
+                * be 6 as well.
+                */
+               if (cmnd_size <= common->cmnd_size) {
+                       DBG(common, "%s is buggy! Expected length %d "
+                           "but we got %d\n", name,
+                           cmnd_size, common->cmnd_size);
+                       cmnd_size = common->cmnd_size;
+               } else {
+                       common->phase_error = 1;
+                       return -EINVAL;
+               }
+       }
+
+       /* Check that the LUN values are consistent */
+       if (common->lun != lun)
+               DBG(common, "using LUN %d from CBW, not LUN %d from CDB\n",
+                   common->lun, lun);
+
+       /* Check the LUN */
+       if (common->lun >= 0 && common->lun < common->nluns) {
+               curlun = &common->luns[common->lun];
+               if (common->cmnd[0] != SC_REQUEST_SENSE) {
+                       curlun->sense_data = SS_NO_SENSE;
+                       curlun->info_valid = 0;
+               }
+       } else {
+               curlun = NULL;
+               common->bad_lun_okay = 0;
+
+               /* INQUIRY and REQUEST SENSE commands are explicitly allowed
+                * to use unsupported LUNs; all others may not. */
+               if (common->cmnd[0] != SC_INQUIRY &&
+                   common->cmnd[0] != SC_REQUEST_SENSE) {
+                       DBG(common, "unsupported LUN %d\n", common->lun);
+                       return -EINVAL;
+               }
+       }
+#if 0
+       /* If a unit attention condition exists, only INQUIRY and
+        * REQUEST SENSE commands are allowed; anything else must fail. */
+       if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
+                       common->cmnd[0] != SC_INQUIRY &&
+                       common->cmnd[0] != SC_REQUEST_SENSE) {
+               curlun->sense_data = curlun->unit_attention_data;
+               curlun->unit_attention_data = SS_NO_SENSE;
+               return -EINVAL;
+       }
+#endif
+       /* Check that only command bytes listed in the mask are non-zero */
+       common->cmnd[1] &= 0x1f;                        /* Mask away the LUN */
+       for (i = 1; i < cmnd_size; ++i) {
+               if (common->cmnd[i] && !(mask & (1 << i))) {
+                       if (curlun)
+                               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+
+static int do_scsi_command(struct fsg_common *common)
+{
+       struct fsg_buffhd       *bh;
+       int                     rc;
+       int                     reply = -EINVAL;
+       int                     i;
+       static char             unknown[16];
+       struct fsg_lun          *curlun = &common->luns[common->lun];
+
+       dump_cdb(common);
+
+       /* Wait for the next buffer to become available for data or status */
+       bh = common->next_buffhd_to_fill;
+       common->next_buffhd_to_drain = bh;
+       while (bh->state != BUF_STATE_EMPTY) {
+               rc = sleep_thread(common);
+               if (rc)
+                       return rc;
+       }
+       common->phase_error = 0;
+       common->short_packet_received = 0;
+
+       down_read(&common->filesem);    /* We're using the backing file */
+       switch (common->cmnd[0]) {
+
+       case SC_INQUIRY:
+               common->data_size_from_cmnd = common->cmnd[4];
+               reply = check_command(common, 6, DATA_DIR_TO_HOST,
+                                     (1<<4), 0,
+                                     "INQUIRY");
+               if (reply == 0)
+                       reply = do_inquiry(common, bh);
+               break;
+
+       case SC_MODE_SELECT_6:
+               common->data_size_from_cmnd = common->cmnd[4];
+               reply = check_command(common, 6, DATA_DIR_FROM_HOST,
+                                     (1<<1) | (1<<4), 0,
+                                     "MODE SELECT(6)");
+               if (reply == 0)
+                       reply = do_mode_select(common, bh);
+               break;
+
+       case SC_MODE_SELECT_10:
+               common->data_size_from_cmnd =
+                       get_unaligned_be16(&common->cmnd[7]);
+               reply = check_command(common, 10, DATA_DIR_FROM_HOST,
+                                     (1<<1) | (3<<7), 0,
+                                     "MODE SELECT(10)");
+               if (reply == 0)
+                       reply = do_mode_select(common, bh);
+               break;
+
+       case SC_MODE_SENSE_6:
+               common->data_size_from_cmnd = common->cmnd[4];
+               reply = check_command(common, 6, DATA_DIR_TO_HOST,
+                                     (1<<1) | (1<<2) | (1<<4), 0,
+                                     "MODE SENSE(6)");
+               if (reply == 0)
+                       reply = do_mode_sense(common, bh);
+               break;
+
+       case SC_MODE_SENSE_10:
+               common->data_size_from_cmnd =
+                       get_unaligned_be16(&common->cmnd[7]);
+               reply = check_command(common, 10, DATA_DIR_TO_HOST,
+                                     (1<<1) | (1<<2) | (3<<7), 0,
+                                     "MODE SENSE(10)");
+               if (reply == 0)
+                       reply = do_mode_sense(common, bh);
+               break;
+
+       case SC_PREVENT_ALLOW_MEDIUM_REMOVAL:
+               common->data_size_from_cmnd = 0;
+               reply = check_command(common, 6, DATA_DIR_NONE,
+                                     (1<<4), 0,
+                                     "PREVENT-ALLOW MEDIUM REMOVAL");
+               if (reply == 0)
+                       reply = do_prevent_allow(common);
+               break;
+
+       case SC_READ_6:
+               i = common->cmnd[4];
+               common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
+               reply = check_command(common, 6, DATA_DIR_TO_HOST,
+                                     (7<<1) | (1<<4), 1,
+                                     "READ(6)");
+               if (reply == 0)
+                       reply = do_read(common);
+               break;
+
+       case SC_READ_10:
+               common->data_size_from_cmnd =
+                               get_unaligned_be16(&common->cmnd[7]) << 9;
+               reply = check_command(common, 10, DATA_DIR_TO_HOST,
+                                     (1<<1) | (0xf<<2) | (3<<7), 1,
+                                     "READ(10)");
+               if (reply == 0)
+                       reply = do_read(common);
+               break;
+
+       case SC_READ_12:
+               common->data_size_from_cmnd =
+                               get_unaligned_be32(&common->cmnd[6]) << 9;
+               reply = check_command(common, 12, DATA_DIR_TO_HOST,
+                                     (1<<1) | (0xf<<2) | (0xf<<6), 1,
+                                     "READ(12)");
+               if (reply == 0)
+                       reply = do_read(common);
+               break;
+
+       case SC_READ_CAPACITY:
+               common->data_size_from_cmnd = 8;
+               reply = check_command(common, 10, DATA_DIR_TO_HOST,
+                                     (0xf<<2) | (1<<8), 1,
+                                     "READ CAPACITY");
+               if (reply == 0)
+                       reply = do_read_capacity(common, bh);
+               break;
+
+       case SC_READ_HEADER:
+               if (!common->luns[common->lun].cdrom)
+                       goto unknown_cmnd;
+               common->data_size_from_cmnd =
+                       get_unaligned_be16(&common->cmnd[7]);
+               reply = check_command(common, 10, DATA_DIR_TO_HOST,
+                                     (3<<7) | (0x1f<<1), 1,
+                                     "READ HEADER");
+               if (reply == 0)
+                       reply = do_read_header(common, bh);
+               break;
+
+       case SC_READ_TOC:
+               if (!common->luns[common->lun].cdrom)
+                       goto unknown_cmnd;
+               common->data_size_from_cmnd =
+                       get_unaligned_be16(&common->cmnd[7]);
+               reply = check_command(common, 10, DATA_DIR_TO_HOST,
+                                     (7<<6) | (1<<1), 1,
+                                     "READ TOC");
+               if (reply == 0)
+                       reply = do_read_toc(common, bh);
+               break;
+
+       case SC_READ_FORMAT_CAPACITIES:
+               common->data_size_from_cmnd =
+                       get_unaligned_be16(&common->cmnd[7]);
+               reply = check_command(common, 10, DATA_DIR_TO_HOST,
+                                     (3<<7), 1,
+                                     "READ FORMAT CAPACITIES");
+               if (reply == 0)
+                       reply = do_read_format_capacities(common, bh);
+               break;
+
+       case SC_REQUEST_SENSE:
+               common->data_size_from_cmnd = common->cmnd[4];
+               reply = check_command(common, 6, DATA_DIR_TO_HOST,
+                                     (1<<4), 0,
+                                     "REQUEST SENSE");
+               if (reply == 0)
+                       reply = do_request_sense(common, bh);
+               break;
+
+       case SC_START_STOP_UNIT:
+               common->data_size_from_cmnd = 0;
+               reply = check_command(common, 6, DATA_DIR_NONE,
+                                     (1<<1) | (1<<4), 0,
+                                     "START-STOP UNIT");
+               if (reply == 0)
+                       reply = do_start_stop(common);
+               break;
+
+       case SC_SYNCHRONIZE_CACHE:
+               common->data_size_from_cmnd = 0;
+               reply = check_command(common, 10, DATA_DIR_NONE,
+                                     (0xf<<2) | (3<<7), 1,
+                                     "SYNCHRONIZE CACHE");
+               if (reply == 0)
+                       reply = do_synchronize_cache(common);
+               break;
+
+       case SC_TEST_UNIT_READY:
+               common->data_size_from_cmnd = 0;
+               reply = check_command(common, 6, DATA_DIR_NONE,
+                               0, 1,
+                               "TEST UNIT READY");
+               break;
+
+       /* Although optional, this command is used by MS-Windows.  We
+        * support a minimal version: BytChk must be 0. */
+       case SC_VERIFY:
+               common->data_size_from_cmnd = 0;
+               reply = check_command(common, 10, DATA_DIR_NONE,
+                                     (1<<1) | (0xf<<2) | (3<<7), 1,
+                                     "VERIFY");
+               if (reply == 0)
+                       reply = do_verify(common);
+               break;
+
+       case SC_WRITE_6:
+               i = common->cmnd[4];
+               common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
+               reply = check_command(common, 6, DATA_DIR_FROM_HOST,
+                                     (7<<1) | (1<<4), 1,
+                                     "WRITE(6)");
+               if (reply == 0)
+                       reply = do_write(common);
+               break;
+
+       case SC_WRITE_10:
+               common->data_size_from_cmnd =
+                               get_unaligned_be16(&common->cmnd[7]) << 9;
+               reply = check_command(common, 10, DATA_DIR_FROM_HOST,
+                                     (1<<1) | (0xf<<2) | (3<<7), 1,
+                                     "WRITE(10)");
+               if (reply == 0)
+                       reply = do_write(common);
+               break;
+
+       case SC_WRITE_12:
+               common->data_size_from_cmnd =
+                               get_unaligned_be32(&common->cmnd[6]) << 9;
+               reply = check_command(common, 12, DATA_DIR_FROM_HOST,
+                                     (1<<1) | (0xf<<2) | (0xf<<6), 1,
+                                     "WRITE(12)");
+               if (reply == 0)
+                       reply = do_write(common);
+               break;
+
+       /* Some mandatory commands that we recognize but don't implement.
+        * They don't mean much in this setting.  It's left as an exercise
+        * for anyone interested to implement RESERVE and RELEASE in terms
+        * of Posix locks. */
+       case SC_FORMAT_UNIT:
+       case SC_RELEASE:
+       case SC_RESERVE:
+       case SC_SEND_DIAGNOSTIC:
+               /* Fall through */
+
+       default:
+unknown_cmnd:
+               common->data_size_from_cmnd = 0;
+               sprintf(unknown, "Unknown x%02x", common->cmnd[0]);
+               reply = check_command(common, common->cmnd_size,
+                                     DATA_DIR_UNKNOWN, 0xff, 0, unknown);
+               if (reply == 0) {
+                       curlun->sense_data = SS_INVALID_COMMAND;
+                       reply = -EINVAL;
+               }
+               break;
+       }
+       up_read(&common->filesem);
+
+       if (reply == -EINTR)
+               return -EINTR;
+
+       /* Set up the single reply buffer for finish_reply() */
+       if (reply == -EINVAL)
+               reply = 0;              /* Error reply length */
+       if (reply >= 0 && common->data_dir == DATA_DIR_TO_HOST) {
+               reply = min((u32) reply, common->data_size_from_cmnd);
+               bh->inreq->length = reply;
+               bh->state = BUF_STATE_FULL;
+               common->residue -= reply;
+       }                               /* Otherwise it's already set */
+
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+       struct usb_request      *req = bh->outreq;
+       struct fsg_bulk_cb_wrap *cbw = req->buf;
+       struct fsg_common       *common = fsg->common;
+
+       /* Was this a real packet?  Should it be ignored? */
+       if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
+               return -EINVAL;
+
+       /* Is the CBW valid? */
+       if (req->actual != USB_BULK_CB_WRAP_LEN ||
+                       cbw->Signature != cpu_to_le32(
+                               USB_BULK_CB_SIG)) {
+               DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
+                               req->actual,
+                               le32_to_cpu(cbw->Signature));
+
+               /* The Bulk-only spec says we MUST stall the IN endpoint
+                * (6.6.1), so it's unavoidable.  It also says we must
+                * retain this state until the next reset, but there's
+                * no way to tell the controller driver it should ignore
+                * Clear-Feature(HALT) requests.
+                *
+                * We aren't required to halt the OUT endpoint; instead
+                * we can simply accept and discard any data received
+                * until the next reset. */
+               wedge_bulk_in_endpoint(fsg);
+               set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
+               return -EINVAL;
+       }
+
+       /* Is the CBW meaningful? */
+       if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG ||
+                       cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
+               DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
+                               "cmdlen %u\n",
+                               cbw->Lun, cbw->Flags, cbw->Length);
+
+               /* We can do anything we want here, so let's stall the
+                * bulk pipes if we are allowed to. */
+               if (common->can_stall) {
+                       fsg_set_halt(fsg, fsg->bulk_out);
+                       halt_bulk_in_endpoint(fsg);
+               }
+               return -EINVAL;
+       }
+
+       /* Save the command for later */
+       common->cmnd_size = cbw->Length;
+       memcpy(common->cmnd, cbw->CDB, common->cmnd_size);
+       if (cbw->Flags & USB_BULK_IN_FLAG)
+               common->data_dir = DATA_DIR_TO_HOST;
+       else
+               common->data_dir = DATA_DIR_FROM_HOST;
+       common->data_size = le32_to_cpu(cbw->DataTransferLength);
+       if (common->data_size == 0)
+               common->data_dir = DATA_DIR_NONE;
+       common->lun = cbw->Lun;
+       common->tag = cbw->Tag;
+       return 0;
+}
+
+
+static int get_next_command(struct fsg_common *common)
+{
+       struct fsg_buffhd       *bh;
+       int                     rc = 0;
+
+       /* Wait for the next buffer to become available */
+       bh = common->next_buffhd_to_fill;
+       while (bh->state != BUF_STATE_EMPTY) {
+               rc = sleep_thread(common);
+               if (rc)
+                       return rc;
+       }
+
+       /* Queue a request to read a Bulk-only CBW */
+       set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN);
+       bh->outreq->short_not_ok = 1;
+       START_TRANSFER_OR(common, bulk_out, bh->outreq,
+                         &bh->outreq_busy, &bh->state)
+               /* Don't know what to do if common->fsg is NULL */
+               return -EIO;
+
+       /* We will drain the buffer in software, which means we
+        * can reuse it for the next filling.  No need to advance
+        * next_buffhd_to_fill. */
+
+       /* Wait for the CBW to arrive */
+       while (bh->state != BUF_STATE_FULL) {
+               rc = sleep_thread(common);
+               if (rc)
+                       return rc;
+       }
+
+       rc = fsg_is_set(common) ? received_cbw(common->fsg, bh) : -EIO;
+       bh->state = BUF_STATE_EMPTY;
+
+       return rc;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int enable_endpoint(struct fsg_common *common, struct usb_ep *ep,
+               const struct usb_endpoint_descriptor *d)
+{
+       int     rc;
+
+       ep->driver_data = common;
+       rc = usb_ep_enable(ep, d);
+       if (rc)
+               ERROR(common, "can't enable %s, result %d\n", ep->name, rc);
+       return rc;
+}
+
+static int alloc_request(struct fsg_common *common, struct usb_ep *ep,
+               struct usb_request **preq)
+{
+       *preq = usb_ep_alloc_request(ep, GFP_ATOMIC);
+       if (*preq)
+               return 0;
+       ERROR(common, "can't allocate request for %s\n", ep->name);
+       return -ENOMEM;
+}
+
+/* Reset interface setting and re-init endpoint state (toggle etc). */
+static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
+{
+       const struct usb_endpoint_descriptor *d;
+       struct fsg_dev *fsg;
+       int i, rc = 0;
+
+       if (common->running)
+               DBG(common, "reset interface\n");
+
+reset:
+       /* Deallocate the requests */
+       if (common->fsg) {
+               fsg = common->fsg;
+
+               for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+                       struct fsg_buffhd *bh = &common->buffhds[i];
+
+                       if (bh->inreq) {
+                               usb_ep_free_request(fsg->bulk_in, bh->inreq);
+                               bh->inreq = NULL;
+                       }
+                       if (bh->outreq) {
+                               usb_ep_free_request(fsg->bulk_out, bh->outreq);
+                               bh->outreq = NULL;
+                       }
+               }
+
+               /* Disable the endpoints */
+               if (fsg->bulk_in_enabled) {
+                       usb_ep_disable(fsg->bulk_in);
+                       fsg->bulk_in_enabled = 0;
+               }
+               if (fsg->bulk_out_enabled) {
+                       usb_ep_disable(fsg->bulk_out);
+                       fsg->bulk_out_enabled = 0;
+               }
+
+               common->fsg = NULL;
+               /* wake_up(&common->fsg_wait); */
+       }
+
+       common->running = 0;
+       if (!new_fsg || rc)
+               return rc;
+
+       common->fsg = new_fsg;
+       fsg = common->fsg;
+
+       /* Enable the endpoints */
+       d = fsg_ep_desc(common->gadget,
+                       &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
+       rc = enable_endpoint(common, fsg->bulk_in, d);
+       if (rc)
+               goto reset;
+       fsg->bulk_in_enabled = 1;
+
+       d = fsg_ep_desc(common->gadget,
+                       &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
+       rc = enable_endpoint(common, fsg->bulk_out, d);
+       if (rc)
+               goto reset;
+       fsg->bulk_out_enabled = 1;
+       common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
+       clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
+
+       /* Allocate the requests */
+       for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+               struct fsg_buffhd       *bh = &common->buffhds[i];
+
+               rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
+               if (rc)
+                       goto reset;
+               rc = alloc_request(common, fsg->bulk_out, &bh->outreq);
+               if (rc)
+                       goto reset;
+               bh->inreq->buf = bh->outreq->buf = bh->buf;
+               bh->inreq->context = bh->outreq->context = bh;
+               bh->inreq->complete = bulk_in_complete;
+               bh->outreq->complete = bulk_out_complete;
+       }
+
+       common->running = 1;
+
+       return rc;
+}
+
+
+/****************************** ALT CONFIGS ******************************/
+
+
+static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+       struct fsg_dev *fsg = fsg_from_func(f);
+       fsg->common->new_fsg = fsg;
+       raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+       return 0;
+}
+
+static void fsg_disable(struct usb_function *f)
+{
+       struct fsg_dev *fsg = fsg_from_func(f);
+       fsg->common->new_fsg = NULL;
+       raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void handle_exception(struct fsg_common *common)
+{
+       int                     i;
+       struct fsg_buffhd       *bh;
+       enum fsg_state          old_state;
+       struct fsg_lun          *curlun;
+       unsigned int            exception_req_tag;
+
+       /* Cancel all the pending transfers */
+       if (common->fsg) {
+               for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+                       bh = &common->buffhds[i];
+                       if (bh->inreq_busy)
+                               usb_ep_dequeue(common->fsg->bulk_in, bh->inreq);
+                       if (bh->outreq_busy)
+                               usb_ep_dequeue(common->fsg->bulk_out,
+                                              bh->outreq);
+               }
+
+               /* Wait until everything is idle */
+               for (;;) {
+                       int num_active = 0;
+                       for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+                               bh = &common->buffhds[i];
+                               num_active += bh->inreq_busy + bh->outreq_busy;
+                       }
+                       if (num_active == 0)
+                               break;
+                       if (sleep_thread(common))
+                               return;
+               }
+
+               /* Clear out the controller's fifos */
+               if (common->fsg->bulk_in_enabled)
+                       usb_ep_fifo_flush(common->fsg->bulk_in);
+               if (common->fsg->bulk_out_enabled)
+                       usb_ep_fifo_flush(common->fsg->bulk_out);
+       }
+
+       /* Reset the I/O buffer states and pointers, the SCSI
+        * state, and the exception.  Then invoke the handler. */
+
+       for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
+               bh = &common->buffhds[i];
+               bh->state = BUF_STATE_EMPTY;
+       }
+       common->next_buffhd_to_fill = &common->buffhds[0];
+       common->next_buffhd_to_drain = &common->buffhds[0];
+       exception_req_tag = common->exception_req_tag;
+       old_state = common->state;
+
+       if (old_state == FSG_STATE_ABORT_BULK_OUT)
+               common->state = FSG_STATE_STATUS_PHASE;
+       else {
+               for (i = 0; i < common->nluns; ++i) {
+                       curlun = &common->luns[i];
+                       curlun->sense_data = SS_NO_SENSE;
+                       curlun->info_valid = 0;
+               }
+               common->state = FSG_STATE_IDLE;
+       }
+
+       /* Carry out any extra actions required for the exception */
+       switch (old_state) {
+       case FSG_STATE_ABORT_BULK_OUT:
+               send_status(common);
+
+               if (common->state == FSG_STATE_STATUS_PHASE)
+                       common->state = FSG_STATE_IDLE;
+               break;
+
+       case FSG_STATE_RESET:
+               /* In case we were forced against our will to halt a
+                * bulk endpoint, clear the halt now.  (The SuperH UDC
+                * requires this.) */
+               if (!fsg_is_set(common))
+                       break;
+               if (test_and_clear_bit(IGNORE_BULK_OUT,
+                                      &common->fsg->atomic_bitflags))
+                       usb_ep_clear_halt(common->fsg->bulk_in);
+
+               if (common->ep0_req_tag == exception_req_tag)
+                       ep0_queue(common);      /* Complete the status stage */
+
+               break;
+
+       case FSG_STATE_CONFIG_CHANGE:
+               do_set_interface(common, common->new_fsg);
+               break;
+
+       case FSG_STATE_EXIT:
+       case FSG_STATE_TERMINATED:
+               do_set_interface(common, NULL);         /* Free resources */
+               common->state = FSG_STATE_TERMINATED;   /* Stop the thread */
+               break;
+
+       case FSG_STATE_INTERFACE_CHANGE:
+       case FSG_STATE_DISCONNECT:
+       case FSG_STATE_COMMAND_PHASE:
+       case FSG_STATE_DATA_PHASE:
+       case FSG_STATE_STATUS_PHASE:
+       case FSG_STATE_IDLE:
+               break;
+       }
+}
+
+/*-------------------------------------------------------------------------*/
+
+int fsg_main_thread(void *common_)
+{
+       struct fsg_common       *common = the_fsg_common;
+       /* The main loop */
+       do {
+               if (exception_in_progress(common)) {
+                       handle_exception(common);
+                       continue;
+               }
+
+               if (!common->running) {
+                       sleep_thread(common);
+                       continue;
+               }
+
+               if (get_next_command(common))
+                       continue;
+
+               if (!exception_in_progress(common))
+                       common->state = FSG_STATE_DATA_PHASE;
+
+               if (do_scsi_command(common) || finish_reply(common))
+                       continue;
+
+               if (!exception_in_progress(common))
+                       common->state = FSG_STATE_STATUS_PHASE;
+
+               if (send_status(common))
+                       continue;
+
+               if (!exception_in_progress(common))
+                       common->state = FSG_STATE_IDLE;
+       } while (0);
+
+       common->thread_task = NULL;
+
+       return 0;
+}
+
+static void fsg_common_release(struct kref *ref);
+
+static struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                         struct usb_composite_dev *cdev)
+{
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_buffhd *bh;
+       struct fsg_lun *curlun;
+       int nluns, i, rc;
+
+       /* Find out how many LUNs there should be */
+       nluns = 1;
+       if (nluns < 1 || nluns > FSG_MAX_LUNS) {
+               printf("invalid number of LUNs: %u\n", nluns);
+               return ERR_PTR(-EINVAL);
+       }
+
+       /* Allocate? */
+       if (!common) {
+               common = calloc(sizeof *common, 1);
+               if (!common)
+                       return ERR_PTR(-ENOMEM);
+               common->free_storage_on_release = 1;
+       } else {
+               memset(common, 0, sizeof common);
+               common->free_storage_on_release = 0;
+       }
+
+       common->ops = NULL;
+       common->private_data = NULL;
+
+       common->gadget = gadget;
+       common->ep0 = gadget->ep0;
+       common->ep0req = cdev->req;
+
+       /* Maybe allocate device-global string IDs, and patch descriptors */
+       if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
+               rc = usb_string_id(cdev);
+               if (unlikely(rc < 0))
+                       goto error_release;
+               fsg_strings[FSG_STRING_INTERFACE].id = rc;
+               fsg_intf_desc.iInterface = rc;
+       }
+
+       /* Create the LUNs, open their backing files, and register the
+        * LUN devices in sysfs. */
+       curlun = calloc(nluns, sizeof *curlun);
+       if (!curlun) {
+               rc = -ENOMEM;
+               goto error_release;
+       }
+       common->nluns = nluns;
+
+       for (i = 0; i < nluns; i++) {
+               common->luns[i].removable = 1;
+
+               rc = fsg_lun_open(&common->luns[i], "");
+               if (rc)
+                       goto error_luns;
+       }
+       common->lun = 0;
+
+       /* Data buffers cyclic list */
+       bh = common->buffhds;
+
+       i = FSG_NUM_BUFFERS;
+       goto buffhds_first_it;
+       do {
+               bh->next = bh + 1;
+               ++bh;
+buffhds_first_it:
+               bh->inreq_busy = 0;
+               bh->outreq_busy = 0;
+               bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
+               if (unlikely(!bh->buf)) {
+                       rc = -ENOMEM;
+                       goto error_release;
+               }
+       } while (--i);
+       bh->next = common->buffhds;
+
+       snprintf(common->inquiry_string, sizeof common->inquiry_string,
+                "%-8s%-16s%04x",
+                "Linux   ",
+                "File-Store Gadget",
+                0xffff);
+
+       /* Some peripheral controllers are known not to be able to
+        * halt bulk endpoints correctly.  If one of them is present,
+        * disable stalls.
+        */
+
+       /* Tell the thread to start working */
+       common->thread_task =
+               kthread_create(fsg_main_thread, common,
+                              OR(cfg->thread_name, "file-storage"));
+       if (IS_ERR(common->thread_task)) {
+               rc = PTR_ERR(common->thread_task);
+               goto error_release;
+       }
+
+#undef OR
+       /* Information */
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+       INFO(common, "Number of LUNs=%d\n", common->nluns);
+
+       return common;
+
+error_luns:
+       common->nluns = i + 1;
+error_release:
+       common->state = FSG_STATE_TERMINATED;   /* The thread is dead */
+       /* Call fsg_common_release() directly, ref might be not
+        * initialised */
+       fsg_common_release(&common->ref);
+       return ERR_PTR(rc);
+}
+
+static void fsg_common_release(struct kref *ref)
+{
+       struct fsg_common *common = container_of(ref, struct fsg_common, ref);
+
+       /* If the thread isn't already dead, tell it to exit now */
+       if (common->state != FSG_STATE_TERMINATED) {
+               raise_exception(common, FSG_STATE_EXIT);
+               wait_for_completion(&common->thread_notifier);
+       }
+
+       if (likely(common->luns)) {
+               struct fsg_lun *lun = common->luns;
+               unsigned i = common->nluns;
+
+               /* In error recovery common->nluns may be zero. */
+               for (; i; --i, ++lun)
+                       fsg_lun_close(lun);
+
+               kfree(common->luns);
+       }
+
+       {
+               struct fsg_buffhd *bh = common->buffhds;
+               unsigned i = FSG_NUM_BUFFERS;
+               do {
+                       kfree(bh->buf);
+               } while (++bh, --i);
+       }
+
+       if (common->free_storage_on_release)
+               kfree(common);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_copy_descriptors - copy a vector of USB descriptors
+ * @src: null-terminated vector to copy
+ * Context: initialization code, which may sleep
+ *
+ * This makes a copy of a vector of USB descriptors.  Its primary use
+ * is to support usb_function objects which can have multiple copies,
+ * each needing different descriptors.  Functions may have static
+ * tables of descriptors, which are used as templates and customized
+ * with identifiers (for interfaces, strings, endpoints, and more)
+ * as needed by a given function instance.
+ */
+struct usb_descriptor_header **
+usb_copy_descriptors(struct usb_descriptor_header **src)
+{
+       struct usb_descriptor_header **tmp;
+       unsigned bytes;
+       unsigned n_desc;
+       void *mem;
+       struct usb_descriptor_header **ret;
+
+       /* count descriptors and their sizes; then add vector size */
+       for (bytes = 0, n_desc = 0, tmp = src; *tmp; tmp++, n_desc++)
+               bytes += (*tmp)->bLength;
+       bytes += (n_desc + 1) * sizeof(*tmp);
+
+       mem = kmalloc(bytes, GFP_KERNEL);
+       if (!mem)
+               return NULL;
+
+       /* fill in pointers starting at "tmp",
+        * to descriptors copied starting at "mem";
+        * and return "ret"
+        */
+       tmp = mem;
+       ret = mem;
+       mem += (n_desc + 1) * sizeof(*tmp);
+       while (*src) {
+               memcpy(mem, *src, (*src)->bLength);
+               *tmp = mem;
+               tmp++;
+               mem += (*src)->bLength;
+               src++;
+       }
+       *tmp = NULL;
+
+       return ret;
+}
+
+
+
+static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct fsg_dev          *fsg = fsg_from_func(f);
+
+       DBG(fsg, "unbind\n");
+       if (fsg->common->fsg == fsg) {
+               fsg->common->new_fsg = NULL;
+               raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+       }
+
+       free(fsg->function.descriptors);
+       free(fsg->function.hs_descriptors);
+       kfree(fsg);
+}
+
+static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct fsg_dev          *fsg = fsg_from_func(f);
+       struct usb_gadget       *gadget = c->cdev->gadget;
+       int                     i;
+       struct usb_ep           *ep;
+       fsg->gadget = gadget;
+
+       /* New interface */
+       i = usb_interface_id(c, f);
+       if (i < 0)
+               return i;
+       fsg_intf_desc.bInterfaceNumber = i;
+       fsg->interface_number = i;
+
+       /* Find all the endpoints we will use */
+       ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
+       if (!ep)
+               goto autoconf_fail;
+       ep->driver_data = fsg->common;  /* claim the endpoint */
+       fsg->bulk_in = ep;
+
+       ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
+       if (!ep)
+               goto autoconf_fail;
+       ep->driver_data = fsg->common;  /* claim the endpoint */
+       fsg->bulk_out = ep;
+
+       /* Copy descriptors */
+       f->descriptors = usb_copy_descriptors(fsg_fs_function);
+       if (unlikely(!f->descriptors))
+               return -ENOMEM;
+
+       if (gadget_is_dualspeed(gadget)) {
+               /* Assume endpoint addresses are the same for both speeds */
+               fsg_hs_bulk_in_desc.bEndpointAddress =
+                       fsg_fs_bulk_in_desc.bEndpointAddress;
+               fsg_hs_bulk_out_desc.bEndpointAddress =
+                       fsg_fs_bulk_out_desc.bEndpointAddress;
+               f->hs_descriptors = usb_copy_descriptors(fsg_hs_function);
+               if (unlikely(!f->hs_descriptors)) {
+                       free(f->descriptors);
+                       return -ENOMEM;
+               }
+       }
+       return 0;
+
+autoconf_fail:
+       ERROR(fsg, "unable to autoconfigure all endpoints\n");
+       return -ENOTSUPP;
+}
+
+
+/****************************** ADD FUNCTION ******************************/
+
+static struct usb_gadget_strings *fsg_strings_array[] = {
+       &fsg_stringtab,
+       NULL,
+};
+
+static int fsg_bind_config(struct usb_composite_dev *cdev,
+                          struct usb_configuration *c,
+                          struct fsg_common *common)
+{
+       struct fsg_dev *fsg;
+       int rc;
+
+       fsg = calloc(1, sizeof *fsg);
+       if (!fsg)
+               return -ENOMEM;
+       fsg->function.name        = FSG_DRIVER_DESC;
+       fsg->function.strings     = fsg_strings_array;
+       fsg->function.bind        = fsg_bind;
+       fsg->function.unbind      = fsg_unbind;
+       fsg->function.setup       = fsg_setup;
+       fsg->function.set_alt     = fsg_set_alt;
+       fsg->function.disable     = fsg_disable;
+
+       fsg->common               = common;
+       common->fsg               = fsg;
+       /* Our caller holds a reference to common structure so we
+        * don't have to be worry about it being freed until we return
+        * from this function.  So instead of incrementing counter now
+        * and decrement in error recovery we increment it only when
+        * call to usb_add_function() was successful. */
+
+       rc = usb_add_function(c, &fsg->function);
+
+       if (rc)
+               kfree(fsg);
+
+       return rc;
+}
+
+int fsg_add(struct usb_configuration *c)
+{
+       struct fsg_common *fsg_common;
+
+       fsg_common = fsg_common_init(NULL, c->cdev);
+
+       fsg_common->vendor_name = 0;
+       fsg_common->product_name = 0;
+       fsg_common->release = 0xffff;
+
+       fsg_common->ops = NULL;
+       fsg_common->private_data = NULL;
+
+       the_fsg_common = fsg_common;
+
+       return fsg_bind_config(c->cdev, c, fsg_common);
+}
+
+int fsg_init(struct ums_board_info *ums)
+{
+       ums_info = ums;
+
+       return 0;
+}
index a5a4c1fe65f3cd0b79a008c0f3ed86a1a1548622..cc3f3449c97c85b2e4fad5ed46f3f55210d845fc 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "gadget_chips.h"
 #include "composite.c"
+#include "f_mass_storage.c"
 
 /*
  * One needs to define the following:
@@ -104,6 +105,8 @@ static int g_dnl_do_config(struct usb_configuration *c)
        printf("GADGET DRIVER: %s\n", s);
        if (!strcmp(s, "usb_dnl_dfu"))
                ret = dfu_add(c);
+       else if (!strcmp(s, "usb_dnl_ums"))
+               ret = fsg_add(c);
 
        return ret;
 }
@@ -188,6 +191,9 @@ int g_dnl_register(const char *type)
        if (!strcmp(type, "dfu")) {
                strcpy(name, shortname);
                strcat(name, type);
+       } else if (!strcmp(type, "ums")) {
+               strcpy(name, shortname);
+               strcat(name, type);
        } else {
                printf("%s: unknown command: %s\n", __func__, type);
                return -EINVAL;
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
new file mode 100644 (file)
index 0000000..594dc10
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+ * storage_common.c -- Common definitions for mass storage functionality
+ *
+ * Copyright (C) 2003-2008 Alan Stern
+ * Copyeight (C) 2009 Samsung Electronics
+ * Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
+ *
+ * Ported to u-boot:
+ * Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+ *
+ * Code refactoring & cleanup:
+ * Łukasz Majewski <l.majewski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+/*
+ * This file requires the following identifiers used in USB strings to
+ * be defined (each of type pointer to char):
+ *  - fsg_string_manufacturer -- name of the manufacturer
+ *  - fsg_string_product      -- name of the product
+ *  - fsg_string_serial       -- product's serial
+ *  - fsg_string_config       -- name of the configuration
+ *  - fsg_string_interface    -- name of the interface
+ * The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS
+ * macro is defined prior to including this file.
+ */
+
+/*
+ * When FSG_NO_INTR_EP is defined fsg_fs_intr_in_desc and
+ * fsg_hs_intr_in_desc objects as well as
+ * FSG_FS_FUNCTION_PRE_EP_ENTRIES and FSG_HS_FUNCTION_PRE_EP_ENTRIES
+ * macros are not defined.
+ *
+ * When FSG_NO_DEVICE_STRINGS is defined FSG_STRING_MANUFACTURER,
+ * FSG_STRING_PRODUCT, FSG_STRING_SERIAL and FSG_STRING_CONFIG are not
+ * defined (as well as corresponding entries in string tables are
+ * missing) and FSG_STRING_INTERFACE has value of zero.
+ *
+ * When FSG_NO_OTG is defined fsg_otg_desc won't be defined.
+ */
+
+/*
+ * When FSG_BUFFHD_STATIC_BUFFER is defined when this file is included
+ * the fsg_buffhd structure's buf field will be an array of FSG_BUFLEN
+ * characters rather then a pointer to void.
+ */
+
+
+/* #include <asm/unaligned.h> */
+
+
+/*
+ * Thanks to NetChip Technologies for donating this product ID.
+ *
+ * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
+ * Instead:  allocate your own, using normal USB-IF procedures.
+ */
+#define FSG_VENDOR_ID  0x0525  /* NetChip */
+#define FSG_PRODUCT_ID 0xa4a5  /* Linux-USB File-backed Storage Gadget */
+
+/*-------------------------------------------------------------------------*/
+
+#ifndef DEBUG
+#undef VERBOSE_DEBUG
+#undef DUMP_MSGS
+#endif /* !DEBUG */
+
+#ifdef VERBOSE_DEBUG
+#define VLDBG  LDBG
+#else
+#define VLDBG(lun, fmt, args...) do { } while (0)
+#endif /* VERBOSE_DEBUG */
+
+/*
+#define LDBG(lun, fmt, args...)   dev_dbg (&(lun)->dev, fmt, ## args)
+#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
+#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
+#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
+*/
+
+#define LDBG(lun, fmt, args...) do { } while (0)
+#define LERROR(lun, fmt, args...) do { } while (0)
+#define LWARN(lun, fmt, args...) do { } while (0)
+#define LINFO(lun, fmt, args...) do { } while (0)
+
+/*
+ * Keep those macros in sync with those in
+ * include/linux/usb/composite.h or else GCC will complain.  If they
+ * are identical (the same names of arguments, white spaces in the
+ * same places) GCC will allow redefinition otherwise (even if some
+ * white space is removed or added) warning will be issued.
+ *
+ * Those macros are needed here because File Storage Gadget does not
+ * include the composite.h header.  For composite gadgets those macros
+ * are redundant since composite.h is included any way.
+ *
+ * One could check whether those macros are already defined (which
+ * would indicate composite.h had been included) or not (which would
+ * indicate we were in FSG) but this is not done because a warning is
+ * desired if definitions here differ from the ones in composite.h.
+ *
+ * We want the definitions to match and be the same in File Storage
+ * Gadget as well as Mass Storage Function (and so composite gadgets
+ * using MSF).  If someone changes them in composite.h it will produce
+ * a warning in this file when building MSF.
+ */
+
+#define DBG(d, fmt, args...)     debug(fmt , ## args)
+#define VDBG(d, fmt, args...)    debug(fmt , ## args)
+/* #define ERROR(d, fmt, args...)   printf(fmt , ## args) */
+/* #define WARNING(d, fmt, args...) printf(fmt , ## args) */
+/* #define INFO(d, fmt, args...)    printf(fmt , ## args) */
+
+/* #define DBG(d, fmt, args...)     do { } while (0) */
+/* #define VDBG(d, fmt, args...)    do { } while (0) */
+#define ERROR(d, fmt, args...)   do { } while (0)
+#define WARNING(d, fmt, args...) do { } while (0)
+#define INFO(d, fmt, args...)    do { } while (0)
+
+#ifdef DUMP_MSGS
+
+/* dump_msg(fsg, const char * label, const u8 * buf, unsigned length); */
+# define dump_msg(fsg, label, buf, length) do {                         \
+       if (length < 512) {                                             \
+               DBG(fsg, "%s, length %u:\n", label, length);            \
+               print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
+                              16, 1, buf, length, 0);                  \
+       }                                                               \
+} while (0)
+
+#  define dump_cdb(fsg) do { } while (0)
+
+#else
+
+#  define dump_msg(fsg, /* const char * */ label, \
+                  /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
+
+#  ifdef VERBOSE_DEBUG
+
+#    define dump_cdb(fsg)                                              \
+       print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
+                      16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
+
+#  else
+
+#    define dump_cdb(fsg) do { } while (0)
+
+#  endif /* VERBOSE_DEBUG */
+
+#endif /* DUMP_MSGS */
+
+/*-------------------------------------------------------------------------*/
+
+/* SCSI device types */
+#define TYPE_DISK      0x00
+#define TYPE_CDROM     0x05
+
+/* USB protocol value = the transport method */
+#define USB_PR_CBI     0x00            /* Control/Bulk/Interrupt */
+#define USB_PR_CB      0x01            /* Control/Bulk w/o interrupt */
+#define USB_PR_BULK    0x50            /* Bulk-only */
+
+/* USB subclass value = the protocol encapsulation */
+#define USB_SC_RBC     0x01            /* Reduced Block Commands (flash) */
+#define USB_SC_8020    0x02            /* SFF-8020i, MMC-2, ATAPI (CD-ROM) */
+#define USB_SC_QIC     0x03            /* QIC-157 (tape) */
+#define USB_SC_UFI     0x04            /* UFI (floppy) */
+#define USB_SC_8070    0x05            /* SFF-8070i (removable) */
+#define USB_SC_SCSI    0x06            /* Transparent SCSI */
+
+/* Bulk-only data structures */
+
+/* Command Block Wrapper */
+struct fsg_bulk_cb_wrap {
+       __le32  Signature;              /* Contains 'USBC' */
+       u32     Tag;                    /* Unique per command id */
+       __le32  DataTransferLength;     /* Size of the data */
+       u8      Flags;                  /* Direction in bit 7 */
+       u8      Lun;                    /* LUN (normally 0) */
+       u8      Length;                 /* Of the CDB, <= MAX_COMMAND_SIZE */
+       u8      CDB[16];                /* Command Data Block */
+};
+
+#define USB_BULK_CB_WRAP_LEN   31
+#define USB_BULK_CB_SIG                0x43425355      /* Spells out USBC */
+#define USB_BULK_IN_FLAG       0x80
+
+/* Command Status Wrapper */
+struct bulk_cs_wrap {
+       __le32  Signature;              /* Should = 'USBS' */
+       u32     Tag;                    /* Same as original command */
+       __le32  Residue;                /* Amount not transferred */
+       u8      Status;                 /* See below */
+};
+
+#define USB_BULK_CS_WRAP_LEN   13
+#define USB_BULK_CS_SIG                0x53425355      /* Spells out 'USBS' */
+#define USB_STATUS_PASS                0
+#define USB_STATUS_FAIL                1
+#define USB_STATUS_PHASE_ERROR 2
+
+/* Bulk-only class specific requests */
+#define USB_BULK_RESET_REQUEST         0xff
+#define USB_BULK_GET_MAX_LUN_REQUEST   0xfe
+
+/* CBI Interrupt data structure */
+struct interrupt_data {
+       u8      bType;
+       u8      bValue;
+};
+
+#define CBI_INTERRUPT_DATA_LEN         2
+
+/* CBI Accept Device-Specific Command request */
+#define USB_CBI_ADSC_REQUEST           0x00
+
+/* Length of a SCSI Command Data Block */
+#define MAX_COMMAND_SIZE       16
+
+/* SCSI commands that we recognize */
+#define SC_FORMAT_UNIT                 0x04
+#define SC_INQUIRY                     0x12
+#define SC_MODE_SELECT_6               0x15
+#define SC_MODE_SELECT_10              0x55
+#define SC_MODE_SENSE_6                        0x1a
+#define SC_MODE_SENSE_10               0x5a
+#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL        0x1e
+#define SC_READ_6                      0x08
+#define SC_READ_10                     0x28
+#define SC_READ_12                     0xa8
+#define SC_READ_CAPACITY               0x25
+#define SC_READ_FORMAT_CAPACITIES      0x23
+#define SC_READ_HEADER                 0x44
+#define SC_READ_TOC                    0x43
+#define SC_RELEASE                     0x17
+#define SC_REQUEST_SENSE               0x03
+#define SC_RESERVE                     0x16
+#define SC_SEND_DIAGNOSTIC             0x1d
+#define SC_START_STOP_UNIT             0x1b
+#define SC_SYNCHRONIZE_CACHE           0x35
+#define SC_TEST_UNIT_READY             0x00
+#define SC_VERIFY                      0x2f
+#define SC_WRITE_6                     0x0a
+#define SC_WRITE_10                    0x2a
+#define SC_WRITE_12                    0xaa
+
+/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
+#define SS_NO_SENSE                            0
+#define SS_COMMUNICATION_FAILURE               0x040800
+#define SS_INVALID_COMMAND                     0x052000
+#define SS_INVALID_FIELD_IN_CDB                        0x052400
+#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE  0x052100
+#define SS_LOGICAL_UNIT_NOT_SUPPORTED          0x052500
+#define SS_MEDIUM_NOT_PRESENT                  0x023a00
+#define SS_MEDIUM_REMOVAL_PREVENTED            0x055302
+#define SS_NOT_READY_TO_READY_TRANSITION       0x062800
+#define SS_RESET_OCCURRED                      0x062900
+#define SS_SAVING_PARAMETERS_NOT_SUPPORTED     0x053900
+#define SS_UNRECOVERED_READ_ERROR              0x031100
+#define SS_WRITE_ERROR                         0x030c02
+#define SS_WRITE_PROTECTED                     0x072700
+
+#define SK(x)          ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
+#define ASC(x)         ((u8) ((x) >> 8))
+#define ASCQ(x)                ((u8) (x))
+
+struct device_attribute { int i; };
+struct rw_semaphore { int i; };
+#define down_write(...)                        do { } while (0)
+#define up_write(...)                  do { } while (0)
+#define down_read(...)                 do { } while (0)
+#define up_read(...)                   do { } while (0)
+#define ETOOSMALL      525
+
+#include <usb_mass_storage.h>
+extern struct ums_board_info           *ums_info;
+
+/*-------------------------------------------------------------------------*/
+
+struct fsg_lun {
+       loff_t          file_length;
+       loff_t          num_sectors;
+
+       unsigned int    initially_ro:1;
+       unsigned int    ro:1;
+       unsigned int    removable:1;
+       unsigned int    cdrom:1;
+       unsigned int    prevent_medium_removal:1;
+       unsigned int    registered:1;
+       unsigned int    info_valid:1;
+       unsigned int    nofua:1;
+
+       u32             sense_data;
+       u32             sense_data_info;
+       u32             unit_attention_data;
+
+       struct device   dev;
+};
+
+#define fsg_lun_is_open(curlun)        ((curlun)->filp != NULL)
+#if 0
+static struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+{
+       return container_of(dev, struct fsg_lun, dev);
+}
+#endif
+
+/* Big enough to hold our biggest descriptor */
+#define EP0_BUFSIZE    256
+#define DELAYED_STATUS (EP0_BUFSIZE + 999)     /* An impossibly large value */
+
+/* Number of buffers we will use.  2 is enough for double-buffering */
+#define FSG_NUM_BUFFERS        2
+
+/* Default size of buffer length. */
+#define FSG_BUFLEN     ((u32)16384)
+
+/* Maximal number of LUNs supported in mass storage function */
+#define FSG_MAX_LUNS   8
+
+enum fsg_buffer_state {
+       BUF_STATE_EMPTY = 0,
+       BUF_STATE_FULL,
+       BUF_STATE_BUSY
+};
+
+struct fsg_buffhd {
+#ifdef FSG_BUFFHD_STATIC_BUFFER
+       char                            buf[FSG_BUFLEN];
+#else
+       void                            *buf;
+#endif
+       enum fsg_buffer_state           state;
+       struct fsg_buffhd               *next;
+
+       /*
+        * The NetChip 2280 is faster, and handles some protocol faults
+        * better, if we don't submit any short bulk-out read requests.
+        * So we will record the intended request length here.
+        */
+       unsigned int                    bulk_out_intended_length;
+
+       struct usb_request              *inreq;
+       int                             inreq_busy;
+       struct usb_request              *outreq;
+       int                             outreq_busy;
+};
+
+enum fsg_state {
+       /* This one isn't used anywhere */
+       FSG_STATE_COMMAND_PHASE = -10,
+       FSG_STATE_DATA_PHASE,
+       FSG_STATE_STATUS_PHASE,
+
+       FSG_STATE_IDLE = 0,
+       FSG_STATE_ABORT_BULK_OUT,
+       FSG_STATE_RESET,
+       FSG_STATE_INTERFACE_CHANGE,
+       FSG_STATE_CONFIG_CHANGE,
+       FSG_STATE_DISCONNECT,
+       FSG_STATE_EXIT,
+       FSG_STATE_TERMINATED
+};
+
+enum data_direction {
+       DATA_DIR_UNKNOWN = 0,
+       DATA_DIR_FROM_HOST,
+       DATA_DIR_TO_HOST,
+       DATA_DIR_NONE
+};
+
+/*-------------------------------------------------------------------------*/
+
+static inline u32 get_unaligned_be24(u8 *buf)
+{
+       return 0xffffff & (u32) get_unaligned_be32(buf - 1);
+}
+
+/*-------------------------------------------------------------------------*/
+
+enum {
+#ifndef FSG_NO_DEVICE_STRINGS
+       FSG_STRING_MANUFACTURER = 1,
+       FSG_STRING_PRODUCT,
+       FSG_STRING_SERIAL,
+       FSG_STRING_CONFIG,
+#endif
+       FSG_STRING_INTERFACE
+};
+
+#ifndef FSG_NO_OTG
+static struct usb_otg_descriptor
+fsg_otg_desc = {
+       .bLength =              sizeof fsg_otg_desc,
+       .bDescriptorType =      USB_DT_OTG,
+
+       .bmAttributes =         USB_OTG_SRP,
+};
+#endif
+
+/* There is only one interface. */
+
+static struct usb_interface_descriptor
+fsg_intf_desc = {
+       .bLength =              sizeof fsg_intf_desc,
+       .bDescriptorType =      USB_DT_INTERFACE,
+
+       .bNumEndpoints =        2,              /* Adjusted during fsg_bind() */
+       .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
+       .bInterfaceSubClass =   USB_SC_SCSI,    /* Adjusted during fsg_bind() */
+       .bInterfaceProtocol =   USB_PR_BULK,    /* Adjusted during fsg_bind() */
+       .iInterface =           FSG_STRING_INTERFACE,
+};
+
+/*
+ * Three full-speed endpoint descriptors: bulk-in, bulk-out, and
+ * interrupt-in.
+ */
+
+static struct usb_endpoint_descriptor
+fsg_fs_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       /* wMaxPacketSize set by autoconfiguration */
+};
+
+static struct usb_endpoint_descriptor
+fsg_fs_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       /* wMaxPacketSize set by autoconfiguration */
+};
+
+#ifndef FSG_NO_INTR_EP
+
+static struct usb_endpoint_descriptor
+fsg_fs_intr_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_INT,
+       .wMaxPacketSize =       cpu_to_le16(2),
+       .bInterval =            32,     /* frames -> 32 ms */
+};
+
+#ifndef FSG_NO_OTG
+#  define FSG_FS_FUNCTION_PRE_EP_ENTRIES       2
+#else
+#  define FSG_FS_FUNCTION_PRE_EP_ENTRIES       1
+#endif
+
+#endif
+
+static struct usb_descriptor_header *fsg_fs_function[] = {
+#ifndef FSG_NO_OTG
+       (struct usb_descriptor_header *) &fsg_otg_desc,
+#endif
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc,
+#ifndef FSG_NO_INTR_EP
+       (struct usb_descriptor_header *) &fsg_fs_intr_in_desc,
+#endif
+       NULL,
+};
+
+/*
+ * USB 2.0 devices need to expose both high speed and full speed
+ * descriptors, unless they only run at full speed.
+ *
+ * That means alternate endpoint descriptors (bigger packets)
+ * and a "device qualifier" ... plus more construction options
+ * for the configuration descriptor.
+ */
+static struct usb_endpoint_descriptor
+fsg_hs_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor
+fsg_hs_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(512),
+       .bInterval =            1,      /* NAK every 1 uframe */
+};
+
+#ifndef FSG_NO_INTR_EP
+
+static struct usb_endpoint_descriptor
+fsg_hs_intr_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
+       .bmAttributes =         USB_ENDPOINT_XFER_INT,
+       .wMaxPacketSize =       cpu_to_le16(2),
+       .bInterval =            9,      /* 2**(9-1) = 256 uframes -> 32 ms */
+};
+
+#ifndef FSG_NO_OTG
+#  define FSG_HS_FUNCTION_PRE_EP_ENTRIES       2
+#else
+#  define FSG_HS_FUNCTION_PRE_EP_ENTRIES       1
+#endif
+
+#endif
+
+static struct usb_descriptor_header *fsg_hs_function[] = {
+#ifndef FSG_NO_OTG
+       (struct usb_descriptor_header *) &fsg_otg_desc,
+#endif
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc,
+#ifndef FSG_NO_INTR_EP
+       (struct usb_descriptor_header *) &fsg_hs_intr_in_desc,
+#endif
+       NULL,
+};
+
+/* Maxpacket and other transfer characteristics vary by speed. */
+static struct usb_endpoint_descriptor *
+fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
+               struct usb_endpoint_descriptor *hs)
+{
+       if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+               return hs;
+       return fs;
+}
+
+/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+static struct usb_string               fsg_strings[] = {
+#ifndef FSG_NO_DEVICE_STRINGS
+       {FSG_STRING_MANUFACTURER,       fsg_string_manufacturer},
+       {FSG_STRING_PRODUCT,            fsg_string_product},
+       {FSG_STRING_SERIAL,             fsg_string_serial},
+       {FSG_STRING_CONFIG,             fsg_string_config},
+#endif
+       {FSG_STRING_INTERFACE,          fsg_string_interface},
+       {}
+};
+
+static struct usb_gadget_strings       fsg_stringtab = {
+       .language       = 0x0409,               /* en-us */
+       .strings        = fsg_strings,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * If the next two routines are called while the gadget is registered,
+ * the caller must own fsg->filesem for writing.
+ */
+
+static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
+{
+       int                             ro;
+       int                             rc = -EINVAL;
+       loff_t                          size;
+       loff_t                          num_sectors;
+       loff_t                          min_sectors;
+
+       /* R/W if we can, R/O if we must */
+       ro = curlun->initially_ro;
+
+       ums_info->get_capacity(&(ums_info->ums_dev), &size);
+       if (size < 0) {
+               printf("unable to find file size: %s\n", filename);
+               rc = (int) size;
+               goto out;
+       }
+       num_sectors = size >> 9;        /* File size in 512-byte blocks */
+       min_sectors = 1;
+       if (num_sectors < min_sectors) {
+               printf("file too small: %s\n", filename);
+               rc = -ETOOSMALL;
+               goto out;
+       }
+
+       curlun->ro = ro;
+       curlun->file_length = size;
+       curlun->num_sectors = num_sectors;
+       debug("open backing file: %s\n", filename);
+       rc = 0;
+
+out:
+       return rc;
+}
+
+static void fsg_lun_close(struct fsg_lun *curlun)
+{
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Sync the file data, don't bother with the metadata.
+ * This code was copied from fs/buffer.c:sys_fdatasync().
+ */
+static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+{
+       return 0;
+}
+
+static void store_cdrom_address(u8 *dest, int msf, u32 addr)
+{
+       if (msf) {
+               /* Convert to Minutes-Seconds-Frames */
+               addr >>= 2;             /* Convert to 2048-byte frames */
+               addr += 2*75;           /* Lead-in occupies 2 seconds */
+               dest[3] = addr % 75;    /* Frames */
+               addr /= 75;
+               dest[2] = addr % 60;    /* Seconds */
+               addr /= 60;
+               dest[1] = addr;         /* Minutes */
+               dest[0] = 0;            /* Reserved */
+       } else {
+               /* Absolute sector */
+               put_unaligned_be32(addr, dest);
+       }
+}
+
+/*-------------------------------------------------------------------------*/
index 6c947949290d8d37609b10fc67fffbd510bc810e..9a6f9820807bf024d814b1155e916c1db5634aec 100644 (file)
@@ -54,6 +54,7 @@ COBJS-$(CONFIG_USB_EHCI_PPC4XX) += ehci-ppc4xx.o
 COBJS-$(CONFIG_USB_EHCI_IXP4XX) += ehci-ixp.o
 COBJS-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o
 COBJS-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
+COBJS-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o
 COBJS-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
 COBJS-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
 
index 3ca4c5c3312680522ac1a32d017b7ac815256d84..0c797aa0420cd108d61684ef23538d143efe753e 100644 (file)
@@ -42,11 +42,15 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 struct exynos_ehci {
        struct exynos_usb_phy *usb;
-       unsigned int *hcd;
+       struct ehci_hccr *hcd;
 };
 
+static struct exynos_ehci exynos;
+
+#ifdef CONFIG_OF_CONTROL
 static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos)
 {
+       fdt_addr_t addr;
        unsigned int node;
        int depth;
 
@@ -59,12 +63,14 @@ static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos)
        /*
         * Get the base address for EHCI controller from the device node
         */
-       exynos->hcd = (unsigned int *)fdtdec_get_addr(blob, node, "reg");
-       if (exynos->hcd == NULL) {
+       addr = fdtdec_get_addr(blob, node, "reg");
+       if (addr == FDT_ADDR_T_NONE) {
                debug("Can't get the EHCI register address\n");
                return -ENXIO;
        }
 
+       exynos->hcd = (struct ehci_hccr *)addr;
+
        depth = 0;
        node = fdtdec_next_compatible_subnode(blob, node,
                                        COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth);
@@ -85,6 +91,7 @@ static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos)
 
        return 0;
 }
+#endif
 
 /* Setup the EHCI host controller. */
 static void setup_usb_phy(struct exynos_usb_phy *usb)
@@ -144,20 +151,21 @@ static void reset_usb_phy(struct exynos_usb_phy *usb)
  */
 int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       struct exynos_ehci *exynos = NULL;
+       struct exynos_ehci *ctx = &exynos;
 
-       exynos = (struct exynos_ehci *)
-                       kzalloc(sizeof(struct exynos_ehci), GFP_KERNEL);
-       if (!exynos) {
-               debug("failed to allocate exynos ehci context\n");
-               return -ENOMEM;
+#ifdef CONFIG_OF_CONTROL
+       if (exynos_usb_parse_dt(gd->fdt_blob, ctx)) {
+               debug("Unable to parse device tree for ehci-exynos\n");
+               return -ENODEV;
        }
+#else
+       ctx->usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy();
+       ctx->hcd = (struct ehci_hccr *)samsung_get_base_usb_ehci();
+#endif
 
-       exynos_usb_parse_dt(gd->fdt_blob, exynos);
+       setup_usb_phy(ctx->usb);
 
-       setup_usb_phy(exynos->usb);
-
-       *hccr = (struct ehci_hccr *)(exynos->hcd);
+       *hccr = ctx->hcd;
        *hcor = (struct ehci_hcor *)((uint32_t) *hccr
                                + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
@@ -165,8 +173,6 @@ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
                (uint32_t)*hccr, (uint32_t)*hcor,
                (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
-       kfree(exynos);
-
        return 0;
 }
 
@@ -176,20 +182,9 @@ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
  */
 int ehci_hcd_stop(int index)
 {
-       struct exynos_ehci *exynos = NULL;
-
-       exynos = (struct exynos_ehci *)
-                       kzalloc(sizeof(struct exynos_ehci), GFP_KERNEL);
-       if (!exynos) {
-               debug("failed to allocate exynos ehci context\n");
-               return -ENOMEM;
-       }
-
-       exynos_usb_parse_dt(gd->fdt_blob, exynos);
-
-       reset_usb_phy(exynos->usb);
+       struct exynos_ehci *ctx = &exynos;
 
-       kfree(exynos);
+       reset_usb_phy(ctx->usb);
 
        return 0;
 }
index 7f98a6354ac4227515cb412f8ed5abde3ed63cdb..c8168782069a3ded3c053c16b04ec0c0c7c9a6ba 100644 (file)
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <errno.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 #include <usb.h>
 #include <asm/io.h>
 #include <malloc.h>
 #include <watchdog.h>
+#include <linux/compiler.h>
 
 #include "ehci.h"
 
@@ -39,7 +41,10 @@ static struct ehci_ctrl {
        struct ehci_hcor *hcor;
        int rootdev;
        uint16_t portreset;
-       struct QH qh_list __attribute__((aligned(USB_DMA_MINALIGN)));
+       struct QH qh_list __aligned(USB_DMA_MINALIGN);
+       struct QH periodic_queue __aligned(USB_DMA_MINALIGN);
+       uint32_t *periodic_list;
+       int ntds;
 } ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
 
 #define ALIGN_END_ADDR(type, ptr, size)                        \
@@ -858,6 +863,8 @@ int usb_lowlevel_init(int index, void **controller)
        uint32_t reg;
        uint32_t cmd;
        struct QH *qh_list;
+       struct QH *periodic;
+       int i;
 
        if (ehci_hcd_init(index, &ehcic[index].hccr, &ehcic[index].hcor))
                return -1;
@@ -870,6 +877,9 @@ int usb_lowlevel_init(int index, void **controller)
        if (ehci_hcd_init(index, &ehcic[index].hccr, &ehcic[index].hcor))
                return -1;
 #endif
+       /* Set the high address word (aka segment) for 64-bit controller */
+       if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1)
+               ehci_writel(ehcic[index].hcor->or_ctrldssegment, 0);
 
        qh_list = &ehcic[index].qh_list;
 
@@ -884,6 +894,40 @@ int usb_lowlevel_init(int index, void **controller)
        qh_list->qh_overlay.qt_token =
                        cpu_to_hc32(QT_TOKEN_STATUS(QT_TOKEN_STATUS_HALTED));
 
+       /* Set async. queue head pointer. */
+       ehci_writel(&ehcic[index].hcor->or_asynclistaddr, (uint32_t)qh_list);
+
+       /*
+        * Set up periodic list
+        * Step 1: Parent QH for all periodic transfers.
+        */
+       periodic = &ehcic[index].periodic_queue;
+       memset(periodic, 0, sizeof(*periodic));
+       periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
+       periodic->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+       periodic->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+
+       /*
+        * Step 2: Setup frame-list: Every microframe, USB tries the same list.
+        *         In particular, device specifications on polling frequency
+        *         are disregarded. Keyboards seem to send NAK/NYet reliably
+        *         when polled with an empty buffer.
+        *
+        *         Split Transactions will be spread across microframes using
+        *         S-mask and C-mask.
+        */
+       ehcic[index].periodic_list = memalign(4096, 1024*4);
+       if (!ehcic[index].periodic_list)
+               return -ENOMEM;
+       for (i = 0; i < 1024; i++) {
+               ehcic[index].periodic_list[i] = (uint32_t)periodic
+                                               | QH_LINK_TYPE_QH;
+       }
+
+       /* Set periodic list base address */
+       ehci_writel(&ehcic[index].hcor->or_periodiclistbase,
+               (uint32_t)ehcic[index].periodic_list);
+
        reg = ehci_readl(&ehcic[index].hccr->cr_hcsparams);
        descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
        debug("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
@@ -953,10 +997,254 @@ submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
        return ehci_submit_async(dev, pipe, buffer, length, setup);
 }
 
+struct int_queue {
+       struct QH *first;
+       struct QH *current;
+       struct QH *last;
+       struct qTD *tds;
+};
+
+#define NEXT_QH(qh) (struct QH *)((qh)->qh_link & ~0x1f)
+
+static int
+enable_periodic(struct ehci_ctrl *ctrl)
+{
+       uint32_t cmd;
+       struct ehci_hcor *hcor = ctrl->hcor;
+       int ret;
+
+       cmd = ehci_readl(&hcor->or_usbcmd);
+       cmd |= CMD_PSE;
+       ehci_writel(&hcor->or_usbcmd, cmd);
+
+       ret = handshake((uint32_t *)&hcor->or_usbsts,
+                       STS_PSS, STS_PSS, 100 * 1000);
+       if (ret < 0) {
+               printf("EHCI failed: timeout when enabling periodic list\n");
+               return -ETIMEDOUT;
+       }
+       udelay(1000);
+       return 0;
+}
+
+static int
+disable_periodic(struct ehci_ctrl *ctrl)
+{
+       uint32_t cmd;
+       struct ehci_hcor *hcor = ctrl->hcor;
+       int ret;
+
+       cmd = ehci_readl(&hcor->or_usbcmd);
+       cmd &= ~CMD_PSE;
+       ehci_writel(&hcor->or_usbcmd, cmd);
+
+       ret = handshake((uint32_t *)&hcor->or_usbsts,
+                       STS_PSS, 0, 100 * 1000);
+       if (ret < 0) {
+               printf("EHCI failed: timeout when disabling periodic list\n");
+               return -ETIMEDOUT;
+       }
+       return 0;
+}
+
+static int periodic_schedules;
+
+struct int_queue *
+create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
+                int elementsize, void *buffer)
+{
+       struct ehci_ctrl *ctrl = dev->controller;
+       struct int_queue *result = NULL;
+       int i;
+
+       debug("Enter create_int_queue\n");
+       if (usb_pipetype(pipe) != PIPE_INTERRUPT) {
+               debug("non-interrupt pipe (type=%lu)", usb_pipetype(pipe));
+               return NULL;
+       }
+
+       /* limit to 4 full pages worth of data -
+        * we can safely fit them in a single TD,
+        * no matter the alignment
+        */
+       if (elementsize >= 16384) {
+               debug("too large elements for interrupt transfers\n");
+               return NULL;
+       }
+
+       result = malloc(sizeof(*result));
+       if (!result) {
+               debug("ehci intr queue: out of memory\n");
+               goto fail1;
+       }
+       result->first = memalign(32, sizeof(struct QH) * queuesize);
+       if (!result->first) {
+               debug("ehci intr queue: out of memory\n");
+               goto fail2;
+       }
+       result->current = result->first;
+       result->last = result->first + queuesize - 1;
+       result->tds = memalign(32, sizeof(struct qTD) * queuesize);
+       if (!result->tds) {
+               debug("ehci intr queue: out of memory\n");
+               goto fail3;
+       }
+       memset(result->first, 0, sizeof(struct QH) * queuesize);
+       memset(result->tds, 0, sizeof(struct qTD) * queuesize);
+
+       for (i = 0; i < queuesize; i++) {
+               struct QH *qh = result->first + i;
+               struct qTD *td = result->tds + i;
+               void **buf = &qh->buffer;
+
+               qh->qh_link = (uint32_t)(qh+1) | QH_LINK_TYPE_QH;
+               if (i == queuesize - 1)
+                       qh->qh_link = QH_LINK_TERMINATE;
+
+               qh->qh_overlay.qt_next = (uint32_t)td;
+               qh->qh_endpt1 = (0 << 28) | /* No NAK reload (ehci 4.9) */
+                       (usb_maxpacket(dev, pipe) << 16) | /* MPS */
+                       (1 << 14) |
+                       QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) |
+                       (usb_pipeendpoint(pipe) << 8) | /* Endpoint Number */
+                       (usb_pipedevice(pipe) << 0);
+               qh->qh_endpt2 = (1 << 30) | /* 1 Tx per mframe */
+                       (1 << 0); /* S-mask: microframe 0 */
+               if (dev->speed == USB_SPEED_LOW ||
+                               dev->speed == USB_SPEED_FULL) {
+                       debug("TT: port: %d, hub address: %d\n",
+                               dev->portnr, dev->parent->devnum);
+                       qh->qh_endpt2 |= (dev->portnr << 23) |
+                               (dev->parent->devnum << 16) |
+                               (0x1c << 8); /* C-mask: microframes 2-4 */
+               }
+
+               td->qt_next = QT_NEXT_TERMINATE;
+               td->qt_altnext = QT_NEXT_TERMINATE;
+               debug("communication direction is '%s'\n",
+                     usb_pipein(pipe) ? "in" : "out");
+               td->qt_token = (elementsize << 16) |
+                       ((usb_pipein(pipe) ? 1 : 0) << 8) | /* IN/OUT token */
+                       0x80; /* active */
+               td->qt_buffer[0] = (uint32_t)buffer + i * elementsize;
+               td->qt_buffer[1] = (td->qt_buffer[0] + 0x1000) & ~0xfff;
+               td->qt_buffer[2] = (td->qt_buffer[0] + 0x2000) & ~0xfff;
+               td->qt_buffer[3] = (td->qt_buffer[0] + 0x3000) & ~0xfff;
+               td->qt_buffer[4] = (td->qt_buffer[0] + 0x4000) & ~0xfff;
+
+               *buf = buffer + i * elementsize;
+       }
+
+       if (disable_periodic(ctrl) < 0) {
+               debug("FATAL: periodic should never fail, but did");
+               goto fail3;
+       }
+
+       /* hook up to periodic list */
+       struct QH *list = &ctrl->periodic_queue;
+       result->last->qh_link = list->qh_link;
+       list->qh_link = (uint32_t)result->first | QH_LINK_TYPE_QH;
+
+       if (enable_periodic(ctrl) < 0) {
+               debug("FATAL: periodic should never fail, but did");
+               goto fail3;
+       }
+       periodic_schedules++;
+
+       debug("Exit create_int_queue\n");
+       return result;
+fail3:
+       if (result->tds)
+               free(result->tds);
+fail2:
+       if (result->first)
+               free(result->first);
+       if (result)
+               free(result);
+fail1:
+       return NULL;
+}
+
+void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+       struct QH *cur = queue->current;
+
+       /* depleted queue */
+       if (cur == NULL) {
+               debug("Exit poll_int_queue with completed queue\n");
+               return NULL;
+       }
+       /* still active */
+       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);
+               return NULL;
+       }
+       if (!(cur->qh_link & QH_LINK_TERMINATE))
+               queue->current++;
+       else
+               queue->current = NULL;
+       debug("Exit poll_int_queue with completed intr transfer. "
+             "token is %x at %p (first at %p)\n", cur->qh_overlay.qt_token,
+             &cur->qh_overlay.qt_token, queue->first);
+       return cur->buffer;
+}
+
+/* Do not free buffers associated with QHs, they're owned by someone else */
+int
+destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+       struct ehci_ctrl *ctrl = dev->controller;
+       int result = -1;
+       unsigned long timeout;
+
+       if (disable_periodic(ctrl) < 0) {
+               debug("FATAL: periodic should never fail, but did");
+               goto out;
+       }
+       periodic_schedules--;
+
+       struct QH *cur = &ctrl->periodic_queue;
+       timeout = get_timer(0) + 500; /* abort after 500ms */
+       while (!(cur->qh_link & QH_LINK_TERMINATE)) {
+               debug("considering %p, with qh_link %x\n", cur, cur->qh_link);
+               if (NEXT_QH(cur) == queue->first) {
+                       debug("found candidate. removing from chain\n");
+                       cur->qh_link = queue->last->qh_link;
+                       result = 0;
+                       break;
+               }
+               cur = NEXT_QH(cur);
+               if (get_timer(0) > timeout) {
+                       printf("Timeout destroying interrupt endpoint queue\n");
+                       result = -1;
+                       goto out;
+               }
+       }
+
+       if (periodic_schedules > 0) {
+               result = enable_periodic(ctrl);
+               if (result < 0)
+                       debug("FATAL: periodic should never fail, but did");
+       }
+
+out:
+       free(queue->tds);
+       free(queue->first);
+       free(queue);
+
+       return result;
+}
+
 int
 submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
               int length, int interval)
 {
+       void *backbuffer;
+       struct int_queue *queue;
+       unsigned long timeout;
+       int result = 0, ret;
+
        debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d",
              dev, pipe, buffer, length, interval);
 
@@ -972,9 +1260,31 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
         * not require more than a single qTD.
         */
        if (length > usb_maxpacket(dev, pipe)) {
-               printf("%s: Interrupt transfers requiring several transactions "
-                       "are not supported.\n", __func__);
+               printf("%s: Interrupt transfers requiring several "
+                       "transactions are not supported.\n", __func__);
                return -1;
        }
-       return ehci_submit_async(dev, pipe, buffer, length, NULL);
+
+       queue = create_int_queue(dev, pipe, 1, length, buffer);
+
+       timeout = get_timer(0) + USB_TIMEOUT_MS(pipe);
+       while ((backbuffer = poll_int_queue(dev, queue)) == NULL)
+               if (get_timer(0) > timeout) {
+                       printf("Timeout poll on interrupt endpoint\n");
+                       result = -ETIMEDOUT;
+                       break;
+               }
+
+       if (backbuffer != buffer) {
+               debug("got wrong buffer back (%x instead of %x)\n",
+                     (uint32_t)backbuffer, (uint32_t)buffer);
+               return -EINVAL;
+       }
+
+       ret = destroy_int_queue(dev, queue);
+       if (ret < 0)
+               return ret;
+
+       /* everything worked out fine */
+       return result;
 }
index 29af02dc5b4b9f2eec558b2d75c14e279e2dc044..90d7a6feb56c5a1b3dc648435e2e43c05ed5bca9 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <common.h>
+#include <errno.h>
 #include <pci.h>
 #include <usb.h>
 
@@ -32,31 +33,76 @@ static struct pci_device_id ehci_pci_ids[] = {
        {0x12D8, 0x400F},       /* Pericom */
        {0, 0}
 };
+#else
+static pci_dev_t ehci_find_class(int index)
+{
+       int bus;
+       int devnum;
+       pci_dev_t bdf;
+       uint32_t class;
+
+       for (bus = 0; bus <= pci_last_busno(); bus++) {
+               for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES-1; devnum++) {
+                       pci_read_config_dword(PCI_BDF(bus, devnum, 0),
+                                             PCI_CLASS_REVISION, &class);
+                       if (class >> 16 == 0xffff)
+                               continue;
+
+                       for (bdf = PCI_BDF(bus, devnum, 0);
+                                       bdf <= PCI_BDF(bus, devnum,
+                                               PCI_MAX_PCI_FUNCTIONS - 1);
+                                       bdf += PCI_BDF(0, 0, 1)) {
+                               pci_read_config_dword(bdf, PCI_CLASS_REVISION,
+                                                     &class);
+                               if ((class >> 8 == PCI_CLASS_SERIAL_USB_EHCI)
+                                               && !index--)
+                                       return bdf;
+                       }
+               }
+       }
+
+       return -ENODEV;
+}
 #endif
 
 /*
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
  */
-int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
+int ehci_hcd_init(int index, struct ehci_hccr **ret_hccr,
+               struct ehci_hcor **ret_hcor)
 {
        pci_dev_t pdev;
+       uint32_t cmd;
+       struct ehci_hccr *hccr;
+       struct ehci_hcor *hcor;
 
+#ifdef CONFIG_PCI_EHCI_DEVICE
        pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE);
-       if (pdev == -1) {
+#else
+       pdev = ehci_find_class(index);
+#endif
+       if (pdev < 0) {
                printf("EHCI host controller not found\n");
                return -1;
        }
 
-       *hccr = (struct ehci_hccr *)pci_map_bar(pdev,
+       hccr = (struct ehci_hccr *)pci_map_bar(pdev,
                        PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
-       *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
-                       HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
+       hcor = (struct ehci_hcor *)((uint32_t) hccr +
+                       HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
 
        debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
-                       (uint32_t)*hccr, (uint32_t)*hcor,
-                       (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
+                       (uint32_t)hccr, (uint32_t)hcor,
+                       (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+       *ret_hccr = hccr;
+       *ret_hcor = hcor;
 
+       /* enable busmaster */
+       pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
+       cmd |= PCI_COMMAND_MASTER;
+       pci_write_config_dword(pdev, PCI_COMMAND, cmd);
        return 0;
 }
 
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
new file mode 100644 (file)
index 0000000..f99bd1f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * (C) Copyright 2010
+ * Armando Visconti, ST Micoelectronics, <armando.visconti@st.com>.
+ *
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <usb.h>
+#include "ehci.h"
+#include <asm/arch/hardware.h>
+
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ */
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
+{
+       *hccr = (struct ehci_hccr *)(CONFIG_SYS_UHC0_EHCI_BASE + 0x100);
+       *hcor = (struct ehci_hcor *)((uint32_t)*hccr
+                       + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
+
+       debug("SPEAr-ehci: init hccr %x and hcor %x hc_length %d\n",
+               (uint32_t)*hccr, (uint32_t)*hcor,
+               (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
+
+       return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop(int index)
+{
+       return 0;
+}
index 1e3cd793b6091650ed1e7ed61b6bfca3f7046a69..d090f0a53e87349ee96a5bfe7d64a917bf153d0e 100644 (file)
@@ -69,6 +69,7 @@ struct ehci_hcor {
 #define CMD_RUN                (1 << 0)                /* start/stop HC */
        uint32_t or_usbsts;
 #define STS_ASS                (1 << 15)
+#define        STS_PSS         (1 << 14)
 #define STS_HALT       (1 << 12)
        uint32_t or_usbintr;
 #define INTR_UE         (1 << 0)                /* USB interrupt enable */
@@ -245,7 +246,10 @@ struct QH {
         * Add dummy fill value to make the size of this struct
         * aligned to 32 bytes
         */
-       uint8_t fill[16];
+       union {
+               uint32_t fill[4];
+               void *buffer;
+       };
 };
 
 /* Low level init functions */
index 170a358b5283849207827f21d7eb49dc419d9acf..e8cecca55a93db2a663e31483a69603e4b0ccab9 100644 (file)
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_S6E63D6) += s6e63d6.o
 COBJS-$(CONFIG_LD9040) += ld9040.o
 COBJS-$(CONFIG_SED156X) += sed156x.o
 COBJS-$(CONFIG_VIDEO_AMBA) += amba.o
+COBJS-$(CONFIG_VIDEO_BCM2835) += bcm2835.o
 COBJS-$(CONFIG_VIDEO_COREBOOT) += coreboot_fb.o
 COBJS-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o
 COBJS-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o
diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
new file mode 100644 (file)
index 0000000..1e9a84a
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <lcd.h>
+#include <asm/arch/mbox.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Global variables that lcd.c expects to exist */
+int lcd_line_length;
+int lcd_color_fg;
+int lcd_color_bg;
+void *lcd_base;
+void *lcd_console_address;
+short console_col;
+short console_row;
+vidinfo_t panel_info;
+char lcd_cursor_enabled;
+ushort lcd_cursor_width;
+ushort lcd_cursor_height;
+
+struct msg_query {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_physical_w_h physical_w_h;
+       u32 end_tag;
+};
+
+struct msg_setup {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_physical_w_h physical_w_h;
+       struct bcm2835_mbox_tag_virtual_w_h virtual_w_h;
+       struct bcm2835_mbox_tag_depth depth;
+       struct bcm2835_mbox_tag_pixel_order pixel_order;
+       struct bcm2835_mbox_tag_alpha_mode alpha_mode;
+       struct bcm2835_mbox_tag_virtual_offset virtual_offset;
+       struct bcm2835_mbox_tag_overscan overscan;
+       struct bcm2835_mbox_tag_allocate_buffer allocate_buffer;
+       u32 end_tag;
+};
+
+void lcd_ctrl_init(void *lcdbase)
+{
+       ALLOC_ALIGN_BUFFER(struct msg_query, msg_query, 1, 16);
+       ALLOC_ALIGN_BUFFER(struct msg_setup, msg_setup, 1, 16);
+       int ret;
+       u32 w, h;
+
+       debug("bcm2835: Query resolution...\n");
+
+       BCM2835_MBOX_INIT_HDR(msg_query);
+       BCM2835_MBOX_INIT_TAG_NO_REQ(&msg_query->physical_w_h,
+                                       GET_PHYSICAL_W_H);
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_query->hdr);
+       if (ret) {
+               printf("bcm2835: Could not query display resolution\n");
+               /* FIXME: How to disable the LCD to prevent errors? hang()? */
+               return;
+       }
+
+       w = msg_query->physical_w_h.body.resp.width;
+       h = msg_query->physical_w_h.body.resp.height;
+
+       debug("bcm2835: Setting up display for %d x %d\n", w, h);
+
+       BCM2835_MBOX_INIT_HDR(msg_setup);
+       BCM2835_MBOX_INIT_TAG(&msg_setup->physical_w_h, SET_PHYSICAL_W_H);
+       msg_setup->physical_w_h.body.req.width = w;
+       msg_setup->physical_w_h.body.req.height = h;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->virtual_w_h, SET_VIRTUAL_W_H);
+       msg_setup->virtual_w_h.body.req.width = w;
+       msg_setup->virtual_w_h.body.req.height = h;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->depth, SET_DEPTH);
+       msg_setup->depth.body.req.bpp = 16;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->pixel_order, SET_PIXEL_ORDER);
+       msg_setup->pixel_order.body.req.order = BCM2835_MBOX_PIXEL_ORDER_BGR;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->alpha_mode, SET_ALPHA_MODE);
+       msg_setup->alpha_mode.body.req.alpha = BCM2835_MBOX_ALPHA_MODE_IGNORED;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->virtual_offset, SET_VIRTUAL_OFFSET);
+       msg_setup->virtual_offset.body.req.x = 0;
+       msg_setup->virtual_offset.body.req.y = 0;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->overscan, SET_OVERSCAN);
+       msg_setup->overscan.body.req.top = 0;
+       msg_setup->overscan.body.req.bottom = 0;
+       msg_setup->overscan.body.req.left = 0;
+       msg_setup->overscan.body.req.right = 0;
+       BCM2835_MBOX_INIT_TAG(&msg_setup->allocate_buffer, ALLOCATE_BUFFER);
+       msg_setup->allocate_buffer.body.req.alignment = 0x100;
+
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_setup->hdr);
+       if (ret) {
+               printf("bcm2835: Could not configure display\n");
+               /* FIXME: How to disable the LCD to prevent errors? hang()? */
+               return;
+       }
+
+       w = msg_setup->physical_w_h.body.resp.width;
+       h = msg_setup->physical_w_h.body.resp.height;
+
+       debug("bcm2835: Final resolution is %d x %d\n", w, h);
+
+       panel_info.vl_col = w;
+       panel_info.vl_row = h;
+       panel_info.vl_bpix = LCD_COLOR16;
+
+       gd->fb_base = msg_setup->allocate_buffer.body.resp.fb_address;
+       lcd_base = (void *)gd->fb_base;
+}
+
+void lcd_enable(void)
+{
+}
index 15e9afcacd0904da1003e1aec88820f2c8281a31..8fb17653b0d22cf9023dc23cdaceeed4ee090f6e 100644 (file)
@@ -217,16 +217,15 @@ void __attribute__((unused)) dummy(void)
 #include <_exports.h>
 }
 
-extern unsigned long __bss_start, _end;
+#include <asm/sections.h>
 
 void app_startup(char * const *argv)
 {
-       unsigned char * cp = (unsigned char *) &__bss_start;
+       char *cp = __bss_start;
 
        /* Zero out BSS */
-       while (cp < (unsigned char *)&_end) {
+       while (cp < _end)
                *cp++ = 0;
-       }
 
 #if defined(CONFIG_X86)
        /* x86 does not have a dedicated register for passing global_data */
index b8ac024045df073bb5f91e668e95dee2ee913525..5416f468b06c6bb4becd6a1fc1f926df2280bd08 100644 (file)
@@ -40,7 +40,7 @@
 typedef struct global_data {
        bd_t *bd;
        unsigned long flags;
-       unsigned long baudrate;
+       unsigned int baudrate;
        unsigned long cpu_clk;  /* CPU clock in Hz!             */
        unsigned long bus_clk;
        /* We cannot bracket this with CONFIG_PCI due to mpc5xxx */
@@ -81,6 +81,8 @@ typedef struct global_data {
        unsigned long reloc_off;
        struct global_data *new_gd;     /* relocated global data */
        const void *fdt_blob;   /* Our device tree, NULL if none */
+       void *new_fdt;          /* Relocated FDT */
+       unsigned long fdt_size; /* Space reserved for relocated FDT */
        void **jt;              /* jump table */
        char env_buf[32];       /* buffer for getenv() before reloc. */
        struct arch_global_data arch;   /* architecture-specific data */
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
new file mode 100644 (file)
index 0000000..cca1edb
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * 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
+ */
+
+/* Taken from Linux kernel, commit f56c3196 */
+
+#ifndef _ASM_GENERIC_SECTIONS_H_
+#define _ASM_GENERIC_SECTIONS_H_
+
+/* References to section boundaries */
+
+extern char _text[], _stext[], _etext[];
+extern char _data[], _sdata[], _edata[];
+extern char __bss_start[], __bss_stop[];
+extern char __init_begin[], __init_end[];
+extern char _sinittext[], _einittext[];
+extern char _end[];
+extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
+extern char __kprobes_text_start[], __kprobes_text_end[];
+extern char __entry_text_start[], __entry_text_end[];
+extern char __initdata_begin[], __initdata_end[];
+extern char __start_rodata[], __end_rodata[];
+
+/* Start and end of .ctors section - used for constructor calls. */
+extern char __ctors_start[], __ctors_end[];
+
+/* function descriptor handling (if any).  Override
+ * in asm/sections.h */
+#ifndef dereference_function_descriptor
+#define dereference_function_descriptor(p) (p)
+#endif
+
+/* random extra sections (if any).  Override
+ * in asm/sections.h */
+#ifndef arch_is_kernel_text
+static inline int arch_is_kernel_text(unsigned long addr)
+{
+       return 0;
+}
+#endif
+
+#ifndef arch_is_kernel_data
+static inline int arch_is_kernel_data(unsigned long addr)
+{
+       return 0;
+}
+#endif
+
+/* U-Boot-specific things begin here */
+
+/* Start of U-Boot text region */
+extern char __text_start[];
+
+/* This marks the end of the text region which must be relocated */
+extern char __image_copy_end[];
+
+/*
+ * This is the U-Boot entry point - prior to relocation it should be same
+ * as __text_start
+ */
+extern void _start(void);
+
+/*
+ * ARM needs to use offsets for symbols, since the values of some symbols
+ * are not resolved prior to relocation (and are just 0). Maybe this can be
+ * resolved, or maybe other architectures are similar, iwc this should be
+ * promoted to an architecture option.
+ */
+#ifdef CONFIG_ARM
+#define CONFIG_SYS_SYM_OFFSETS
+#endif
+
+#ifdef CONFIG_SYS_SYM_OFFSETS
+/* Start/end of the relocation entries, as an offset from _start */
+extern ulong _rel_dyn_start_ofs;
+extern ulong _rel_dyn_end_ofs;
+
+/* Start/end of the relocation symbol table, as an offset from _start */
+extern ulong _dynsym_start_ofs;
+
+/* End of the region to be relocated, as an offset form _start */
+extern ulong _image_copy_end_ofs;
+
+extern ulong _bss_start_ofs;   /* BSS start relative to _start */
+extern ulong _bss_end_ofs;             /* BSS end relative to _start */
+extern ulong _end_ofs;         /* end of image relative to _start */
+
+extern ulong _TEXT_BASE;       /* code start */
+
+#else /* don't use offsets: */
+
+/* Exports from the Linker Script */
+extern ulong __data_end;
+extern ulong __rel_dyn_start;
+extern ulong __rel_dyn_end;
+extern ulong __bss_end;
+
+extern ulong _TEXT_BASE;       /* code start */
+
+#endif
+
+#endif /* _ASM_GENERIC_SECTIONS_H_ */
diff --git a/include/asm-generic/u-boot.h b/include/asm-generic/u-boot.h
new file mode 100644 (file)
index 0000000..a9aa8ba
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * (C) Copyright 2000 - 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ ********************************************************************
+ * NOTE: This header file defines an interface to U-Boot. Including
+ * this (unmodified) header file in another file is considered normal
+ * use of U-Boot, and does *not* fall under the heading of "derived
+ * work".
+ ********************************************************************
+ */
+
+#ifndef __ASM_GENERIC_U_BOOT_H__
+#define __ASM_GENERIC_U_BOOT_H__
+
+/*
+ * Board information passed to Linux kernel from U-Boot
+ *
+ * include/asm-ppc/u-boot.h
+ */
+
+#ifndef __ASSEMBLY__
+
+typedef struct bd_info {
+       unsigned long   bi_memstart;    /* start of DRAM memory */
+       phys_size_t     bi_memsize;     /* size  of DRAM memory in bytes */
+       unsigned long   bi_flashstart;  /* start of FLASH memory */
+       unsigned long   bi_flashsize;   /* size  of FLASH memory */
+       unsigned long   bi_flashoffset; /* reserved area for startup monitor */
+       unsigned long   bi_sramstart;   /* start of SRAM memory */
+       unsigned long   bi_sramsize;    /* size  of SRAM memory */
+#ifdef CONFIG_ARM
+       unsigned long   bi_arm_freq; /* arm frequency */
+       unsigned long   bi_dsp_freq; /* dsp core frequency */
+       unsigned long   bi_ddr_freq; /* ddr frequency */
+#endif
+#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \
+       || defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
+       unsigned long   bi_immr_base;   /* base of IMMR register */
+#endif
+#if defined(CONFIG_MPC5xxx)
+       unsigned long   bi_mbar_base;   /* base of internal registers */
+#endif
+#if defined(CONFIG_MPC83xx)
+       unsigned long   bi_immrbar;
+#endif
+#if defined(CONFIG_MPC8220)
+       unsigned long   bi_mbar_base;   /* base of internal registers */
+       unsigned long   bi_inpfreq;     /* Input Freq, In MHz */
+       unsigned long   bi_pcifreq;     /* PCI Freq, in MHz */
+       unsigned long   bi_pevfreq;     /* PEV Freq, in MHz */
+       unsigned long   bi_flbfreq;     /* Flexbus Freq, in MHz */
+       unsigned long   bi_vcofreq;     /* VCO Freq, in MHz */
+#endif
+       unsigned long   bi_bootflags;   /* boot / reboot flag (Unused) */
+       unsigned long   bi_ip_addr;     /* IP Address */
+       unsigned char   bi_enetaddr[6]; /* OLD: see README.enetaddr */
+       unsigned short  bi_ethspeed;    /* Ethernet speed in Mbps */
+       unsigned long   bi_intfreq;     /* Internal Freq, in MHz */
+       unsigned long   bi_busfreq;     /* Bus Freq, in MHz */
+#if defined(CONFIG_CPM2)
+       unsigned long   bi_cpmfreq;     /* CPM_CLK Freq, in MHz */
+       unsigned long   bi_brgfreq;     /* BRG_CLK Freq, in MHz */
+       unsigned long   bi_sccfreq;     /* SCC_CLK Freq, in MHz */
+       unsigned long   bi_vco;         /* VCO Out from PLL, in MHz */
+#endif
+#if defined(CONFIG_MPC512X)
+       unsigned long   bi_ipsfreq;     /* IPS Bus Freq, in MHz */
+#endif /* CONFIG_MPC512X */
+#if defined(CONFIG_MPC5xxx)
+       unsigned long   bi_ipbfreq;     /* IPB Bus Freq, in MHz */
+       unsigned long   bi_pcifreq;     /* PCI Bus Freq, in MHz */
+#endif
+       unsigned int    bi_baudrate;    /* Console Baudrate */
+#if defined(CONFIG_405)   || \
+               defined(CONFIG_405GP) || \
+               defined(CONFIG_405CR) || \
+               defined(CONFIG_405EP) || \
+               defined(CONFIG_405EZ) || \
+               defined(CONFIG_405EX) || \
+               defined(CONFIG_440)
+       unsigned char   bi_s_version[4];        /* Version of this structure */
+       unsigned char   bi_r_version[32];       /* Version of the ROM (AMCC) */
+       unsigned int    bi_procfreq;    /* CPU (Internal) Freq, in Hz */
+       unsigned int    bi_plb_busfreq; /* PLB Bus speed, in Hz */
+       unsigned int    bi_pci_busfreq; /* PCI Bus speed, in Hz */
+       unsigned char   bi_pci_enetaddr[6];     /* PCI Ethernet MAC address */
+#endif
+#if defined(CONFIG_HYMOD)
+       hymod_conf_t    bi_hymod_conf;  /* hymod configuration information */
+#endif
+
+#ifdef CONFIG_HAS_ETH1
+       unsigned char   bi_enet1addr[6];        /* OLD: see README.enetaddr */
+#endif
+#ifdef CONFIG_HAS_ETH2
+       unsigned char   bi_enet2addr[6];        /* OLD: see README.enetaddr */
+#endif
+#ifdef CONFIG_HAS_ETH3
+       unsigned char   bi_enet3addr[6];        /* OLD: see README.enetaddr */
+#endif
+#ifdef CONFIG_HAS_ETH4
+       unsigned char   bi_enet4addr[6];        /* OLD: see README.enetaddr */
+#endif
+#ifdef CONFIG_HAS_ETH5
+       unsigned char   bi_enet5addr[6];        /* OLD: see README.enetaddr */
+#endif
+
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || \
+               defined(CONFIG_405EZ) || defined(CONFIG_440GX) || \
+               defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+               defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+               defined(CONFIG_460EX) || defined(CONFIG_460GT)
+       unsigned int    bi_opbfreq;             /* OPB clock in Hz */
+       int             bi_iic_fast[2];         /* Use fast i2c mode */
+#endif
+#if defined(CONFIG_NX823)
+       unsigned char   bi_sernum[8];
+#endif
+#if defined(CONFIG_4xx)
+#if defined(CONFIG_440GX) || \
+               defined(CONFIG_460EX) || defined(CONFIG_460GT)
+       int             bi_phynum[4];           /* Determines phy mapping */
+       int             bi_phymode[4];          /* Determines phy mode */
+#elif defined(CONFIG_405EP) || defined(CONFIG_405EX) || defined(CONFIG_440)
+       int             bi_phynum[2];           /* Determines phy mapping */
+       int             bi_phymode[2];          /* Determines phy mode */
+#else
+       int             bi_phynum[1];           /* Determines phy mapping */
+       int             bi_phymode[1];          /* Determines phy mode */
+#endif
+#endif /* defined(CONFIG_4xx) */
+       ulong           bi_arch_number; /* unique id for this board */
+       ulong           bi_boot_params; /* where this board expects params */
+#ifdef CONFIG_NR_DRAM_BANKS
+       struct {                        /* RAM configuration */
+               ulong start;
+               ulong size;
+       } bi_dram[CONFIG_NR_DRAM_BANKS];
+#endif /* CONFIG_NR_DRAM_BANKS */
+} bd_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_GENERIC_U_BOOT_H__ */
index 6d5292422596c5df03f93b94a301ac8b20ffe506..d41aeb4f47835f0102ecc561b0e53d0fd4285d7a 100644 (file)
@@ -311,6 +311,8 @@ extern ulong monitor_flash_len;
 int mac_read_from_eeprom(void);
 extern u8 _binary_dt_dtb_start[];      /* embedded device tree blob */
 int set_cpu_clk_info(void);
+int print_cpuinfo(void);
+int update_flash_size(int flash_size);
 
 /**
  * Show the DRAM size in a board-specific way
index 0930781d83c8bb4e484f41bdf760502614ac3a89..53a2f054f9488b8e3fc08fcb62f69a8fc282bbe0 100644 (file)
@@ -57,7 +57,8 @@
 #define CONFIG_CMD_LOADB       /* loadb                        */
 #define CONFIG_CMD_LOADS       /* loads                        */
 #define CONFIG_CMD_MEMINFO     /* meminfo                      */
-#define CONFIG_CMD_MEMORY      /* md mm nm mw cp cmp crc base loop mtest */
+#define CONFIG_CMD_MEMORY      /* md mm nm mw cp cmp crc base loop */
+#define CONFIG_CMD_MEMTEST     /* mtest                        */
 #define CONFIG_CMD_MFSL                /* FSL support for Microblaze   */
 #define CONFIG_CMD_MII         /* MII support                  */
 #define CONFIG_CMD_MISC                /* Misc functions like sleep etc*/
index 6e3903c4d4166951da385d689e4b4cb8014d5a59..a52110396b2fc7c9a316739dcf45735cd7e10dd7 100644 (file)
@@ -30,7 +30,8 @@
 #endif
 #define CONFIG_CMD_LOADB       /* loadb                        */
 #define CONFIG_CMD_LOADS       /* loads                        */
-#define CONFIG_CMD_MEMORY      /* md mm nm mw cp cmp crc base loop mtest */
+#define CONFIG_CMD_MEMORY      /* md mm nm mw cp cmp crc base loop */
+#define CONFIG_CMD_MEMTEST     /* mtest                        */
 #define CONFIG_CMD_MISC                /* Misc functions like sleep etc*/
 #define CONFIG_CMD_NET         /* bootp, tftpboot, rarpboot    */
 #define CONFIG_CMD_NFS         /* NFS support                  */
index d023c632d98288a777f119df0c84620be498f0dc..567b46c87a5a6fc7bf8451255eb9383da1de3016 100644 (file)
@@ -12,6 +12,7 @@
 /* Support bootm-ing different OSes */
 #define CONFIG_BOOTM_LINUX 1
 #define CONFIG_BOOTM_NETBSD 1
+#define CONFIG_BOOTM_PLAN9 1
 #define CONFIG_BOOTM_RTEMS 1
 
 #define CONFIG_GZIP 1
diff --git a/include/configs/PCIPPC2.h b/include/configs/PCIPPC2.h
deleted file mode 100644 (file)
index 90cee88..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * (C) Copyright 2002-2005
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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
- */
-
-/*
- *
- * Configuration settings for the PCIPPC-2 board.
- *
- */
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * board/config.h - configuration options, board specific
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/*
- * High Level Configuration Options
- * (easy to change)
- */
-
-#define CONFIG_PCIPPC2         1       /* this is a PCIPPC2 board      */
-
-#define        CONFIG_SYS_TEXT_BASE    0xfff00000
-
-#define CONFIG_BOARD_EARLY_INIT_F 1
-#define CONFIG_MISC_INIT_R     1
-
-#define CONFIG_CONS_INDEX      1
-#define CONFIG_BAUDRATE                9600
-
-#define CONFIG_PREBOOT         ""
-#define CONFIG_BOOTDELAY       5
-
-#ifndef __ASSEMBLY__
-#include <galileo/core.h>
-#endif
-
-/*
- * BOOTP options
- */
-#define CONFIG_BOOTP_SUBNETMASK
-#define CONFIG_BOOTP_GATEWAY
-#define CONFIG_BOOTP_HOSTNAME
-#define CONFIG_BOOTP_BOOTPATH
-#define CONFIG_BOOTP_BOOTFILESIZE
-
-#define CONFIG_MAC_PARTITION
-#define CONFIG_DOS_PARTITION
-
-
-/*
- * Command line configuration.
- */
-#include <config_cmd_default.h>
-
-#define CONFIG_CMD_ASKENV
-#define CONFIG_CMD_BSP
-#define CONFIG_CMD_DATE
-#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_ELF
-#define CONFIG_CMD_NFS
-#define CONFIG_CMD_PCI
-#define CONFIG_CMD_SNTP
-
-#define CONFIG_PCI             1
-#define CONFIG_PCI_PNP         1       /* PCI plug-and-play */
-
-/*
- * Miscellaneous configurable options
- */
-#define CONFIG_SYS_LONGHELP                    /* undef to save memory         */
-#define CONFIG_SYS_PROMPT      "=> "           /* Monitor Command Prompt       */
-
-#define        CONFIG_SYS_HUSH_PARSER          1       /* use "hush" command parser    */
-#define CONFIG_SYS_CBSIZE      256             /* Console I/O Buffer Size      */
-
-/* Print Buffer Size
- */
-#define CONFIG_SYS_PBSIZE      (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
-
-#define        CONFIG_SYS_MAXARGS      64              /* max number of command args   */
-#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE       /* Boot Argument Buffer Size    */
-#define CONFIG_SYS_LOAD_ADDR   0x00100000      /* Default load address         */
-
-/*-----------------------------------------------------------------------
- * Start addresses for the final memory configuration
- * (Set up by the startup code)
- * Please note that CONFIG_SYS_SDRAM_BASE _must_ start at 0
- */
-#define CONFIG_SYS_SDRAM_BASE      0x00000000
-#define CONFIG_SYS_FLASH_BASE      0xFFF00000
-#define CONFIG_SYS_FLASH_MAX_SIZE  0x00100000
-/* Maximum amount of RAM.
- */
-#define CONFIG_SYS_MAX_RAM_SIZE    0x20000000  /* 512Mb                        */
-
-#define CONFIG_SYS_RESET_ADDRESS   0xFFF00100
-
-#define CONFIG_SYS_MONITOR_BASE    CONFIG_SYS_TEXT_BASE
-
-#define CONFIG_SYS_MONITOR_LEN     (256 << 10) /* Reserve 256 kB for Monitor   */
-#define CONFIG_SYS_MALLOC_LEN      (128 << 10) /* Reserve 128 kB for malloc()  */
-
-#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_SDRAM_BASE && \
-    CONFIG_SYS_MONITOR_BASE < CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_MAX_RAM_SIZE
-#define CONFIG_SYS_RAMBOOT
-#else
-#undef CONFIG_SYS_RAMBOOT
-#endif
-
-#define CONFIG_SYS_MEMTEST_START   0x00004000  /* memtest works on             */
-#define CONFIG_SYS_MEMTEST_END     0x02000000  /* 0 ... 32 MB in DRAM          */
-
-/*-----------------------------------------------------------------------
- * Definitions for initial stack pointer and data area
- */
-
-#define CONFIG_SYS_INIT_RAM_ADDR     0x40000000
-#define CONFIG_SYS_INIT_RAM_SIZE      0x8000
-#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_INIT_RAM_LOCK
-
-/*
- * Temporary buffer for serial data until the real serial driver
- * is initialised (memtest will destroy this buffer)
- */
-#define CONFIG_SYS_SCONSOLE_ADDR     CONFIG_SYS_INIT_RAM_ADDR
-#define CONFIG_SYS_SCONSOLE_SIZE     0x0002000
-
-/* SDRAM 0 - 256MB
- */
-#define CONFIG_SYS_DBAT0L            (CONFIG_SYS_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
-#define CONFIG_SYS_DBAT0U            (CONFIG_SYS_SDRAM_BASE | \
-                              BATU_BL_256M | BATU_VS | BATU_VP)
-/* SDRAM 1 - 256MB
- */
-#define CONFIG_SYS_DBAT1L            ((CONFIG_SYS_SDRAM_BASE + 0x10000000) | \
-                              BATL_PP_10 | BATL_MEMCOHERENCE)
-#define CONFIG_SYS_DBAT1U            ((CONFIG_SYS_SDRAM_BASE + 0x10000000) | \
-                              BATU_BL_256M | BATU_VS | BATU_VP)
-
-/* Init RAM in the CPU DCache (no backing memory)
- */
-#define CONFIG_SYS_DBAT2L            (CONFIG_SYS_INIT_RAM_ADDR | \
-                              BATL_PP_10 | BATL_MEMCOHERENCE)
-#define CONFIG_SYS_DBAT2U            (CONFIG_SYS_INIT_RAM_ADDR | \
-                              BATU_BL_128K | BATU_VS | BATU_VP)
-
-/* I/O and PCI memory at 0xf0000000
- */
-#define CONFIG_SYS_DBAT3L            (0xf0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
-#define CONFIG_SYS_DBAT3U            (0xf0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
-
-#define CONFIG_SYS_IBAT0L            CONFIG_SYS_DBAT0L
-#define CONFIG_SYS_IBAT0U            CONFIG_SYS_DBAT0U
-#define CONFIG_SYS_IBAT1L            CONFIG_SYS_DBAT1L
-#define CONFIG_SYS_IBAT1U            CONFIG_SYS_DBAT1U
-#define CONFIG_SYS_IBAT2L            CONFIG_SYS_DBAT2L
-#define CONFIG_SYS_IBAT2U            CONFIG_SYS_DBAT2U
-#define CONFIG_SYS_IBAT3L            CONFIG_SYS_DBAT3L
-#define CONFIG_SYS_IBAT3U            CONFIG_SYS_DBAT3U
-
-/*
- * Low Level Configuration Settings
- * (address mappings, register initial values, etc.)
- * You should know what you are doing if you make changes here.
- * For the detail description refer to the PCIPPC2 user's manual.
- */
-#define CONFIG_SYS_HZ                1000
-#define CONFIG_SYS_BUS_CLK            100000000 /* bus speed - 100 mhz          */
-#define CONFIG_SYS_CPU_CLK           300000000
-
-/*
- * For booting Linux, the board info and command line data
- * have to be in the first 8 MB of memory, since this is
- * the maximum mapped by the Linux kernel during initialization.
- */
-#define CONFIG_SYS_BOOTMAPSZ         (8 << 20) /* Initial Memory map for Linux */
-
-/*-----------------------------------------------------------------------
- * FLASH organization
- */
-#define CONFIG_SYS_MAX_FLASH_BANKS     1       /* Max number of flash banks            */
-#define CONFIG_SYS_MAX_FLASH_SECT      16      /* Max number of sectors in one bank    */
-
-#define CONFIG_SYS_FLASH_ERASE_TOUT    120000  /* Timeout for Flash Erase (in ms)      */
-#define CONFIG_SYS_FLASH_WRITE_TOUT    1000    /* Timeout for Flash Write (in ms)      */
-
-/*
- * Note: environment is not EMBEDDED in the U-Boot code.
- * It's stored in flash separately.
- */
-#define CONFIG_ENV_IS_IN_FLASH 1
-#define CONFIG_ENV_ADDR                (CONFIG_SYS_FLASH_BASE + 0x70000)
-#define CONFIG_ENV_SIZE                0x1000  /* Size of the Environment              */
-#define CONFIG_ENV_SECT_SIZE   0x10000 /* Size of the Environment Sector       */
-
-/*-----------------------------------------------------------------------
- * Cache Configuration
- */
-#define CONFIG_SYS_CACHELINE_SIZE      32
-#if defined(CONFIG_CMD_KGDB)
-#  define CONFIG_SYS_CACHELINE_SHIFT   5       /* log base 2 of the above value        */
-#endif
-
-/*
- * L2 cache
- */
-#undef CONFIG_SYS_L2
-#define L2_INIT   (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \
-                  L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT)
-#define L2_ENABLE (L2_INIT | L2CR_L2E)
-
-/*-----------------------------------------------------------------------
-  RTC m48t59
-*/
-#define CONFIG_RTC_MK48T59
-
-#define CONFIG_WATCHDOG
-
-
-#define CONFIG_EEPRO100
-#define CONFIG_SYS_RX_ETH_BUFFER       8               /* use 8 rx buffer on eepro100  */
-#define CONFIG_TULIP
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/PCIPPC6.h b/include/configs/PCIPPC6.h
deleted file mode 100644 (file)
index 10b81c1..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * (C) Copyright 2002-2005
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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
- */
-
-/*
- *
- * Configuration settings for the PCIPPC-6 board.
- *
- */
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * board/config.h - configuration options, board specific
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/*
- * High Level Configuration Options
- * (easy to change)
- */
-
-#define CONFIG_PCIPPC2         1       /* this is a PCIPPC2 board      */
-
-#define        CONFIG_SYS_TEXT_BASE    0xfff00000
-
-#define CONFIG_BOARD_EARLY_INIT_F 1
-#define CONFIG_MISC_INIT_R     1
-
-#define CONFIG_CONS_INDEX      1
-#define CONFIG_BAUDRATE                9600
-
-#define CONFIG_PREBOOT         ""
-#define CONFIG_BOOTDELAY       5
-
-#ifndef __ASSEMBLY__
-#include <galileo/core.h>
-#endif
-
-/*
- * BOOTP options
- */
-#define CONFIG_BOOTP_SUBNETMASK
-#define CONFIG_BOOTP_GATEWAY
-#define CONFIG_BOOTP_HOSTNAME
-#define CONFIG_BOOTP_BOOTPATH
-#define CONFIG_BOOTP_BOOTFILESIZE
-
-#define CONFIG_MAC_PARTITION
-#define CONFIG_DOS_PARTITION
-
-
-/*
- * Command line configuration.
- */
-#include <config_cmd_default.h>
-
-#define CONFIG_CMD_ASKENV
-#define CONFIG_CMD_BSP
-#define CONFIG_CMD_DATE
-#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_ELF
-#define CONFIG_CMD_NFS
-#define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
-#define CONFIG_CMD_SNTP
-
-
-#define CONFIG_PCI             1
-#define CONFIG_PCI_PNP         1       /* PCI plug-and-play */
-
-/*
- * Miscellaneous configurable options
- */
-#define CONFIG_SYS_LONGHELP                    /* undef to save memory         */
-#define CONFIG_SYS_PROMPT      "=> "           /* Monitor Command Prompt       */
-
-#define CONFIG_SYS_HUSH_PARSER         1       /* use "hush" command parser    */
-#define CONFIG_SYS_CBSIZE      256             /* Console I/O Buffer Size      */
-
-/* Print Buffer Size
- */
-#define CONFIG_SYS_PBSIZE      (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
-
-#define CONFIG_SYS_MAXARGS     64              /* max number of command args   */
-#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE       /* Boot Argument Buffer Size    */
-#define CONFIG_SYS_LOAD_ADDR   0x00100000      /* Default load address         */
-
-/*-----------------------------------------------------------------------
- * Start addresses for the final memory configuration
- * (Set up by the startup code)
- * Please note that CONFIG_SYS_SDRAM_BASE _must_ start at 0
- */
-#define CONFIG_SYS_SDRAM_BASE      0x00000000
-#define CONFIG_SYS_FLASH_BASE      0xFFF00000
-#define CONFIG_SYS_FLASH_MAX_SIZE  0x00100000
-/* Maximum amount of RAM.
- */
-#define CONFIG_SYS_MAX_RAM_SIZE    0x20000000  /* 512Mb                        */
-
-#define CONFIG_SYS_RESET_ADDRESS   0xFFF00100
-
-#define CONFIG_SYS_MONITOR_BASE    CONFIG_SYS_TEXT_BASE
-
-#define CONFIG_SYS_MONITOR_LEN     (256 << 10) /* Reserve 256 kB for Monitor   */
-#define CONFIG_SYS_MALLOC_LEN      (128 << 10) /* Reserve 128 kB for malloc()  */
-
-#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_SDRAM_BASE && \
-    CONFIG_SYS_MONITOR_BASE < CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_MAX_RAM_SIZE
-#define CONFIG_SYS_RAMBOOT
-#else
-#undef CONFIG_SYS_RAMBOOT
-#endif
-
-#define CONFIG_SYS_MEMTEST_START   0x00004000  /* memtest works on             */
-#define CONFIG_SYS_MEMTEST_END     0x02000000  /* 0 ... 32 MB in DRAM          */
-
-/*-----------------------------------------------------------------------
- * Definitions for initial stack pointer and data area
- */
-
-#define CONFIG_SYS_INIT_RAM_ADDR     0x40000000
-#define CONFIG_SYS_INIT_RAM_SIZE      0x8000
-#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_INIT_RAM_LOCK
-
-/*
- * Temporary buffer for serial data until the real serial driver
- * is initialised (memtest will destroy this buffer)
- */
-#define CONFIG_SYS_SCONSOLE_ADDR     CONFIG_SYS_INIT_RAM_ADDR
-#define CONFIG_SYS_SCONSOLE_SIZE     0x0002000
-
-/* SDRAM 0 - 256MB
- */
-#define CONFIG_SYS_DBAT0L            (CONFIG_SYS_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
-#define CONFIG_SYS_DBAT0U            (CONFIG_SYS_SDRAM_BASE | \
-                              BATU_BL_256M | BATU_VS | BATU_VP)
-/* SDRAM 1 - 256MB
- */
-#define CONFIG_SYS_DBAT1L            ((CONFIG_SYS_SDRAM_BASE + 0x10000000) | \
-                              BATL_PP_10 | BATL_MEMCOHERENCE)
-#define CONFIG_SYS_DBAT1U            ((CONFIG_SYS_SDRAM_BASE + 0x10000000) | \
-                              BATU_BL_256M | BATU_VS | BATU_VP)
-
-/* Init RAM in the CPU DCache (no backing memory)
- */
-#define CONFIG_SYS_DBAT2L            (CONFIG_SYS_INIT_RAM_ADDR | \
-                              BATL_PP_10 | BATL_MEMCOHERENCE)
-#define CONFIG_SYS_DBAT2U            (CONFIG_SYS_INIT_RAM_ADDR | \
-                              BATU_BL_128K | BATU_VS | BATU_VP)
-
-/* I/O and PCI memory at 0xf0000000
- */
-#define CONFIG_SYS_DBAT3L            (0xf0000000 | BATL_PP_10 | BATL_CACHEINHIBIT)
-#define CONFIG_SYS_DBAT3U            (0xf0000000 | BATU_BL_256M | BATU_VS | BATU_VP)
-
-#define CONFIG_SYS_IBAT0L            CONFIG_SYS_DBAT0L
-#define CONFIG_SYS_IBAT0U            CONFIG_SYS_DBAT0U
-#define CONFIG_SYS_IBAT1L            CONFIG_SYS_DBAT1L
-#define CONFIG_SYS_IBAT1U            CONFIG_SYS_DBAT1U
-#define CONFIG_SYS_IBAT2L            CONFIG_SYS_DBAT2L
-#define CONFIG_SYS_IBAT2U            CONFIG_SYS_DBAT2U
-#define CONFIG_SYS_IBAT3L            CONFIG_SYS_DBAT3L
-#define CONFIG_SYS_IBAT3U            CONFIG_SYS_DBAT3U
-
-/*
- * Low Level Configuration Settings
- * (address mappings, register initial values, etc.)
- * You should know what you are doing if you make changes here.
- * For the detail description refer to the PCIPPC2 user's manual.
- */
-#define CONFIG_SYS_HZ                1000
-#define CONFIG_SYS_BUS_CLK           100000000 /* bus speed - 100 mhz          */
-#define CONFIG_SYS_CPU_CLK           300000000
-
-/*
- * For booting Linux, the board info and command line data
- * have to be in the first 8 MB of memory, since this is
- * the maximum mapped by the Linux kernel during initialization.
- */
-#define CONFIG_SYS_BOOTMAPSZ         (8 << 20) /* Initial Memory map for Linux */
-
-/*-----------------------------------------------------------------------
- * FLASH organization
- */
-#define CONFIG_SYS_MAX_FLASH_BANKS     1       /* Max number of flash banks            */
-#define CONFIG_SYS_MAX_FLASH_SECT      16      /* Max number of sectors in one bank    */
-
-#define CONFIG_SYS_FLASH_ERASE_TOUT    120000  /* Timeout for Flash Erase (in ms)      */
-#define CONFIG_SYS_FLASH_WRITE_TOUT    1000    /* Timeout for Flash Write (in ms)      */
-
-/*
- * Note: environment is not EMBEDDED in the U-Boot code.
- * It's stored in flash separately.
- */
-#define CONFIG_ENV_IS_IN_FLASH 1
-#define CONFIG_ENV_ADDR                (CONFIG_SYS_FLASH_BASE + 0x70000)
-#define CONFIG_ENV_SIZE                0x1000  /* Size of the Environment              */
-#define CONFIG_ENV_SECT_SIZE   0x10000 /* Size of the Environment Sector       */
-
-/*-----------------------------------------------------------------------
- * Cache Configuration
- */
-#define CONFIG_SYS_CACHELINE_SIZE      32
-#if defined(CONFIG_CMD_KGDB)
-#  define CONFIG_SYS_CACHELINE_SHIFT   5       /* log base 2 of the above value        */
-#endif
-
-/*
- * L2 cache
- */
-#undef CONFIG_SYS_L2
-#define L2_INIT          (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \
-                  L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT)
-#define L2_ENABLE (L2_INIT | L2CR_L2E)
-
-/*-----------------------------------------------------------------------
-  RTC m48t59
-*/
-#define CONFIG_RTC_MK48T59
-
-#define CONFIG_WATCHDOG
-
-
-#define CONFIG_EEPRO100
-#define CONFIG_SYS_RX_ETH_BUFFER       8               /* use 8 rx buffer on eepro100  */
-#define CONFIG_TULIP
-
-
-#define CONFIG_SCSI_SYM53C8XX
-#define CONFIG_SCSI_DEV_ID     0x000B  /* 53c896 */
-#define CONFIG_SYS_SCSI_MAX_LUN        8       /* number of supported LUNs */
-#define CONFIG_SYS_SCSI_MAX_SCSI_ID    15      /* maximum SCSI ID (0..6) */
-#define CONFIG_SYS_SCSI_MAX_DEVICE     CONFIG_SYS_SCSI_MAX_SCSI_ID * CONFIG_SYS_SCSI_MAX_LUN /* maximum Target devices */
-#define CONFIG_SYS_SCSI_SPIN_UP_TIME   2
-#define CONFIG_SYS_SCSI_SCAN_BUS_REVERSE 0
-#define CONFIG_DOS_PARTITION
-#define CONFIG_MAC_PARTITION
-#define CONFIG_ISO_PARTITION
-
-#endif /* __CONFIG_H */
index df3b4ae90a29c59d141da1db2586850e6bca7a6f..13f32267e925e5dde83214b53412163124960d5b 100644 (file)
 #define CONFIG_MPC5200
 #define CONFIG_MPC5xxx         1       /* This is an MPC5xxx CPU */
 #define CONFIG_A3M071                  /* ... on A3M071 board */
-#define CONFIG_MPC5200_DDR             /* ... use DDR RAM      */
 
 #define        CONFIG_SYS_TEXT_BASE    0x01000000      /* boot low for 32 MiB boards */
 
+#define CONFIG_SPL_TARGET      "u-boot-img.bin"
+
 #define CONFIG_SYS_MPC5XXX_CLKIN       33000000 /* ... running at 33MHz */
 
 #define CONFIG_MISC_INIT_R
 #define CONFIG_SYS_LOWBOOT             /* Enable lowboot       */
 
+#ifdef CONFIG_A4M2K
+#define CONFIG_HOSTNAME                a4m2k
+#else
+#define CONFIG_HOSTNAME                a3m071
+#endif
+
 /*
  * Serial console configuration
  */
@@ -50,9 +57,6 @@
 
 #define CONFIG_CMD_BSP
 #define CONFIG_CMD_CACHE
-#define CONFIG_CMD_DATE
-#define CONFIG_CMD_EEPROM
-#define CONFIG_CMD_I2C
 #define CONFIG_CMD_MII
 #define CONFIG_CMD_REGINFO
 
  */
 #define CONFIG_SYS_IPBCLK_EQUALS_XLBCLK                /* define for 133MHz speed */
 /* define for 66MHz speed - undef for 33MHz PCI clock speed */
+#ifdef CONFIG_A4M2K
+#define CONFIG_SYS_PCICLK_EQUALS_IPBCLK_DIV2
+#else
 #undef CONFIG_SYS_PCICLK_EQUALS_IPBCLK_DIV2
+#endif
 
 /* pass open firmware flat tree */
 #define CONFIG_OF_LIBFDT
 #define OF_TBCLK               (bd->bi_busfreq / 4)
 #define OF_STDOUT_PATH         "/soc5200@f0000000/serial@2000"
 
-/*
- * I2C configuration
- */
-#define CONFIG_HARD_I2C                                /* I2C with hardware support */
-#define CONFIG_SYS_I2C_MODULE          2       /* Select I2C module #1 or #2 */
-
-#define CONFIG_SYS_I2C_SPEED           100000 /* 100 kHz */
-#define CONFIG_SYS_I2C_SLAVE           0x7F
-
-/*
- * EEPROM configuration
- */
-#define CONFIG_SYS_I2C_EEPROM_ADDR             0x53
-#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         2
-#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      6
-#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  10
-
-/*
- * RTC configuration
- */
-#define CONFIG_RTC_PCF8563
-#define CONFIG_SYS_I2C_RTC_ADDR                0x51
-
 /*
  * NOR flash configuration
  */
 #define CONFIG_SYS_FLASH_BASE          0xfc000000
-#define CONFIG_SYS_FLASH_SIZE          0x01000000
+#define CONFIG_SYS_FLASH_SIZE          0x02000000
 #define CONFIG_ENV_ADDR                        (CONFIG_SYS_FLASH_BASE + 0x40000)
 
 #define CONFIG_SYS_MAX_FLASH_BANKS     1
  */
 #define CONFIG_MPC5xxx_FEC
 #define CONFIG_MPC5xxx_FEC_MII100
+#ifdef CONFIG_A4M2K
+#define CONFIG_PHY_ADDR                        0x01
+#else
 #define CONFIG_PHY_ADDR                        0x00
+#endif
 
 /*
  * GPIO configuration
  *          2 means fpga ok
  */
 
+#ifdef CONFIG_A4M2K
+#define CONFIG_SYS_GPS_PORT_CONFIG     0x0005C805
+#else
 /* for failsave-level 0 - full failsave */
 #define CONFIG_SYS_GPS_PORT_CONFIG     0x1005C005
 /* for failsave-level 1 - only digiboard ok */
 #define CONFIG_SYS_GPS_PORT_CONFIG_1   0x1005C005
 /* for failsave-level 2 - all ok */
 #define CONFIG_SYS_GPS_PORT_CONFIG_2   0x1005C005
+#endif
+
+#define CONFIG_WDOG_GPIO_PIN           GPIO_WKUP_7
+#if defined(CONFIG_A4M2K) && !defined(CONFIG_SPL_BUILD)
+#define CONFIG_HW_WATCHDOG             /* Use external HW-Watchdog     */
+#endif
 
 /*
  * Configuration matrix
  *                        MSB                          LSB
- * failsave 0  0x1005C005  00010000000001011100000001100101  ( full failsave )
- * failsave 1  0x1005C005  00010000000001011100000001100101  ( digib.-ver ok )
- * failsave 2  0x1005C005  00010000000001011100000001100101  ( all ok )
+ * failsave 0  0x1005C005  00010000000001011100000000000101  ( full failsave )
+ * failsave 1  0x1005C005  00010000000001011100000000000101  ( digib.-ver ok )
+ * failsave 2  0x1005C005  00010000000001011100000000000101  ( all ok )
  *                         || ||| ||  |   ||| |   |   |   |
  *                         || ||| ||  |   ||| |   |   |   |  bit rev name
  *                         ++-+++-++--+---+++-+---+---+---+-  0   31 CS1
 #define CONFIG_SYS_BOOTCS_SIZE         CONFIG_SYS_FLASH_SIZE
 #define CONFIG_SYS_CS0_START           CONFIG_SYS_FLASH_BASE
 #define CONFIG_SYS_CS0_SIZE            CONFIG_SYS_FLASH_SIZE
+
+#ifdef CONFIG_A4M2K
+/* external MRAM */
+#define CONFIG_SYS_CS1_START           0xf1000000
+#define CONFIG_SYS_CS1_SIZE            (512 << 10)     /* 512KiB MRAM */
+#endif
+
 #define CONFIG_SYS_CS2_START           0xe0000000
 #define CONFIG_SYS_CS2_SIZE            0x00100000
 
-/* FPGA slave io (512kiB) - see ticket #66 */
+/* FPGA slave io (512kiB / 1MiB) - see ticket #66 */
 #define CONFIG_SYS_CS3_START           0xE9000000
+#ifdef CONFIG_A4M2K
+#define CONFIG_SYS_CS3_SIZE            0x00100000
+#else
 #define CONFIG_SYS_CS3_SIZE            0x00080000
+#endif
 /* 00000000 00110010 1 0 1 1 10 01 00 00 0 0 0 0  = 0x0032B900 */
 #define CONFIG_SYS_CS3_CFG             0x0032B900
 
+#ifndef CONFIG_A4M2K
 /* Diagnosis Interface - see ticket #63 */
 #define CONFIG_SYS_CS4_START           0xEA000000
 #define CONFIG_SYS_CS4_SIZE            0x00000001
 /* 00000000 00000010 1 0 1 1 10 01 00 00 0 0 0 0  = 0x0002B900 */
 #define CONFIG_SYS_CS4_CFG             0x0002B900
+#endif
 
-/* FPGA master io (64kiB) - see ticket #66 */
+/* FPGA master io (64kiB / 1MiB) - see ticket #66 */
 #define CONFIG_SYS_CS5_START           0xE8000000
+#ifdef CONFIG_A4M2K
+#define CONFIG_SYS_CS5_SIZE            0x00100000
+#else
 #define CONFIG_SYS_CS5_SIZE            0x00010000
+#endif
 /* 00000000 00110010 1 0 1 1 10 01 00 00 0 0 0 0  = 0x0032B900 */
 #define CONFIG_SYS_CS5_CFG             0x0032B900
 
 #ifdef CONFIG_SYS_PCICLK_EQUALS_IPBCLK_DIV2    /* for pci_clk  = 66 MHz */
 #define CONFIG_SYS_BOOTCS_CFG          0x0006F900
-#define CONFIG_SYS_CS1_CFG             0x0004FB00
+#define CONFIG_SYS_CS1_CFG             0x0008FD00
 #define CONFIG_SYS_CS2_CFG             0x0006F90C
 #else  /* for pci_clk = 33 MHz */
 #define CONFIG_SYS_BOOTCS_CFG          0x0002F900
 #define CONFIG_SYS_OS_BASE     0xfc080000
 #define CONFIG_SYS_FDT_BASE    0xfc060000
 
-#define xstr(s)        str(s)
-#define str(s) #s
-
 #define        CONFIG_EXTRA_ENV_SETTINGS                                       \
+       "hostname=" __stringify(CONFIG_HOSTNAME) "\0"                   \
        "netdev=eth0\0"                                                 \
        "verify=no\0"                                                   \
+       "loadaddr=200000\0"                                             \
+       "kernel_addr=" __stringify(CONFIG_SYS_OS_BASE) "\0"             \
+       "kernel_addr_r=1000000\0"                                       \
+       "fdt_addr=" __stringify(CONFIG_SYS_FDT_BASE) "\0"               \
+       "fdt_addr_r=1800000\0"                                          \
+       "bootfile=" __stringify(CONFIG_HOSTNAME) "/uImage\0"            \
+       "fdtfile=" __stringify(CONFIG_HOSTNAME) "/"                     \
+               __stringify(CONFIG_HOSTNAME) ".dtb\0"                   \
+       "rootpath=/opt/eldk-5.2.1/powerpc/"                             \
+               "core-image-minimal-mtdutils-dropbear-generic\0"        \
        "consoledev=ttyPSC0\0"                                          \
        "nfsargs=setenv bootargs root=/dev/nfs rw "                     \
                "nfsroot=${serverip}:${rootpath}\0"                     \
        "ramargs=setenv bootargs root=/dev/ram rw\0"                    \
-       "mtdargs=setenv bootargs root=/dev/mtdblock4 rw rootfstype=jffs2\0"\
+       "mtdargs=setenv bootargs root=/dev/mtdblock4 rw rootfstype=jffs2\0" \
        "addip=setenv bootargs ${bootargs} "                            \
                "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"      \
                ":${hostname}:${netdev}:off panic=1\0"                  \
        "flash_mtd=run mtdargs addip addtty;"                           \
                "bootm ${kernel_addr} - ${fdtaddr}\0"                   \
        "flash_self=run ramargs addip addtty;"                          \
-               "bootm ${kernel_addr} ${ramdisk_addr} ${fdtaddr}\0"     \
-       "net_nfs=sleep 2; tftp ${loadaddr} ${bootfile};"                \
-               "tftp c00000 ${fdtfile};"                               \
+               "bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0"    \
+       "net_nfs=tftp ${kernel_addr_r} ${bootfile};"                    \
+               "tftp ${fdt_addr_r} ${fdtfile};"                        \
                "run nfsargs addip addtty;"                             \
-               "bootm ${loadaddr} - c00000\0"                          \
-       "load=tftp ${loadaddr} u-boot.bin\0"                            \
+               "bootm ${kernel_addr_r} - ${fdt_addr_r}\0"              \
+       "load=tftp ${loadaddr} " __stringify(CONFIG_HOSTNAME)           \
+               "/u-boot-img.bin\0"                                     \
        "update=protect off fc000000 fc03ffff; "                        \
-               "era fc000000 fc03ffff; cp.b ${loadaddr} fc000000 40000\0"\
+               "era fc000000 fc03ffff; cp.b ${loadaddr} fc000000 40000\0" \
        "upd=run load;run update\0"                                     \
-       "fdtaddr=" xstr(CONFIG_SYS_FDT_BASE) "\0"                       \
-       "fdtfile=dtbFile\0"                                             \
-       "kernel_addr=" xstr(CONFIG_SYS_OS_BASE) "\0"                    \
+       "bootdelay=3\0"                                                 \
+       "bootcmd=run net_nfs\0"                                         \
        ""
 
 #define CONFIG_BOOTCOMMAND     "run flash_mtd"
  */
 #define CONFIG_SPL
 #define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_BOARD_INIT
 #define CONFIG_SPL_NOR_SUPPORT
 #define CONFIG_SPL_TEXT_BASE   0xfc000000
 #define        CONFIG_SPL_START_S_PATH "arch/powerpc/cpu/mpc5xxx"
diff --git a/include/configs/ac14xx.h b/include/configs/ac14xx.h
new file mode 100644 (file)
index 0000000..ac7e877
--- /dev/null
@@ -0,0 +1,591 @@
+/*
+ * (C) Copyright 2009 Wolfgang Denk <wd@denx.de>
+ * (C) Copyright 2010 DAVE Srl <www.dave.eu>
+ *
+ * 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.
+ */
+
+/*
+ * ifm AC14xx (MPC5121e based) board configuration file
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_AC14XX 1
+/*
+ * Memory map for the ifm AC14xx board:
+ *
+ * 0x0000_0000-0x0FFF_FFFF     DDR RAM (256 MB)
+ * 0x3000_0000-0x3001_FFFF     On Chip SRAM (128 KB)
+ * 0x8000_0000-0x803F_FFFF     IMMR (4 MB)
+ * 0xE000_0000-0xEFFF_FFFF     several LPB attached hardware (CSx)
+ * 0xFC00_0000-0xFFFF_FFFF     NOR Boot FLASH (64 MB)
+ */
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_E300            1       /* E300 Family */
+#define CONFIG_MPC512X         1       /* MPC512X family */
+
+#define CONFIG_SYS_TEXT_BASE   0xFFF00000
+
+#if defined(CONFIG_VIDEO)
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_VGA_AS_SINGLE_DEVICE
+#endif
+
+#define CONFIG_SYS_MPC512X_CLKIN       25000000        /* in Hz */
+#define SCFR1_IPS_DIV                  2
+#define SCFR1_LPC_DIV                  2
+#define SCFR1_NFC_DIV                  2
+#define SCFR1_DIU_DIV                  240
+
+#define CONFIG_MISC_INIT_R
+
+#define CONFIG_SYS_IMMR                        0x80000000
+#define CONFIG_SYS_DIU_ADDR            (CONFIG_SYS_IMMR + 0x2100)
+
+/* more aggressive 'mtest' over a wider address range */
+#define CONFIG_SYS_ALT_MEMTEST
+#define CONFIG_SYS_MEMTEST_START       0x00100000      /* memtest region */
+#define CONFIG_SYS_MEMTEST_END         0x0FE00000
+
+/*
+ * DDR Setup - manually set all parameters as there's no SPD etc.
+ */
+#define CONFIG_SYS_DDR_SIZE            256             /* MB */
+#define CONFIG_SYS_DDR_BASE            0x00000000
+#define CONFIG_SYS_SDRAM_BASE          CONFIG_SYS_DDR_BASE
+#define CONFIG_SYS_MAX_RAM_SIZE                0x20000000
+
+/*
+ * DDR Controller Configuration XXX TODO
+ *
+ * SYS_CFG:
+ *     [31:31] MDDRC Soft Reset:       Diabled
+ *     [30:30] DRAM CKE pin:           Enabled
+ *     [29:29] DRAM CLK:               Enabled
+ *     [28:28] Command Mode:           Enabled (For initialization only)
+ *     [27:25] DRAM Row Select:        dram_row[15:0] = magenta_address[25:10]
+ *     [24:21] DRAM Bank Select:       dram_bank[1:0] = magenta_address[11:10]
+ *     [20:19] Read Test:              DON'T USE
+ *     [18:18] Self Refresh:           Enabled
+ *     [17:17] 16bit Mode:             Disabled
+ *     [16:13] Ready Delay:            2
+ *     [12:12] Half DQS Delay:         Disabled
+ *     [11:11] Quarter DQS Delay:      Disabled
+ *     [10:08] Write Delay:            2
+ *     [07:07] Early ODT:              Disabled
+ *     [06:06] On DIE Termination:     Disabled
+ *     [05:05] FIFO Overflow Clear:    DON'T USE here
+ *     [04:04] FIFO Underflow Clear:   DON'T USE here
+ *     [03:03] FIFO Overflow Pending:  DON'T USE here
+ *     [02:02] FIFO Underlfow Pending: DON'T USE here
+ *     [01:01] FIFO Overlfow Enabled:  Enabled
+ *     [00:00] FIFO Underflow Enabled: Enabled
+ * TIME_CFG0
+ *     [31:16] DRAM Refresh Time:      0 CSB clocks
+ *     [15:8]  DRAM Command Time:      0 CSB clocks
+ *     [07:00] DRAM Precharge Time:    0 CSB clocks
+ * TIME_CFG1
+ *     [31:26] DRAM tRFC:
+ *     [25:21] DRAM tWR1:
+ *     [20:17] DRAM tWRT1:
+ *     [16:11] DRAM tDRR:
+ *     [10:05] DRAM tRC:
+ *     [04:00] DRAM tRAS:
+ * TIME_CFG2
+ *     [31:28] DRAM tRCD:
+ *     [27:23] DRAM tFAW:
+ *     [22:19] DRAM tRTW1:
+ *     [18:15] DRAM tCCD:
+ *     [14:10] DRAM tRTP:
+ *     [09:05] DRAM tRP:
+ *     [04:00] DRAM tRPA
+ */
+
+/*
+ * NOTE: although this board uses DDR1 only, the common source brings defaults
+ * for DDR2 init sequences, that's why we have to keep those here as well
+ */
+
+/* DDR1 -- 32bit, drive strength (pad configuration) 3 for control and data */
+#define CONFIG_SYS_IOCTRL_MUX_DDR      ((0 << 6) | (3 << 3) | (3 << 0))
+
+#define CONFIG_SYS_MDDRC_SYS_CFG (/* 0xEAA09100 */ 0 \
+                       | (1 << 31)     /* RST_B */ \
+                       | (1 << 30)     /* CKE */ \
+                       | (1 << 29)     /* CLK_ON */ \
+                       | (0 << 28)     /* CMD_MODE */ \
+                       | (5 << 25)     /* DRAM_ROW_SELECT */ \
+                       | (5 << 21)     /* DRAM_BANK_SELECT */ \
+                       | (0 << 18)     /* SELF_REF_EN */ \
+                       | (0 << 17)     /* 16BIT_MODE */ \
+                       | (4 << 13)     /* RDLY */ \
+                       | (1 << 12)     /* HALF_DQS_DLY */ \
+                       | (0 << 11)     /* QUART_DQS_DLY */ \
+                       | (1 <<  8)     /* WDLY */ \
+                       | (0 <<  7)     /* EARLY_ODT */ \
+                       | (0 <<  6)     /* ON_DIE_TERMINATE */ \
+                       | (0 <<  5)     /* FIFO_OV_CLEAR */ \
+                       | (0 <<  4)     /* FIFO_UV_CLEAR */ \
+                       | (0 <<  1)     /* FIFO_OV_EN */ \
+                       | (0 <<  0)     /* FIFO_UV_EN */ \
+                       )
+
+#define CONFIG_SYS_MDDRC_TIME_CFG0     0x04E03124
+#define CONFIG_SYS_MDDRC_TIME_CFG1     0x30CA1147
+#define CONFIG_SYS_MDDRC_TIME_CFG2     0x32B10864
+
+/* register address only, i.e. template without values */
+#define CONFIG_SYS_MICRON_BMODE                0x01000000
+#define CONFIG_SYS_MICRON_EMODE                0x01010000
+#define CONFIG_SYS_MICRON_EMODE2       0x01020000
+#define CONFIG_SYS_MICRON_EMODE3       0x01030000
+/*
+ * values for mode registers (without mode register address)
+ */
+/* CAS 2.5 (6), burst seq (0) and length 4 (2) */
+#define CONFIG_SYS_MICRON_BMODE_PARAM  0x00000062
+#define CONFIG_SYS_MICRON_BMODE_RSTDLL 0x00000100
+/* DLL enable, reduced drive strength */
+#define CONFIG_SYS_MICRON_EMODE_PARAM  0x00000002
+
+#define CONFIG_SYS_DDRCMD_NOP          0x01380000
+#define CONFIG_SYS_DDRCMD_PCHG_ALL     0x01100400
+#define CONFIG_SYS_MICRON_EMR         ((1 << 24) |     /* CMD_REQ */ \
+                                       (0 << 22) |     /* DRAM_CS */ \
+                                       (0 << 21) |     /* DRAM_RAS */ \
+                                       (0 << 20) |     /* DRAM_CAS */ \
+                                       (0 << 19) |     /* DRAM_WEB */ \
+                                       (1 << 16) |     /* DRAM_BS[2:0] */ \
+                                       (0 << 15) |     /* */ \
+                                       (0 << 12) |     /* A12->out */ \
+                                       (0 << 11) |     /* A11->RDQS */ \
+                                       (0 << 10) |     /* A10->DQS# */ \
+                                       (0 <<  7) |     /* OCD program */ \
+                                       (0 <<  6) |     /* Rtt1 */ \
+                                       (0 <<  3) |     /* posted CAS# */ \
+                                       (0 <<  2) |     /* Rtt0 */ \
+                                       (1 <<  1) |     /* ODS */ \
+                                       (0 <<  0)       /* DLL */ \
+                                    )
+#define CONFIG_SYS_MICRON_EMR2         0x01020000
+#define CONFIG_SYS_MICRON_EMR3         0x01030000
+#define CONFIG_SYS_DDRCMD_RFSH         0x01080000
+#define CONFIG_SYS_MICRON_INIT_DEV_OP  0x01000432
+#define CONFIG_SYS_MICRON_EMR_OCD      ((1 << 24) |    /* CMD_REQ */ \
+                                       (0 << 22) |     /* DRAM_CS */ \
+                                       (0 << 21) |     /* DRAM_RAS */ \
+                                       (0 << 20) |     /* DRAM_CAS */ \
+                                       (0 << 19) |     /* DRAM_WEB */ \
+                                       (1 << 16) |     /* DRAM_BS[2:0] */ \
+                                       (0 << 15) |     /* */ \
+                                       (0 << 12) |     /* A12->out */ \
+                                       (0 << 11) |     /* A11->RDQS */ \
+                                       (1 << 10) |     /* A10->DQS# */ \
+                                       (7 <<  7) |     /* OCD program */ \
+                                       (0 <<  6) |     /* Rtt1 */ \
+                                       (0 <<  3) |     /* posted CAS# */ \
+                                       (1 <<  2) |     /* Rtt0 */ \
+                                       (0 <<  1) |     /* ODS */ \
+                                       (0 <<  0)       /* DLL */ \
+                                    )
+
+/*
+ * Backward compatible definitions,
+ * so we do not have to change arch/powerpc/cpu/mpc512x/fixed_sdram.c
+ */
+#define        CONFIG_SYS_DDRCMD_EM2           (CONFIG_SYS_MICRON_EMR2)
+#define CONFIG_SYS_DDRCMD_EM3          (CONFIG_SYS_MICRON_EMR3)
+#define CONFIG_SYS_DDRCMD_EN_DLL       (CONFIG_SYS_MICRON_EMR)
+#define CONFIG_SYS_DDRCMD_OCD_DEFAULT  (CONFIG_SYS_MICRON_EMR_OCD)
+
+/* DDR Priority Manager Configuration */
+#define CONFIG_SYS_MDDRCGRP_PM_CFG1    0x00077777
+#define CONFIG_SYS_MDDRCGRP_PM_CFG2    0x00000000
+#define CONFIG_SYS_MDDRCGRP_HIPRIO_CFG 0x00000001
+#define CONFIG_SYS_MDDRCGRP_LUT0_MU    0xFFEEDDCC
+#define CONFIG_SYS_MDDRCGRP_LUT0_ML    0xBBAAAAAA
+#define CONFIG_SYS_MDDRCGRP_LUT1_MU    0x66666666
+#define CONFIG_SYS_MDDRCGRP_LUT1_ML    0x55555555
+#define CONFIG_SYS_MDDRCGRP_LUT2_MU    0x44444444
+#define CONFIG_SYS_MDDRCGRP_LUT2_ML    0x44444444
+#define CONFIG_SYS_MDDRCGRP_LUT3_MU    0x55555555
+#define CONFIG_SYS_MDDRCGRP_LUT3_ML    0x55555558
+#define CONFIG_SYS_MDDRCGRP_LUT4_MU    0x11111111
+#define CONFIG_SYS_MDDRCGRP_LUT4_ML    0x11111122
+#define CONFIG_SYS_MDDRCGRP_LUT0_AU    0xaaaaaaaa
+#define CONFIG_SYS_MDDRCGRP_LUT0_AL    0xaaaaaaaa
+#define CONFIG_SYS_MDDRCGRP_LUT1_AU    0x66666666
+#define CONFIG_SYS_MDDRCGRP_LUT1_AL    0x66666666
+#define CONFIG_SYS_MDDRCGRP_LUT2_AU    0x11111111
+#define CONFIG_SYS_MDDRCGRP_LUT2_AL    0x11111111
+#define CONFIG_SYS_MDDRCGRP_LUT3_AU    0x11111111
+#define CONFIG_SYS_MDDRCGRP_LUT3_AL    0x11111111
+#define CONFIG_SYS_MDDRCGRP_LUT4_AU    0x11111111
+#define CONFIG_SYS_MDDRCGRP_LUT4_AL    0x11111111
+
+/*
+ * NOR FLASH on the Local Bus
+ */
+#define CONFIG_SYS_FLASH_CFI                           /* use the CFI code */
+#define CONFIG_FLASH_CFI_DRIVER                                /* use the CFI driver */
+#define CONFIG_SYS_FLASH_BASE          0xFC000000      /* start of FLASH */
+#define CONFIG_SYS_FLASH_SIZE          0x04000000      /* max flash size */
+
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+#define CONFIG_SYS_MAX_FLASH_BANKS     1               /* number of banks */
+#define CONFIG_SYS_FLASH_BANKS_LIST    { \
+       CONFIG_SYS_FLASH_BASE + 0 * CONFIG_SYS_FLASH_SIZE, \
+       }
+#define CONFIG_SYS_MAX_FLASH_SECT      512     /* max sectors per device */
+
+#undef CONFIG_SYS_FLASH_CHECKSUM
+#define CONFIG_SYS_FLASH_PROTECTION
+
+/*
+ * SRAM support
+ */
+#define CONFIG_SYS_SRAM_BASE           0x30000000
+#define CONFIG_SYS_SRAM_SIZE           0x00020000      /* 128 KB */
+
+/*
+ * CS related parameters
+ * TODO document these
+ */
+/* CS0 Flash */
+#define CONFIG_SYS_CS0_CFG             0x00031110
+#define CONFIG_SYS_CS0_START           0xFC000000
+#define CONFIG_SYS_CS0_SIZE            0x04000000
+/* CS1 FRAM */
+#define CONFIG_SYS_CS1_CFG             0x00011000
+#define CONFIG_SYS_CS1_START           0xE0000000
+#define CONFIG_SYS_CS1_SIZE            0x00010000
+/* CS2 AS-i 1 */
+#define CONFIG_SYS_CS2_CFG             0x00009100
+#define CONFIG_SYS_CS2_START           0xE0100000
+#define CONFIG_SYS_CS2_SIZE            0x00080000
+/* CS3 netX */
+#define CONFIG_SYS_CS3_CFG             0x000A1140
+#define CONFIG_SYS_CS3_START           0xE0300000
+#define CONFIG_SYS_CS3_SIZE            0x00020000
+/* CS5 safety */
+#define CONFIG_SYS_CS5_CFG             0x0011F000
+#define CONFIG_SYS_CS5_START           0xE0400000
+#define CONFIG_SYS_CS5_SIZE            0x00010000
+/* CS6 AS-i 2 */
+#define CONFIG_SYS_CS6_CFG             0x00009100
+#define CONFIG_SYS_CS6_START           0xE0200000
+#define CONFIG_SYS_CS6_SIZE            0x00080000
+
+/* Don't use alternative CS timing for any CS */
+#define CONFIG_SYS_CS_ALETIMING                0x00000000
+#define CONFIG_SYS_CS_BURST            0x00000000
+#define CONFIG_SYS_CS_DEADCYCLE                0x00000020
+#define CONFIG_SYS_CS_HOLDCYCLE                0x00000020
+
+/* Use SRAM for initial stack */
+#define CONFIG_SYS_INIT_RAM_ADDR       CONFIG_SYS_SRAM_BASE
+#define CONFIG_SYS_INIT_RAM_END                CONFIG_SYS_SRAM_SIZE
+
+#define CONFIG_SYS_GBL_DATA_SIZE       0x100
+#define CONFIG_SYS_GBL_DATA_OFFSET     (CONFIG_SYS_INIT_RAM_END - \
+                                        CONFIG_SYS_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_OFFSET      CONFIG_SYS_GBL_DATA_OFFSET
+
+#define CONFIG_SYS_MONITOR_BASE                CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_MONITOR_LEN         (256 * 1024)
+
+#ifdef CONFIG_FSL_DIU_FB
+#define CONFIG_SYS_MALLOC_LEN          (6 * 1024 * 1024)
+#else
+#define CONFIG_SYS_MALLOC_LEN          (512 * 1024)
+#endif
+
+/*
+ * Serial Port
+ */
+#define CONFIG_CONS_INDEX              1
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_PSC_CONSOLE             3       /* console on PSC3 */
+#define CONFIG_SYS_PSC3
+#if CONFIG_PSC_CONSOLE != 3
+#error CONFIG_PSC_CONSOLE must be 3
+#endif
+
+#define CONFIG_BAUDRATE                        115200  /* ... at 115200 bps */
+#define CONFIG_SYS_BAUDRATE_TABLE  \
+       {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 115200}
+
+#define CONSOLE_FIFO_TX_SIZE           FIFOC_PSC3_TX_SIZE
+#define CONSOLE_FIFO_TX_ADDR           FIFOC_PSC3_TX_ADDR
+#define CONSOLE_FIFO_RX_SIZE           FIFOC_PSC3_RX_SIZE
+#define CONSOLE_FIFO_RX_ADDR           FIFOC_PSC3_RX_ADDR
+
+/*
+ * Clocks in use
+ */
+#define SCCR1_CLOCKS_EN        (CLOCK_SCCR1_CFG_EN |           \
+                        CLOCK_SCCR1_LPC_EN |           \
+                        CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) | \
+                        CLOCK_SCCR1_PSC_EN(7) |        \
+                        CLOCK_SCCR1_PSCFIFO_EN |       \
+                        CLOCK_SCCR1_DDR_EN |           \
+                        CLOCK_SCCR1_FEC_EN |           \
+                        CLOCK_SCCR1_TPR_EN)
+
+#define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_MEM_EN |           \
+                        CLOCK_SCCR2_SPDIF_EN |         \
+                        CLOCK_SCCR2_DIU_EN |           \
+                        CLOCK_SCCR2_I2C_EN)
+
+
+#define CONFIG_CMDLINE_EDITING         1       /* command line history */
+
+/* I2C */
+#define CONFIG_HARD_I2C                        /* I2C with hardware support */
+#define CONFIG_I2C_MULTI_BUS
+
+/* I2C speed and slave address */
+#define CONFIG_SYS_I2C_SPEED           100000
+#define CONFIG_SYS_I2C_SLAVE           0x7F
+
+/*
+ * EEPROM configuration for Atmel AT24C01:
+ * 8-bit addresses, 30ms write delay, 32-Byte Page Write Mode
+ */
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_I2C_EEPROM_ADDR             0x52
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  30
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      5
+
+/*
+ * Ethernet configuration
+ */
+#define CONFIG_MPC512x_FEC             1
+#define CONFIG_NET_MULTI
+#define CONFIG_PHY_ADDR                        0x1F
+#define CONFIG_MII                     1       /* MII PHY management */
+#define CONFIG_FEC_AN_TIMEOUT          1
+#define CONFIG_HAS_ETH0
+
+/*
+ * Environment
+ */
+#define CONFIG_ENV_IS_IN_FLASH         1
+/* This has to be a multiple of the flash sector size */
+#define CONFIG_ENV_ADDR                        0xFFF40000
+#define CONFIG_ENV_SIZE                        0x2000
+#define CONFIG_ENV_SECT_SIZE           0x20000
+
+/* Address and size of Redundant Environment Sector */
+#define CONFIG_ENV_ADDR_REDUND         (CONFIG_ENV_ADDR + \
+                                        CONFIG_ENV_SECT_SIZE)
+#define CONFIG_ENV_SIZE_REDUND         (CONFIG_ENV_SIZE)
+
+#define CONFIG_LOADS_ECHO              1
+#define CONFIG_SYS_LOADS_BAUD_CHANGE   1
+
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_EEPROM
+#undef CONFIG_CMD_FUSE
+#define CONFIG_CMD_I2C
+#undef CONFIG_CMD_IDE
+#undef CONFIG_CMD_EXT2
+#define CONFIG_CMD_JFFS2
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_NFS
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_REGINFO
+
+#if defined(CONFIG_PCI)
+#define CONFIG_CMD_PCI
+#endif
+
+#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_EXT2)
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION
+#endif /* defined(CONFIG_CMD_IDE) */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP                    /* undef to save memory */
+#define CONFIG_SYS_LOAD_ADDR   0x2000000       /* default load address */
+#define CONFIG_SYS_PROMPT      "ac14xx> "      /* Monitor Command Prompt */
+
+#ifdef 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)
+/* max number of command args */
+#define CONFIG_SYS_MAXARGS     32
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
+
+/* decrementer freq: 1ms ticks */
+#define CONFIG_SYS_HZ          1000
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CONFIG_SYS_BOOTMAPSZ           (8 << 20)
+
+/* Cache Configuration */
+#define CONFIG_SYS_DCACHE_SIZE         32768
+#define CONFIG_SYS_CACHELINE_SIZE      32
+#ifdef CONFIG_CMD_KGDB
+#define CONFIG_SYS_CACHELINE_SHIFT     5       /* log base 2 of 32 */
+#endif
+
+#define CONFIG_SYS_HID0_INIT           0x000000000
+#define CONFIG_SYS_HID0_FINAL          (HID0_ENABLE_MACHINE_CHECK | \
+                                        HID0_ICE)
+#define CONFIG_SYS_HID2        HID2_HBE
+
+#define CONFIG_HIGH_BATS               1       /* High BATs supported */
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD                  0x01
+#define BOOTFLAG_WARM                  0x02
+
+#ifdef CONFIG_CMD_KGDB
+#define CONFIG_KGDB_BAUDRATE           230400  /* speed of kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX          2       /* which serial port to use */
+#endif
+
+/*
+ * Environment Configuration
+ */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_TIMESTAMP
+
+#define CONFIG_HOSTNAME                ac14xx
+#define CONFIG_BOOTFILE                "ac14xx/uImage"
+#define CONFIG_ROOTPATH                "/opt/eldk/ppc_6xx"
+
+/* default load addr for tftp and bootm */
+#define CONFIG_LOADADDR                400000
+
+#define CONFIG_BOOTDELAY       2       /* -1 disables auto-boot */
+
+/* XXX TODO need to specify the builtin environment */
+#define CONFIG_PREBOOT "echo;" \
+       "echo Type \\\"run flash_nfs\\\" to mount root filesystem over NFS;" \
+       "echo"
+
+#define CONFIG_EXTRA_ENV_SETTINGS_DEVEL                                        \
+       "muster_nr=00\0"                                                \
+       "fromram=run ramargs addip addtty; "                            \
+               "tftp ${fdt_addr_r} k6m2/ac14xx.dtb-${muster_nr}; "     \
+               "tftp ${kernel_addr_r} k6m2/uImage-${muster_nr}; "      \
+               "tftp ${ramdisk_addr_r} k6m2/uFS-${muster_nr}; "        \
+               "bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}\0" \
+       "fromnfs=run nfsargs addip addtty; "                            \
+               "tftp ${fdt_addr_r} k6m2/ac14xx.dtb-${muster_nr}; "     \
+               "tftp ${kernel_addr_r} k6m2/uImage-${muster_nr}; "      \
+               "bootm ${kernel_addr_r} - ${fdt_addr_r}\0"              \
+       "fromflash=run nfsargs addip addtty; "                          \
+               "bootm fc020000 - fc000000\0"                           \
+       "mtdargsrec=setenv bootargs root=/dev/mtdblock1 ro\0"           \
+       "recovery=run mtdargsrec addip addtty; "                        \
+               "bootm ffd20000 - ffee0000\0"                           \
+       "production=run ramargs addip addtty; "                         \
+               "bootm fc020000 fc400000 fc000000\0"                    \
+       "mtdargs=setenv bootargs root=/dev/mtdblock1 ro\0"              \
+       "prodmtd=run mtdargs addip addtty; "                            \
+               "bootm fc020000 - fc000000\0"                           \
+       ""
+
+#define        CONFIG_EXTRA_ENV_SETTINGS                                       \
+       "u-boot_addr_r=200000\0"                                        \
+       "kernel_addr_r=600000\0"                                        \
+       "fdt_addr_r=a00000\0"                                           \
+       "ramdisk_addr_r=b00000\0"                                       \
+       "u-boot_addr=FFF00000\0"                                        \
+       "kernel_addr=FC020000\0"                                        \
+       "fdt_addr=FC000000\0"                                           \
+       "ramdisk_addr=FC400000\0"                                       \
+       "verify=n\0"                                                    \
+       "ramdiskfile=ac14xx/uRamdisk\0"                                 \
+       "u-boot=ac14xx/u-boot.bin\0"                                    \
+       "bootfile=ac14xx/uImage\0"                                      \
+       "fdtfile=ac14xx/ac14xx.dtb\0"                                   \
+       "rootpath=/opt/eldk/ppc_6xx\n"                                  \
+       "netdev=eth0\0"                                                 \
+       "consdev=ttyPSC0\0"                                             \
+       "hostname=ac14xx\0"                                             \
+       "nfsargs=setenv bootargs root=/dev/nfs rw "                     \
+               "nfsroot=${serverip}:${rootpath}-${muster_nr}\0"        \
+       "ramargs=setenv bootargs root=/dev/ram rw\0"                    \
+       "addip=setenv bootargs ${bootargs} "                            \
+               "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"      \
+               ":${hostname}:${netdev}:off panic=1\0"                  \
+       "addtty=setenv bootargs ${bootargs} "                           \
+               "console=${consdev},${baudrate}\0"                      \
+       "flash_nfs=run nfsargs addip addtty;"                           \
+               "bootm ${kernel_addr} - ${fdt_addr}\0"                  \
+       "flash_self=run ramargs addip addtty;"                          \
+               "bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0"    \
+       "net_nfs=tftp ${kernel_addr_r} ${bootfile};"                    \
+               "tftp ${fdt_addr_r} ${fdtfile};"                        \
+               "run nfsargs addip addtty;"                             \
+               "bootm ${kernel_addr_r} - ${fdt_addr_r}\0"              \
+       "net_self=tftp ${kernel_addr_r} ${bootfile};"                   \
+               "tftp ${ramdisk_addr_r} ${ramdiskfile};"                \
+               "tftp ${fdt_addr_r} ${fdtfile};"                        \
+               "run ramargs addip addtty;"                             \
+               "bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}\0"\
+       "load=tftp ${u-boot_addr_r} ${u-boot}\0"                        \
+       "update=protect off ${u-boot_addr} +${filesize};"               \
+               "era ${u-boot_addr} +${filesize};"                      \
+               "cp.b ${u-boot_addr_r} ${u-boot_addr} ${filesize}\0"    \
+       CONFIG_EXTRA_ENV_SETTINGS_DEVEL                                 \
+       "upd=run load update\0"                                         \
+       ""
+
+#define CONFIG_BOOTCOMMAND     "run production"
+
+#define CONFIG_FIT             1
+#define CONFIG_OF_LIBFDT       1
+#define CONFIG_OF_BOARD_SETUP  1
+#define CONFIG_OF_SUPPORT_OLD_DEVICE_TREES     1
+
+#define OF_CPU                 "PowerPC,5121@0"
+#define OF_SOC_COMPAT          "fsl,mpc5121-immr"
+#define OF_TBCLK               (bd->bi_busfreq / 4)
+#define OF_STDOUT_PATH         "/soc@80000000/serial@11300"
+
+#endif /* __CONFIG_H */
index 9eada95c04f2e7dda90d2cf30aadfaabf874543d..b7c443c573f0284a88b1fe582c656ce582044591 100644 (file)
@@ -18,8 +18,7 @@
 
 #define CONFIG_AM33XX
 
-#include <asm/arch/cpu.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
 
 #define CONFIG_DMA_COHERENT
 #define CONFIG_DMA_COHERENT_SIZE       (1 << 20)
        "fdtaddr=0x80F80000\0" \
        "fdt_high=0xffffffff\0" \
        "rdaddr=0x81000000\0" \
-       "bootfile=/boot/uImage\0" \
+       "bootdir=/boot\0" \
+       "bootfile=uImage\0" \
        "fdtfile=\0" \
        "console=ttyO0,115200n8\0" \
        "optargs=\0" \
        "mmcdev=0\0" \
        "mmcroot=/dev/mmcblk0p2 ro\0" \
        "mmcrootfstype=ext4 rootwait\0" \
+       "bootpart=0:2\0" \
        "nandroot=ubi0:rootfs rw ubi.mtd=7,2048\0" \
        "nandrootfstype=ubifs rootwait=1\0" \
        "nandsrcaddr=0x280000\0" \
                "nfsroot=${serverip}:${rootpath},${nfsopts} rw " \
                "ip=dhcp\0" \
        "bootenv=uEnv.txt\0" \
-       "loadbootenv=fatload mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \
+       "loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \
        "importbootenv=echo Importing environment from mmc ...; " \
                "env import -t $loadaddr $filesize\0" \
        "ramargs=setenv bootargs console=${console} " \
                "${optargs} " \
                "root=${ramroot} " \
                "rootfstype=${ramrootfstype}\0" \
-       "loadramdisk=fatload mmc ${mmcdev} ${rdaddr} ramdisk.gz\0" \
-       "loaduimagefat=fatload mmc ${mmcdev} ${loadaddr} ${bootfile}\0" \
-       "loaduimage=ext2load mmc ${mmcdev}:2 ${loadaddr} ${bootfile}\0" \
+       "loadramdisk=load mmc ${mmcdev} ${rdaddr} ramdisk.gz\0" \
+       "loaduimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}\0" \
+       "loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}\0" \
        "mmcboot=echo Booting from mmc ...; " \
                "run mmcargs; " \
-               "bootm ${loadaddr}\0" \
+               "bootm ${loadaddr} - ${fdtaddr}\0" \
        "nandboot=echo Booting from nand ...; " \
                "run nandargs; " \
                "nand read ${loadaddr} ${nandsrcaddr} ${nandimgsize}; " \
                "setenv autoload no; " \
                "dhcp; " \
                "tftp ${loadaddr} ${bootfile}; " \
+               "tftp ${fdtaddr} ${fdtfile}; " \
                "run netargs; " \
-               "bootm ${loadaddr}\0" \
+               "bootm ${loadaddr} - ${fdtaddr}\0" \
        "ramboot=echo Booting from ramdisk ...; " \
                "run ramargs; " \
-               "bootm ${loadaddr}\0" \
+               "bootm ${loadaddr} ${rdaddr} ${fdtaddr}\0" \
        "findfdt="\
                "if test $board_name = A335BONE; then " \
                        "setenv fdtfile am335x-bone.dtb; fi; " \
+               "if test $board_name = A335BNLT; then " \
+                       "setenv fdtfile am335x-boneblack.dtb; fi; " \
                "if test $board_name = A33515BB; then " \
                        "setenv fdtfile am335x-evm.dtb; fi; " \
                "if test $board_name = A335X_SK; then " \
 #endif
 
 #define CONFIG_BOOTCOMMAND \
+       "run findfdt; " \
        "mmc dev ${mmcdev}; if mmc rescan; then " \
                "echo SD/MMC found on device ${mmcdev};" \
                "if run loadbootenv; then " \
                        "run uenvcmd;" \
                "fi;" \
                "if run loaduimage; then " \
+                       "run loadfdt;" \
                        "run mmcboot;" \
                "fi;" \
        "else " \
 #define CONFIG_DOS_PARTITION
 #define CONFIG_CMD_FAT
 #define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EXT4
+#define CONFIG_CMD_FS_GENERIC
 
 #define CONFIG_SPI
 #define CONFIG_OMAP3_SPI
index 0b31c50daf4da0dde659700e502c8648fa86f486..b4253996a01b0add87b9eaa5d391e3f0ce7948ee 100644 (file)
@@ -64,7 +64,6 @@
 
 #define CONFIG_SYS_MPC512X_CLKIN       33000000        /* in Hz */
 
-#define CONFIG_BOARD_EARLY_INIT_F              /* call board_early_init_f() */
 #define CONFIG_MISC_INIT_R
 
 #define CONFIG_SYS_IMMR                        0x80000000
 #define CONFIG_SYS_ARIA_SRAM_BASE      (CONFIG_SYS_SRAM_BASE + \
                                         CONFIG_SYS_SRAM_SIZE)
 #define CONFIG_SYS_ARIA_SRAM_SIZE      0x00100000      /* reserve 1MB-window */
+#define CONFIG_SYS_CS6_START           CONFIG_SYS_ARIA_SRAM_BASE
+#define CONFIG_SYS_CS6_SIZE            CONFIG_SYS_ARIA_SRAM_SIZE
 
 #define CONFIG_SYS_ARIA_FPGA_BASE      (CONFIG_SYS_ARIA_SRAM_BASE + \
                                         CONFIG_SYS_ARIA_SRAM_SIZE)
 #define CONFIG_SYS_ARIA_FPGA_SIZE      0x20000         /* 128 KB */
 
+#define CONFIG_SYS_CS2_START           CONFIG_SYS_ARIA_FPGA_BASE
+#define CONFIG_SYS_CS2_SIZE            CONFIG_SYS_ARIA_FPGA_SIZE
+
 #define CONFIG_SYS_CS0_CFG             0x05059150
 #define CONFIG_SYS_CS2_CFG             (       (5 << 24) | \
                                                (5 << 16) | \
 #define FSL_ATA_CTRL_DMA_WRITE         0x02000000
 #define FSL_ATA_CTRL_IORDY_EN          0x01000000
 
+/* Clocks in use */
+#define SCCR1_CLOCKS_EN        (CLOCK_SCCR1_CFG_EN |                           \
+                        CLOCK_SCCR1_LPC_EN |                           \
+                        CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) |       \
+                        CLOCK_SCCR1_PSCFIFO_EN |                       \
+                        CLOCK_SCCR1_DDR_EN |                           \
+                        CLOCK_SCCR1_FEC_EN |                           \
+                        CLOCK_SCCR1_NFC_EN |                           \
+                        CLOCK_SCCR1_PATA_EN |                          \
+                        CLOCK_SCCR1_PCI_EN |                           \
+                        CLOCK_SCCR1_TPR_EN)
+
+#define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_MEM_EN |           \
+                        CLOCK_SCCR2_SPDIF_EN |         \
+                        CLOCK_SCCR2_DIU_EN |           \
+                        CLOCK_SCCR2_I2C_EN)
+
 #endif /* __CONFIG_H */
index 55dc83da6a187bfc00f94d84182c17ba5737a979..6a991752114ae70ecba7c5829dec2eebf35ae533 100644 (file)
@@ -60,7 +60,7 @@
 #define CONFIG_SYS_MMC_ENV_PART                2
 
 /* SPI */
-#define CONFIG_TEGRA_SLINK
+#define CONFIG_TEGRA20_SLINK
 #define CONFIG_TEGRA_SLINK_CTRLS       6
 #define CONFIG_SPI_FLASH
 #define CONFIG_SPI_FLASH_WINBOND
index 8d79ffd48a4b438a083ede26e10d2857390ee543..726714dd2118f8c193d8921406c385d3adf15d5d 100644 (file)
 #define LCD_BPP                LCD_COLOR16
 
 #define CONFIG_LCD
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_CMD_BMP
+#define CONFIG_BMP_16BPP
+#define CONFIG_SPLASH_SCREEN_PREPARE
 
 #endif /* __CONFIG_H */
index 49f05decc0374ac26538426c7b843736403ef8ef..a4aa8f74535e4d3f1d769e8b2c4e51759c2a840a 100644 (file)
 #define CONFIG_CMD_SAVEENV
 #define CONFIG_CMD_SETGETDCR
 #define CONFIG_CMD_SOURCE
+#define CONFIG_CMD_TIME
+#define CONFIG_CMD_GETTIME
 #define CONFIG_CMD_XIMG
 #define CONFIG_CMD_SCSI
 
 /*-----------------------------------------------------------------------
  * FLASH configuration
  */
+#define CONFIG_ICH_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_MACRONIX
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_SPI_FLASH_GIGADEVICE
 #define CONFIG_SYS_NO_FLASH
-#undef CONFIG_FLASH_CFI_DRIVER
-#define CONFIG_SYS_MAX_FLASH_SECT              1
-#define CONFIG_SYS_MAX_FLASH_BANKS             1
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SF_TEST
+#define CONFIG_CMD_SPI
+#define CONFIG_SPI
 
 /*-----------------------------------------------------------------------
  * Environment configuration
  */
 #define CONFIG_PCI
 
+/*-----------------------------------------------------------------------
+ * USB configuration
+ */
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_PCI
+#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     12
+#define CONFIG_USB_MAX_CONTROLLER_COUNT        2
+#define CONFIG_USB_STORAGE
+#define CONFIG_USB_KEYBOARD
+#define CONFIG_SYS_USB_EVENT_POLL
+
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_ASIX
+#define CONFIG_USB_ETHER_SMSC95XX
+
+#define CONFIG_CMD_USB
+
 #define CONFIG_EXTRA_ENV_SETTINGS \
        CONFIG_STD_DEVICES_SETTINGS
 
index b1a6e34ebad93b4c914002a1545f039d0f085d39..7b68f7ca987515d5473a56ebc3637927e348d33f 100644 (file)
 #define CONFIG_SYS_I2C_SPEED           100000
 #define CONFIG_CMD_I2C
 
-#define CONFIG_ENV_IS_NOWHERE
+/* SD/MMC */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_TEGRA_MMC
+#define CONFIG_CMD_MMC
+
+/* Environment in eMMC, at the end of 2nd "boot sector" */
+#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 MACH_TYPE_DALMORE      4304    /* not yet in mach-types.h */
 
+/* SPI */
+#define CONFIG_TEGRA114_SPI
+#define CONFIG_TEGRA114_SPI_CTRLS      6
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_SF_DEFAULT_MODE         SPI_MODE_0
+#define CONFIG_SF_DEFAULT_SPEED        24000000
+#define CONFIG_CMD_SPI
+#define CONFIG_CMD_SF
+#define CONFIG_SPI_FLASH_SIZE          (4 << 20)
+
 #include "tegra-common-post.h"
 
 #endif /* __CONFIG_H */
index cabd2f2524a7254e5c8088eaa1cc39bc4f0b6f7e..2b9d6ac061e226d812431a93d74ea3bc464a8991 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <asm/arch/cpu.h>              /* get chip and board defs */
 
+#define CONFIG_SYS_GENERIC_BOARD
 #define CONFIG_ARCH_CPU_INIT
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 #define CONFIG_BOOTDELAY               3
 #define CONFIG_ZERO_BOOTDELAY_CHECK
 
+/* Thermal Management Unit */
+#define CONFIG_EXYNOS_TMU
+#define CONFIG_CMD_DTT
+#define CONFIG_TMU_CMD_DTT
+
 /* USB */
 #define CONFIG_CMD_USB
 #define CONFIG_USB_EHCI
 #ifdef CONFIG_CMD_SOUND
 #define CONFIG_SOUND
 #define CONFIG_I2S
+#define CONFIG_SOUND_MAX98095
 #define CONFIG_SOUND_WM8994
 #endif
 
index 559e3759deff0d9f5473498cd28b27b96cf7eacf..849fb1624f0d8625df874bcb028d79f22ec40374 100644 (file)
@@ -55,7 +55,8 @@
 #define CONFIG_INITRD_TAG              1
 #define CONFIG_REVISION_TAG            1
 
-#define CONFIG_OF_LIBFDT               1
+#define CONFIG_OF_LIBFDT
+#define CONFIG_CMD_BOOTZ
 
 /*
  * NS16550 Configuration
index 796f33080d359a3f47c696ab30e4f76bd519c495..3b15c4e6910010197a6fa9c7952e47a8caa4b690 100644 (file)
 #ifndef __CONFIG_KEYMILE_H
 #define __CONFIG_KEYMILE_H
 
-/* Do boardspecific init for all boards */
-#define CONFIG_BOARD_EARLY_INIT_R
-#define CONFIG_LAST_STAGE_INIT
-
 #define CONFIG_BOOTCOUNT_LIMIT
 
 /*
index bd5bdbcb4895a6b3dd856af6915104fe9e7d1ed7..b84f12dbebddcd484ac7e435711180e2c8be1f0f 100644 (file)
 #ifndef __CONFIG_KEYMILE_POWERPC_H
 #define __CONFIG_KEYMILE_POWERPC_H
 
+/* Do boardspecific init for all boards */
+#define CONFIG_BOARD_EARLY_INIT_R
+#define CONFIG_LAST_STAGE_INIT
+
 #define CONFIG_BOOTCOUNT_LIMIT
 
 #define CONFIG_CMD_DTT
index cafc273c8c2c8c379311bde1e196c342508ec025..af302573e6782db8edeb550a30cc6c1a6664a923 100644 (file)
 #define CONFIG_SYS_SRAM_BASE           0x30000000
 #define CONFIG_SYS_SRAM_SIZE           0x00020000      /* 128 KB */
 
+/* Initialize Local Window for NOR FLASH access */
+#define CONFIG_SYS_CS0_START           CONFIG_SYS_FLASH_BASE
+#define CONFIG_SYS_CS0_SIZE            CONFIG_SYS_FLASH_SIZE
+
 /* ALE active low, data size 4bytes */
 #define CONFIG_SYS_CS0_CFG             0x05051150
 
 #define CONFIG_SYS_CS1_CFG             0x1f1f3090
 #define CONFIG_SYS_VPC3_BASE           0x82000000      /* start of VPC3 space */
 #define CONFIG_SYS_VPC3_SIZE           0x00010000      /* max VPC3 size */
+/* Initialize Local Window for VPC3 access */
+#define CONFIG_SYS_CS1_START           CONFIG_SYS_VPC3_BASE
+#define CONFIG_SYS_CS1_SIZE            CONFIG_SYS_VPC3_SIZE
 
 /* Use SRAM for initial stack */
 #define CONFIG_SYS_INIT_RAM_ADDR       CONFIG_SYS_SRAM_BASE /* Init RAM addr */
 #define CONSOLE_FIFO_RX_SIZE   FIFOC_PSC3_RX_SIZE
 #define CONSOLE_FIFO_RX_ADDR   FIFOC_PSC3_RX_ADDR
 
+/*
+ * Clocks in use
+ */
+#define SCCR1_CLOCKS_EN        (CLOCK_SCCR1_CFG_EN |                           \
+                        CLOCK_SCCR1_LPC_EN |                           \
+                        CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) |       \
+                        CLOCK_SCCR1_PSCFIFO_EN |                       \
+                        CLOCK_SCCR1_DDR_EN |                           \
+                        CLOCK_SCCR1_FEC_EN |                           \
+                        CLOCK_SCCR1_NFC_EN |                           \
+                        CLOCK_SCCR1_PCI_EN |                           \
+                        CLOCK_SCCR1_TPR_EN)
+
+#define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_MEM_EN |   \
+                        CLOCK_SCCR2_I2C_EN)
+
+
 #define CONFIG_CMDLINE_EDITING 1       /* add command line history     */
 /* Use the HUSH parser */
 #define CONFIG_SYS_HUSH_PARSER
index 3f55d354ef7d28b81a5d50bd6548ad026e29c91e..6e6af62ccad5b7d5ca5a3da7c2ecdd07fa714ade 100644 (file)
  */
 #define CONFIG_SYS_CPLD_BASE           0x82000000
 #define CONFIG_SYS_CPLD_SIZE           0x00010000      /* 64 KB */
+#define CONFIG_SYS_CS2_START           CONFIG_SYS_CPLD_BASE
+#define CONFIG_SYS_CS2_SIZE            CONFIG_SYS_CPLD_SIZE
 
 #define CONFIG_SYS_SRAM_BASE           0x30000000
 #define CONFIG_SYS_SRAM_SIZE           0x00020000      /* 128 KB */
 #ifdef  CONFIG_SYS_HUSH_PARSER
 #endif
 
+/*
+ * Clocks in use
+ */
+#define SCCR1_CLOCKS_EN        (CLOCK_SCCR1_CFG_EN |                           \
+                        CLOCK_SCCR1_DDR_EN |                           \
+                        CLOCK_SCCR1_FEC_EN |                           \
+                        CLOCK_SCCR1_LPC_EN |                           \
+                        CLOCK_SCCR1_NFC_EN |                           \
+                        CLOCK_SCCR1_PATA_EN |                          \
+                        CLOCK_SCCR1_PCI_EN |                           \
+                        CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) |       \
+                        CLOCK_SCCR1_PSCFIFO_EN |                       \
+                        CLOCK_SCCR1_TPR_EN)
+
+#define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_DIU_EN |           \
+                        CLOCK_SCCR2_I2C_EN |           \
+                        CLOCK_SCCR2_MEM_EN |           \
+                        CLOCK_SCCR2_SPDIF_EN |         \
+                        CLOCK_SCCR2_USB1_EN |          \
+                        CLOCK_SCCR2_USB2_EN)
+
 /*
  * PCI
  */
index 63ab12329b489389743060fd6f764238b972ab8f..d0ea74e0b48dfcf06cd36283f4289b60c6f72678 100644 (file)
@@ -21,8 +21,7 @@
 
 #define CONFIG_AM33XX
 
-#include <asm/arch/cpu.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
 
 #define CONFIG_DMA_COHERENT
 #define CONFIG_DMA_COHERENT_SIZE       (1 << 20)
index 671e9eb1e5ef866dea43edf9718fc38f75643029..306abcc8e1a4697266b38ef58ef58472901a628f 100644 (file)
@@ -68,7 +68,6 @@
 
 #define CONFIG_SYS_MPC512X_CLKIN       33333333        /* in Hz */
 
-#define CONFIG_BOARD_EARLY_INIT_F      /* call board_early_init_f() */
 #define CONFIG_MISC_INIT_R
 
 #define CONFIG_SYS_IMMR                        0x80000000
 #define CONFIG_SYS_SRAM_BASE           0x50000000
 #define CONFIG_SYS_SRAM_SIZE           0x00020000      /* 128 KB */
 
+#define CONFIG_SYS_CS1_START           CONFIG_SYS_FLASH1_BASE
+#define CONFIG_SYS_CS1_SIZE            CONFIG_SYS_FLASH_SIZE
+
 /* ALE active low, data size 4 bytes */
 #define CONFIG_SYS_CS0_CFG             0x05059350
 /* ALE active low, data size 4 bytes */
 
 #define CONFIG_SYS_MRAM_BASE           0x50040000
 #define CONFIG_SYS_MRAM_SIZE           0x00020000
+#define CONFIG_SYS_CS2_START           CONFIG_SYS_MRAM_BASE
+#define CONFIG_SYS_CS2_SIZE            CONFIG_SYS_MRAM_SIZE
+
 /* ALE active low, data size 4 bytes */
 #define CONFIG_SYS_CS2_CFG             0x05059110
 
 #define CONSOLE_FIFO_RX_SIZE   FIFOC_PSC6_RX_SIZE
 #define CONSOLE_FIFO_RX_ADDR   FIFOC_PSC6_RX_ADDR
 
+/*
+ * Clocks in use
+ */
+#define SCCR1_CLOCKS_EN        (CLOCK_SCCR1_CFG_EN |                           \
+                        CLOCK_SCCR1_LPC_EN |                           \
+                        CLOCK_SCCR1_NFC_EN |                           \
+                        CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) |       \
+                        CLOCK_SCCR1_PSCFIFO_EN |                       \
+                        CLOCK_SCCR1_DDR_EN |                           \
+                        CLOCK_SCCR1_FEC_EN |                           \
+                        CLOCK_SCCR1_TPR_EN)
+
+#define SCCR2_CLOCKS_EN        (CLOCK_SCCR2_MEM_EN |           \
+                        CLOCK_SCCR2_SPDIF_EN |         \
+                        CLOCK_SCCR2_DIU_EN |           \
+                        CLOCK_SCCR2_I2C_EN)
+
 /*
  * Used PSC UART devices
  */
index cf62e45e8b7dd12b3776009e2576b2b9221e926b..c18b35b0578a64e09aa43a66d86371d84779b18b 100644 (file)
@@ -23,6 +23,7 @@
 #define CONFIG_ARM1176
 #define CONFIG_BCM2835
 #define CONFIG_ARCH_CPU_INIT
+#define CONFIG_SYS_DCACHE_OFF
 /*
  * 2835 is a SKU in a series for which the 2708 is the first or primary SoC,
  * so 2708 has historically been used rather than a dedicated 2835 ID.
@@ -30,7 +31,7 @@
 #define CONFIG_MACH_TYPE               MACH_TYPE_BCM2708
 
 /* Timer */
-#define CONFIG_SYS_HZ                  1000000
+#define CONFIG_SYS_HZ                  1000
 
 /* Memory layout */
 #define CONFIG_NR_DRAM_BANKS           1
@@ -50,6 +51,7 @@
 #define CONFIG_SYS_MALLOC_LEN          SZ_4M
 #define CONFIG_SYS_MEMTEST_START       0x00100000
 #define CONFIG_SYS_MEMTEST_END         0x00200000
+#define CONFIG_LOADADDR                        0x00200000
 
 /* Flash */
 #define CONFIG_SYS_NO_FLASH
 /* Devices */
 /* GPIO */
 #define CONFIG_BCM2835_GPIO
+/* LCD */
+#define CONFIG_LCD
+#define LCD_BPP                                LCD_COLOR16
+/*
+ * Prevent allocation of RAM for FB; the real FB address is queried
+ * dynamically from the VideoCore co-processor, and comes from RAM
+ * not owned by the ARM CPU.
+ */
+#define CONFIG_FB_ADDR                 0
+#define CONFIG_VIDEO_BCM2835
+#define CONFIG_SYS_WHITE_ON_BLACK
+
+/* SD/MMC configuration */
+#define CONFIG_GENERIC_MMC
+#define CONFIG_MMC
+#define CONFIG_SDHCI
+#define CONFIG_MMC_SDHCI_IO_ACCESSORS
+#define CONFIG_BCM2835_SDHCI
 
 /* Console UART */
 #define CONFIG_PL011_SERIAL
 /* Environment */
 #define CONFIG_ENV_SIZE                        SZ_16K
 #define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_VARS_UBOOT_CONFIG
 #define CONFIG_SYS_LOAD_ADDR           0x1000000
+#define CONFIG_CONSOLE_MUX
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+/*
+ * Memory layout for where various images get loaded by boot scripts:
+ *
+ * scriptaddr can be pretty much anywhere that doesn't conflict with something
+ *   else. Put it low in memory to avoid conflicts.
+ *
+ * kernel_addr_r must be within the first 128M of RAM in order for the
+ *   kernel's CONFIG_AUTO_ZRELADDR option to work. Since the kernel will
+ *   decompress itself to 0x8000 after the start of RAM, kernel_addr_r
+ *   should not overlap that area, or the kernel will have to copy itself
+ *   somewhere else before decompression. Similarly, the address of any other
+ *   data passed to the kernel shouldn't overlap the start of RAM. Pushing
+ *   this up to 16M allows for a sizable kernel to be decompressed below the
+ *   compressed load address.
+ *
+ * fdt_addr_r simply shouldn't overlap anything else. Choosing 32M allows for
+ *   the compressed kernel to be up to 16M too.
+ *
+ * ramdisk_addr_r simply shouldn't overlap anything else. Choosing 33M allows
+ *   for the FDT/DTB to be up to 1M, which is hopefully plenty.
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "stdin=serial\0" \
+       "stderr=serial,lcd\0" \
+       "stdout=serial,lcd\0" \
+       "scriptaddr=0x00000000\0" \
+       "kernel_addr_r=0x01000000\0" \
+       "fdt_addr_r=0x02000000\0" \
+       "ramdisk_addr_r=0x02100000\0" \
+       "boot_targets=mmc0\0" \
+       \
+       "script_boot=" \
+               "if fatload ${devtype} ${devnum}:1 " \
+                                       "${scriptaddr} boot.scr.uimg; then " \
+                       "source ${scriptaddr}; " \
+               "fi;\0" \
+       \
+       "mmc_boot=" \
+               "setenv devtype mmc; " \
+               "if mmc dev ${devnum}; then " \
+                       "run script_boot; " \
+               "fi\0" \
+       \
+       "bootcmd_mmc0=setenv devnum 0; run mmc_boot\0" \
+
+#define CONFIG_BOOTCOMMAND \
+       "for target in ${boot_targets}; do run bootcmd_${target}; done"
+
+#define CONFIG_BOOTDELAY               2
 
 /* Shell */
 #define CONFIG_SYS_HUSH_PARSER
 #include <config_cmd_default.h>
 #define CONFIG_CMD_BOOTZ
 #define CONFIG_CMD_GPIO
+#define CONFIG_CMD_MMC
+#define CONFIG_DOS_PARTITION
+#define CONFIG_PARTITION_UUIDS
+#define CONFIG_CMD_PART
+#define CONFIG_CMD_FS_GENERIC
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT
 /* Some things don't make sense on this HW or yet */
 #undef CONFIG_CMD_FPGA
 #undef CONFIG_CMD_NET
diff --git a/include/configs/snow.h b/include/configs/snow.h
new file mode 100644 (file)
index 0000000..b8460fd
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics
+ *
+ * Configuration settings for the SAMSUNG EXYNOS5 Snow board.
+ *
+ * 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_SNOW_H
+#define __CONFIG_SNOW_H
+
+#include <configs/exynos5250-dt.h>
+
+#undef CONFIG_DEFAULT_DEVICE_TREE
+#define CONFIG_DEFAULT_DEVICE_TREE     exynos5250-snow
+
+#endif /* __CONFIG_SNOW_H */
index f2a70b1a35c87fcaed23f2eace5ded446d8a3f43..bf186995ed4417b8f0c186e64645845ae23f8cca 100644 (file)
        MEM_LAYOUT_ENV_SETTINGS \
        BOOTCMDS_COMMON
 
+#if defined(CONFIG_TEGRA20_SFLASH) || defined(CONFIG_TEGRA20_SLINK) || defined(CONFIG_TEGRA114_SPI)
+#define CONFIG_FDT_SPI
+#endif
+
 /* overrides for SPL build here */
 #ifdef CONFIG_SPL_BUILD
 
index 4cc35e5a887cc288d40a5d606c7a3b7377fe8b45..036ded0c79f485230b8bd08f1a05212722f6b6dd 100644 (file)
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_GPIO_SUPPORT
 
+#define CONFIG_SYS_GENERIC_BOARD
 /* Misc utility code */
 #define CONFIG_BOUNCE_BUFFER
 
index e464e06173e8bf570e166a0d69b4a9bb13485bcc..395a657584f2dc8b5736c2a08a51befb88146bc1 100644 (file)
@@ -28,6 +28,7 @@
 /*
  * Errata configuration
  */
+#define CONFIG_ARM_ERRATA_716044
 #define CONFIG_ARM_ERRATA_742230
 #define CONFIG_ARM_ERRATA_751472
 
diff --git a/include/configs/ti814x_evm.h b/include/configs/ti814x_evm.h
new file mode 100644 (file)
index 0000000..16547e3
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * ti814x_evm.h
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __CONFIG_TI814X_EVM_H
+#define __CONFIG_TI814X_EVM_H
+
+#define CONFIG_TI81XX
+#define CONFIG_TI814X
+#define CONFIG_SYS_NO_FLASH
+
+#include <asm/arch/omap.h>
+
+#define CONFIG_DMA_COHERENT
+#define CONFIG_DMA_COHERENT_SIZE       (1 << 20)
+
+#define CONFIG_ENV_SIZE                        (128 << 10)     /* 128 KiB */
+#define CONFIG_SYS_MALLOC_LEN          (1024 << 10)
+#define CONFIG_SYS_LONGHELP            /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER         /* Use HUSH for command parsing */
+#define CONFIG_SYS_PROMPT              "U-Boot# "
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_MACH_TYPE               MACH_TYPE_TI8148EVM
+
+#define CONFIG_OF_LIBFDT
+#define CONFIG_CMDLINE_TAG             /* enable passing of ATAGs  */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG              /* for ramdisk support */
+
+/* commands to include */
+# include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_VERSION_VARIABLE
+
+#define CONFIG_BOOTDELAY               1       /* negative for no autoboot */
+#define CONFIG_ENV_VARS_UBOOT_CONFIG
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "loadaddr=0x80200000\0" \
+       "fdtaddr=0x80F80000\0" \
+       "rdaddr=0x81000000\0" \
+       "bootfile=/boot/uImage\0" \
+       "fdtfile=\0" \
+       "console=ttyO0,115200n8\0" \
+       "optargs=\0" \
+       "mmcdev=0\0" \
+       "mmcroot=/dev/mmcblk0p2 ro\0" \
+       "mmcrootfstype=ext4 rootwait\0" \
+       "ramroot=/dev/ram0 rw ramdisk_size=65536 initrd=${rdaddr},64M\0" \
+       "ramrootfstype=ext2\0" \
+       "mmcargs=setenv bootargs console=${console} " \
+               "${optargs} " \
+               "root=${mmcroot} " \
+               "rootfstype=${mmcrootfstype}\0" \
+       "bootenv=uEnv.txt\0" \
+       "loadbootenv=fatload mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \
+       "importbootenv=echo Importing environment from mmc ...; " \
+               "env import -t $loadaddr $filesize\0" \
+       "ramargs=setenv bootargs console=${console} " \
+               "${optargs} " \
+               "root=${ramroot} " \
+               "rootfstype=${ramrootfstype}\0" \
+       "loadramdisk=fatload mmc ${mmcdev} ${rdaddr} ramdisk.gz\0" \
+       "loaduimagefat=fatload mmc ${mmcdev} ${loadaddr} ${bootfile}\0" \
+       "loaduimage=ext2load mmc ${mmcdev}:2 ${loadaddr} ${bootfile}\0" \
+       "mmcboot=echo Booting from mmc ...; " \
+               "run mmcargs; " \
+               "bootm ${loadaddr}\0" \
+       "ramboot=echo Booting from ramdisk ...; " \
+               "run ramargs; " \
+               "bootm ${loadaddr}\0" \
+       "fdtfile=ti814x-evm.dtb\0" \
+
+#define CONFIG_BOOTCOMMAND \
+       "mmc dev ${mmcdev}; if mmc rescan; then " \
+               "echo SD/MMC found on device ${mmcdev};" \
+               "if run loadbootenv; then " \
+                       "echo Loaded environment from ${bootenv};" \
+                       "run importbootenv;" \
+               "fi;" \
+               "if test -n $uenvcmd; then " \
+                       "echo Running uenvcmd ...;" \
+                       "run uenvcmd;" \
+               "fi;" \
+               "if run loaduimage; then " \
+                       "run mmcboot;" \
+               "fi;" \
+       "fi;" \
+
+/* Clock Defines */
+#define V_OSCK                 24000000        /* Clock output from T2 */
+#define V_SCLK                 (V_OSCK >> 1)
+
+#define CONFIG_CMD_ECHO
+
+/* max number of command args */
+#define CONFIG_SYS_MAXARGS             16
+
+/* Console I/O Buffer Size */
+#define CONFIG_SYS_CBSIZE              512
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE              (CONFIG_SYS_CBSIZE \
+                                       + sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
+
+#define CONFIG_SYS_MEMTEST_START       PHYS_DRAM_1
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START \
+                                       + PHYS_DRAM_1_SIZE - (8 << 12))
+
+#define CONFIG_SYS_LOAD_ADDR           0x81000000      /* Default */
+#define CONFIG_SYS_HZ                  1000            /* 1ms clock */
+
+#define CONFIG_OMAP_GPIO
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_OMAP_HSMMC
+#define CONFIG_CMD_MMC
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+
+/**
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS           1               /* 1 banks of DRAM */
+#define PHYS_DRAM_1                    0x80000000      /* DRAM Bank #1 */
+#define PHYS_DRAM_1_SIZE               0x20000000      /* 512MB */
+#define CONFIG_MAX_RAM_BANK_SIZE       (1024 << 20)    /* 1024MB */
+
+#define CONFIG_SYS_SDRAM_BASE          PHYS_DRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR                (NON_SECURE_SRAM_END - \
+                                        GENERATED_GBL_DATA_SIZE)
+
+/**
+ * Platform/Board specific defs
+ */
+#define CONFIG_SYS_TIMERBASE           0x4802E000
+#define CONFIG_SYS_PTV                 2       /* Divisor: 2^(PTV+1) => 8 */
+#define CONFIG_SYS_HZ                  1000
+
+/* NS16550 Configuration */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE    (-4)
+#define CONFIG_SYS_NS16550_CLK         (48000000)
+#define CONFIG_SYS_NS16550_COM1                0x48020000      /* Base EVM has UART0 */
+
+#define CONFIG_BAUDRATE                        115200
+
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_CONS_INDEX              1
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+#define CONFIG_ENV_IS_NOWHERE
+
+/* Defines for SPL */
+#define CONFIG_SPL
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_TEXT_BASE           0x40300000
+#define CONFIG_SPL_MAX_SIZE            ((128 - 18) * 1024)
+#define CONFIG_SPL_STACK               CONFIG_SYS_INIT_SP_ADDR
+
+#define CONFIG_SPL_BSS_START_ADDR      0x80000000
+#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"
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SPL_FAT_SUPPORT
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBDISK_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL_YMODEM_SUPPORT
+#define CONFIG_SYS_SPI_U_BOOT_OFFS     0x20000
+#define CONFIG_SYS_SPI_U_BOOT_SIZE     0x40000
+#define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
+
+#define CONFIG_SPL_BOARD_INIT
+
+/*
+ * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
+ * 64 bytes before this address should be set aside for u-boot.img's
+ * header. That is 0x800FFFC0--0x80800000 should not be used for any
+ * other needs.
+ */
+#define CONFIG_SYS_TEXT_BASE           0x80800000
+#define CONFIG_SYS_SPL_MALLOC_START    0x80208000
+#define CONFIG_SYS_SPL_MALLOC_SIZE     0x100000
+
+/*
+ * Since SPL did pll and ddr initialization for us,
+ * we don't need to do it twice.
+ */
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#endif
+
+/* Unsupported features */
+#undef CONFIG_USE_IRQ
+
+#endif /* ! __CONFIG_TI814X_EVM_H */
index 63745ac8f1c9fdbc6e25eee47352a66307d805b3..31d81901bcd097962bcfb1deb240ab57177fab34 100644 (file)
 #define CONFIG_VIDEO_BMP_GZIP
 #define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 120 * 4) + (1 << 12))
 
+#define CONFIG_CMD_USB_MASS_STORAGE
+#if defined(CONFIG_CMD_USB_MASS_STORAGE)
+#define CONFIG_USB_GADGET_MASS_STORAGE
+#endif
+
 #endif /* __CONFIG_H */
index 0644f7a5b8f668351358989f762d80b555a29c62..b92531477e78580edf1e0a0e2b4e60c3eb54ae48 100644 (file)
@@ -46,7 +46,7 @@
 #define CONFIG_BOARD_EARLY_INIT_F
 
 /* SPI */
-#define CONFIG_TEGRA_SPI
+#define CONFIG_TEGRA20_SFLASH
 #define CONFIG_SPI_FLASH
 #define CONFIG_SPI_FLASH_WINBOND
 #define CONFIG_SF_DEFAULT_MODE         SPI_MODE_0
index e89b6dadc9421f9bf9dc8435795f99d588283a1f..b8560006540041e43d36928f470e08f341dc0846 100644 (file)
@@ -67,7 +67,6 @@ struct env_clbk_tbl {
                int flags);
 };
 
-struct env_clbk_tbl *find_env_callback(const char *);
 void env_callback_init(ENTRY *var_entry);
 
 /*
index 21894835d1b4c9414313ad3243d1142d3a26cab1..e7e3ff9e0384f10157a671ff36ee153654ae34bf 100644 (file)
  */
 #ifdef CONFIG_PHYS_64BIT
 typedef u64 fdt_addr_t;
+typedef u64 fdt_size_t;
 #define FDT_ADDR_T_NONE (-1ULL)
 #define fdt_addr_to_cpu(reg) be64_to_cpu(reg)
 #define fdt_size_to_cpu(reg) be64_to_cpu(reg)
 #else
 typedef u32 fdt_addr_t;
+typedef u32 fdt_size_t;
 #define FDT_ADDR_T_NONE (-1U)
 #define fdt_addr_to_cpu(reg) be32_to_cpu(reg)
 #define fdt_size_to_cpu(reg) be32_to_cpu(reg)
@@ -75,6 +77,7 @@ enum fdt_compat_id {
        COMPAT_NVIDIA_TEGRA20_SDMMC,    /* Tegra20 SDMMC controller */
        COMPAT_NVIDIA_TEGRA20_SFLASH,   /* Tegra 2 SPI flash controller */
        COMPAT_NVIDIA_TEGRA20_SLINK,    /* Tegra 2 SPI SLINK controller */
+       COMPAT_NVIDIA_TEGRA114_SPI,     /* Tegra 114 SPI controller */
        COMPAT_SMSC_LAN9215,            /* SMSC 10/100 Ethernet LAN9215 */
        COMPAT_SAMSUNG_EXYNOS5_SROMC,   /* Exynos5 SROMC */
        COMPAT_SAMSUNG_S3C2440_I2C,     /* Exynos I2C Controller */
@@ -83,7 +86,10 @@ enum fdt_compat_id {
        COMPAT_SAMSUNG_EXYNOS_SPI,      /* Exynos SPI */
        COMPAT_SAMSUNG_EXYNOS_EHCI,     /* Exynos EHCI controller */
        COMPAT_SAMSUNG_EXYNOS_USB_PHY,  /* Exynos phy controller for usb2.0 */
+       COMPAT_SAMSUNG_EXYNOS_TMU,      /* Exynos TMU */
        COMPAT_MAXIM_MAX77686_PMIC,     /* MAX77686 PMIC */
+       COMPAT_GENERIC_SPI_FLASH,       /* Generic SPI Flash chip */
+       COMPAT_MAXIM_98095_CODEC,       /* MAX98095 Codec */
 
        COMPAT_COUNT,
 };
@@ -199,6 +205,19 @@ int fdtdec_next_compatible_subnode(const void *blob, int node,
 fdt_addr_t fdtdec_get_addr(const void *blob, int node,
                const char *prop_name);
 
+/**
+ * Look up an address property in a node and return it as an address.
+ * The property must hold one address with a length. This is only tested
+ * on 32-bit machines.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name    name of property to find
+ * @return address, if found, or FDT_ADDR_T_NONE if not
+ */
+fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
+               const char *prop_name, fdt_size_t *sizep);
+
 /**
  * Look up a 32-bit integer property in a node and return it. The property
  * must have at least 4 bytes of data. The value of the first cell is
index 158e1beaf9510385353dde29dfbf33c7665125d5..afea85cdc2cb3b5739e390d3bd02001f782fe9d3 100644 (file)
@@ -85,4 +85,11 @@ void ide_output_data(int dev, const ulong *sect_buf, int words);
 void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts);
 void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts);
 
+/**
+ * board_start_ide() - Start up the board IDE interfac
+ *
+ * @return 0 if ok
+ */
+int board_start_ide(void);
+
 #endif /* _IDE_H */
index 8e285f9b9ff963877bc954871473d6cdd70a3fd8..4ad0e6b21ac1e26839c0bfa8da54549386e6067c 100644 (file)
@@ -84,6 +84,7 @@
 #define IH_OS_UNITY            20      /* Unity OS     */
 #define IH_OS_INTEGRITY                21      /* INTEGRITY    */
 #define IH_OS_OSE              22      /* OSE          */
+#define IH_OS_PLAN9            23      /* Plan 9       */
 
 /*
  * CPU Architecture Codes (supported by Linux)
similarity index 53%
rename from arch/arm/include/asm/arch-tegra20/uart-spi-switch.h
rename to include/initcall.h
index 82ac180acd181b027b7a2849e340a646c0b3463c..9e54fa5c262e0581751f5aef7df029f2ff65cae8 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors.
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -10,7 +11,7 @@
  *
  * 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
+ * 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
  * MA 02111-1307 USA
  */
 
-#ifndef _UART_SPI_SWITCH_H
-#define _UART_SPI_SWITCH_H
-
-#if defined(CONFIG_SPI_UART_SWITCH)
-/*
- * Signal that we are about to use the UART. This unfortunate hack is
- * required by Seaboard, which cannot use its console and SPI at the same
- * time! If the board file provides this, the board config will declare it.
- * Let this be a lesson for others.
- */
-void pinmux_select_uart(void);
-
-/*
- * Signal that we are about the use the SPI bus.
- */
-void pinmux_select_spi(void);
-
-#else /* not CONFIG_SPI_UART_SWITCH */
-
-static inline void pinmux_select_uart(void) {}
-static inline void pinmux_select_spi(void) {}
-
-#endif
+typedef int (*init_fnc_t)(void);
 
-#endif
+int initcall_run_list(init_fnc_t init_sequence[]);
index d949aced0921630b68c78514dbc2d136c041e8c8..fdc7ca9e5a02954f16c4dd116cea4aba4d29efee 100644 (file)
@@ -155,4 +155,36 @@ enum {
        EN_LDO = (0x3 << 6),
 };
 
+/* Buck1 1 volt value */
+#define MAX77686_BUCK1OUT_1V   0x5
+#define MAX77686_BUCK1CTRL_EN  (3 << 0)
+/* Buck2 1.3 volt value */
+#define MAX77686_BUCK2DVS1_1_3V        0x38
+#define MAX77686_BUCK2CTRL_ON  (1 << 4)
+/* Buck3 1.0125 volt value */
+#define MAX77686_BUCK3DVS1_1_0125V     0x21
+#define MAX77686_BUCK3CTRL_ON  (1 << 4)
+/* Buck4 1.2 volt value */
+#define MAX77686_BUCK4DVS1_1_2V        0x30
+#define MAX77686_BUCK4CTRL_ON  (1 << 4)
+/* LDO2 1.5 volt value */
+#define MAX77686_LD02CTRL1_1_5V        0x1c
+/* LDO3 1.8 volt value */
+#define MAX77686_LD03CTRL1_1_8V        0x14
+/* LDO5 1.8 volt value */
+#define MAX77686_LD05CTRL1_1_8V        0x14
+/* LDO10 1.8 volt value */
+#define MAX77686_LD10CTRL1_1_8V        0x14
+/*
+ * MAX77686_REG_PMIC_32KHZ set to 32KH CP
+ * output is activated
+ */
+#define MAX77686_32KHCP_EN     (1 << 1)
+/*
+ * MAX77686_REG_PMIC_BBAT set to
+ * Back up batery charger on and
+ * limit voltage setting to 3.5v
+ */
+#define MAX77686_BBCHOSTEN     (1 << 0)
+#define MAX77686_BBCVS_3_5V    (3 << 3)
 #endif /* __MAX77686_PMIC_H_ */
index d73839d9f04a08b7891f5bac48b4289c712bebdf..94922f66daeaf6d5a56c3722d243eeeb254d9f8a 100644 (file)
@@ -28,6 +28,7 @@
 enum en_sound_codec {
        CODEC_WM_8994,
        CODEC_WM_8995,
+       CODEC_MAX_98095,
        CODEC_MAX
 };
 
index 60e85db9a46e052c97b638c58bb93114a378e3b7..3fe2e1eab2defc568079cd8a035225bbf682b18d 100644 (file)
  *
  *   bus:      ID of the bus that the slave is attached to.
  *   cs:       ID of the chip select connected to the slave.
+ *   max_write_size:   If non-zero, the maximum number of bytes which can
+ *             be written at once, excluding command bytes.
  */
 struct spi_slave {
        unsigned int    bus;
        unsigned int    cs;
+       unsigned int max_write_size;
 };
 
 /*-----------------------------------------------------------------------
@@ -62,6 +65,47 @@ struct spi_slave {
  */
 void spi_init(void);
 
+/**
+ * spi_do_alloc_slave - Allocate a new SPI slave (internal)
+ *
+ * Allocate and zero all fields in the spi slave, and set the bus/chip
+ * select. Use the helper macro spi_alloc_slave() to call this.
+ *
+ * @offset: Offset of struct spi_slave within slave structure
+ * @size: Size of slave structure
+ * @bus: Bus ID of the slave chip.
+ * @cs: Chip select ID of the slave chip on the specified bus.
+ */
+void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
+                        unsigned int cs);
+
+/**
+ * spi_alloc_slave - Allocate a new SPI slave
+ *
+ * Allocate and zero all fields in the spi slave, and set the bus/chip
+ * select.
+ *
+ * @_struct: Name of structure to allocate (e.g. struct tegra_spi). This
+ *     structure must contain a member 'struct spi_slave *slave'.
+ * @bus: Bus ID of the slave chip.
+ * @cs: Chip select ID of the slave chip on the specified bus.
+ */
+#define spi_alloc_slave(_struct, bus, cs) \
+       spi_do_alloc_slave(offsetof(_struct, slave), \
+                           sizeof(_struct), bus, cs)
+
+/**
+ * spi_alloc_slave_base - Allocate a new SPI slave with no private data
+ *
+ * Allocate and zero all fields in the spi slave, and set the bus/chip
+ * select.
+ *
+ * @bus: Bus ID of the slave chip.
+ * @cs: Chip select ID of the slave chip on the specified bus.
+ */
+#define spi_alloc_slave_base(bus, cs) \
+       spi_do_alloc_slave(0, sizeof(struct spi_slave), bus, cs)
+
 /*-----------------------------------------------------------------------
  * Set up communications parameters for a SPI slave.
  *
index 9da90624f23d665fc58c95e37da02096b1adde07..3b6a44edcef6a1e8707ecd20572f191c9f05da46 100644 (file)
@@ -39,6 +39,7 @@ struct spi_flash {
        /* Erase (sector) size */
        u32             sector_size;
 
+       void *memory_map;       /* Address of read-only SPI flash access */
        int             (*read)(struct spi_flash *flash, u32 offset,
                                size_t len, void *buf);
        int             (*write)(struct spi_flash *flash, u32 offset,
@@ -47,6 +48,44 @@ struct spi_flash {
                                size_t len);
 };
 
+/**
+ * spi_flash_do_alloc - Allocate a new spi flash structure
+ *
+ * The structure is allocated and cleared with default values for
+ * read, write and erase, which the caller can modify. The caller must set
+ * up size, page_size and sector_size.
+ *
+ * Use the helper macro spi_flash_alloc() to call this.
+ *
+ * @offset: Offset of struct spi_slave within slave structure
+ * @size: Size of slave structure
+ * @spi: SPI slave
+ * @name: Name of SPI flash device
+ */
+void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi,
+                        const char *name);
+
+/**
+ * spi_flash_alloc - Allocate a new SPI flash structure
+ *
+ * @_struct: Name of structure to allocate (e.g. struct ramtron_spi_fram). This
+ *     structure must contain a member 'struct spi_flash *flash'.
+ * @spi: SPI slave
+ * @name: Name of SPI flash device
+ */
+#define spi_flash_alloc(_struct, spi, name) \
+       spi_flash_do_alloc(offsetof(_struct, flash), sizeof(_struct), \
+                               spi, name)
+
+/**
+ * spi_flash_alloc_base - Allocate a new SPI flash structure with no private data
+ *
+ * @spi: SPI slave
+ * @name: Name of SPI flash device
+ */
+#define spi_flash_alloc_base(spi, name) \
+       spi_flash_do_alloc(0, sizeof(struct spi_flash), spi, name)
+
 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
                unsigned int max_hz, unsigned int spi_mode);
 void spi_flash_free(struct spi_flash *flash);
diff --git a/include/tmu.h b/include/tmu.h
new file mode 100644 (file)
index 0000000..da07a22
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *      http://www.samsung.com
+ * Akshay Saraswat <akshay.s@samsung.com>
+ *
+ * Thermal Management Unit
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ * 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 _TMU_H
+#define _TMU_H
+
+enum tmu_status_t {
+       TMU_STATUS_INIT = -1,
+       TMU_STATUS_NORMAL = 0,
+       TMU_STATUS_WARNING,
+       TMU_STATUS_TRIPPED,
+};
+
+/*
+ * Monitors status of the TMU device and exynos temperature
+ *
+ * @param temp pointer to the current temperature value
+ * @return     enum tmu_status_t value, code indicating event to execute
+ *             and -1 on error
+ */
+enum tmu_status_t tmu_monitor(int *temp);
+
+/*
+ * Initialize TMU device
+ *
+ * @param blob  FDT blob
+ * @return     int value, 0 for success
+ */
+int tmu_init(const void *blob);
+#endif /* _THERMAL_H_ */
diff --git a/include/usb_mass_storage.h b/include/usb_mass_storage.h
new file mode 100644 (file)
index 0000000..ffc3a13
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 Samsung Electrnoics
+ * Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * aloong with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __USB_MASS_STORAGE_H__
+#define __USB_MASS_STORAGE_H__
+
+#define SECTOR_SIZE            0x200
+
+#include <mmc.h>
+
+struct ums_device {
+       struct mmc *mmc;
+       int dev_num;
+       int offset;
+       int part_size;
+};
+
+struct ums_board_info {
+       int (*read_sector)(struct ums_device *ums_dev,
+                          ulong start, lbaint_t blkcnt, void *buf);
+       int (*write_sector)(struct ums_device *ums_dev,
+                           ulong start, lbaint_t blkcnt, const void *buf);
+       void (*get_capacity)(struct ums_device *ums_dev,
+                            long long int *capacity);
+       const char *name;
+       struct ums_device ums_dev;
+};
+
+extern void board_usb_init(void);
+
+extern int fsg_init(struct ums_board_info *);
+extern void fsg_cleanup(void);
+extern struct ums_board_info *board_ums_init(unsigned int,
+                                            unsigned int, unsigned int);
+extern int usb_gadget_handle_interrupts(void);
+extern int fsg_main_thread(void *);
+
+#endif /* __USB_MASS_STORAGE_H__ */
index 3edaf8bcc268a66212cb56a3dac8d67b4a9aae4b..7037efd33eb0c85dede846b5fd62dc6babf8d708 100644 (file)
@@ -475,7 +475,9 @@ typedef struct urb_link {
  * function driver to inform it that data has arrived.
  */
 
-#define URB_BUF_SIZE 128 /* in linux we'd malloc this, but in u-boot we prefer static data */
+/* in linux we'd malloc this, but in u-boot we prefer static data */
+#define URB_BUF_SIZE 512
+
 struct urb {
 
        struct usb_endpoint_instance *endpoint;
index 8c92a0b31beaa2fe52210d7a2dbf2ed22cb28168..97ec186be32e43fa2d40173b57718f1f1bb34eee 100644 (file)
 #ifndef _WATCHDOG_H_
 #define _WATCHDOG_H_
 
+#if !defined(__ASSEMBLY__)
+/*
+ * Reset the watchdog timer, always returns 0
+ *
+ * This function is here since it is shared between board_f() and board_r(),
+ * and the legacy arch/<arch>/board.c code.
+ */
+int init_func_watchdog_reset(void);
+#endif
+
+#ifdef CONFIG_WATCHDOG
+#define INIT_FUNC_WATCHDOG_INIT        init_func_watchdog_init,
+#define INIT_FUNC_WATCHDOG_RESET       init_func_watchdog_reset,
+#else
+#define INIT_FUNC_WATCHDOG_INIT
+#define INIT_FUNC_WATCHDOG_RESET
+#endif
+
 #if defined(CONFIG_HW_WATCHDOG) && defined(CONFIG_WATCHDOG)
 #  error "Configuration error: CONFIG_HW_WATCHDOG and CONFIG_WATCHDOG can't be used together."
 #endif
index 86ca1a6ec1db0b16e2c3a036ddf3ba977ed034e2..1bfd3ee1240a9e2b77d4e09c49fcfc743419ac68 100644 (file)
@@ -44,6 +44,7 @@ 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
 COBJS-$(CONFIG_MD5) += md5.o
index 0339970e7d6963cac8f7f1ad2d322c012c7ae966..e6d684bd60bdc3e18ef077775d8f532eaeb8d352 100644 (file)
@@ -115,14 +115,15 @@ int print_buffer(ulong addr, const void *data, uint width, uint count,
                linelen = DEFAULT_LINE_LENGTH_BYTES / width;
 
        while (count) {
+               uint thislinelen = linelen;
                printf("%08lx:", addr);
 
                /* check for overflow condition */
-               if (count < linelen)
-                       linelen = count;
+               if (count < thislinelen)
+                       thislinelen = count;
 
                /* Copy from memory into linebuf and print hex values */
-               for (i = 0; i < linelen; i++) {
+               for (i = 0; i < thislinelen; i++) {
                        uint32_t x;
                        if (width == 4)
                                x = lb.ui[i] = *(volatile uint32_t *)data;
@@ -134,8 +135,15 @@ int print_buffer(ulong addr, const void *data, uint width, uint count,
                        data += width;
                }
 
+               while (thislinelen < linelen) {
+                       /* fill line with whitespace for nice ASCII print */
+                       for (i=0; i<width*2+1; i++)
+                               puts(" ");
+                       linelen--;
+               }
+
                /* Print data in ASCII characters */
-               for (i = 0; i < linelen * width; i++) {
+               for (i = 0; i < thislinelen * width; i++) {
                        if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80)
                                lb.uc[i] = '.';
                }
@@ -143,8 +151,8 @@ int print_buffer(ulong addr, const void *data, uint width, uint count,
                printf("    %s\n", lb.uc);
 
                /* update references */
-               addr += linelen * width;
-               count -= linelen;
+               addr += thislinelen * width;
+               count -= thislinelen;
 
                if (ctrlc())
                        return -1;
index 43f29f5c6b40992fbc2087a80053a74262149452..e17dd001ca2a0c6b578c88ce76c90251e89ea0d3 100644 (file)
@@ -50,6 +50,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"),
        COMPAT(NVIDIA_TEGRA20_SFLASH, "nvidia,tegra20-sflash"),
        COMPAT(NVIDIA_TEGRA20_SLINK, "nvidia,tegra20-slink"),
+       COMPAT(NVIDIA_TEGRA114_SPI, "nvidia,tegra114-spi"),
        COMPAT(SMSC_LAN9215, "smsc,lan9215"),
        COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),
        COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),
@@ -58,7 +59,10 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(SAMSUNG_EXYNOS_SPI, "samsung,exynos-spi"),
        COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"),
        COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
+       COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"),
        COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
+       COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
+       COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
@@ -68,25 +72,40 @@ const char *fdtdec_get_compatible(enum fdt_compat_id id)
        return compat_names[id];
 }
 
-fdt_addr_t fdtdec_get_addr(const void *blob, int node,
-               const char *prop_name)
+fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
+               const char *prop_name, fdt_size_t *sizep)
 {
        const fdt_addr_t *cell;
        int len;
 
        debug("%s: %s: ", __func__, prop_name);
        cell = fdt_getprop(blob, node, prop_name, &len);
-       if (cell && (len == sizeof(fdt_addr_t) ||
-                       len == sizeof(fdt_addr_t) * 2)) {
+       if (cell && ((!sizep && len == sizeof(fdt_addr_t)) ||
+                    len == sizeof(fdt_addr_t) * 2)) {
                fdt_addr_t addr = fdt_addr_to_cpu(*cell);
-
-               debug("%p\n", (void *)addr);
+               if (sizep) {
+                       const fdt_size_t *size;
+
+                       size = (fdt_size_t *)((char *)cell +
+                                       sizeof(fdt_addr_t));
+                       *sizep = fdt_size_to_cpu(*size);
+                       debug("addr=%p, size=%p\n", (void *)addr,
+                             (void *)*sizep);
+               } else {
+                       debug("%p\n", (void *)addr);
+               }
                return addr;
        }
        debug("(not found)\n");
        return FDT_ADDR_T_NONE;
 }
 
+fdt_addr_t fdtdec_get_addr(const void *blob, int node,
+               const char *prop_name)
+{
+       return fdtdec_get_addr_size(blob, node, prop_name, NULL);
+}
+
 s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
                s32 default_val)
 {
diff --git a/lib/initcall.c b/lib/initcall.c
new file mode 100644 (file)
index 0000000..fc91bf6
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ *
+ * 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 <initcall.h>
+
+int initcall_run_list(init_fnc_t init_sequence[])
+{
+       init_fnc_t *init_fnc_ptr;
+
+       for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+               debug("initcall: %p\n", *init_fnc_ptr);
+               if ((*init_fnc_ptr)()) {
+                       debug("initcall sequence %p failed at call %p\n",
+                             init_sequence, *init_fnc_ptr);
+                       return -1;
+               }
+       }
+       return 0;
+}
index 44a6f816c2663a49c489493a6dee2183b521abf8..5e14b0cd66b471446fe79b692f1fbb31a2046800 100644 (file)
@@ -60,5 +60,5 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
 }
index d4ea67ae8ae0af216087e19c66949744296b4bd8..d8edffe7766041fa4dd57d9c01810213cefb0bf3 100644 (file)
@@ -62,5 +62,5 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
 }
index 794f041034223fb6cde63a30264af7a2e83a305d..70001bff9165fad321df9f6a50b99b6a862e5baa 100644 (file)
@@ -62,5 +62,5 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
 }
index 4e860ad59eaaf9410e7a83f20e54afad8d328745..0d7e6de08a166ed7358598dada1b33689648425c 100644 (file)
@@ -60,5 +60,5 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
 }
index 8ff6ac5cc1107777f0d690d10fb392b3e0240b8d..d28fe616376820e823a22681eb7ac660c60baa6f 100644 (file)
@@ -62,5 +62,5 @@ SECTIONS
    . = ALIGN(4);
   }
 
-  __bss_end__ = . ;
+  __bss_end = . ;
 }
index d140453d49734a29c0c3cd9da8b25ebfcb1fd40e..870b47d6af4ab910e60f6ea407c19a2260c4e4ef 100644 (file)
@@ -49,7 +49,7 @@ SECTIONS
        .bss (NOLOAD) : {
                *(.*bss)
        }
-       __bss_end__ = .;
+       __bss_end = .;
 }
 ENTRY(_start)
-ASSERT(__bss_end__ <= 0xfff01000, "NAND bootstrap too big");
+ASSERT(__bss_end <= 0xfff01000, "NAND bootstrap too big");
index 06561769309f4ef88899b79754b946245ae397d5..5f2b5e20228950c38e77f70d9bec859bb6c50799 100644 (file)
@@ -73,7 +73,7 @@ SECTIONS
                __bss_start = .;
                *(.bss)
                 . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        }
 
        /DISCARD/ : { *(.bss*) }
index ea84d64f3f1b0b4e0e3d3402da59e46b2a9ad916..4d1aac367799f37672cc638f874403d0c6416ffd 100644 (file)
@@ -71,7 +71,7 @@ SECTIONS
                __bss_start = .;
                *(.bss)
                 . = ALIGN(4);
-               __bss_end__ = .;
+               __bss_end = .;
        }
 
        /DISCARD/ : { *(.bss*) }
index 66b412e4aa964b15cc060113b32c0ee3302d4263..b6c573be5c32acf57648d0f4d63f76d366d7f84a 100644 (file)
@@ -75,6 +75,6 @@ SECTIONS
        __bss_start = .;
        *(.bss)
        . = ALIGN(4);
-       __bss_end__ = .;
+       __bss_end = .;
        }
 }
index 534a0c8654fd6c2304f06a275abe3aa36a6b1d81..7ab408bb5af1c4b5f992cb79257029b33738c8ec 100644 (file)
@@ -48,7 +48,7 @@ SECTIONS
        . = ALIGN(8);
        __bss_start = .;
        .bss (NOLOAD) : { *(.*bss) }
-       __bss_end__ = .;
+       __bss_end = .;
 }
 ENTRY(_start)
-ASSERT(__bss_end__ <= 0xfff01000, "NAND bootstrap too big");
+ASSERT(__bss_end <= 0xfff01000, "NAND bootstrap too big");
index 14095c8df7a45e9f891a6307dbc793bd3fad094d..b5a8de7835f6da4a5324815fea8831e553f21ecf 100644 (file)
@@ -84,7 +84,7 @@ LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/libphy.o
 LIBS-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/libusb_musb-new.o
 LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/libusb_gadget.o
 
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
 LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
 endif
 
index c7475f9e3361d2a01e08b69c1588ee69ddb69bc8..9f23901872c9b7aa85d5d993016ba7094b016401 100755 (executable)
@@ -33,6 +33,7 @@ my %ignore_type = ();
 my @ignore = ();
 my $help = 0;
 my $configuration_file = ".checkpatch.conf";
+my $max_line_length = 80;
 
 sub help {
        my ($exitcode) = @_;
@@ -51,6 +52,7 @@ Options:
   -f, --file                 treat FILE as regular source file
   --subjective, --strict     enable more subjective tests
   --ignore TYPE(,TYPE2...)   ignore various comma separated message types
+  --max-line-length=n        set the maximum line length, if exceeded, warn
   --show-types               show the message "types" in the output
   --root=PATH                PATH to the kernel tree root
   --no-summary               suppress the per-file summary
@@ -107,6 +109,7 @@ GetOptions(
        'strict!'       => \$check,
        'ignore=s'      => \@ignore,
        'show-types!'   => \$show_types,
+       'max-line-length=i' => \$max_line_length,
        'root=s'        => \$root,
        'summary!'      => \$summary,
        'mailback!'     => \$mailback,
@@ -227,8 +230,12 @@ our $Inline        = qr{inline|__always_inline|noinline};
 our $Member    = qr{->$Ident|\.$Ident|\[[^]]*\]};
 our $Lval      = qr{$Ident(?:$Member)*};
 
-our $Constant  = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
-our $Assignment        = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
+our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
+our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
+our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
+our $Float     = qr{$Float_hex|$Float_dec|$Float_int};
+our $Constant  = qr{$Float|(?i)(?:0x[0-9a-f]+|[0-9]+)[ul]*};
+our $Assignment        = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
 our $Compare    = qr{<=|>=|==|!=|<|>};
 our $Operators = qr{
                        <=|>=|==|!=|
@@ -240,9 +247,8 @@ our $NonptrType;
 our $Type;
 our $Declare;
 
-our $UTF8      = qr {
-       [\x09\x0A\x0D\x20-\x7E]              # ASCII
-       | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
+our $NON_ASCII_UTF8    = qr{
+       [\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
        |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
        | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
        |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
@@ -251,6 +257,11 @@ our $UTF8  = qr {
        |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
 }x;
 
+our $UTF8      = qr{
+       [\x09\x0A\x0D\x20-\x7E]              # ASCII
+       | $NON_ASCII_UTF8
+}x;
+
 our $typeTypedefs = qr{(?x:
        (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
        atomic_t
@@ -261,6 +272,7 @@ our $logFunctions = qr{(?x:
        [a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
        WARN(?:_RATELIMIT|_ONCE|)|
        panic|
+       debug|
        MODULE_[A-Z_]+
 )};
 
@@ -311,7 +323,7 @@ sub build_types {
        $NonptrType     = qr{
                        (?:$Modifier\s+|const\s+)*
                        (?:
-                               (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)|
+                               (?:typeof|__typeof__)\s*\([^\)]*\)|
                                (?:$typeTypedefs\b)|
                                (?:${all}\b)
                        )
@@ -319,17 +331,23 @@ sub build_types {
                  }x;
        $Type   = qr{
                        $NonptrType
-                       (?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)?
+                       (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
                        (?:\s+$Inline|\s+$Modifier)*
                  }x;
        $Declare        = qr{(?:$Storage\s+)?$Type};
 }
 build_types();
 
-our $match_balanced_parentheses = qr/(\((?:[^\(\)]+|(-1))*\))/;
 
 our $Typecast  = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
-our $LvalOrFunc        = qr{($Lval)\s*($match_balanced_parentheses{0,1})\s*};
+
+# Using $balanced_parens, $LvalOrFunc, or $FuncArg
+# requires at least perl version v5.10.0
+# Any use must be runtime checked with $^V
+
+our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
+our $LvalOrFunc        = qr{($Lval)\s*($balanced_parens{0,1})\s*};
+our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)};
 
 sub deparenthesize {
        my ($string) = @_;
@@ -342,27 +360,6 @@ sub deparenthesize {
 
 $chk_signoff = 0 if ($file);
 
-my @dep_includes = ();
-my @dep_functions = ();
-my $removal = "Documentation/feature-removal-schedule.txt";
-if ($tree && -f "$root/$removal") {
-       open(my $REMOVE, '<', "$root/$removal") ||
-                               die "$P: $removal: open failed - $!\n";
-       while (<$REMOVE>) {
-               if (/^Check:\s+(.*\S)/) {
-                       for my $entry (split(/[, ]+/, $1)) {
-                               if ($entry =~ m@include/(.*)@) {
-                                       push(@dep_includes, $1);
-
-                               } elsif ($entry !~ m@/@) {
-                                       push(@dep_functions, $entry);
-                               }
-                       }
-               }
-       }
-       close($REMOVE);
-}
-
 my @rawlines = ();
 my @lines = ();
 my $vname;
@@ -411,7 +408,7 @@ sub top_of_kernel_tree {
                }
        }
        return 1;
-    }
+}
 
 sub parse_email {
        my ($formatted_email) = @_;
@@ -672,6 +669,10 @@ sub ctx_statement_block {
                        if ($off >= $len) {
                                last;
                        }
+                       if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
+                               $level++;
+                               $type = '#';
+                       }
                }
                $p = $c;
                $c = substr($blk, $off, 1);
@@ -734,6 +735,13 @@ sub ctx_statement_block {
                                last;
                        }
                }
+               # Preprocessor commands end at the newline unless escaped.
+               if ($type eq '#' && $c eq "\n" && $p ne "\\") {
+                       $level--;
+                       $type = '';
+                       $off++;
+                       last;
+               }
                $off++;
        }
        # We are truly at the end, so shuffle to the next line.
@@ -1016,7 +1024,7 @@ sub annotate_values {
                } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
                        print "CAST($1)\n" if ($dbg_values > 1);
                        push(@av_paren_type, $type);
-                       $type = 'C';
+                       $type = 'c';
 
                } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
                        print "DECLARE($1)\n" if ($dbg_values > 1);
@@ -1208,7 +1216,9 @@ sub possible {
                        case|
                        else|
                        asm|__asm__|
-                       do
+                       do|
+                       \#|
+                       \#\#|
                )(?:\s|$)|
                ^(?:typedef|struct|enum)\b
            )}x;
@@ -1312,6 +1322,36 @@ sub check_absolute_file {
        }
 }
 
+sub pos_last_openparen {
+       my ($line) = @_;
+
+       my $pos = 0;
+
+       my $opens = $line =~ tr/\(/\(/;
+       my $closes = $line =~ tr/\)/\)/;
+
+       my $last_openparen = 0;
+
+       if (($opens == 0) || ($closes >= $opens)) {
+               return -1;
+       }
+
+       my $len = length($line);
+
+       for ($pos = 0; $pos < $len; $pos++) {
+               my $string = substr($line, $pos);
+               if ($string =~ /^($FuncArg|$balanced_parens)/) {
+                       $pos += length($1) - 1;
+               } elsif (substr($line, $pos, 1) eq '(') {
+                       $last_openparen = $pos;
+               } elsif (index($string, '(') == -1) {
+                       last;
+               }
+       }
+
+       return $last_openparen + 1;
+}
+
 sub process {
        my $filename = shift;
 
@@ -1330,6 +1370,11 @@ sub process {
        my $signoff = 0;
        my $is_patch = 0;
 
+       my $in_header_lines = 1;
+       my $in_commit_log = 0;          #Scanning lines before patch
+
+       my $non_utf8_charset = 0;
+
        our @report = ();
        our $cnt_lines = 0;
        our $cnt_error = 0;
@@ -1352,6 +1397,9 @@ sub process {
        my %suppress_ifbraces;
        my %suppress_whiletrailers;
        my %suppress_export;
+       my $suppress_statement = 0;
+
+       my %camelcase = ();
 
        # Pre-scan the patch sanitizing the lines.
        # Pre-scan the patch looking for any __setup documentation.
@@ -1461,6 +1509,7 @@ sub process {
                        %suppress_ifbraces = ();
                        %suppress_whiletrailers = ();
                        %suppress_export = ();
+                       $suppress_statement = 0;
                        next;
 
 # track the line number as we move through the hunk, note that
@@ -1497,10 +1546,11 @@ sub process {
                if ($line =~ /^diff --git.*?(\S+)$/) {
                        $realfile = $1;
                        $realfile =~ s@^([^/]*)/@@;
-
+                       $in_commit_log = 0;
                } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
                        $realfile = $1;
                        $realfile =~ s@^([^/]*)/@@;
+                       $in_commit_log = 0;
 
                        $p1_prefix = $1;
                        if (!$file && $tree && $p1_prefix ne '' &&
@@ -1536,16 +1586,22 @@ sub process {
 # Check the patch for a signoff:
                if ($line =~ /^\s*signed-off-by:/i) {
                        $signoff++;
+                       $in_commit_log = 0;
                }
 
 # Check signature styles
-               if ($line =~ /^(\s*)($signature_tags)(\s*)(.*)/) {
+               if (!$in_header_lines &&
+                   $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
                        my $space_before = $1;
                        my $sign_off = $2;
                        my $space_after = $3;
                        my $email = $4;
                        my $ucfirst_sign_off = ucfirst(lc($sign_off));
 
+                       if ($sign_off !~ /$signature_tags/) {
+                               WARN("BAD_SIGN_OFF",
+                                    "Non-standard signature: $sign_off\n" . $herecurr);
+                       }
                        if (defined $space_before && $space_before ne "") {
                                WARN("BAD_SIGN_OFF",
                                     "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr);
@@ -1613,6 +1669,28 @@ sub process {
                            "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
                }
 
+# Check if it's the start of a commit log
+# (not a header line and we haven't seen the patch filename)
+               if ($in_header_lines && $realfile =~ /^$/ &&
+                   $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) {
+                       $in_header_lines = 0;
+                       $in_commit_log = 1;
+               }
+
+# Check if there is UTF-8 in a commit log when a mail header has explicitly
+# declined it, i.e defined some charset where it is missing.
+               if ($in_header_lines &&
+                   $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
+                   $1 !~ /utf-8/i) {
+                       $non_utf8_charset = 1;
+               }
+
+               if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
+                   $rawline =~ /$NON_ASCII_UTF8/) {
+                       WARN("UTF8_BEFORE_PATCH",
+                           "8-bit UTF-8 used in possible commit log\n" . $herecurr);
+               }
+
 # ignore non-hunk lines and lines being removed
                next if (!$hunk_line || $line =~ /^-/);
 
@@ -1633,19 +1711,26 @@ sub process {
 # Only applies when adding the entry originally, after that we do not have
 # sufficient context to determine whether it is indeed long enough.
                if ($realfile =~ /Kconfig/ &&
-                   $line =~ /\+\s*(?:---)?help(?:---)?$/) {
+                   $line =~ /.\s*config\s+/) {
                        my $length = 0;
                        my $cnt = $realcnt;
                        my $ln = $linenr + 1;
                        my $f;
+                       my $is_start = 0;
                        my $is_end = 0;
-                       while ($cnt > 0 && defined $lines[$ln - 1]) {
+                       for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
                                $f = $lines[$ln - 1];
                                $cnt-- if ($lines[$ln - 1] !~ /^-/);
                                $is_end = $lines[$ln - 1] =~ /^\+/;
-                               $ln++;
 
                                next if ($f =~ /^-/);
+
+                               if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) {
+                                       $is_start = 1;
+                               } elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) {
+                                       $length = -1;
+                               }
+
                                $f =~ s/^.//;
                                $f =~ s/#.*//;
                                $f =~ s/^\s+//;
@@ -1657,22 +1742,58 @@ sub process {
                                $length++;
                        }
                        WARN("CONFIG_DESCRIPTION",
-                            "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4);
-                       #print "is_end<$is_end> length<$length>\n";
+                            "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4);
+                       #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
+               }
+
+# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig.
+               if ($realfile =~ /Kconfig/ &&
+                   $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) {
+                       WARN("CONFIG_EXPERIMENTAL",
+                            "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
+               }
+
+               if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
+                   ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
+                       my $flag = $1;
+                       my $replacement = {
+                               'EXTRA_AFLAGS' =>   'asflags-y',
+                               'EXTRA_CFLAGS' =>   'ccflags-y',
+                               'EXTRA_CPPFLAGS' => 'cppflags-y',
+                               'EXTRA_LDFLAGS' =>  'ldflags-y',
+                       };
+
+                       WARN("DEPRECATED_VARIABLE",
+                            "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
                }
 
 # check we are in a valid source file if not then ignore this hunk
                next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
 
-#80 column limit
+#line length limit
                if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
                    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
                    !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||
                    $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
-                   $length > 80)
+                   $length > $max_line_length)
                {
                        WARN("LONG_LINE",
-                            "line over 80 characters\n" . $herecurr);
+                            "line over $max_line_length characters\n" . $herecurr);
+               }
+
+# Check for user-visible strings broken across lines, which breaks the ability
+# to grep for the string.  Limited to strings used as parameters (those
+# following an open parenthesis), which almost completely eliminates false
+# positives, as well as warning only once per parameter rather than once per
+# line of the string.  Make an exception when the previous string ends in a
+# newline (multiple lines in one string constant) or \n\t (common in inline
+# assembly to indent the instruction on the following line).
+               if ($line =~ /^\+\s*"/ &&
+                   $prevline =~ /"\s*$/ &&
+                   $prevline =~ /\(/ &&
+                   $prevrawline !~ /\\n(?:\\t)*"\s*$/) {
+                       WARN("SPLIT_STRING",
+                            "quoted string split across lines\n" . $hereprev);
                }
 
 # check for spaces before a quoted newline
@@ -1721,6 +1842,58 @@ sub process {
                             "please, no space before tabs\n" . $herevet);
                }
 
+# check for && or || at the start of a line
+               if ($rawline =~ /^\+\s*(&&|\|\|)/) {
+                       CHK("LOGICAL_CONTINUATIONS",
+                           "Logical continuations should be on the previous line\n" . $hereprev);
+               }
+
+# check multi-line statement indentation matches previous line
+               if ($^V && $^V ge 5.10.0 &&
+                   $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) {
+                       $prevline =~ /^\+(\t*)(.*)$/;
+                       my $oldindent = $1;
+                       my $rest = $2;
+
+                       my $pos = pos_last_openparen($rest);
+                       if ($pos >= 0) {
+                               $line =~ /^(\+| )([ \t]*)/;
+                               my $newindent = $2;
+
+                               my $goodtabindent = $oldindent .
+                                       "\t" x ($pos / 8) .
+                                       " "  x ($pos % 8);
+                               my $goodspaceindent = $oldindent . " "  x $pos;
+
+                               if ($newindent ne $goodtabindent &&
+                                   $newindent ne $goodspaceindent) {
+                                       CHK("PARENTHESIS_ALIGNMENT",
+                                           "Alignment should match open parenthesis\n" . $hereprev);
+                               }
+                       }
+               }
+
+               if ($line =~ /^\+.*\*[ \t]*\)[ \t]+/) {
+                       CHK("SPACING",
+                           "No space is necessary after a cast\n" . $hereprev);
+               }
+
+               if ($realfile =~ m@^(drivers/net/|net/)@ &&
+                   $rawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
+                   $prevrawline =~ /^\+[ \t]*$/) {
+                       WARN("NETWORKING_BLOCK_COMMENT_STYLE",
+                            "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
+               }
+
+               if ($realfile =~ m@^(drivers/net/|net/)@ &&
+                   $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&       #trailing */
+                   $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&      #inline /*...*/
+                   $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&       #trailing **/
+                   $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {    #non blank */
+                       WARN("NETWORKING_BLOCK_COMMENT_STYLE",
+                            "networking block comments put the trailing */ on a separate line\n" . $herecurr);
+               }
+
 # check for spaces at the beginning of a line.
 # Exceptions:
 #  1) within comments
@@ -1735,6 +1908,12 @@ sub process {
 # check we are in a valid C source file if not then ignore this hunk
                next if ($realfile !~ /\.(h|c)$/);
 
+# discourage the addition of CONFIG_EXPERIMENTAL in #if(def).
+               if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) {
+                       WARN("CONFIG_EXPERIMENTAL",
+                            "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
+               }
+
 # check for RCS/CVS revision markers
                if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
                        WARN("CVS_KEYWORD",
@@ -1753,15 +1932,33 @@ sub process {
                              "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
                }
 
+# check for old HOTPLUG __dev<foo> section markings
+               if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
+                       WARN("HOTPLUG_SECTION",
+                            "Using $1 is unnecessary\n" . $herecurr);
+               }
+
 # Check for potential 'bare' types
                my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
                    $realline_next);
-               if ($realcnt && $line =~ /.\s*\S/) {
+#print "LINE<$line>\n";
+               if ($linenr >= $suppress_statement &&
+                   $realcnt && $line =~ /.\s*\S/) {
                        ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
                                ctx_statement_block($linenr, $realcnt, 0);
                        $stat =~ s/\n./\n /g;
                        $cond =~ s/\n./\n /g;
 
+#print "linenr<$linenr> <$stat>\n";
+                       # If this statement has no statement boundaries within
+                       # it there is no point in retrying a statement scan
+                       # until we hit end of it.
+                       my $frag = $stat; $frag =~ s/;+\s*$//;
+                       if ($frag !~ /(?:{|;)/) {
+#print "skip<$line_nr_next>\n";
+                               $suppress_statement = $line_nr_next;
+                       }
+
                        # Find the real next line.
                        $realline_next = $line_nr_next;
                        if (defined $realline_next &&
@@ -1850,6 +2047,12 @@ sub process {
                        my $pre_ctx = "$1$2";
 
                        my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
+
+                       if ($line =~ /^\+\t{6,}/) {
+                               WARN("DEEP_INDENTATION",
+                                    "Too many leading tabs - consider code refactoring\n" . $herecurr);
+                       }
+
                        my $ctx_cnt = $realcnt - $#ctx - 1;
                        my $ctx = join("\n", @ctx);
 
@@ -1887,6 +2090,9 @@ sub process {
 
 # Check relative indent for conditionals and blocks.
                if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
+                       ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
+                               ctx_statement_block($linenr, $realcnt, 0)
+                                       if (!defined $stat);
                        my ($s, $c) = ($stat, $cond);
 
                        substr($s, 0, length($c), '');
@@ -2027,8 +2233,11 @@ sub process {
                        my $path = $1;
                        if ($path =~ m{//}) {
                                ERROR("MALFORMED_INCLUDE",
-                                     "malformed #include filename\n" .
-                                       $herecurr);
+                                     "malformed #include filename\n" . $herecurr);
+                       }
+                       if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
+                               ERROR("UAPI_INCLUDE",
+                                     "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
                        }
                }
 
@@ -2054,7 +2263,7 @@ sub process {
                        #   XXX(foo);
                        #   EXPORT_SYMBOL(something_foo);
                        my $name = $1;
-                       if ($stat =~ /^.([A-Z_]+)\s*\(\s*($Ident)/ &&
+                       if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
                            $name =~ /^${Ident}_$2/) {
 #print "FOO C name<$name>\n";
                                $suppress_export{$realline_next} = 1;
@@ -2132,8 +2341,9 @@ sub process {
 
 # * goes on variable not on type
                # (char*[ const])
-               if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) {
-                       my ($from, $to) = ($1, $1);
+               while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
+                       #print "AA<$1>\n";
+                       my ($from, $to) = ($2, $2);
 
                        # Should start with a space.
                        $to =~ s/^(\S)/ $1/;
@@ -2148,8 +2358,10 @@ sub process {
                                ERROR("POINTER_LOCATION",
                                      "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr);
                        }
-               } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) {
-                       my ($from, $to, $ident) = ($1, $1, $2);
+               }
+               while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
+                       #print "BB<$1>\n";
+                       my ($from, $to, $ident) = ($2, $2, $3);
 
                        # Should start with a space.
                        $to =~ s/^(\S)/ $1/;
@@ -2210,6 +2422,30 @@ sub process {
                        }
                }
 
+               if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
+                       my $orig = $1;
+                       my $level = lc($orig);
+                       $level = "warn" if ($level eq "warning");
+                       my $level2 = $level;
+                       $level2 = "dbg" if ($level eq "debug");
+                       WARN("PREFER_PR_LEVEL",
+                            "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
+               }
+
+               if ($line =~ /\bpr_warning\s*\(/) {
+                       WARN("PREFER_PR_LEVEL",
+                            "Prefer pr_warn(... to pr_warning(...\n" . $herecurr);
+               }
+
+               if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
+                       my $orig = $1;
+                       my $level = lc($orig);
+                       $level = "warn" if ($level eq "warning");
+                       $level = "dbg" if ($level eq "debug");
+                       WARN("PREFER_DEV_LEVEL",
+                            "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
+               }
+
 # function brace can't be on same line, except for #defines of do while,
 # or if closed on same line
                if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and
@@ -2239,7 +2475,7 @@ sub process {
                        my ($where, $prefix) = ($-[1], $1);
                        if ($prefix !~ /$Type\s+$/ &&
                            ($where != 0 || $prefix !~ /^.\s+$/) &&
-                           $prefix !~ /{\s+$/) {
+                           $prefix !~ /[{,]\s+$/) {
                                ERROR("BRACKET_SPACE",
                                      "space prohibited before open square bracket '['\n" . $herecurr);
                        }
@@ -2276,6 +2512,13 @@ sub process {
                                     "space prohibited between function name and open parenthesis '('\n" . $herecurr);
                        }
                }
+
+# check for whitespace before a non-naked semicolon
+               if ($line =~ /^\+.*\S\s+;/) {
+                       CHK("SPACING",
+                           "space prohibited before semicolon\n" . $herecurr);
+               }
+
 # Check operator spacing.
                if (!($line=~/\#\s*include/)) {
                        my $ops = qr{
@@ -2532,7 +2775,7 @@ sub process {
                        # Flatten any parentheses
                        $value =~ s/\(/ \(/g;
                        $value =~ s/\)/\) /g;
-                       while ($value =~ s/\[[^\{\}]*\]/1/ ||
+                       while ($value =~ s/\[[^\[\]]*\]/1/ ||
                               $value !~ /(?:$Ident|-?$Constant)\s*
                                             $Compare\s*
                                             (?:$Ident|-?$Constant)/x &&
@@ -2557,28 +2800,6 @@ sub process {
                        }
                }
 
-# typecasts on min/max could be min_t/max_t
-               if ($line =~ /^\+(?:.*?)\b(min|max)\s*\($Typecast{0,1}($LvalOrFunc)\s*,\s*$Typecast{0,1}($LvalOrFunc)\s*\)/) {
-                       if (defined $2 || defined $8) {
-                               my $call = $1;
-                               my $cast1 = deparenthesize($2);
-                               my $arg1 = $3;
-                               my $cast2 = deparenthesize($8);
-                               my $arg2 = $9;
-                               my $cast;
-
-                               if ($cast1 ne "" && $cast2 ne "") {
-                                       $cast = "$cast1 or $cast2";
-                               } elsif ($cast1 ne "") {
-                                       $cast = $cast1;
-                               } else {
-                                       $cast = $cast2;
-                               }
-                               WARN("MINMAX",
-                                    "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . $herecurr);
-                       }
-               }
-
 # Need a space before open parenthesis after if, while etc
                if ($line=~/\b(if|while|for|switch)\(/) {
                        ERROR("SPACING", "space required before the open parenthesis '('\n" . $herecurr);
@@ -2587,6 +2808,9 @@ sub process {
 # Check for illegal assignment in if conditional -- and check for trailing
 # statements after the conditional.
                if ($line =~ /do\s*(?!{)/) {
+                       ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
+                               ctx_statement_block($linenr, $realcnt, 0)
+                                       if (!defined $stat);
                        my ($stat_next) = ctx_statement_block($line_nr_next,
                                                $remain_next, $off_next);
                        $stat_next =~ s/\n./\n /g;
@@ -2702,12 +2926,18 @@ sub process {
                        }
                }
 
-#studly caps, commented out until figure out how to distinguish between use of existing and adding new
-#              if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) {
-#                  print "No studly caps, use _\n";
-#                  print "$herecurr";
-#                  $clean = 0;
-#              }
+#CamelCase
+               while ($line =~ m{($Constant|$Lval)}g) {
+                       my $var = $1;
+                       if ($var !~ /$Constant/ &&
+                           $var =~ /[A-Z]\w*[a-z]|[a-z]\w*[A-Z]/ &&
+                           $var !~ /"^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
+                           !defined $camelcase{$var}) {
+                               $camelcase{$var} = 1;
+                               WARN("CAMELCASE",
+                                    "Avoid CamelCase: <$var>\n" . $herecurr);
+                       }
+               }
 
 #no spaces allowed after \ in define
                if ($line=~/\#\s*define.*\\\s$/) {
@@ -2742,47 +2972,13 @@ sub process {
                        my $cnt = $realcnt;
                        my ($off, $dstat, $dcond, $rest);
                        my $ctx = '';
-
-                       my $args = defined($1);
-
-                       # Find the end of the macro and limit our statement
-                       # search to that.
-                       while ($cnt > 0 && defined $lines[$ln - 1] &&
-                               $lines[$ln - 1] =~ /^(?:-|..*\\$)/)
-                       {
-                               $ctx .= $rawlines[$ln - 1] . "\n";
-                               $cnt-- if ($lines[$ln - 1] !~ /^-/);
-                               $ln++;
-                       }
-                       $ctx .= $rawlines[$ln - 1];
-
                        ($dstat, $dcond, $ln, $cnt, $off) =
-                               ctx_statement_block($linenr, $ln - $linenr + 1, 0);
+                               ctx_statement_block($linenr, $realcnt, 0);
+                       $ctx = $dstat;
                        #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
                        #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
 
-                       # Extract the remainder of the define (if any) and
-                       # rip off surrounding spaces, and trailing \'s.
-                       $rest = '';
-                       while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) {
-                               #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n";
-                               if ($off != 0 || $lines[$ln - 1] !~ /^-/) {
-                                       $rest .= substr($lines[$ln - 1], $off) . "\n";
-                                       $cnt--;
-                               }
-                               $ln++;
-                               $off = 0;
-                       }
-                       $rest =~ s/\\\n.//g;
-                       $rest =~ s/^\s*//s;
-                       $rest =~ s/\s*$//s;
-
-                       # Clean up the original statement.
-                       if ($args) {
-                               substr($dstat, 0, length($dcond), '');
-                       } else {
-                               $dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//;
-                       }
+                       $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
                        $dstat =~ s/$;//g;
                        $dstat =~ s/\\\n.//g;
                        $dstat =~ s/^\s*//s;
@@ -2791,14 +2987,20 @@ sub process {
                        # Flatten any parentheses and braces
                        while ($dstat =~ s/\([^\(\)]*\)/1/ ||
                               $dstat =~ s/\{[^\{\}]*\}/1/ ||
-                              $dstat =~ s/\[[^\{\}]*\]/1/)
+                              $dstat =~ s/\[[^\[\]]*\]/1/)
+                       {
+                       }
+
+                       # Flatten any obvious string concatentation.
+                       while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
+                              $dstat =~ s/$Ident\s*("X*")/$1/)
                        {
                        }
 
                        my $exceptions = qr{
                                $Declare|
                                module_param_named|
-                               MODULE_PARAM_DESC|
+                               MODULE_PARM_DESC|
                                DECLARE_PER_CPU|
                                DEFINE_PER_CPU|
                                __typeof__\(|
@@ -2808,23 +3010,84 @@ sub process {
                                ^\"|\"$
                        }x;
                        #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
-                       if ($rest ne '' && $rest ne ',') {
-                               if ($rest !~ /while\s*\(/ &&
-                                   $dstat !~ /$exceptions/)
-                               {
-                                       ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
-                                             "Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n");
+                       if ($dstat ne '' &&
+                           $dstat !~ /^(?:$Ident|-?$Constant),$/ &&                    # 10, // foo(),
+                           $dstat !~ /^(?:$Ident|-?$Constant);$/ &&                    # foo();
+                           $dstat !~ /^[!~-]?(?:$Ident|$Constant)$/ &&         # 10 // foo() // !foo // ~foo // -foo
+                           $dstat !~ /^'X'$/ &&                                        # character constants
+                           $dstat !~ /$exceptions/ &&
+                           $dstat !~ /^\.$Ident\s*=/ &&                                # .foo =
+                           $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&       # do {...} while (...); // do {...} while (...)
+                           $dstat !~ /^for\s*$Constant$/ &&                            # for (...)
+                           $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&   # for (...) bar()
+                           $dstat !~ /^do\s*{/ &&                                      # do {...
+                           $dstat !~ /^\({/)                                           # ({...
+                       {
+                               $ctx =~ s/\n*$//;
+                               my $herectx = $here . "\n";
+                               my $cnt = statement_rawlines($ctx);
+
+                               for (my $n = 0; $n < $cnt; $n++) {
+                                       $herectx .= raw_line($linenr, $n) . "\n";
                                }
 
-                       } elsif ($ctx !~ /;/) {
-                               if ($dstat ne '' &&
-                                   $dstat !~ /^(?:$Ident|-?$Constant)$/ &&
-                                   $dstat !~ /$exceptions/ &&
-                                   $dstat !~ /^\.$Ident\s*=/ &&
-                                   $dstat =~ /$Operators/)
-                               {
+                               if ($dstat =~ /;/) {
+                                       ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
+                                             "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
+                               } else {
                                        ERROR("COMPLEX_MACRO",
-                                             "Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n");
+                                             "Macros with complex values should be enclosed in parenthesis\n" . "$herectx");
+                               }
+                       }
+
+# check for line continuations outside of #defines, preprocessor #, and asm
+
+               } else {
+                       if ($prevline !~ /^..*\\$/ &&
+                           $line !~ /^\+\s*\#.*\\$/ &&         # preprocessor
+                           $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&   # asm
+                           $line =~ /^\+.*\\$/) {
+                               WARN("LINE_CONTINUATIONS",
+                                    "Avoid unnecessary line continuations\n" . $herecurr);
+                       }
+               }
+
+# do {} while (0) macro tests:
+# single-statement macros do not need to be enclosed in do while (0) loop,
+# macro should not end with a semicolon
+               if ($^V && $^V ge 5.10.0 &&
+                   $realfile !~ m@/vmlinux.lds.h$@ &&
+                   $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
+                       my $ln = $linenr;
+                       my $cnt = $realcnt;
+                       my ($off, $dstat, $dcond, $rest);
+                       my $ctx = '';
+                       ($dstat, $dcond, $ln, $cnt, $off) =
+                               ctx_statement_block($linenr, $realcnt, 0);
+                       $ctx = $dstat;
+
+                       $dstat =~ s/\\\n.//g;
+
+                       if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
+                               my $stmts = $2;
+                               my $semis = $3;
+
+                               $ctx =~ s/\n*$//;
+                               my $cnt = statement_rawlines($ctx);
+                               my $herectx = $here . "\n";
+
+                               for (my $n = 0; $n < $cnt; $n++) {
+                                       $herectx .= raw_line($linenr, $n) . "\n";
+                               }
+
+                               if (($stmts =~ tr/;/;/) == 1 &&
+                                   $stmts !~ /^\s*(if|while|for|switch)\b/) {
+                                       WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
+                                            "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
+                               }
+                               if (defined $semis && $semis ne "") {
+                                       WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
+                                            "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
                                }
                        }
                }
@@ -2846,7 +3109,8 @@ sub process {
                        #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
                        #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
                        if ($#chunks > 0 && $level == 0) {
-                               my $allowed = 0;
+                               my @allowed = ();
+                               my $allow = 0;
                                my $seen = 0;
                                my $herectx = $here . "\n";
                                my $ln = $linenr - 1;
@@ -2857,6 +3121,7 @@ sub process {
                                        my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
                                        my $offset = statement_rawlines($whitespace) - 1;
 
+                                       $allowed[$allow] = 0;
                                        #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
 
                                        # We have looked at and allowed this specific line.
@@ -2869,23 +3134,34 @@ sub process {
 
                                        $seen++ if ($block =~ /^\s*{/);
 
-                                       #print "cond<$cond> block<$block> allowed<$allowed>\n";
+                                       #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
                                        if (statement_lines($cond) > 1) {
                                                #print "APW: ALLOWED: cond<$cond>\n";
-                                               $allowed = 1;
+                                               $allowed[$allow] = 1;
                                        }
                                        if ($block =~/\b(?:if|for|while)\b/) {
                                                #print "APW: ALLOWED: block<$block>\n";
-                                               $allowed = 1;
+                                               $allowed[$allow] = 1;
                                        }
                                        if (statement_block_size($block) > 1) {
                                                #print "APW: ALLOWED: lines block<$block>\n";
-                                               $allowed = 1;
+                                               $allowed[$allow] = 1;
                                        }
+                                       $allow++;
                                }
-                               if ($seen && !$allowed) {
-                                       WARN("BRACES",
-                                            "braces {} are not necessary for any arm of this statement\n" . $herectx);
+                               if ($seen) {
+                                       my $sum_allowed = 0;
+                                       foreach (@allowed) {
+                                               $sum_allowed += $_;
+                                       }
+                                       if ($sum_allowed == 0) {
+                                               WARN("BRACES",
+                                                    "braces {} are not necessary for any arm of this statement\n" . $herectx);
+                                       } elsif ($sum_allowed != $allow &&
+                                                $seen != $allow) {
+                                               CHK("BRACES",
+                                                   "braces {} should be used on all arms of this statement\n" . $herectx);
+                                       }
                                }
                        }
                }
@@ -2932,11 +3208,11 @@ sub process {
                                }
                        }
                        if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
-                               my $herectx = $here . "\n";;
+                               my $herectx = $here . "\n";
                                my $cnt = statement_rawlines($block);
 
                                for (my $n = 0; $n < $cnt; $n++) {
-                                       $herectx .= raw_line($linenr, $n) . "\n";;
+                                       $herectx .= raw_line($linenr, $n) . "\n";
                                }
 
                                WARN("BRACES",
@@ -2944,20 +3220,14 @@ sub process {
                        }
                }
 
-# don't include deprecated include files (uses RAW line)
-               for my $inc (@dep_includes) {
-                       if ($rawline =~ m@^.\s*\#\s*include\s*\<$inc>@) {
-                               ERROR("DEPRECATED_INCLUDE",
-                                     "Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr);
-                       }
+# check for unnecessary blank lines around braces
+               if (($line =~ /^..*}\s*$/ && $prevline =~ /^.\s*$/)) {
+                       CHK("BRACES",
+                           "Blank lines aren't necessary before a close brace '}'\n" . $hereprev);
                }
-
-# don't use deprecated functions
-               for my $func (@dep_functions) {
-                       if ($line =~ /\b$func\b/) {
-                               ERROR("DEPRECATED_FUNCTION",
-                                     "Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr);
-                       }
+               if (($line =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
+                       CHK("BRACES",
+                           "Blank lines aren't necessary after an open brace '{'\n" . $hereprev);
                }
 
 # no volatiles please
@@ -2974,27 +3244,19 @@ sub process {
                                $herecurr);
                }
 
-# check for needless kfree() checks
-               if ($prevline =~ /\bif\s*\(([^\)]*)\)/) {
-                       my $expr = $1;
-                       if ($line =~ /\bkfree\(\Q$expr\E\);/) {
-                               WARN("NEEDLESS_KFREE",
-                                    "kfree(NULL) is safe this check is probably not required\n" . $hereprev);
-                       }
-               }
-# check for needless usb_free_urb() checks
-               if ($prevline =~ /\bif\s*\(([^\)]*)\)/) {
-                       my $expr = $1;
-                       if ($line =~ /\busb_free_urb\(\Q$expr\E\);/) {
-                               WARN("NEEDLESS_USB_FREE_URB",
-                                    "usb_free_urb(NULL) is safe this check is probably not required\n" . $hereprev);
+# check for needless "if (<foo>) fn(<foo>)" uses
+               if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
+                       my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;';
+                       if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) {
+                               WARN('NEEDLESS_IF',
+                                    "$1(NULL) is safe this check is probably not required\n" . $hereprev);
                        }
                }
 
 # prefer usleep_range over udelay
-               if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) {
+               if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
                        # ignore udelay's < 10, however
-                       if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) {
+                       if (! ($1 < 10) ) {
                                CHK("USLEEP_RANGE",
                                    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
                        }
@@ -3075,18 +3337,100 @@ sub process {
                             "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
                }
 
+# Check for __attribute__ format(printf, prefer __printf
+               if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
+                       WARN("PREFER_PRINTF",
+                            "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr);
+               }
+
+# Check for __attribute__ format(scanf, prefer __scanf
+               if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
+                       WARN("PREFER_SCANF",
+                            "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr);
+               }
+
 # check for sizeof(&)
                if ($line =~ /\bsizeof\s*\(\s*\&/) {
                        WARN("SIZEOF_ADDRESS",
                             "sizeof(& should be avoided\n" . $herecurr);
                }
 
+# check for sizeof without parenthesis
+               if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
+                       WARN("SIZEOF_PARENTHESIS",
+                            "sizeof $1 should be sizeof($1)\n" . $herecurr);
+               }
+
 # check for line continuations in quoted strings with odd counts of "
                if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
                        WARN("LINE_CONTINUATIONS",
                             "Avoid line continuations in quoted strings\n" . $herecurr);
                }
 
+# check for struct spinlock declarations
+               if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
+                       WARN("USE_SPINLOCK_T",
+                            "struct spinlock should be spinlock_t\n" . $herecurr);
+               }
+
+# Check for misused memsets
+               if ($^V && $^V ge 5.10.0 &&
+                   defined $stat &&
+                   $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
+
+                       my $ms_addr = $2;
+                       my $ms_val = $7;
+                       my $ms_size = $12;
+
+                       if ($ms_size =~ /^(0x|)0$/i) {
+                               ERROR("MEMSET",
+                                     "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
+                       } elsif ($ms_size =~ /^(0x|)1$/i) {
+                               WARN("MEMSET",
+                                    "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
+                       }
+               }
+
+# typecasts on min/max could be min_t/max_t
+               if ($^V && $^V ge 5.10.0 &&
+                   defined $stat &&
+                   $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
+                       if (defined $2 || defined $7) {
+                               my $call = $1;
+                               my $cast1 = deparenthesize($2);
+                               my $arg1 = $3;
+                               my $cast2 = deparenthesize($7);
+                               my $arg2 = $8;
+                               my $cast;
+
+                               if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
+                                       $cast = "$cast1 or $cast2";
+                               } elsif ($cast1 ne "") {
+                                       $cast = $cast1;
+                               } else {
+                                       $cast = $cast2;
+                               }
+                               WARN("MINMAX",
+                                    "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
+                       }
+               }
+
+# check usleep_range arguments
+               if ($^V && $^V ge 5.10.0 &&
+                   defined $stat &&
+                   $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
+                       my $min = $1;
+                       my $max = $7;
+                       if ($min eq $max) {
+                               WARN("USLEEP_RANGE",
+                                    "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
+                       } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
+                                $min > $max) {
+                               WARN("USLEEP_RANGE",
+                                    "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
+                       }
+               }
+
 # check for new externs in .c files.
                if ($realfile =~ /\.c$/ && defined $stat &&
                    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
@@ -3133,16 +3477,30 @@ sub process {
                             "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
                }
 
+# check for alloc argument mismatch
+               if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
+                       WARN("ALLOC_ARRAY_ARGS",
+                            "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
+               }
+
 # check for multiple semicolons
                if ($line =~ /;\s*;\s*$/) {
-                   WARN("ONE_SEMICOLON",
-                        "Statements terminations use 1 semicolon\n" . $herecurr);
+                       WARN("ONE_SEMICOLON",
+                            "Statements terminations use 1 semicolon\n" . $herecurr);
                }
 
-# check for whitespace before semicolon - not allowed at end-of-line
-               if ($line =~ /\s+;$/) {
-                   WARN("SPACEBEFORE_SEMICOLON",
-                        "Whitespace before semicolon\n" . $herecurr);
+# check for switch/default statements without a break;
+               if ($^V && $^V ge 5.10.0 &&
+                   defined $stat &&
+                   $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
+                       my $ctx = '';
+                       my $herectx = $here . "\n";
+                       my $cnt = statement_rawlines($stat);
+                       for (my $n = 0; $n < $cnt; $n++) {
+                               $herectx .= raw_line($linenr, $n) . "\n";
+                       }
+                       WARN("DEFAULT_NO_BREAK",
+                            "switch default: should use break\n" . $herectx);
                }
 
 # check for gcc specific __FUNCTION__
@@ -3151,22 +3509,30 @@ sub process {
                             "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
                }
 
+# check for use of yield()
+               if ($line =~ /\byield\s*\(\s*\)/) {
+                       WARN("YIELD",
+                            "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
+               }
+
 # check for semaphores initialized locked
                if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
                        WARN("CONSIDER_COMPLETION",
                             "consider using a completion\n" . $herecurr);
-
                }
-# recommend kstrto* over simple_strto*
-               if ($line =~ /\bsimple_(strto.*?)\s*\(/) {
+
+# recommend kstrto* over simple_strto* and strict_strto*
+               if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
                        WARN("CONSIDER_KSTRTO",
-                            "consider using kstrto* in preference to simple_$1\n" . $herecurr);
+                            "$1 is obsolete, use k$3 instead\n" . $herecurr);
                }
+
 # check for __initcall(), use device_initcall() explicitly please
                if ($line =~ /^.\s*__initcall\s*\(/) {
                        WARN("USE_DEVICE_INITCALL",
                             "please use device_initcall() instead of __initcall()\n" . $herecurr);
                }
+
 # check for various ops structs, ensure they are const.
                my $struct_ops = qr{acpi_dock_ops|
                                address_space_operations|
@@ -3264,12 +3630,6 @@ sub process {
                        WARN("EXPORTED_WORLD_WRITABLE",
                             "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
                }
-
-               # Check for memset with swapped arguments
-               if ($line =~ /memset.*\,(\ |)(0x|)0(\ |0|)\);/) {
-                       ERROR("MEMSET",
-                             "memset size is 3rd argument, not the second.\n" . $herecurr);
-               }
        }
 
        # If we have no input at all, then there is nothing to report on
@@ -3309,6 +3669,12 @@ sub process {
        }
 
        if ($quiet == 0) {
+
+               if ($^V lt 5.10.0) {
+                       print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
+                       print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
+               }
+
                # If there were whitespace errors which cleanpatch can fix
                # then suggest that.
                if ($rpt_cleaners) {
@@ -3318,13 +3684,12 @@ sub process {
                }
        }
 
-       if (keys %ignore_type) {
+       if ($quiet == 0 && keys %ignore_type) {
            print "NOTE: Ignored message types:";
            foreach my $ignore (sort keys %ignore_type) {
                print " $ignore";
            }
-           print "\n";
-           print "\n" if ($quiet == 0);
+           print "\n\n";
        }
 
        if ($clean == 1 && $quiet == 0) {
index df020e4afd43d4540937a834ea8be14c9e0ed466..1020b57b059c5c4508551efd364caac55f9aa0be 100644 (file)
@@ -8,7 +8,7 @@ In order to cross-compile fw_printenv, run
 in the root directory of the U-Boot distribution. For example,
     make HOSTCC=arm-linux-gcc env
 
-For the run-time utiltity configuration uncomment the line
+For the run-time utility configuration uncomment the line
 #define CONFIG_FILE  "/etc/fw_env.config"
 in fw_env.h.
 
@@ -34,7 +34,7 @@ following lines are relevant:
 #define DEVICE2_ESIZE     0x4000
 #define DEVICE2_ENVSECTORS     2
 
-Un-define HAVE_REDUND, if you want to use the utlities on a system
+Un-define HAVE_REDUND, if you want to use the utilities on a system
 that does not have support for redundant environment enabled.
 If HAVE_REDUND is undefined, DEVICE2_NAME is ignored,
 as is ENV2_SIZE and DEVICE2_ESIZE.
index 37b60b80a7624566d9ecefdd04c0658134bd654d..bf30234190c0d2368dbf3ed83a9e86b507b4c2e1 100644 (file)
@@ -836,9 +836,9 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
 
                erase.start = blockstart;
                ioctl (fd, MEMUNLOCK, &erase);
-
-               /* Dataflash does not need an explicit erase cycle */
-               if (mtd_type != MTD_DATAFLASH)
+               /* These do not need an explicit erase cycle */
+               if (mtd_type != MTD_ABSENT &&
+                   mtd_type != MTD_DATAFLASH)
                        if (ioctl (fd, MEMERASE, &erase) != 0) {
                                fprintf (stderr, "MTD erase error on %s: %s\n",
                                         DEVNAME (dev),
@@ -949,19 +949,33 @@ static int flash_write (int fd_current, int fd_target, int dev_target)
 static int flash_read (int fd)
 {
        struct mtd_info_user mtdinfo;
+       struct stat st;
        int rc;
 
-       rc = ioctl (fd, MEMGETINFO, &mtdinfo);
+       rc = fstat(fd, &st);
        if (rc < 0) {
-               perror ("Cannot get MTD information");
+               fprintf(stderr, "Cannot stat the file %s\n",
+                       DEVNAME(dev_current));
                return -1;
        }
 
-       if (mtdinfo.type != MTD_NORFLASH &&
-           mtdinfo.type != MTD_NANDFLASH &&
-           mtdinfo.type != MTD_DATAFLASH) {
-               fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type);
-               return -1;
+       if (S_ISCHR(st.st_mode)) {
+               rc = ioctl(fd, MEMGETINFO, &mtdinfo);
+               if (rc < 0) {
+                       fprintf(stderr, "Cannot get MTD information for %s\n",
+                               DEVNAME(dev_current));
+                       return -1;
+               }
+               if (mtdinfo.type != MTD_NORFLASH &&
+                   mtdinfo.type != MTD_NANDFLASH &&
+                   mtdinfo.type != MTD_DATAFLASH) {
+                       fprintf (stderr, "Unsupported flash type %u on %s\n",
+                                mtdinfo.type, DEVNAME(dev_current));
+                       return -1;
+               }
+       } else {
+               memset(&mtdinfo, 0, sizeof(mtdinfo));
+               mtdinfo.type = MTD_ABSENT;
        }
 
        DEVTYPE(dev_current) = mtdinfo.type;
index 9d3b1a46927bf6724c65e269b2add4863691db3c..90e499da1e092ae84ebbb67d3aa223b5eb642480 100644 (file)
@@ -17,3 +17,6 @@
 
 # NAND example
 #/dev/mtd0             0x4000          0x4000          0x20000                 2
+
+# Block device example
+#/dev/mmcblk0          0xc0000         0x20000