]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot into master
authorStefano Babic <sbabic@denx.de>
Sat, 8 Dec 2012 11:02:45 +0000 (12:02 +0100)
committerStefano Babic <sbabic@denx.de>
Sat, 8 Dec 2012 11:02:45 +0000 (12:02 +0100)
Conflicts:
drivers/power/power_fsl.c
include/configs/mx35pdk.h
include/configs/mx53loco.h
include/configs/woodburn_common.h
board/woodburn/woodburn.c

These boards still use the old old PMIC framework, so they
do not merge properly after the power framework was merged into
mainline.

Fix all conflicts and update woodburn to use Power Framework.

Signed-off-by: Stefano Babic <sbabic@denx.de>
384 files changed:
.gitignore
MAINTAINERS
MAKEALL
Makefile
README
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock.c
arch/arm/cpu/armv7/omap3/Makefile
arch/arm/cpu/armv7/omap3/am35x_musb.c [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/hardware.h
arch/arm/include/asm/arch-exynos/dwmmc.h [new file with mode: 0644]
arch/arm/include/asm/arch-omap3/am35x_def.h
arch/arm/include/asm/arch-omap3/musb.h [moved from board/chromebook-x86/coreboot/coreboot_start16.S with 56% similarity]
arch/arm/include/asm/imx-common/mx5_video.h [new file with mode: 0644]
arch/arm/include/asm/omap_musb.h [new file with mode: 0644]
arch/arm/lib/board.c
arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
arch/mips/cpu/mips32/time.c
arch/mips/cpu/mips64/time.c
arch/powerpc/config.mk
arch/powerpc/cpu/mpc5xxx/Makefile
arch/powerpc/cpu/mpc5xxx/spl_boot.c [new file with mode: 0644]
arch/powerpc/cpu/mpc5xxx/start.S
arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds [new file with mode: 0644]
arch/powerpc/cpu/mpc5xxx/usb_ohci.c
arch/powerpc/cpu/mpc85xx/Makefile
arch/powerpc/cpu/mpc85xx/cmd_errata.c
arch/powerpc/cpu/mpc85xx/cpu.c
arch/powerpc/cpu/mpc85xx/cpu_init.c
arch/powerpc/cpu/mpc85xx/ddr-gen1.c
arch/powerpc/cpu/mpc85xx/ddr-gen2.c
arch/powerpc/cpu/mpc85xx/ddr-gen3.c
arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
arch/powerpc/cpu/mpc85xx/release.S
arch/powerpc/cpu/mpc85xx/spl_minimal.c [moved from arch/powerpc/cpu/mpc85xx/cpu_init_nand.c with 76% similarity]
arch/powerpc/cpu/mpc85xx/start.S
arch/powerpc/cpu/mpc85xx/tlb.c
arch/powerpc/cpu/mpc85xx/u-boot-spl.lds [new file with mode: 0644]
arch/powerpc/cpu/mpc86xx/ddr-8641.c
arch/powerpc/cpu/mpc8xxx/Makefile
arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
arch/powerpc/cpu/mpc8xxx/ddr/util.c
arch/powerpc/cpu/mpc8xxx/fdt.c
arch/powerpc/cpu/mpc8xxx/law.c [moved from drivers/misc/fsl_law.c with 95% similarity]
arch/powerpc/cpu/ppc4xx/usb_ohci.c
arch/powerpc/include/asm/config_mpc85xx.h
arch/powerpc/include/asm/immap_83xx.h
arch/powerpc/include/asm/immap_85xx.h
arch/powerpc/include/asm/immap_86xx.h
arch/powerpc/include/asm/processor.h
arch/powerpc/include/asm/spl.h [moved from board/chromebook-x86/coreboot/coreboot_pci.c with 71% similarity]
arch/powerpc/lib/Makefile
arch/powerpc/lib/bootm.c
arch/powerpc/lib/spl.c [new file with mode: 0644]
arch/sh/include/asm/system.h
arch/x86/cpu/Makefile
arch/x86/cpu/coreboot/Makefile
arch/x86/cpu/coreboot/car.S [moved from arch/x86/cpu/coreboot/coreboot_car.S with 100% similarity]
arch/x86/cpu/coreboot/config.mk [moved from board/BuS/eb_cpu5282/config.mk with 78% similarity]
arch/x86/cpu/coreboot/coreboot.c [moved from board/chromebook-x86/coreboot/coreboot.c with 55% similarity]
arch/x86/cpu/coreboot/pci.c [new file with mode: 0644]
arch/x86/cpu/coreboot/sdram.c
arch/x86/cpu/coreboot/sysinfo.c [deleted file]
arch/x86/cpu/coreboot/tables.c
arch/x86/cpu/coreboot/timestamp.c [new file with mode: 0644]
arch/x86/cpu/cpu.c
arch/x86/cpu/interrupts.c
arch/x86/cpu/start.S
arch/x86/cpu/start16.S
arch/x86/cpu/timer.c [new file with mode: 0644]
arch/x86/cpu/u-boot.lds
arch/x86/dts/coreboot.dtsi [new file with mode: 0644]
arch/x86/dts/skeleton.dtsi [new file with mode: 0644]
arch/x86/include/asm/arch-coreboot/sysinfo.h
arch/x86/include/asm/arch-coreboot/tables.h
arch/x86/include/asm/arch-coreboot/timestamp.h [new file with mode: 0644]
arch/x86/include/asm/bitops.h
arch/x86/include/asm/cache.h
arch/x86/include/asm/control_regs.h [new file with mode: 0644]
arch/x86/include/asm/global_data.h
arch/x86/include/asm/gpio.h [moved from arch/nios2/include/asm/status_led.h with 68% similarity]
arch/x86/include/asm/init_helpers.h
arch/x86/include/asm/io.h
arch/x86/include/asm/msr-index.h [new file with mode: 0644]
arch/x86/include/asm/msr.h [new file with mode: 0644]
arch/x86/include/asm/mtrr.h [new file with mode: 0644]
arch/x86/include/asm/pci.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/types.h
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/init_wrappers.c
arch/x86/lib/pcat_timer.c
arch/x86/lib/physmem.c [new file with mode: 0644]
arch/x86/lib/relocate.c
arch/x86/lib/timer.c
arch/x86/lib/video.c
arch/x86/lib/zimage.c
board/BuS/eb_cpu5282/Makefile
board/BuS/eb_cpu5282/cfm_flash.c [deleted file]
board/BuS/eb_cpu5282/cfm_flash.h [deleted file]
board/BuS/eb_cpu5282/eb_cpu5282.c
board/BuS/eb_cpu5282/flash.c [deleted file]
board/a3m071/Makefile [new file with mode: 0644]
board/a3m071/README [new file with mode: 0644]
board/a3m071/a3m071.c [new file with mode: 0644]
board/a3m071/mt46v16m16-75.h [new file with mode: 0644]
board/chromebook-x86/coreboot/Makefile
board/chromebook-x86/coreboot/config.mk [new file with mode: 0644]
board/chromebook-x86/dts/alex.dts [new file with mode: 0644]
board/chromebook-x86/dts/link.dts [new file with mode: 0644]
board/davedenx/qong/qong.c
board/exmeritus/hww1u1a/hww1u1a.c
board/freescale/common/Makefile
board/freescale/common/ngpixis.h
board/freescale/corenet_ds/Makefile
board/freescale/corenet_ds/corenet_ds.c
board/freescale/corenet_ds/ddr.c
board/freescale/corenet_ds/eth_superhydra.c [new file with mode: 0644]
board/freescale/corenet_ds/p5040ds_ddr.c [new file with mode: 0644]
board/freescale/mpc8540ads/mpc8540ads.c
board/freescale/mpc8560ads/mpc8560ads.c
board/freescale/mpc8569mds/mpc8569mds.c
board/freescale/mx31pdk/mx31pdk.c
board/freescale/mx35pdk/mx35pdk.c
board/freescale/mx51evk/Makefile
board/freescale/mx51evk/mx51evk.c
board/freescale/mx51evk/mx51evk_video.c [new file with mode: 0644]
board/freescale/mx53evk/mx53evk.c
board/freescale/mx53loco/Makefile
board/freescale/mx53loco/mx53loco.c
board/freescale/mx53loco/mx53loco_video.c [new file with mode: 0644]
board/freescale/p1023rds/p1023rds.c
board/freescale/p1_p2_rdb_pc/Makefile
board/freescale/p1_p2_rdb_pc/ddr.c
board/freescale/p1_p2_rdb_pc/law.c
board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
board/freescale/p1_p2_rdb_pc/spl_minimal.c [moved from nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c with 93% similarity]
board/freescale/p1_p2_rdb_pc/tlb.c
board/freescale/p2020ds/p2020ds.c
board/genesi/mx51_efikamx/efikamx.c
board/hale/tt01/tt01.c
board/iomega/iconnect/iconnect.c
board/iomega/iconnect/iconnect.h
board/iomega/iconnect/kwbimage.cfg
board/logicpd/am3517evm/am3517evm.c
board/raidsonic/ib62x0/ib62x0.c
board/raidsonic/ib62x0/ib62x0.h
board/raidsonic/ib62x0/kwbimage.cfg
board/samsung/goni/goni.c
board/samsung/trats/trats.c
board/samsung/universal_c210/universal.c
board/sbc8548/ddr.c
board/socrates/sdram.c
board/ti/am335x/board.c
board/ti/beagle/beagle.c
board/ttcontrol/vision2/vision2.c
board/woodburn/woodburn.c
boards.cfg
common/Makefile
common/bouncebuf.c
common/cmd_bmp.c
common/cmd_bootm.c
common/cmd_led.c
common/cmd_mmc.c
common/cmd_nand.c
common/cmd_usb.c
common/image.c
common/lcd.c
common/main.c
common/spl/spl.c
common/stdio.c
common/usb.c
common/usb_kbd.c
disk/part.c
doc/DocBook/Makefile
doc/README.mpc85xx
doc/README.nand
doc/kwboot.1
drivers/gpio/Makefile
drivers/gpio/intel_ich6_gpio.c [new file with mode: 0644]
drivers/misc/Makefile
drivers/misc/cbmem_console.c [new file with mode: 0644]
drivers/misc/pmic_core.c [deleted file]
drivers/mmc/Makefile
drivers/mmc/exynos_dw_mmc.c [new file with mode: 0644]
drivers/mmc/mmc.c
drivers/mmc/mxsmmc.c
drivers/mmc/sdhci.c
drivers/mmc/tegra_mmc.c
drivers/mtd/nand/Makefile
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_elbc_spl.c [new file with mode: 0644]
drivers/mtd/nand/fsl_ifc_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_util.c
drivers/net/fm/Makefile
drivers/net/fm/p5040.c [new file with mode: 0644]
drivers/pci/fsl_pci_init.c
drivers/power/Makefile
drivers/power/battery/Makefile [new file with mode: 0644]
drivers/power/battery/bat_trats.c [new file with mode: 0644]
drivers/power/fuel_gauge/Makefile [new file with mode: 0644]
drivers/power/fuel_gauge/fg_max17042.c [new file with mode: 0644]
drivers/power/pmic/Makefile [new file with mode: 0644]
drivers/power/pmic/muic_max8997.c [new file with mode: 0644]
drivers/power/pmic/pmic_max8997.c [new file with mode: 0644]
drivers/power/pmic/pmic_max8998.c [moved from drivers/misc/pmic_max8998.c with 82% similarity]
drivers/power/power_core.c [new file with mode: 0644]
drivers/power/power_dialog.c [moved from drivers/misc/pmic_dialog.c with 81% similarity]
drivers/power/power_fsl.c [moved from drivers/misc/pmic_fsl.c with 83% similarity]
drivers/power/power_i2c.c [moved from drivers/misc/pmic_i2c.c with 62% similarity]
drivers/power/power_spi.c [moved from drivers/misc/pmic_spi.c with 97% similarity]
drivers/rtc/mc13xxx-rtc.c
drivers/serial/ns16550.c
drivers/serial/serial_ns16550.c
drivers/serial/serial_pl01x.c
drivers/serial/serial_sh.c
drivers/usb/gadget/config.c
drivers/usb/gadget/epautoconf.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/f_dfu.c
drivers/usb/gadget/gadget_chips.h
drivers/usb/gadget/s3c_udc_otg.c
drivers/usb/gadget/usbstring.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-s3c24xx.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/sl811-hcd.c
drivers/usb/musb-new/Makefile [new file with mode: 0644]
drivers/usb/musb-new/am35x.c [new file with mode: 0644]
drivers/usb/musb-new/linux-compat.h [new file with mode: 0644]
drivers/usb/musb-new/musb_core.c [new file with mode: 0644]
drivers/usb/musb-new/musb_core.h [new file with mode: 0644]
drivers/usb/musb-new/musb_debug.h [new file with mode: 0644]
drivers/usb/musb-new/musb_dma.h [new file with mode: 0644]
drivers/usb/musb-new/musb_dsps.c [new file with mode: 0644]
drivers/usb/musb-new/musb_gadget.c [new file with mode: 0644]
drivers/usb/musb-new/musb_gadget.h [new file with mode: 0644]
drivers/usb/musb-new/musb_gadget_ep0.c [new file with mode: 0644]
drivers/usb/musb-new/musb_host.c [new file with mode: 0644]
drivers/usb/musb-new/musb_host.h [new file with mode: 0644]
drivers/usb/musb-new/musb_io.h [new file with mode: 0644]
drivers/usb/musb-new/musb_regs.h [new file with mode: 0644]
drivers/usb/musb-new/musb_uboot.c [new file with mode: 0644]
drivers/usb/musb-new/omap2430.c [new file with mode: 0644]
drivers/usb/musb-new/omap2430.h [new file with mode: 0644]
drivers/usb/musb-new/usb-compat.h [new file with mode: 0644]
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_hcd.c
drivers/video/Makefile
drivers/video/atmel_hlcdfb.c
drivers/video/bus_vcxk.c
drivers/video/cfb_console.c
drivers/video/coreboot_fb.c [new file with mode: 0644]
drivers/video/ipu_common.c
fs/cbfs/Makefile
fs/cbfs/cbfs.c
fs/ext4/dev.c
fs/ext4/ext4_common.c
fs/ext4/ext4_journal.c
fs/ext4/ext4fs.c
fs/fs.c
fs/zfs/zfs.c
include/atmel_hlcdc.h
include/bouncebuf.h
include/cbfs.h
include/configs/CPCI405.h
include/configs/CPCI4052.h
include/configs/CPCI405AB.h
include/configs/CPCI405DT.h
include/configs/P1010RDB.h
include/configs/P1022DS.h
include/configs/P1023RDS.h
include/configs/P2041RDB.h
include/configs/P3041DS.h
include/configs/P5020DS.h
include/configs/P5040DS.h [new file with mode: 0644]
include/configs/PK1C20.h
include/configs/a3m071.h [new file with mode: 0644]
include/configs/am335x_evm.h
include/configs/am3517_crane.h
include/configs/am3517_evm.h
include/configs/at91sam9x5ek.h
include/configs/cam_enc_4xx.h
include/configs/coreboot.h
include/configs/corenet_ds.h
include/configs/da850evm.h
include/configs/devkit8000.h
include/configs/eNET.h
include/configs/eb_cpu5282.h
include/configs/hawkboard.h
include/configs/ib62x0.h
include/configs/iconnect.h
include/configs/igep00x0.h
include/configs/imx31_litekit.h
include/configs/lwmon5.h
include/configs/mcx.h
include/configs/mx31ads.h
include/configs/mx31pdk.h
include/configs/mx35pdk.h
include/configs/mx51_efikamx.h
include/configs/mx51evk.h
include/configs/mx53evk.h
include/configs/mx53loco.h
include/configs/mx6qarm2.h
include/configs/mx6qsabre_common.h
include/configs/mx6qsabrelite.h
include/configs/nios2-generic.h
include/configs/omap3_beagle.h
include/configs/omap3_evm.h
include/configs/omap3_evm_quick_nand.h
include/configs/omap3_overo.h
include/configs/p1_p2_rdb_pc.h
include/configs/qong.h
include/configs/s5p_goni.h
include/configs/s5pc210_universal.h
include/configs/sc_sps_1.h
include/configs/seaboard.h
include/configs/sequoia.h
include/configs/tam3517-common.h
include/configs/tegra-common-post.h
include/configs/tegra20-common.h
include/configs/trats.h
include/configs/tricorder.h
include/configs/tt01.h
include/configs/vct.h
include/configs/ventana.h
include/configs/vision2.h
include/configs/woodburn_common.h
include/fdtdec.h
include/g_dnl.h
include/image.h
include/lcd.h
include/linux/byteorder/swab.h
include/linux/mtd/nand.h
include/linux/usb/ch9.h
include/linux/usb/musb.h [new file with mode: 0644]
include/nand.h
include/nios2.h
include/pci.h
include/physmem.h [new file with mode: 0644]
include/power/battery.h [moved from drivers/misc/pmic_max8997.c with 71% similarity]
include/power/fg_battery_cell_params.h [new file with mode: 0644]
include/power/max17042_fg.h [new file with mode: 0644]
include/power/max8997_muic.h [new file with mode: 0644]
include/power/max8997_pmic.h [moved from include/max8997_pmic.h with 88% similarity]
include/power/max8998_pmic.h [moved from include/max8998_pmic.h with 100% similarity]
include/power/pmic.h [moved from include/pmic.h with 58% similarity]
include/power/power_chrg.h [moved from nand_spl/board/freescale/common.c with 59% similarity]
include/sdhci.h
include/status_led.h
include/stdio_dev.h
include/usb.h
include/usb/s3c_udc.h
include/usb_defs.h
include/video.h
lib/Makefile
lib/fdtdec.c
lib/lzma/LzmaDec.c
lib/lzma/LzmaDec.h
lib/lzma/Types.h
lib/lzma/history.txt
lib/lzma/lzma.txt
lib/physmem.c [new file with mode: 0644]
nand_spl/board/freescale/mpc8536ds/Makefile
nand_spl/board/freescale/mpc8569mds/Makefile
nand_spl/board/freescale/mpc8572ds/Makefile
nand_spl/board/freescale/mx31pdk/Makefile
nand_spl/board/freescale/p1010rdb/Makefile
nand_spl/board/freescale/p1010rdb/nand_boot.c
nand_spl/board/freescale/p1023rds/Makefile
nand_spl/board/freescale/p1023rds/nand_boot.c
nand_spl/board/freescale/p1_p2_rdb/Makefile
nand_spl/board/freescale/p1_p2_rdb_pc/Makefile [deleted file]
nand_spl/board/karo/tx25/Makefile
spl/Makefile
tools/patman/series.py

index 1ac43f2825666d93f2f611e86ab2f735777bf83f..a163728832eb0fc7b01ece5d81c6239f3b824671 100644 (file)
 /u-boot.sha1
 /u-boot.dis
 /u-boot.lds
-/u-boot.lst
 /u-boot.ubl
 /u-boot.ais
 /u-boot.dtb
 /u-boot.sb
 /u-boot.geany
+/include/u-boot.lst
 
 #
 # Generated files
index e34d9f3ec36811ae170b10c7397da604e4379f2b..36b47b741ad2f63cef57856cd58ff99d4d9b827b 100644 (file)
@@ -7,6 +7,10 @@
 # and Cc: the <u-boot@lists.denx.de> mailing list.                     #
 #                                                                      #
 # Note: lists sorted by Maintainer Name                                        #
+# Note: These are the maintainers for specific *boards*.  The          #
+#      custodians for general architectures and subsystems can         #
+#      be found here -- http://www.denx.de/wiki/U-Boot/Custodians      #
+#                                                                      #
 #########################################################################
 
 
@@ -388,6 +392,8 @@ Ricardo Ribalda <ricardo.ribalda@uam.es>
 
 Stefan Roese <sr@denx.de>
 
+       a3m071          MPC5200
+
        P3M7448         MPC7448
 
        uc100           MPC857
@@ -800,7 +806,7 @@ Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
 
        apx4devkit      i.MX28
 
-Luka Perkov <uboot@lukaperkov.net>
+Luka Perkov <luka@openwrt.org>
 
        ib62x0          ARM926EJS
        iconnect        ARM926EJS
diff --git a/MAKEALL b/MAKEALL
index 84a5c92cf39308ddef93ab17908b84811c4971d3..5b06c5477decafc2d18dafd0ad8520e96a572ca0 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -20,6 +20,8 @@ usage()
          -m,        --maintainers     List all targets and maintainer email
          -M,        --mails           List all targets and all affilated emails
          -C,        --check           Enable build checking
+         -n,        --continue        Continue (skip boards already built)
+         -r,        --rebuild-errors  Rebuild any boards that errored
          -h,        --help            This help output
 
        Selections by these options are logically ANDed; if the same option
@@ -52,8 +54,8 @@ usage()
        exit ${ret}
 }
 
-SHORT_OPTS="ha:c:v:s:lmMC"
-LONG_OPTS="help,arch:,cpu:,vendor:,soc:,list,maintainers,mails,check"
+SHORT_OPTS="ha:c:v:s:lmMCnr"
+LONG_OPTS="help,arch:,cpu:,vendor:,soc:,list,maintainers,mails,check,continue,rebuild-errors"
 
 # Option processing based on util-linux-2.13/getopt-parse.bash
 
@@ -73,6 +75,8 @@ SELECTED=''
 ONLY_LIST=''
 PRINT_MAINTS=''
 MAINTAINERS_ONLY=''
+CONTINUE=''
+REBUILD_ERRORS=''
 
 while true ; do
        case "$1" in
@@ -115,6 +119,12 @@ while true ; do
        -C|--check)
                CHECK='C=1'
                shift ;;
+       -n|--continue)
+               CONTINUE='y'
+               shift ;;
+       -r|--rebuild-errors)
+               REBUILD_ERRORS='y'
+               shift ;;
        -l|--list)
                ONLY_LIST='y'
                shift ;;
@@ -198,7 +208,9 @@ fi
 OUTPUT_PREFIX="${BUILD_DIR}"
 
 [ -d ${LOG_DIR} ] || mkdir "${LOG_DIR}" || exit 1
-find "${LOG_DIR}/" -type f -exec rm -f {} +
+if [ "$CONTINUE" != 'y' -a "$REBUILD_ERRORS" != 'y' ] ; then
+       find "${LOG_DIR}/" -type f -exec rm -f {} +
+fi
 
 LIST=""
 
@@ -208,6 +220,7 @@ ERR_LIST=""
 WRN_CNT=0
 WRN_LIST=""
 TOTAL_CNT=0
+SKIP_CNT=0
 CURRENT_CNT=0
 OLDEST_IDX=1
 RC=0
@@ -380,6 +393,12 @@ LIST_pxa="$(boards_by_cpu pxa)"
 
 LIST_ixp="$(boards_by_cpu ixp)"
 
+#########################################################################
+## SPEAr Systems
+#########################################################################
+
+LIST_spear="$(boards_by_soc spear)"
+
 #########################################################################
 ## ARM groups
 #########################################################################
@@ -610,6 +629,13 @@ list_target() {
 donep="${LOG_DIR}/._done_"
 skipp="${LOG_DIR}/._skip_"
 
+build_target_killed() {
+       echo "Aborted $target build."
+       # Remove the logs for this board since it was aborted
+       rm -f ${LOG_DIR}/$target.MAKELOG ${LOG_DIR}/$target.ERR
+       exit
+}
+
 build_target() {
        target=$1
        build_idx=$2
@@ -622,6 +648,7 @@ build_target() {
        if [ $BUILD_MANY == 1 ] ; then
                output_dir="${OUTPUT_PREFIX}/${target}"
                mkdir -p "${output_dir}"
+               trap build_target_killed TERM
        else
                output_dir="${OUTPUT_PREFIX}"
        fi
@@ -640,6 +667,8 @@ build_target() {
        fi
 
        if [ $BUILD_MANY == 1 ] ; then
+               trap - TERM
+
                ${MAKE} -s tidy
 
                if [ -s ${LOG_DIR}/${target}.ERR ] ; then
@@ -718,10 +747,20 @@ build_targets() {
                        : $((CURRENT_CNT += 1))
                        rm -f "${donep}${TOTAL_CNT}"
                        rm -f "${skipp}${TOTAL_CNT}"
-                       if [ $BUILD_MANY == 1 ] ; then
-                               build_target ${t} ${TOTAL_CNT} &
+                       if [ "$CONTINUE" = 'y' -a -e ${LOG_DIR}/$t.MAKELOG ] ; then
+                               : $((SKIP_CNT += 1))
+                               touch "${donep}${TOTAL_CNT}"
+                       elif [ "$REBUILD_ERRORS" = 'y' -a ! -e ${LOG_DIR}/$t.ERR ] ; then
+                               : $((SKIP_CNT += 1))
+                               touch "${donep}${TOTAL_CNT}"
                        else
-                               build_target ${t} ${TOTAL_CNT}
+                               if [ $BUILD_MANY == 1 ] ; then
+                                       build_target ${t} ${TOTAL_CNT} &
+                               else
+                                       CUR_TGT="${t}"
+                                       build_target ${t} ${TOTAL_CNT}
+                                       CUR_TGT=''
+                               fi
                        fi
                fi
 
@@ -745,7 +784,11 @@ build_targets() {
 #-----------------------------------------------------------------------
 
 kill_children() {
-       kill -- "-$1"
+       local pgid=`ps -p $$ --no-headers -o "%r" | tr -d ' '`
+       local children=`pgrep -g $pgid | grep -v $$ | grep -v $pgid`
+
+       kill $children 2> /dev/null
+       wait $children 2> /dev/null
 
        exit
 }
@@ -753,6 +796,9 @@ kill_children() {
 print_stats() {
        if [ "$ONLY_LIST" == 'y' ] ; then return ; fi
 
+       # Only count boards that completed
+       : $((TOTAL_CNT = `find ${skipp}* 2> /dev/null | wc -l`))
+
        rm -f ${donep}* ${skipp}*
 
        if [ $BUILD_MANY == 1 ] && [ -e "${OUTPUT_PREFIX}/ERR" ] ; then
@@ -762,10 +808,17 @@ print_stats() {
                WRN_LIST=`grep -riwL error ${OUTPUT_PREFIX}/ERR/`
                WRN_LIST=`for f in $WRN_LIST ; do echo -n " $(basename $f)" ; done`
                WRN_CNT=`echo $WRN_LIST | wc -w | awk '{print $1}'`
+       else
+               # Remove the logs for any board that was interrupted
+               rm -f ${LOG_DIR}/${CUR_TGT}.MAKELOG ${LOG_DIR}/${CUR_TGT}.ERR
        fi
 
+       : $((TOTAL_CNT -= ${SKIP_CNT}))
        echo ""
        echo "--------------------- SUMMARY ----------------------------"
+       if [ "$CONTINUE" = 'y' -o "$REBUILD_ERRORS" = 'y' ] ; then
+               echo "Boards skipped: ${SKIP_CNT}"
+       fi
        echo "Boards compiled: ${TOTAL_CNT}"
        if [ ${ERR_CNT} -gt 0 ] ; then
                echo "Boards with errors: ${ERR_CNT} (${ERR_LIST} )"
@@ -776,7 +829,7 @@ print_stats() {
        echo "----------------------------------------------------------"
 
        if [ $BUILD_MANY == 1 ] ; then
-               kill_children $$ &
+               kill_children
        fi
 
        exit $RC
index 86546a286a6b51b0d7dc9c31db6d34c2d78c0a68..d3766b901744b3a855c3e2d03a32e108bb810da3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -231,8 +231,8 @@ endif
 
 OBJS  = $(CPUDIR)/start.o
 ifeq ($(CPU),x86)
-OBJS += $(CPUDIR)/start16.o
-OBJS += $(CPUDIR)/resetvec.o
+RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/start16.o
+RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/resetvec.o
 endif
 ifeq ($(CPU),ppc4xx)
 OBJS += $(CPUDIR)/resetvec.o
@@ -241,7 +241,7 @@ ifeq ($(CPU),mpc85xx)
 OBJS += $(CPUDIR)/resetvec.o
 endif
 
-OBJS := $(addprefix $(obj),$(OBJS))
+OBJS := $(addprefix $(obj),$(OBJS) $(RESET_OBJS-))
 
 HAVE_VENDOR_COMMON_LIB = $(if $(wildcard board/$(VENDOR)/common/Makefile),y,n)
 
@@ -293,7 +293,10 @@ LIBS-y += drivers/net/libnet.o
 LIBS-y += drivers/net/phy/libphy.o
 LIBS-y += drivers/pci/libpci.o
 LIBS-y += drivers/pcmcia/libpcmcia.o
-LIBS-y += drivers/power/libpower.o
+LIBS-y += drivers/power/libpower.o \
+       drivers/power/fuel_gauge/libfuel_gauge.o \
+       drivers/power/pmic/libpmic.o \
+       drivers/power/battery/libbattery.o
 LIBS-y += drivers/spi/libspi.o
 LIBS-y += drivers/dfu/libdfu.o
 ifeq ($(CPU),mpc83xx)
@@ -319,6 +322,7 @@ LIBS-y += drivers/usb/eth/libusb_eth.o
 LIBS-y += drivers/usb/gadget/libusb_gadget.o
 LIBS-y += drivers/usb/host/libusb_host.o
 LIBS-y += drivers/usb/musb/libusb_musb.o
+LIBS-y += drivers/usb/musb-new/libusb_musb-new.o
 LIBS-y += drivers/usb/phy/libusb_phy.o
 LIBS-y += drivers/usb/ulpi/libusb_ulpi.o
 LIBS-y += drivers/video/libvideo.o
@@ -386,12 +390,12 @@ __LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
 ifneq ($(CONFIG_BOARD_SIZE_LIMIT),)
 BOARD_SIZE_CHECK = \
        @actual=`wc -c $@ | awk '{print $$1}'`; \
-       limit=$(CONFIG_BOARD_SIZE_LIMIT); \
+       limit=`printf "%d" $(CONFIG_BOARD_SIZE_LIMIT)`; \
        if test $$actual -gt $$limit; then \
-               echo "$@ exceeds file size limit:"; \
-               echo "  limit:  $$limit bytes"; \
-               echo "  actual: $$actual bytes"; \
-               echo "  excess: $$((actual - limit)) bytes"; \
+               echo "$@ exceeds file size limit:" >&2 ; \
+               echo "  limit:  $$limit bytes" >&2 ; \
+               echo "  actual: $$actual bytes" >&2 ; \
+               echo "  excess: $$((actual - limit)) bytes" >&2; \
                exit 1; \
        fi
 else
@@ -404,6 +408,7 @@ ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map
 ALL-$(CONFIG_NAND_U_BOOT) += $(obj)u-boot-nand.bin
 ALL-$(CONFIG_ONENAND_U_BOOT) += $(obj)u-boot-onenand.bin
 ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin
+ALL-$(CONFIG_SPL) += $(obj)$(subst ",,$(CONFIG_SPL_TARGET))
 ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin
 
 # enable combined SPL/u-boot/dtb rules for tegra
@@ -445,9 +450,18 @@ $(obj)u-boot.ldr.hex:      $(obj)u-boot.ldr
 $(obj)u-boot.ldr.srec: $(obj)u-boot.ldr
                $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary
 
+#
+# U-Boot entry point, needed for booting of full-blown U-Boot
+# from the SPL U-Boot version.
+#
+ifndef CONFIG_SYS_UBOOT_START
+CONFIG_SYS_UBOOT_START := 0
+endif
+
 $(obj)u-boot.img:      $(obj)u-boot.bin
                $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
-               -O u-boot -a $(CONFIG_SYS_TEXT_BASE) -e 0 \
+               -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \
+               -e $(CONFIG_SYS_UBOOT_START) \
                -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
                        sed -e 's/"[     ]*$$/ for $(BOARD) board"/') \
                -d $< $@
@@ -471,14 +485,15 @@ $(obj)u-boot.sha1:        $(obj)u-boot.bin
 $(obj)u-boot.dis:      $(obj)u-boot
                $(OBJDUMP) -d $< > $@
 
-$(obj)u-boot.ubl:       $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
+$(obj)u-boot-with-spl.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
                $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin
-               cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $(obj)u-boot-ubl.bin
-               $(obj)tools/mkimage -n $(UBL_CONFIG) -T ublimage \
-               -e $(CONFIG_SYS_TEXT_BASE) -d $(obj)u-boot-ubl.bin $(obj)u-boot.ubl
-               rm $(obj)u-boot-ubl.bin
+               cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $@
                rm $(obj)spl/u-boot-spl-pad.bin
 
+$(obj)u-boot.ubl:       $(obj)u-boot-with-spl.bin
+               $(obj)tools/mkimage -n $(UBL_CONFIG) -T ublimage \
+               -e $(CONFIG_SYS_TEXT_BASE) -d $< $(obj)u-boot.ubl
+
 $(obj)u-boot.ais:       $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
                $(obj)tools/mkimage -s -n $(if $(CONFIG_AIS_CONFIG_FILE),$(CONFIG_AIS_CONFIG_FILE),"/dev/null") \
                        -T aisimage \
@@ -529,6 +544,9 @@ $(obj)u-boot-$(nodtb)-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin $(dtb
                rm $(obj)spl/u-boot-spl-pad.bin
 endif
 
+$(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
+               cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@
+
 ifeq ($(CONFIG_SANDBOX),y)
 GEN_UBOOT = \
                cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
@@ -638,6 +656,16 @@ checkthumb:
                echo '*** Your board is configured for THUMB mode.'; \
                false; \
        fi
+
+# GCC 3.x is reported to have problems generating the type of relocation
+# that U-Boot wants.
+# See http://lists.denx.de/pipermail/u-boot/2012-September/135156.html
+checkgcc4:
+       @if test $(call cc-version) -lt 0400; then \
+               echo -n '*** Your GCC is too old, please upgrade to GCC 4.x or newer'; \
+               false; \
+       fi
+
 #
 # Auto-generate the autoconf.mk file (which is included by all makefiles)
 #
@@ -811,7 +839,7 @@ clean:
        @rm -f $(obj)include/generated/asm-offsets.h
        @rm -f $(obj)$(CPUDIR)/$(SOC)/asm-offsets.s
        @rm -f $(TIMESTAMP_FILE) $(VERSION_FILE)
-       @$(MAKE) -C doc/DocBook/ cleandocs
+       @$(MAKE) -s -C doc/DocBook/ cleandocs
        @find $(OBJTREE) -type f \
                \( -name 'core' -o -name '*.bak' -o -name '*~' -o -name '*.su' \
                -o -name '*.o'  -o -name '*.a' -o -name '*.exe' \) -print \
diff --git a/README b/README
index afdf591c623f6cfa5c507d6918e738dea12b2c79..5a86ae9c5f9188dd53a8b54ce3eb9554f2485f41 100644 (file)
--- a/README
+++ b/README
@@ -54,6 +54,11 @@ In case of problems see the CHANGELOG and CREDITS files to find out
 who contributed the specific port. The MAINTAINERS file lists board
 maintainers.
 
+Note: There is no CHANGELOG file in the actual U-Boot source tree;
+it can be created dynamically from the Git log using:
+
+       make CHANGELOG
+
 
 Where to get help:
 ==================
@@ -1409,6 +1414,13 @@ CBFS (Coreboot Filesystem) support
                boot.  See the documentation file README.video for a
                description of this variable.
 
+               CONFIG_VIDEO_VGA
+
+               Enable the VGA video / BIOS for x86. The alternative if you
+               are using coreboot is to use the coreboot frame buffer
+               driver.
+
+
 - Keyboard Support:
                CONFIG_KEYBOARD
 
@@ -1469,6 +1481,11 @@ CBFS (Coreboot Filesystem) support
                Normally display is black on white background; define
                CONFIG_SYS_WHITE_ON_BLACK to get it inverted.
 
+               CONFIG_LCD_BMP_RLE8
+
+               Support drawing of RLE8-compressed bitmaps on the LCD.
+
+
 - Splash Screen Support: CONFIG_SPLASH_SCREEN
 
                If this option is set, the environment is checked for
@@ -2195,6 +2212,14 @@ CBFS (Coreboot Filesystem) support
                        HERMES, IP860, RPXlite, LWMON,
                        FLAGADM, TQM8260
 
+- Access to physical memory region (> 4GB)
+               Some basic support is provided for operations on memory not
+               normally accessible to U-Boot - e.g. some architectures
+               support access to more than 4GB of memory on 32-bit
+               machines using physical address extension or similar.
+               Define CONFIG_PHYSMEM to access this basic support, which
+               currently only supports clearing the memory.
+
 - Error Recovery:
                CONFIG_PANIC_HANG
 
@@ -2597,6 +2622,17 @@ FIT uImage format:
  -150  common/cmd_nand.c       Incorrect FIT image format
   151  common/cmd_nand.c       FIT image format OK
 
+- FIT image support:
+               CONFIG_FIT
+               Enable support for the FIT uImage format.
+
+               CONFIG_FIT_BEST_MATCH
+               When no configuration is explicitly selected, default to the
+               one whose fdt's compatibility field best matches that of
+               U-Boot itself. A match is considered "best" if it matches the
+               most specific compatibility entry of U-Boot's fdt's root node.
+               The order of entries in the configuration's fdt is ignored.
+
 - Standalone program support:
                CONFIG_STANDALONE_LOAD_ADDR
 
@@ -2648,6 +2684,10 @@ FIT uImage format:
                CONFIG_SPL_TEXT_BASE
                TEXT_BASE for linking the SPL binary.
 
+               CONFIG_SPL_RELOC_TEXT_BASE
+               Address to relocate to.  If unspecified, this is equal to
+               CONFIG_SPL_TEXT_BASE (i.e. no relocation is done).
+
                CONFIG_SPL_BSS_START_ADDR
                Link address for the BSS within the SPL binary.
 
@@ -2657,6 +2697,11 @@ FIT uImage format:
                CONFIG_SPL_STACK
                Adress of the start of the stack SPL will use
 
+               CONFIG_SPL_RELOC_STACK
+               Adress of the start of the stack SPL will use after
+               relocation.  If unspecified, this is equal to
+               CONFIG_SPL_STACK.
+
                CONFIG_SYS_SPL_MALLOC_START
                Starting address of the malloc pool used in SPL.
 
@@ -2672,6 +2717,9 @@ FIT uImage format:
                For ARM, enable an optional function to print more information
                about the running system.
 
+               CONFIG_SPL_INIT_MINIMAL
+               Arch init code should be built for a very small image
+
                CONFIG_SPL_LIBCOMMON_SUPPORT
                Support for common/libcommon.o in SPL binary
 
@@ -2699,8 +2747,19 @@ FIT uImage format:
                CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
                Filename to read to load U-Boot when reading from FAT
 
+               CONFIG_SPL_NAND_BASE
+               Include nand_base.c in the SPL.  Requires
+               CONFIG_SPL_NAND_DRIVERS.
+
+               CONFIG_SPL_NAND_DRIVERS
+               SPL uses normal NAND drivers, not minimal drivers.
+
+               CONFIG_SPL_NAND_ECC
+               Include standard software ECC in the SPL
+
                CONFIG_SPL_NAND_SIMPLE
-               Support for drivers/mtd/nand/libnand.o in SPL binary
+               Support for NAND boot using simple NAND drivers that
+               expose the cmd_ctrl() interface.
 
                CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_COUNT,
                CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE,
@@ -2708,15 +2767,19 @@ FIT uImage format:
                CONFIG_SYS_NAND_ECCPOS, CONFIG_SYS_NAND_ECCSIZE,
                CONFIG_SYS_NAND_ECCBYTES
                Defines the size and behavior of the NAND that SPL uses
-               to read U-Boot with CONFIG_SPL_NAND_SIMPLE
+               to read U-Boot
 
                CONFIG_SYS_NAND_U_BOOT_OFFS
-               Location in NAND for CONFIG_SPL_NAND_SIMPLE to read U-Boot
-               from.
+               Location in NAND to read U-Boot from
+
+               CONFIG_SYS_NAND_U_BOOT_DST
+               Location in memory to load U-Boot to
+
+               CONFIG_SYS_NAND_U_BOOT_SIZE
+               Size of image to load
 
                CONFIG_SYS_NAND_U_BOOT_START
-               Location in memory for CONFIG_SPL_NAND_SIMPLE to load U-Boot
-               to.
+               Entry point in loaded image to jump to
 
                CONFIG_SYS_NAND_HW_ECC_OOBFIRST
                Define this if you need to first read the OOB and then the
@@ -2741,6 +2804,11 @@ FIT uImage format:
                CONFIG_SPL_LIBGENERIC_SUPPORT
                Support for lib/libgeneric.o in SPL binary
 
+               CONFIG_SPL_TARGET
+               Final target image containing SPL and payload.  Some SPLs
+               use an arch-specific makefile fragment instead, for
+               example if more than one image needs to be produced.
+
 Modem Support:
 --------------
 
@@ -3616,6 +3684,16 @@ Low Level (hardware related) configuration options:
                be used if available. These functions may be faster under some
                conditions but may increase the binary size.
 
+- CONFIG_X86_NO_RESET_VECTOR
+               If defined, the x86 reset vector code is excluded. You will need
+               to do this when U-Boot is running from Coreboot.
+
+- CONFIG_X86_NO_REAL_MODE
+               If defined, x86 real mode code is omitted. This assumes a
+               32-bit environment where such code is not needed. You will
+               need to do this when U-Boot is running from Coreboot.
+
+
 Freescale QE/FMAN Firmware Support:
 -----------------------------------
 
@@ -3843,6 +3921,7 @@ saveenv - save environment variables to persistent storage
 protect - enable or disable FLASH write protection
 erase  - erase FLASH memory
 flinfo - print FLASH memory information
+nand   - NAND memory operations (see doc/README.nand)
 bdinfo - print Board Info structure
 iminfo - print header information for application image
 coninfo - print console devices and informations
index e4c123cd21d614f3b2bee6a3aabf6a9e5288be56..da5bc731852c428078fe76fa484240096f62c6a0 100644 (file)
 #include <i2c.h>
 #include <miiphy.h>
 #include <cpsw.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
+#include <asm/omap_musb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -63,3 +68,83 @@ void setup_clocks_for_console(void)
        /* Not yet implemented */
        return;
 }
+
+/* AM33XX has two MUSB controllers which can be host or gadget */
+#if (defined(CONFIG_MUSB_GADGET) || defined(CONFIG_MUSB_HOST)) && \
+       (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1))
+static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
+/* USB 2.0 PHY Control */
+#define CM_PHY_PWRDN                   (1 << 0)
+#define CM_PHY_OTG_PWRDN               (1 << 1)
+#define OTGVDET_EN                     (1 << 19)
+#define OTGSESSENDEN                   (1 << 20)
+
+static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr)
+{
+       if (on) {
+               clrsetbits_le32(reg_addr, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN,
+                               OTGVDET_EN | OTGSESSENDEN);
+       } else {
+               clrsetbits_le32(reg_addr, 0, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN);
+       }
+}
+
+static struct musb_hdrc_config musb_config = {
+       .multipoint     = 1,
+       .dyn_fifo       = 1,
+       .num_eps        = 16,
+       .ram_bits       = 12,
+};
+
+#ifdef CONFIG_AM335X_USB0
+static void am33xx_otg0_set_phy_power(u8 on)
+{
+       am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0);
+}
+
+struct omap_musb_board_data otg0_board_data = {
+       .set_phy_power = am33xx_otg0_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg0_plat = {
+       .mode           = CONFIG_AM335X_USB0_MODE,
+       .config         = &musb_config,
+       .power          = 50,
+       .platform_ops   = &musb_dsps_ops,
+       .board_data     = &otg0_board_data,
+};
+#endif
+
+#ifdef CONFIG_AM335X_USB1
+static void am33xx_otg1_set_phy_power(u8 on)
+{
+       am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1);
+}
+
+struct omap_musb_board_data otg1_board_data = {
+       .set_phy_power = am33xx_otg1_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg1_plat = {
+       .mode           = CONFIG_AM335X_USB1_MODE,
+       .config         = &musb_config,
+       .power          = 50,
+       .platform_ops   = &musb_dsps_ops,
+       .board_data     = &otg1_board_data,
+};
+#endif
+#endif
+
+int arch_misc_init(void)
+{
+#ifdef CONFIG_AM335X_USB0
+       musb_register(&otg0_plat, &otg0_board_data,
+               (void *)AM335X_USB0_OTG_BASE);
+#endif
+#ifdef CONFIG_AM335X_USB1
+       musb_register(&otg1_plat, &otg1_board_data,
+               (void *)AM335X_USB1_OTG_BASE);
+#endif
+       return 0;
+}
index bc2abb657cf3d54a6dcc5fc4b2a7dd67b0131b33..0b4cb4e529e6c5301c7809890355e41d68fd5ece 100644 (file)
@@ -40,6 +40,7 @@
 #define CLK_MODE_MASK          0xfffffff8
 #define CLK_DIV_SEL            0xFFFFFFE0
 #define CPGMAC0_IDLE           0x30000
+#define DPLL_CLKDCOLDO_GATE_CTRL        0x300
 
 const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
 const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
@@ -194,6 +195,11 @@ static void enable_per_clocks(void)
        writel(PRCM_MOD_EN, &cmrtc->rtcclkctrl);
        while (readl(&cmrtc->rtcclkctrl) != PRCM_MOD_EN)
                ;
+
+       /* MUSB */
+       writel(PRCM_MOD_EN, &cmper->usb0clkctrl);
+       while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN)
+               ;
 }
 
 static void mpu_pll_config(void)
@@ -290,6 +296,8 @@ static void per_pll_config(void)
 
        while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
                ;
+
+       writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper);
 }
 
 void ddr_pll_config(unsigned int ddrpll_m)
index ac597be25aaebe8557057d86e7b8cd483ce0dade..de167eea56f5c43eb02a06cb3d3e98826672d3fc 100644 (file)
@@ -38,6 +38,7 @@ endif
 COBJS-$(CONFIG_DRIVER_TI_EMAC) += emac.o
 COBJS-$(CONFIG_EMIF4)  += emif4.o
 COBJS-$(CONFIG_SDRC)   += sdrc.o
+COBJS-$(CONFIG_USB_MUSB_AM35X) += am35x_musb.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
diff --git a/arch/arm/cpu/armv7/omap3/am35x_musb.c b/arch/arm/cpu/armv7/omap3/am35x_musb.c
new file mode 100644 (file)
index 0000000..7183c4f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * This file configures the internal USB PHY in AM35X.
+ *
+ * Copyright (C) 2012 Ilya Yanok <ilya.yanok@gmail.com>
+ *
+ * Based on omap_phy_internal.c code from Linux by
+ * Hema HK <hemahk@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.
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/am35x_def.h>
+
+void am35x_musb_reset(void)
+{
+       /* Reset the musb interface */
+       clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset,
+                       0, USBOTGSS_SW_RST);
+       clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset,
+                       USBOTGSS_SW_RST, 0);
+}
+
+void am35x_musb_phy_power(u8 on)
+{
+       unsigned long start = get_timer(0);
+
+       if (on) {
+               /*
+                * Start the on-chip PHY and its PLL.
+                */
+               clrsetbits_le32(&am35x_scm_general_regs->devconf2,
+                               CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN,
+                               CONF2_PHY_PLLON);
+
+               debug("Waiting for PHY clock good...\n");
+               while (!(readl(&am35x_scm_general_regs->devconf2)
+                               & CONF2_PHYCLKGD)) {
+
+                       if (get_timer(start) > CONFIG_SYS_HZ / 10) {
+                               printf("musb PHY clock good timed out\n");
+                               break;
+                       }
+               }
+       } else {
+               /*
+                * Power down the on-chip PHY.
+                */
+               clrsetbits_le32(&am35x_scm_general_regs->devconf2,
+                               CONF2_PHY_PLLON,
+                               CONF2_PHYPWRDN | CONF2_OTGPWRDN);
+       }
+}
+
+void am35x_musb_clear_irq(void)
+{
+       clrsetbits_le32(&am35x_scm_general_regs->lvl_intr_clr,
+                       0, USBOTGSS_INT_CLR);
+       readl(&am35x_scm_general_regs->lvl_intr_clr);
+}
+
index 819fd2f026900bf82491035b4e513fc9b84f8e46..d6c038e3aec225a46dd13af6ded8e59c1ed621e9 100644 (file)
@@ -82,7 +82,8 @@ struct cm_wkuppll {
        unsigned int clkseldpllcore;    /* offset 0x68 */
        unsigned int resv9[1];
        unsigned int idlestdpllper;     /* offset 0x70 */
-       unsigned int resv10[3];
+       unsigned int resv10[2];
+       unsigned int clkdcoldodpllper;  /* offset 0x7c */
        unsigned int divm4dpllcore;     /* offset 0x80 */
        unsigned int divm5dpllcore;     /* offset 0x84 */
        unsigned int clkmoddpllmpu;     /* offset 0x88 */
@@ -275,12 +276,16 @@ struct ctrl_stat {
 /* Control Device Register */
 struct ctrl_dev {
        unsigned int deviceid;          /* offset 0x00 */
-       unsigned int resv1[11];
+       unsigned int resv1[7];
+       unsigned int usb_ctrl0;         /* offset 0x20 */
+       unsigned int resv2;
+       unsigned int usb_ctrl1;         /* offset 0x28 */
+       unsigned int resv3;
        unsigned int macid0l;           /* offset 0x30 */
        unsigned int macid0h;           /* offset 0x34 */
        unsigned int macid1l;           /* offset 0x38 */
        unsigned int macid1h;           /* offset 0x3c */
-       unsigned int resv2[4];
+       unsigned int resv4[4];
        unsigned int miisel;            /* offset 0x50 */
 };
 #endif /* __ASSEMBLY__ */
index 5bd4bc8722016e04c86fe0e4b33daeafaa1d9454..24ab365ea31ebdfa6faeb4a07defd197e59a40f9 100644 (file)
@@ -87,4 +87,8 @@
 /* RTC base address */
 #define AM335X_RTC_BASE                        0x44E3E000
 
+/* OTG */
+#define AM335X_USB0_OTG_BASE           0x47401000
+#define AM335X_USB1_OTG_BASE           0x47401800
+
 #endif /* __AM33XX_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h
new file mode 100644 (file)
index 0000000..8acdf9b
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * (C) Copyright 2012 SAMSUNG Electronics
+ * Jaehoon Chung <jh80.chung@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
+ *
+ */
+
+#define DWMCI_CLKSEL           0x09C
+#define DWMCI_SHIFT_0          0x0
+#define DWMCI_SHIFT_1          0x1
+#define DWMCI_SHIFT_2          0x2
+#define DWMCI_SHIFT_3          0x3
+#define DWMCI_SET_SAMPLE_CLK(x)        (x)
+#define DWMCI_SET_DRV_CLK(x)   ((x) << 16)
+#define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
+
+int exynos_dwmci_init(u32 regbase, int bus_width, int index);
+
+static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
+{
+       unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
+       return exynos_dwmci_init(base, bus_width, index);
+}
index bbaf1bc97b5b779afaf9ba75a2cf0fc387807c99..67698bc7ef88ba2ba2940a30b8b784d7a921bd16 100644 (file)
 #ifndef __KERNEL_STRICT_NAMES
 #ifndef __ASSEMBLY__
 
+/* LVL_INTR_CLEAR bits */
+#define USBOTGSS_INT_CLR       (1 << 4)
+
 /* IP_SW_RESET bits */
+#define USBOTGSS_SW_RST                (1 << 0)        /* reset USBOTG */
 #define CPGMACSS_SW_RST                (1 << 1)        /* reset CPGMAC */
 
+/* DEVCONF2 bits */
+#define CONF2_PHY_GPIOMODE     (1 << 23)
+#define CONF2_OTGMODE          (3 << 14)
+#define CONF2_NO_OVERRIDE      (0 << 14)
+#define CONF2_FORCE_HOST       (1 << 14)
+#define CONF2_FORCE_DEVICE     (2 << 14)
+#define CONF2_FORCE_HOST_VBUS_LOW (3 << 14)
+#define CONF2_SESENDEN         (1 << 13)
+#define CONF2_VBDTCTEN         (1 << 12)
+#define CONF2_REFFREQ_24MHZ    (2 << 8)
+#define CONF2_REFFREQ_26MHZ    (7 << 8)
+#define CONF2_REFFREQ_13MHZ    (6 << 8)
+#define CONF2_REFFREQ          (0xf << 8)
+#define CONF2_PHYCLKGD         (1 << 7)
+#define CONF2_VBUSSENSE                (1 << 6)
+#define CONF2_PHY_PLLON                (1 << 5)
+#define CONF2_RESET            (1 << 4)
+#define CONF2_PHYPWRDN         (1 << 3)
+#define CONF2_OTGPWRDN         (1 << 2)
+#define CONF2_DATPOL           (1 << 1)
+
 /* General register mappings of system control module */
 #define AM35X_SCM_GEN_BASE     0x48002270
 struct am35x_scm_general {
@@ -49,6 +74,8 @@ struct am35x_scm_general {
 };
 #define am35x_scm_general_regs ((struct am35x_scm_general *)AM35X_SCM_GEN_BASE)
 
+#define AM35XX_IPSS_USBOTGSS_BASE      0x5C040000
+
 #endif /*__ASSEMBLY__ */
 #endif /* __KERNEL_STRICT_NAMES */
 
similarity index 56%
rename from board/chromebook-x86/coreboot/coreboot_start16.S
rename to arch/arm/include/asm/arch-omap3/musb.h
index 9ad06df8bc643a411179adeb1e7e3bca71b2c76b..423ac500f4ee5a04d62be96b81e5f202338b448b 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * Copyright (c) 2011 The Chromium OS Authors.
- * (C) Copyright 2008
- * Graeme Russ, graeme.russ@gmail.com.
+ * (C) Copyright 2012
+ * Ilya Yanok, <ilya.yanok@gmail.com>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
  * 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
+ * Foundation, Inc.
  */
 
-/*
- * 16bit initialization code.
- * This code have to map the area of the boot flash
- * that is used by U-boot to its final destination.
- */
-
-.text
-.section .start16, "ax"
-.code16
-.globl board_init16
-board_init16:
-       jmp     board_init16_ret
-
-.section .bios, "ax"
-.code16
-.globl realmode_reset
-.hidden realmode_reset
-.type realmode_reset, @function
-realmode_reset:
-
-1:     hlt
-       jmp     1
+#ifndef __ASM_ARCH_OMAP3_MUSB_H
+#define __ASM_ARCH_OMAP3_MUSB_H
+extern void am35x_musb_reset(void);
+extern void am35x_musb_phy_power(u8 on);
+extern void am35x_musb_clear_irq(void);
+#endif
diff --git a/arch/arm/include/asm/imx-common/mx5_video.h b/arch/arm/include/asm/imx-common/mx5_video.h
new file mode 100644 (file)
index 0000000..e54c25a
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012
+ * Anatolij Gustschin, DENX Software Engineering, <agust@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.
+ */
+#ifndef __MX5_VIDEO_H
+#define __MX5_VIDEO_H
+
+#ifdef CONFIG_VIDEO
+void lcd_enable(void);
+void setup_iomux_lcd(void);
+#else
+static inline void lcd_enable(void) { }
+static inline void setup_iomux_lcd(void) { }
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/omap_musb.h b/arch/arm/include/asm/omap_musb.h
new file mode 100644 (file)
index 0000000..b04d865
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Board data structure for musb gadget on OMAPs
+ *
+ * Copyright (C) 2012, Ilya Yanok <ilya.yanok@gmail.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 __ASM_ARM_OMAP_MUSB_H
+#define __ASM_ARM_OMAP_MUSB_H
+
+extern struct musb_platform_ops musb_dsps_ops;
+extern const struct musb_platform_ops am35x_ops;
+extern const struct musb_platform_ops omap2430_ops;
+
+struct omap_musb_board_data {
+       u8 interface_type;
+       void (*set_phy_power)(u8 on);
+       void (*clear_irq)(void);
+       void (*reset)(void);
+};
+
+enum musb_interface    {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
+#endif /* __ASM_ARM_OMAP_MUSB_H */
index 92cad9a6eb1a8c2f0b71ad7d6c19bb61780fc383..22a4d9cc0e59d4c877fb8892e2f960b0cad32843 100644 (file)
@@ -224,6 +224,13 @@ int __arch_cpu_init(void)
 int arch_cpu_init(void)
        __attribute__((weak, alias("__arch_cpu_init")));
 
+int __power_init_board(void)
+{
+       return 0;
+}
+int power_init_board(void)
+       __attribute__((weak, alias("__power_init_board")));
+
 init_fnc_t *init_sequence[] = {
        arch_cpu_init,          /* basic arch cpu dependent setup */
 
@@ -525,6 +532,7 @@ void board_init_r(gd_t *id, ulong dest_addr)
 #ifdef CONFIG_ARCH_EARLY_INIT_R
        arch_early_init_r();
 #endif
+       power_init_board();
 
 #if !defined(CONFIG_SYS_NO_FLASH)
        puts("Flash: ");
index c747767e1e2c9469fa226c14d5557dacc6c7644e..b9b0998d48f199e74511e06f72733719f0771907 100644 (file)
@@ -615,7 +615,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
                        | usb_pipeendpoint (pipe) << 7
                        | (usb_pipeisoc (pipe)? 0x8000: 0)
                        | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
-                       | usb_pipeslow (pipe) << 13
+                       | (usb_dev->speed == USB_SPEED_LOW) << 13
                        | usb_maxpacket (usb_dev, pipe) << 16);
 
        return ed_ret;
index 350896a2a5657e4cd08b2ab428fd6b1ce1e1ef1e..09fc842b502cd6dc18647ffb646aafbcd5874a95 100644 (file)
@@ -36,7 +36,6 @@ static unsigned long timestamp;
 int timer_init(void)
 {
        /* Set up the timer for the first expiration. */
-       timestamp = 0;
        write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
 
        return 0;
index 51542808dd6a48c604dc0eaf3c33826e5b253b65..720f7b7f8cbada89007fbea88a93283b4e4a2d1e 100644 (file)
@@ -37,7 +37,6 @@ static unsigned long timestamp;
 int timer_init(void)
 {
        /* Set up the timer for the first expiration. */
-       timestamp = 0;
        write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
 
        return 0;
index a30715459de952a543cd85d6fe21eac74260ac0c..b7062818bbf45c458ebf34c713eedaefa7939c06 100644 (file)
@@ -42,3 +42,8 @@ endif
 ifeq ($(CROSS_COMPILE),powerpc-openbsd-)
 PLATFORM_CPPFLAGS+= -D__PPC__
 endif
+
+# Only test once
+ifneq ($(CONFIG_SPL_BUILD),y)
+ALL-y += checkgcc4
+endif
index 1a088b77bc54c9d836f9b1cb8a504753dae1d255..8de2c13598be98774ce78a0f333b8d410c7275fb 100644 (file)
@@ -41,6 +41,10 @@ COBJS-y += speed.o
 COBJS-$(CONFIG_CMD_USB) += usb_ohci.o
 COBJS-$(CONFIG_CMD_USB) += usb.o
 
+ifdef CONFIG_SPL_BUILD
+COBJS-y += spl_boot.o
+endif
+
 SRCS   := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
 START  := $(addprefix $(obj),$(SSTART) $(CSTART))
diff --git a/arch/powerpc/cpu/mpc5xxx/spl_boot.c b/arch/powerpc/cpu/mpc5xxx/spl_boot.c
new file mode 100644 (file)
index 0000000..9f14127
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 Stefan Roese <sr@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.
+ */
+
+#include <common.h>
+#include <spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Needed to align size SPL image to a 4-byte length
+ */
+u32 end_align __attribute__ ((section(".end_align")));
+
+/*
+ * Return selected boot device. On MPC5200 its only NOR flash right now.
+ */
+u32 spl_boot_device(void)
+{
+       return BOOT_DEVICE_NOR;
+}
+
+/*
+ * SPL version of board_init_f()
+ */
+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
+        */
+       initdram(0);
+
+       /* Clear bss */
+       memset(__bss_start, '\0', __bss_end__ - __bss_start);
+
+       /*
+        * Init global_data pointer. Has to be done before calling
+        * get_clocks(), as it stores some clock values into gd needed
+        * later on in the serial driver.
+        */
+       /* Pointer is writable since we allocated a register for it */
+       gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
+       /* Clear initial global data */
+       memset((void *)gd, 0, sizeof(gd_t));
+
+       /*
+        * get_clocks() needs to be called so that the serial driver
+        * works correctly
+        */
+       get_clocks();
+
+       /*
+        * Do rudimental console / serial setup
+        */
+       preloader_console_init();
+
+       /*
+        * Call board_init_r() (SPL framework version) to load and boot
+        * real U-Boot or OS
+        */
+       board_init_r(NULL, 0);
+       /* Does not return!!! */
+}
index 51cc4e2a105e3b16cca80c277fffab3ddc8f6ede..ad5bc0a17947ed7261a1c1b3243510cf6dd97d30 100644 (file)
@@ -50,6 +50,7 @@
 #define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
 #endif
 
+#ifndef CONFIG_SPL_BUILD
 /*
  * Set up GOT: Global Offset Table
  *
@@ -68,6 +69,7 @@
        GOT_ENTRY(__bss_end__)
        GOT_ENTRY(__bss_start)
        END_GOT
+#endif
 
 /*
  * Version string
@@ -84,6 +86,18 @@ version_string:
        . = EXC_OFF_SYS_RESET
        .globl  _start
 _start:
+
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+       /*
+        * This is the entry of the real U-Boot from a board port
+        * that supports SPL booting on the MPC5200. We only need
+        * to call board_init_f() here. Everything else has already
+        * been done in the SPL u-boot version.
+        */
+       GET_GOT                 /* initialize GOT access                */
+       bl      board_init_f    /* run 1st part of board init code (in Flash)*/
+       /* NOTREACHED - board_init_f() does not return */
+#else
        mfmsr   r5                      /* save msr contents            */
 
        /* Move CSBoot and adjust instruction pointer                   */
@@ -152,7 +166,9 @@ lowboot_reentry:
        /* Be careful to keep code relocatable !                        */
        /*--------------------------------------------------------------*/
 
+#ifndef CONFIG_SPL_BUILD
        GET_GOT                 /* initialize GOT access                */
+#endif
 
        /* r3: IMMR */
        bl      cpu_init_f      /* run low-level CPU init code (in Flash)*/
@@ -160,7 +176,9 @@ lowboot_reentry:
        bl      board_init_f    /* run 1st part of board init code (in Flash)*/
 
        /* NOTREACHED - board_init_f() does not return */
+#endif
 
+#ifndef CONFIG_SPL_BUILD
 /*
  * Vector Table
  */
@@ -333,6 +351,7 @@ int_return:
        lwz     r1,GPR1(r1)
        SYNC
        rfi
+#endif /* CONFIG_SPL_BUILD */
 
 /*
  * This code initialises the MPC5xxx processor core
@@ -522,6 +541,7 @@ get_pvr:
        mfspr   r3, PVR
        blr
 
+#ifndef CONFIG_SPL_BUILD
 /*------------------------------------------------------------------------------*/
 
 /*
@@ -759,3 +779,5 @@ trap_init:
 
        mtlr    r4                      /* restore link register    */
        blr
+
+#endif /* CONFIG_SPL_BUILD */
diff --git a/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds b/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds
new file mode 100644 (file)
index 0000000..cab9b92
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 Stefan Roese <sr@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
+ */
+
+MEMORY
+{
+       sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
+               LENGTH = CONFIG_SPL_BSS_MAX_SIZE
+       flash : ORIGIN = CONFIG_SPL_TEXT_BASE,
+               LENGTH = CONFIG_SYS_SPL_MAX_LEN
+}
+
+OUTPUT_ARCH(powerpc)
+ENTRY(_start)
+SECTIONS
+{
+       .text :
+       {
+               __start = .;
+               arch/powerpc/cpu/mpc5xxx/start.o        (.text)
+               *(.text*)
+       } > flash
+
+       . = ALIGN(4);
+       .data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash
+
+       . = ALIGN(4);
+       .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash
+
+       . = ALIGN(4);
+       .end_align : { *(.end_align*) } > flash
+       __spl_flash_end = .;
+
+       .bss :
+       {
+               . = ALIGN(4);
+               __bss_start = .;
+               *(.bss*)
+               . = ALIGN(4);
+               __bss_end__ = .;
+       } > sdram
+}
index 607034b7c652d673446d39c2f30376edc5f475a0..de07343d93fc9c45cd6e7a0f577cd3b019562ae7 100644 (file)
@@ -618,7 +618,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
                        | usb_pipeendpoint (pipe) << 7
                        | (usb_pipeisoc (pipe)? 0x8000: 0)
                        | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
-                       | usb_pipeslow (pipe) << 13
+                       | (usb_dev->speed == USB_SPEED_LOW) << 13
                        | usb_maxpacket (usb_dev, pipe) << 16);
 
        return ed_ret;
index 78c412d9f31b7e6927fce5ca2651e128ddf55958..4c2b1040d4613317b2365ddce77bdf23ffc21493 100644 (file)
@@ -28,7 +28,22 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(CPU).o
 
-START  = start.o resetvec.o
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+START = start.o resetvec.o
+
+ifdef MINIMAL
+
+COBJS-y        += cpu_init_early.o tlb.o spl_minimal.o
+
+else
+
 SOBJS-$(CONFIG_MP)     += release.o
 SOBJS  = $(SOBJS-y)
 
@@ -121,17 +136,20 @@ COBJS-$(CONFIG_PPC_P5040) += p5040_serdes.o
 COBJS-$(CONFIG_PPC_T4240) += t4240_serdes.o
 COBJS-$(CONFIG_PPC_B4860) += b4860_serdes.o
 
-COBJS  = $(COBJS-y)
-COBJS  += cpu.o
-COBJS  += cpu_init.o
-COBJS  += cpu_init_early.o
-COBJS  += interrupts.o
-COBJS  += speed.o
-COBJS  += tlb.o
-COBJS  += traps.o
+COBJS-y        += cpu.o
+COBJS-y        += cpu_init.o
+COBJS-y        += cpu_init_early.o
+COBJS-y        += interrupts.o
+COBJS-y        += speed.o
+COBJS-y        += tlb.o
+COBJS-y        += traps.o
 
 # Stub implementations of cache management functions for USB
-COBJS += cache.o
+COBJS-y += cache.o
+
+endif # not minimal
+
+COBJS  = $(COBJS-y)
 
 SRCS   := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
index 2be192d578f5ae46818451c459b23203b974d38a..e5ecf5dae59d2384cdf671a58fc49a4a66a7e457 100644 (file)
 #include <command.h>
 #include <linux/compiler.h>
 #include <asm/processor.h>
+#include "fsl_corenet_serdes.h"
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A004849
+/*
+ * This work-around is implemented in PBI, so just check to see if the
+ * work-around was actually applied.  To do this, we check for specific data
+ * at specific addresses in DCSR.
+ *
+ * Array offsets[] contains a list of offsets within DCSR.  According to the
+ * erratum document, the value at each offset should be 2.
+ */
+static void check_erratum_a4849(uint32_t svr)
+{
+       void __iomem *dcsr = (void *)CONFIG_SYS_DCSRBAR + 0xb0000;
+       unsigned int i;
+
+#if defined(CONFIG_PPC_P2041) || defined(CONFIG_PPC_P3041)
+       static const uint8_t offsets[] = {
+               0x50, 0x54, 0x58, 0x90, 0x94, 0x98
+       };
+#endif
+#ifdef CONFIG_PPC_P4080
+       static const uint8_t offsets[] = {
+               0x60, 0x64, 0x68, 0x6c, 0xa0, 0xa4, 0xa8, 0xac
+       };
+#endif
+       uint32_t x108; /* The value that should be at offset 0x108 */
+
+       for (i = 0; i < ARRAY_SIZE(offsets); i++) {
+               if (in_be32(dcsr + offsets[i]) != 2) {
+                       printf("Work-around for Erratum A004849 is not enabled\n");
+                       return;
+               }
+       }
+
+#if defined(CONFIG_PPC_P2041) || defined(CONFIG_PPC_P3041)
+       x108 = 0x12;
+#endif
+
+#ifdef CONFIG_PPC_P4080
+       /*
+        * For P4080, the erratum document says that the value at offset 0x108
+        * should be 0x12 on rev2, or 0x1c on rev3.
+        */
+       if (SVR_MAJ(svr) == 2)
+               x108 = 0x12;
+       if (SVR_MAJ(svr) == 3)
+               x108 = 0x1c;
+#endif
+
+       if (in_be32(dcsr + 0x108) != x108) {
+               printf("Work-around for Erratum A004849 is not enabled\n");
+               return;
+       }
+
+       /* Everything matches, so the erratum work-around was applied */
+
+       printf("Work-around for Erratum A004849 enabled\n");
+}
+#endif
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A004580
+/*
+ * This work-around is implemented in PBI, so just check to see if the
+ * work-around was actually applied.  To do this, we check for specific data
+ * at specific addresses in the SerDes register block.
+ *
+ * The work-around says that for each SerDes lane, write BnTTLCRy0 =
+ * 0x1B00_0001, Register 2 = 0x0088_0000, and Register 3 = 0x4000_0000.
+
+ */
+static void check_erratum_a4580(uint32_t svr)
+{
+       const serdes_corenet_t __iomem *srds_regs =
+               (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
+       unsigned int lane;
+
+       for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
+               if (serdes_lane_enabled(lane)) {
+                       const struct serdes_lane __iomem *srds_lane =
+                               &srds_regs->lane[serdes_get_lane_idx(lane)];
+
+                       /*
+                        * Verify that the values we were supposed to write in
+                        * the PBI are actually there.  Also, the lower 15
+                        * bits of res4[3] should be the same as the upper 15
+                        * bits of res4[1].
+                        */
+                       if ((in_be32(&srds_lane->ttlcr0) != 0x1b000001) ||
+                           (in_be32(&srds_lane->res4[1]) != 0x880000) ||
+                           (in_be32(&srds_lane->res4[3]) != 0x40000044)) {
+                               printf("Work-around for Erratum A004580 is "
+                                      "not enabled\n");
+                               return;
+                       }
+               }
+       }
+
+       /* Everything matches, so the erratum work-around was applied */
+
+       printf("Work-around for Erratum A004580 enabled\n");
+}
+#endif
 
 static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -136,6 +239,17 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #endif
 #ifdef CONFIG_SYS_FSL_ERRATUM_A_004934
        puts("Work-around for Erratum A004934 enabled\n");
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A004849
+       /* This work-around is implemented in PBI, so just check for it */
+       check_erratum_a4849(svr);
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A004580
+       /* This work-around is implemented in PBI, so just check for it */
+       check_erratum_a4580(svr);
+#endif
+#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
+       puts("Work-around for Erratum PCIe-A003 enabled\n");
 #endif
        return 0;
 }
index db232e64f841aac58a7a8d6357aaeb695c6a20a5..9b9832cfc3363b71d53893f85a7e90b8fbd46895 100644 (file)
@@ -332,7 +332,8 @@ void mpc85xx_reginfo(void)
 
 /* Common ddr init for non-corenet fsl 85xx platforms */
 #ifndef CONFIG_FSL_CORENET
-#if defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SYS_INIT_L2_ADDR)
+#if (defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)) && \
+       !defined(CONFIG_SYS_INIT_L2_ADDR)
 phys_size_t initdram(int board_type)
 {
 #if defined(CONFIG_SPD_EEPROM) || defined(CONFIG_DDR_SPD)
@@ -450,21 +451,21 @@ static void dump_spd_ddr_reg(void)
        for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
                switch (i) {
                case 0:
-                       ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+                       ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
                        break;
-#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+#if defined(CONFIG_SYS_MPC8xxx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
                case 1:
-                       ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
+                       ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR2_ADDR;
                        break;
 #endif
-#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+#if defined(CONFIG_SYS_MPC8xxx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
                case 2:
-                       ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
+                       ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR3_ADDR;
                        break;
 #endif
-#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+#if defined(CONFIG_SYS_MPC8xxx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
                case 3:
-                       ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR;
+                       ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR4_ADDR;
                        break;
 #endif
                default:
index f01804bbb9984228a0d8c0ee2f21e2e53343383d..d1155e81263e8d948144cb1d84a3098e3c41f161 100644 (file)
@@ -350,6 +350,10 @@ int cpu_init_r(void)
 #elif defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2)
        struct ccsr_cluster_l2 * l2cache = (void __iomem *)CONFIG_SYS_FSL_CLUSTER_1_L2;
 #endif
+#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
+       extern int spin_table_compat;
+       const char *spin;
+#endif
 
 #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \
        defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011)
@@ -395,6 +399,14 @@ int cpu_init_r(void)
        }
 #endif
 
+#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
+       spin = getenv("spin_table_compat");
+       if (spin && (*spin == 'n'))
+               spin_table_compat = 0;
+       else
+               spin_table_compat = 1;
+#endif
+
        puts ("L2:    ");
 
 #if defined(CONFIG_L2_CACHE)
@@ -470,7 +482,7 @@ int cpu_init_r(void)
                                && l2srbar >= CONFIG_SYS_FLASH_BASE) {
                        l2srbar = CONFIG_SYS_INIT_L2_ADDR;
                        l2cache->l2srbar0 = l2srbar;
-                       printf("moving to 0x%08x", CONFIG_SYS_INIT_L2_ADDR);
+                       printf("moving to 0x%08x", CONFIG_SYS_INIT_L2_ADDR);
                }
 #endif /* CONFIG_SYS_INIT_L2_ADDR */
                puts("\n");
index 54437dd0cbd3e5b7ff5978738ba239fb1b6c2979..8a86819fb52ab0010cd1975af4e36328fada5761 100644 (file)
@@ -18,7 +18,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
                             unsigned int ctrl_num)
 {
        unsigned int i;
-       volatile ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+       volatile ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
 
        if (ctrl_num != 0) {
                printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
@@ -73,7 +73,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 void
 ddr_enable_ecc(unsigned int dram_size)
 {
-       volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
+       volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC8xxx_DDR_ADDR);
 
        dma_meminit(CONFIG_MEM_INIT_VALUE, dram_size);
 
index 49000a19e832f2ad9d72080f91e1bc8c0de8f54d..a7058625227bdcaa333731b8c5785b779c0299e2 100644 (file)
@@ -19,14 +19,11 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
                             unsigned int ctrl_num)
 {
        unsigned int i;
-#ifdef CONFIG_MPC83xx
-       ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC83xx_DDR_ADDR;
-#else
-       ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
-#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120
+       ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
+
+#if defined(CONFIG_SYS_FSL_ERRATUM_NMG_DDR120) && defined(CONFIG_MPC85xx)
        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
        uint svr;
-#endif
 #endif
 
        if (ctrl_num) {
index f118dd5daf0a08e3fc3994951844217457cc6db7..ef0dd1da64ccb5a2f0e211dfbbd5000747b8a1b4 100644 (file)
@@ -32,21 +32,21 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 
        switch (ctrl_num) {
        case 0:
-               ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+               ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
                break;
-#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+#if defined(CONFIG_SYS_MPC8xxx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
        case 1:
-               ddr = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
+               ddr = (void *)CONFIG_SYS_MPC8xxx_DDR2_ADDR;
                break;
 #endif
-#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+#if defined(CONFIG_SYS_MPC8xxx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
        case 2:
-               ddr = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
+               ddr = (void *)CONFIG_SYS_MPC8xxx_DDR3_ADDR;
                break;
 #endif
-#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+#if defined(CONFIG_SYS_MPC8xxx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
        case 3:
-               ddr = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR;
+               ddr = (void *)CONFIG_SYS_MPC8xxx_DDR4_ADDR;
                break;
 #endif
        default:
index 7f466ac6a94f2cb38796544d298eb947300aec5a..5495dc59eef868aaa3d90af882c6df23ae506646 100644 (file)
@@ -714,9 +714,13 @@ void fsl_serdes_init(void)
 
 #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
                /*
-                * Set BnTTLCRy0[FLT_SEL] = 000011 and set BnTTLCRy0[17] = 1 for
-                * each of the SerDes lanes selected as SGMII, XAUI, SRIO, or
-                * AURORA before the device is initialized.
+                * Set BnTTLCRy0[FLT_SEL] = 011011 and set BnTTLCRy0[31] = 1
+                * for each of the SerDes lanes selected as SGMII, XAUI, SRIO,
+                * or AURORA before the device is initialized.
+                *
+                * Note that this part of the SERDES-9 work-around is
+                * redundant if the work-around for A-4580 has already been
+                * applied via PBI.
                 */
                switch (lane_prtcl) {
                case SGMII_FM1_DTSEC1:
@@ -733,10 +737,12 @@ void fsl_serdes_init(void)
                case SRIO1:
                case SRIO2:
                case AURORA:
-                       clrsetbits_be32(&srds_regs->lane[idx].ttlcr0,
-                                       SRDS_TTLCR0_FLT_SEL_MASK,
-                                       SRDS_TTLCR0_FLT_SEL_750PPM |
-                                       SRDS_TTLCR0_PM_DIS);
+                       out_be32(&srds_regs->lane[idx].ttlcr0,
+                                SRDS_TTLCR0_FLT_SEL_KFR_26 |
+                                SRDS_TTLCR0_FLT_SEL_KPH_28 |
+                                SRDS_TTLCR0_FLT_SEL_750PPM |
+                                SRDS_TTLCR0_FREQOVD_EN);
+                       break;
                default:
                        break;
                }
index 4ba44a9028b0e98e912a1a6a7e039329dc5c8489..5c4b1e3b754648c96b1d7eabe8c1d7bfc7fb3295 100644 (file)
@@ -351,7 +351,13 @@ __secondary_reset_vector:
        .align L1_CACHE_SHIFT
        .global __second_half_boot_page
 __second_half_boot_page:
-#define EPAPR_MAGIC            0x45504150
+#ifdef CONFIG_PPC_SPINTABLE_COMPATIBLE
+       lis     r3,(spin_table_compat - __second_half_boot_page)@h
+       ori     r3,r3,(spin_table_compat - __second_half_boot_page)@l
+       add     r3,r3,r11 /* r11 has the address of __second_half_boot_page */
+       lwz     r14,0(r3)
+#endif
+
 #define ENTRY_ADDR_UPPER       0
 #define ENTRY_ADDR_LOWER       4
 #define ENTRY_R3_UPPER         8
@@ -383,7 +389,24 @@ __second_half_boot_page:
        stw     r8,ENTRY_ADDR_LOWER(r10)
 
        /* spin waiting for addr */
-3:     lwz     r4,ENTRY_ADDR_LOWER(r10)
+3:
+/*
+ * To comply with ePAPR 1.1, the spin table has been moved to cache-enabled
+ * memory. Old OS may not work with this change. A patch is waiting to be
+ * accepted for Linux kernel. Other OS needs similar fix to spin table.
+ * For OSes with old spin table code, we can enable this temporary fix by
+ * setting environmental variable "spin_table_compat". For new OSes, set
+ * "spin_table_compat=no". After Linux is fixed, we can remove this macro
+ * and related code. For now, it is enabled by default.
+ */
+#ifdef CONFIG_PPC_SPINTABLE_COMPATIBLE
+       cmpwi   r14,0
+       beq     4f
+       dcbf    0, r10
+       sync
+4:
+#endif
+       lwz     r4,ENTRY_ADDR_LOWER(r10)
        andi.   r11,r4,1
        bne     3b
        isync
@@ -460,5 +483,14 @@ __second_half_boot_page:
        .globl __spin_table
 __spin_table:
        .space CONFIG_MAX_CPUS*ENTRY_SIZE
+
+#ifdef CONFIG_PPC_SPINTABLE_COMPATIBLE
+       .align L1_CACHE_SHIFT
+       .global spin_table_compat
+spin_table_compat:
+       .long   1
+
+#endif
+
 __spin_table_end:
        .space 4096 - (__spin_table_end - __spin_table)
similarity index 76%
rename from arch/powerpc/cpu/mpc85xx/cpu_init_nand.c
rename to arch/powerpc/cpu/mpc85xx/spl_minimal.c
index bf7a6f6be69cf8bebaa79e137b77a93ffc871f82..c6b9cd0accf2c07383bc1869c09177335f0ba0cf 100644 (file)
  */
 
 #include <common.h>
+#include <asm/processor.h>
+#include <asm/global_data.h>
 #include <asm/fsl_ifc.h>
 #include <asm/io.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 void cpu_init_f(void)
 {
-#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L2_ADDR)
+#ifdef CONFIG_SYS_INIT_L2_ADDR
        ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR;
 
        out_be32(&l2cache->l2srbar0, CONFIG_SYS_INIT_L2_ADDR);
@@ -40,3 +44,16 @@ void cpu_init_f(void)
                (MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2SRAM_ENTIRE));
 #endif
 }
+
+#ifndef CONFIG_SYS_FSL_TBCLK_DIV
+#define CONFIG_SYS_FSL_TBCLK_DIV 8
+#endif
+
+void udelay(unsigned long usec)
+{
+       u32 ticks_per_usec = gd->bus_clk / (CONFIG_SYS_FSL_TBCLK_DIV * 1000000);
+       u32 ticks = ticks_per_usec * usec;
+       u32 s = mfspr(SPRN_TBRL);
+
+       while ((mfspr(SPRN_TBRL) - s) < ticks);
+}
index ac17f9d3caa12da4e4326b0bb3119d8ce3695fea..bb0dc1a653e193fb1f141e13ede0980f0c075198 100644 (file)
 #undef MSR_KERNEL
 #define MSR_KERNEL ( MSR_ME )  /* Machine Check */
 
+#if defined(CONFIG_NAND_SPL) || \
+       (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_INIT_MINIMAL))
+#define MINIMAL_SPL
+#endif
+
+#if !defined(CONFIG_SPL) && !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT)
+#define NOR_BOOT
+#endif
+
 /*
  * Set up GOT: Global Offset Table
  *
@@ -53,7 +62,7 @@
        GOT_ENTRY(_GOT2_TABLE_)
        GOT_ENTRY(_FIXUP_TABLE_)
 
-#ifndef CONFIG_NAND_SPL
+#ifndef MINIMAL_SPL
        GOT_ENTRY(_start)
        GOT_ENTRY(_start_of_vectors)
        GOT_ENTRY(_end_of_vectors)
@@ -282,51 +291,8 @@ l2_disabled:
        isync
        .endm
 
-#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_NAND_SPL)
-/*
- * TLB entry for debuggging in AS1
- * Create temporary TLB entry in AS0 to handle debug exception
- * As on debug exception MSR is cleared i.e. Address space is changed
- * to 0. A TLB entry (in AS0) is required to handle debug exception generated
- * in AS1.
- */
-
-#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT)
-/*
- * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
- * bacause flash's virtual address maps to 0xff800000 - 0xffffffff.
- * and this window is outside of 4K boot window.
- */
-       create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
-               0, BOOKE_PAGESZ_4M, \
-               CONFIG_SYS_MONITOR_BASE & 0xffc00000,  MAS2_I|MAS2_G, \
-               0xffc00000, MAS3_SX|MAS3_SW|MAS3_SR, \
-               0, r6
-
-#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT)
-       create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
-               0, BOOKE_PAGESZ_1M, \
-               CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \
-               CONFIG_SYS_PBI_FLASH_WINDOW, MAS3_SX|MAS3_SW|MAS3_SR, \
-               0, r6
-#else
-/*
- * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
- * because "nexti" will resize TLB to 4K
- */
-       create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
-               0, BOOKE_PAGESZ_256K, \
-               CONFIG_SYS_MONITOR_BASE, MAS2_I, \
-               CONFIG_SYS_MONITOR_BASE, MAS3_SX|MAS3_SW|MAS3_SR, \
-               0, r6
-#endif
-#endif
-
-/*
- * Ne need to setup interrupt vector for NAND SPL
- * because NAND SPL never compiles it.
- */
-#if !defined(CONFIG_NAND_SPL)
+/* Interrupt vectors do not fit in minimal SPL. */
+#if !defined(MINIMAL_SPL)
        /* Setup interrupt vectors */
        lis     r1,CONFIG_SYS_MONITOR_BASE@h
        mtspr   IVPR,r1
@@ -534,10 +500,6 @@ nexti:     mflr    r1              /* R1 = our PC */
        li      r3, 0
        mtspr   MAS1, r3
 1:     cmpw    r3, r14
-#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_NAND_SPL)
-       cmpwi   cr1, r3, CONFIG_SYS_PPC_E500_DEBUG_TLB
-       cror    cr0*4+eq, cr0*4+eq, cr1*4+eq
-#endif
        rlwinm  r5, r3, 16, MAS0_ESEL_MSK
        addi    r3, r3, 1
        beq     2f              /* skip the entry we're executing from */
@@ -553,6 +515,46 @@ nexti:     mflr    r1              /* R1 = our PC */
 2:     cmpw    r3, r4
        blt     1b
 
+#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(MINIMAL_SPL)
+/*
+ * TLB entry for debuggging in AS1
+ * Create temporary TLB entry in AS0 to handle debug exception
+ * As on debug exception MSR is cleared i.e. Address space is changed
+ * to 0. A TLB entry (in AS0) is required to handle debug exception generated
+ * in AS1.
+ */
+
+#ifdef NOR_BOOT
+/*
+ * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
+ * bacause flash's virtual address maps to 0xff800000 - 0xffffffff.
+ * and this window is outside of 4K boot window.
+ */
+       create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
+               0, BOOKE_PAGESZ_4M, \
+               CONFIG_SYS_MONITOR_BASE & 0xffc00000,  MAS2_I|MAS2_G, \
+               0xffc00000, MAS3_SX|MAS3_SW|MAS3_SR, \
+               0, r6
+
+#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT)
+       create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
+               0, BOOKE_PAGESZ_1M, \
+               CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \
+               CONFIG_SYS_PBI_FLASH_WINDOW, MAS3_SX|MAS3_SW|MAS3_SR, \
+               0, r6
+#else
+/*
+ * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
+ * because "nexti" will resize TLB to 4K
+ */
+       create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
+               0, BOOKE_PAGESZ_256K, \
+               CONFIG_SYS_MONITOR_BASE & 0xfffc0000, MAS2_I, \
+               CONFIG_SYS_MONITOR_BASE & 0xfffc0000, MAS3_SX|MAS3_SW|MAS3_SR, \
+               0, r6
+#endif
+#endif
+
 /*
  * Relocate CCSR, if necessary.  We relocate CCSR if (obviously) the default
  * location is not where we want it.  This typically happens on a 36-bit
@@ -1036,7 +1038,7 @@ create_init_ram_area:
        lis     r6,FSL_BOOKE_MAS0(1, 15, 0)@h
        ori     r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l
 
-#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT)
+#ifdef NOR_BOOT
        /* create a temp mapping in AS=1 to the 4M boot window */
        create_tlb1_entry 15, \
                1, BOOKE_PAGESZ_4M, \
@@ -1050,8 +1052,8 @@ create_init_ram_area:
        */
        create_tlb1_entry 15, \
                1, BOOKE_PAGESZ_1M, \
-               CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \
-               CONFIG_SYS_PBI_FLASH_WINDOW, MAS3_SX|MAS3_SW|MAS3_SR, \
+               CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
+               CONFIG_SYS_PBI_FLASH_WINDOW & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
                0, r6
 #else
        /*
@@ -1060,8 +1062,8 @@ create_init_ram_area:
         */
        create_tlb1_entry 15, \
                1, BOOKE_PAGESZ_1M, \
-               CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \
-               CONFIG_SYS_MONITOR_BASE, MAS3_SX|MAS3_SW|MAS3_SR, \
+               CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
+               CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
                0, r6
 #endif
 
@@ -1111,7 +1113,8 @@ switch_as:
        bdnz    1b
 
        /* Jump out the last 4K page and continue to 'normal' start */
-#ifdef CONFIG_SYS_RAMBOOT
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
+       /* We assume that we're already running at the address we're linked at */
        b       _start_cont
 #else
        /* Calculate absolute address in FLASH and jump there           */
@@ -1157,7 +1160,7 @@ _start_cont:
 
        /* NOTREACHED - board_init_f() does not return */
 
-#ifndef CONFIG_NAND_SPL
+#ifndef MINIMAL_SPL
        . = EXC_OFF_SYS_RESET
        .globl  _start_of_vectors
 _start_of_vectors:
@@ -1601,7 +1604,7 @@ in32:
 in32r:
        lwbrx   r3,r0,r3
        blr
-#endif  /* !CONFIG_NAND_SPL */
+#endif  /* !MINIMAL_SPL */
 
 /*------------------------------------------------------------------------------*/
 
@@ -1798,7 +1801,7 @@ clear_bss:
        mr      r4,r10          /* Destination Address          */
        bl      board_init_r
 
-#ifndef CONFIG_NAND_SPL
+#ifndef MINIMAL_SPL
        /*
         * Copy exception vector code to low memory
         *
@@ -1971,4 +1974,4 @@ setup_ivors:
 
 #include "fixed_ivor.S"
        blr
-#endif /* !CONFIG_NAND_SPL */
+#endif /* !MINIMAL_SPL */
index a548dec9a7cffa22115fe3d5eddb93db629d5839..f44fadcffd80599143faca65b6f38c278e34e097 100644 (file)
@@ -55,7 +55,7 @@ void init_tlbs(void)
        return ;
 }
 
-#ifndef CONFIG_NAND_SPL
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
 void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn,
                       phys_addr_t *rpn)
 {
@@ -332,4 +332,4 @@ void clear_ddr_tlbs(unsigned int memsize_in_meg)
 }
 
 
-#endif /* !CONFIG_NAND_SPL */
+#endif /* not SPL */
diff --git a/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds b/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds
new file mode 100644 (file)
index 0000000..1c408e2
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de
+ *
+ * Copyright 2009 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "config.h"    /* CONFIG_BOARDDIR */
+
+OUTPUT_ARCH(powerpc)
+SECTIONS
+{
+       . = CONFIG_SPL_TEXT_BASE;
+       .text : {
+               *(.text*)
+       }
+       _etext = .;
+
+       .reloc : {
+               _GOT2_TABLE_ = .;
+               KEEP(*(.got2))
+               KEEP(*(.got))
+               PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
+               _FIXUP_TABLE_ = .;
+               KEEP(*(.fixup))
+       }
+       __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
+       __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+       . = ALIGN(8);
+       .data : {
+               *(.rodata*)
+               *(.data*)
+               *(.sdata*)
+       }
+       _edata  =  .;
+
+       . = ALIGN(8);
+       __init_begin = .;
+       __init_end = .;
+/* FIXME for non-NAND SPL */
+#if defined(CONFIG_FSL_IFC) /* Restrict bootpg at 4K boundry for IFC */
+       .bootpg ADDR(.text) + 0x1000 :
+       {
+               start.o (.bootpg)
+       }
+#define RESET_VECTOR_OFFSET 0x1ffc /* IFC has 8K sram */
+#elif defined(CONFIG_FSL_ELBC)
+#define RESET_VECTOR_OFFSET 0xffc /* LBC has 4k sram */
+#else
+#error unknown NAND controller
+#endif
+       .resetvec ADDR(.text) + RESET_VECTOR_OFFSET : {
+               KEEP(*(.resetvec))
+       } = 0xffff
+
+       /*
+        * Make sure that the bss segment isn't linked at 0x0, otherwise its
+        * address won't be updated during relocation fixups.
+        */
+       . |= 0x10;
+
+       __bss_start = .;
+       .bss : {
+               *(.sbss*)
+               *(.bss*)
+       }
+       __bss_end__ = .;
+}
index b8f2c9387f591ba70d54f825e7f14763c21d01db..92ba26dc8ea1708b5d9842b42ef2a36854360121 100644 (file)
@@ -22,10 +22,10 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 
        switch (ctrl_num) {
        case 0:
-               ddr = (void *)CONFIG_SYS_MPC86xx_DDR_ADDR;
+               ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
                break;
        case 1:
-               ddr = (void *)CONFIG_SYS_MPC86xx_DDR2_ADDR;
+               ddr = (void *)CONFIG_SYS_MPC8xxx_DDR2_ADDR;
                break;
        default:
                printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
index 4ae26e42104b896208f2e9f584f109b72f76af7d..3dc8e055b68ba905bdddb0fecc08478a82ca6ff8 100644 (file)
@@ -10,6 +10,20 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib8xxx.o
 
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+
+COBJS-$(CONFIG_FSL_LAW) += law.o
+
+else
+
 ifneq ($(CPU),mpc83xx)
 COBJS-y        += cpu.o
 endif
@@ -18,6 +32,9 @@ COBJS-$(CONFIG_OF_LIBFDT) += fdt.o
 COBJS-$(CONFIG_FSL_IFC) += fsl_ifc.o
 COBJS-$(CONFIG_FSL_LBC) += fsl_lbc.o
 COBJS-$(CONFIG_SYS_SRIO) += srio.o
+COBJS-$(CONFIG_FSL_LAW) += law.o
+
+endif
 
 SRCS   := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
index 088cc0e855074e1b3fc74e0b6072626082e8cccb..8016bcdc22ec8b54a12ef1d7f7cf7bf4aa0d5f27 100644 (file)
 
 #include "ddr.h"
 
-#ifdef CONFIG_MPC83xx
-       #define _DDR_ADDR CONFIG_SYS_MPC83xx_DDR_ADDR
-#elif defined(CONFIG_MPC85xx)
-       #define _DDR_ADDR CONFIG_SYS_MPC85xx_DDR_ADDR
-#elif defined(CONFIG_MPC86xx)
-       #define _DDR_ADDR CONFIG_SYS_MPC86xx_DDR_ADDR
-#else
-       #error "Undefined _DDR_ADDR"
-#endif
+#define _DDR_ADDR CONFIG_SYS_MPC8xxx_DDR_ADDR
 
 static u32 fsl_ddr_get_version(void)
 {
index 940ffff773a20f40ee6f2850b709bdf00acf8ad1..acfe1f095fe4c541c3b2126211c2b7ae580658dc 100644 (file)
@@ -133,14 +133,8 @@ u32 fsl_ddr_get_intl3r(void)
 
 void board_add_ram_info(int use_default)
 {
-#if defined(CONFIG_MPC83xx)
-       immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
-       ccsr_ddr_t *ddr = (void *)&immap->ddr;
-#elif defined(CONFIG_MPC85xx)
-       ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
-#elif defined(CONFIG_MPC86xx)
-       ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR);
-#endif
+       ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC8xxx_DDR_ADDR);
+
 #if    defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3)
        u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
 #endif
@@ -152,13 +146,13 @@ void board_add_ram_info(int use_default)
 
 #if CONFIG_NUM_DDR_CONTROLLERS >= 2
        if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
-               ddr = (void __iomem *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
+               ddr = (void __iomem *)CONFIG_SYS_MPC8xxx_DDR2_ADDR;
                sdram_cfg = in_be32(&ddr->sdram_cfg);
        }
 #endif
 #if CONFIG_NUM_DDR_CONTROLLERS >= 3
        if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
-               ddr = (void __iomem *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
+               ddr = (void __iomem *)CONFIG_SYS_MPC8xxx_DDR3_ADDR;
                sdram_cfg = in_be32(&ddr->sdram_cfg);
        }
 #endif
index 68db8e2448a4c6bfb7a581607ae15d486175a570..1986fea030a4eaa25ea533c838f2d9d2810df63b 100644 (file)
@@ -217,7 +217,7 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd)
 #if CONFIG_SYS_FSL_SEC_COMPAT == 2 /* SEC 2.x/3.x */
 void fdt_fixup_crypto_node(void *blob, int sec_rev)
 {
-       const struct sec_rev_prop {
+       static const struct sec_rev_prop {
                u32 sec_rev;
                u32 num_channels;
                u32 channel_fifo_len;
@@ -232,8 +232,8 @@ void fdt_fixup_crypto_node(void *blob, int sec_rev)
                { 0x0301, 4, 24, 0xbfe, 0x03ab0ebf }, /* SEC 3.1 */
                { 0x0303, 4, 24, 0x97c, 0x03a30abf }, /* SEC 3.3 */
        };
-       char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) *
-                           sizeof("fsl,secX.Y")];
+       static char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) *
+                                  sizeof("fsl,secX.Y")];
        int crypto_node, sec_idx, err;
        char *p;
        u32 val;
similarity index 95%
rename from drivers/misc/fsl_law.c
rename to arch/powerpc/cpu/mpc8xxx/law.c
index 223cd5d65c816aac52f969e05332a970b73e7e51..ce1d71e307a02f081e8222392a5bc53b845f574b 100644 (file)
@@ -92,7 +92,7 @@ void disable_law(u8 idx)
        return;
 }
 
-#ifndef CONFIG_NAND_SPL
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
 static int get_law_entry(u8 i, struct law_entry *e)
 {
        u32 lawar;
@@ -122,7 +122,7 @@ int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
        return idx;
 }
 
-#ifndef CONFIG_NAND_SPL
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
 int set_last_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
 {
        u32 idx;
@@ -233,7 +233,7 @@ int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id)
 
        return 0;
 }
-#endif
+#endif /* not SPL */
 
 void init_laws(void)
 {
@@ -258,9 +258,10 @@ void init_laws(void)
                        gd->used_laws |= (1 << i);
        }
 
-#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+#if (defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)) || \
+       (defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD))
        /*
-        * in NAND boot we've already parsed the law_table and setup those LAWs
+        * in SPL boot we've already parsed the law_table and setup those LAWs
         * so don't do it again.
         */
        return;
index 4ce27262970624099119f267d602d8fca9d1afa6..f820c37a8f15d7d857b849b7637ddd776a5f423d 100644 (file)
@@ -621,7 +621,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
                        | usb_pipeendpoint (pipe) << 7
                        | (usb_pipeisoc (pipe)? 0x8000: 0)
                        | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
-                       | usb_pipeslow (pipe) << 13
+                       | (usb_dev->speed == USB_SPEED_LOW) << 13
                        | usb_maxpacket (usb_dev, pipe) << 16);
 
        return ed_ret;
index 03baaee1b70657d0fa0fd119a02b97f63cb93629..0b9638bceef0bf565610dbaae045aa66de83d86c 100644 (file)
 #error "Do not define CONFIG_SYS_CCSRBAR_DEFAULT in the board header file."
 #endif
 
+/*
+ * This macro should be removed when we no longer care about backwards
+ * compatibility with older operating systems.
+ */
+#define CONFIG_PPC_SPINTABLE_COMPATIBLE
+
 #define FSL_DDR_VER_4_7        47
 
 /* Number of TLB CAM entries we have on FSL Book-E chips */
 #define CONFIG_SYS_PPC_E500_DEBUG_TLB  3
 #define CONFIG_TSECV2
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
-#define CONFIG_FSL_SATA_V2
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_NUM_DDR_CONTROLLERS     1
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_SYS_PPC_E500_DEBUG_TLB  2
 #define CONFIG_TSECV2
 #define CONFIG_SYS_FSL_SEC_COMPAT      2
-#define CONFIG_FSL_SATA_V2
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_PPC_E500_DEBUG_TLB  3
 #define CONFIG_TSECV2
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
-#define CONFIG_FSL_SATA_V2
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_NUM_DDR_CONTROLLERS     1
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_SYS_PPC_E500_DEBUG_TLB  2
 #define CONFIG_TSECV2
 #define CONFIG_SYS_FSL_SEC_COMPAT      2
-#define CONFIG_FSL_SATA_V2
 #define CONFIG_SYS_CCSRBAR_DEFAULT     0xff700000
 #define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_NUM_CC_PLLS     2
 #define CONFIG_SYS_FSL_NUM_LAWS                32
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
-#define CONFIG_FSL_SATA_V2
 #define CONFIG_SYS_NUM_FMAN            1
 #define CONFIG_SYS_NUM_FM1_DTSEC       5
 #define CONFIG_SYS_NUM_FM1_10GEC       1
 #define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2        0x11
 #define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000
 #define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
+#define CONFIG_SYS_FSL_ERRATUM_A004849
 
 #elif defined(CONFIG_PPC_P3041)
 #define CONFIG_SYS_FSL_QORIQ_CHASSIS1
 #define CONFIG_SYS_FSL_NUM_CC_PLLS     2
 #define CONFIG_SYS_FSL_NUM_LAWS                32
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
-#define CONFIG_FSL_SATA_V2
 #define CONFIG_SYS_NUM_FMAN            1
 #define CONFIG_SYS_NUM_FM1_DTSEC       5
 #define CONFIG_SYS_NUM_FM1_10GEC       1
 #define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2        0x11
 #define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000
 #define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
+#define CONFIG_SYS_FSL_ERRATUM_A004849
 
 #elif defined(CONFIG_PPC_P4080) /* also supports P4040 */
 #define CONFIG_SYS_FSL_QORIQ_CHASSIS1
 #define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x20
 #define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xff000000
 #define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
+#define CONFIG_SYS_FSL_ERRATUM_A004849
+#define CONFIG_SYS_FSL_ERRATUM_A004580
+#define CONFIG_SYS_P4080_ERRATUM_PCIE_A003
 
 #elif defined(CONFIG_PPC_P5020) /* also supports P5010 */
 #define CONFIG_SYS_PPC64               /* 64-bit core */
 #define CONFIG_SYS_FSL_NUM_CC_PLLS     2
 #define CONFIG_SYS_FSL_NUM_LAWS                32
 #define CONFIG_SYS_FSL_SEC_COMPAT      4
-#define CONFIG_FSL_SATA_V2
 #define CONFIG_SYS_NUM_FMAN            1
 #define CONFIG_SYS_NUM_FM1_DTSEC       5
 #define CONFIG_SYS_NUM_FM1_10GEC       1
 #define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
 
 #elif defined(CONFIG_PPC_P5040)
+#define CONFIG_SYS_PPC64
 #define CONFIG_SYS_FSL_QORIQ_CHASSIS1
 #define CONFIG_MAX_CPUS                        4
 #define CONFIG_SYS_FSL_NUM_CC_PLLS     3
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_ERRATUM_A004699
-#define CONFIG_SYS_FSL_ELBC_MULTIBIT_ECC
 #define CONFIG_SYS_FSL_ERRATUM_A004510
 #define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10
 #define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000
index 679832cd6c774397161d185cedce0b4f365d85b5..8ac13fc05c08d19f25ca8b77abf261ebfb7a4b82 100644 (file)
@@ -1035,9 +1035,9 @@ typedef struct immap {
 } immap_t;
 #endif
 
-#define CONFIG_SYS_MPC83xx_DDR_OFFSET  (0x2000)
-#define CONFIG_SYS_MPC83xx_DDR_ADDR \
-                       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DDR_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR_OFFSET  (0x2000)
+#define CONFIG_SYS_MPC8xxx_DDR_ADDR \
+                       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR_OFFSET)
 #define CONFIG_SYS_MPC83xx_DMA_OFFSET  (0x8000)
 #define CONFIG_SYS_MPC83xx_DMA_ADDR \
                        (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DMA_OFFSET)
index 969f726c36296f8b749da050538fa0f357bb88d7..296b5497798ee08c86e1f9fec78c899e4a4ca93a 100644 (file)
@@ -2619,7 +2619,7 @@ typedef struct serdes_corenet {
 #define SRDS_PCCR2_RST_XGMII1          0x00800000
 #define SRDS_PCCR2_RST_XGMII2          0x00400000
        u32     res5[197];
-       struct {
+       struct serdes_lane {
                u32     gcr0;   /* General Control Register 0 */
 #define SRDS_GCR0_RRST                 0x00400000
 #define SRDS_GCR0_1STLANE              0x00010000
@@ -2637,8 +2637,11 @@ typedef struct serdes_corenet {
                u32     res3;
                u32     ttlcr0; /* Transition Tracking Loop Ctrl 0 */
 #define SRDS_TTLCR0_FLT_SEL_MASK       0x3f000000
+#define SRDS_TTLCR0_FLT_SEL_KFR_26     0x10000000
+#define SRDS_TTLCR0_FLT_SEL_KPH_28     0x08000000
 #define SRDS_TTLCR0_FLT_SEL_750PPM     0x03000000
 #define SRDS_TTLCR0_PM_DIS             0x00004000
+#define SRDS_TTLCR0_FREQOVD_EN         0x00000001
                u32     res4[7];
        } lane[24];
        u32 res6[384];
@@ -2867,9 +2870,9 @@ struct ccsr_pman {
 #define CONFIG_SYS_FSL_CORENET_PMAN2_OFFSET    0x5000
 #define CONFIG_SYS_FSL_CORENET_PMAN3_OFFSET    0x6000
 #endif
-#define CONFIG_SYS_MPC85xx_DDR_OFFSET          0x8000
-#define CONFIG_SYS_MPC85xx_DDR2_OFFSET         0x9000
-#define CONFIG_SYS_MPC85xx_DDR3_OFFSET         0xA000
+#define CONFIG_SYS_MPC8xxx_DDR_OFFSET          0x8000
+#define CONFIG_SYS_MPC8xxx_DDR2_OFFSET         0x9000
+#define CONFIG_SYS_MPC8xxx_DDR3_OFFSET         0xA000
 #define CONFIG_SYS_FSL_CORENET_CLK_OFFSET      0xE1000
 #define CONFIG_SYS_FSL_CORENET_RCPM_OFFSET     0xE2000
 #define CONFIG_SYS_FSL_CORENET_SERDES_OFFSET   0xEA000
@@ -2929,9 +2932,9 @@ struct ccsr_pman {
 #define CONFIG_SYS_FSL_CLUSTER_1_L2_OFFSET     0xC20000
 #else
 #define CONFIG_SYS_MPC85xx_ECM_OFFSET          0x0000
-#define CONFIG_SYS_MPC85xx_DDR_OFFSET          0x2000
+#define CONFIG_SYS_MPC8xxx_DDR_OFFSET          0x2000
 #define CONFIG_SYS_MPC85xx_LBC_OFFSET          0x5000
-#define CONFIG_SYS_MPC85xx_DDR2_OFFSET         0x6000
+#define CONFIG_SYS_MPC8xxx_DDR2_OFFSET         0x6000
 #define CONFIG_SYS_MPC85xx_ESPI_OFFSET         0x7000
 #define CONFIG_SYS_MPC85xx_PCI1_OFFSET         0x8000
 #define CONFIG_SYS_MPC85xx_PCIX_OFFSET         0x8000
@@ -2998,12 +3001,12 @@ struct ccsr_pman {
        (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CORENET_RCPM_OFFSET)
 #define CONFIG_SYS_MPC85xx_ECM_ADDR \
        (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_ECM_OFFSET)
-#define CONFIG_SYS_MPC85xx_DDR_ADDR \
-       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR_OFFSET)
-#define CONFIG_SYS_MPC85xx_DDR2_ADDR \
-       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR2_OFFSET)
-#define CONFIG_SYS_MPC85xx_DDR3_ADDR \
-       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR3_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR_ADDR \
+       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR2_ADDR \
+       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR2_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR3_ADDR \
+       (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR3_OFFSET)
 #define CONFIG_SYS_LBC_ADDR \
        (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_LBC_OFFSET)
 #define CONFIG_SYS_IFC_ADDR \
index cc338e4739f45a4602219b4bf51c22b830c15f28..2a704fe6b7be430349aec7daef3ecafd5e6d26ee 100644 (file)
@@ -1252,10 +1252,10 @@ typedef struct immap {
 
 extern immap_t  *immr;
 
-#define CONFIG_SYS_MPC86xx_DDR_OFFSET  0x2000
-#define CONFIG_SYS_MPC86xx_DDR_ADDR    (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DDR_OFFSET)
-#define CONFIG_SYS_MPC86xx_DDR2_OFFSET 0x6000
-#define CONFIG_SYS_MPC86xx_DDR2_ADDR   (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DDR2_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR_OFFSET  0x2000
+#define CONFIG_SYS_MPC8xxx_DDR_ADDR    (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR2_OFFSET 0x6000
+#define CONFIG_SYS_MPC8xxx_DDR2_ADDR   (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR2_OFFSET)
 #define CONFIG_SYS_MPC86xx_DMA_OFFSET  0x21000
 #define CONFIG_SYS_MPC86xx_DMA_ADDR    (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DMA_OFFSET)
 #define CONFIG_SYS_MPC86xx_PIC_OFFSET  0x40000
index 7aa3231ad4a39996116cb99967260767cf48fce4..19fe250305729f29dabeba4438e034143903d938 100644 (file)
@@ -1342,4 +1342,10 @@ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
 #endif
 #endif /* CONFIG_MACH_SPECIFIC */
 
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_440)
+ #define EPAPR_MAGIC   (0x45504150)
+#else
+ #define EPAPR_MAGIC   (0x65504150)
+#endif
+
 #endif /* __ASM_PPC_PROCESSOR_H */
similarity index 71%
rename from board/chromebook-x86/coreboot/coreboot_pci.c
rename to arch/powerpc/include/asm/spl.h
index 732ca3ceaff8fa8e01ed072ba0ea05a122dc947b..f43bc23c92d72e04528f70395bfa356c5e02d93d 100644 (file)
@@ -1,10 +1,6 @@
 /*
- * Copyright (c) 2011 The Chromium OS Authors.
- * (C) Copyright 2008,2009
- * Graeme Russ, <graeme.russ@gmail.com>
- *
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -16,7 +12,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
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  */
+#ifndef        _ASM_SPL_H_
+#define        _ASM_SPL_H_
+
+#define BOOT_DEVICE_NOR                1
+
+/* Linker symbols */
+extern char __bss_start[], __bss_end__[];
 
-void pci_init_board(void)
-{
-}
+#endif
index 808021c42ef11ef805a9fb5f5ff6cf701e7c822a..844fe8636de9f2a4a92178c76a46dd4cd4ddc921 100644 (file)
@@ -38,13 +38,28 @@ endif
 
 LIB    = $(obj)lib$(ARCH).o
 
-SOBJS-y        += ppccache.o
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+COBJS-y += cache.o
+else
+
 SOBJS-y        += ppcstring.o
+
+SOBJS-y        += ppccache.o
 SOBJS-y        += ticks.o
 SOBJS-y        += reloc.o
 
 COBJS-$(CONFIG_BAT_RW) += bat_rw.o
+ifndef CONFIG_SPL_BUILD
 COBJS-y        += board.o
+endif
 COBJS-y        += bootm.o
 COBJS-y        += cache.o
 COBJS-y        += extable.o
@@ -53,6 +68,11 @@ COBJS-$(CONFIG_CMD_KGDB) += kgdb.o
 COBJS-${CONFIG_CMD_IDE} += ide.o
 COBJS-y        += time.o
 
+# Don't include the MPC5xxx special memcpy into the
+# SPL U-Boot image. memcpy is used in the SPL NOR
+# flash driver. And we need the real, fast memcpy
+# here. We have no problems with unaligned access.
+ifndef CONFIG_SPL_BUILD
 # Workaround for local bus unaligned access problems
 # on MPC512x and MPC5200
 ifdef CONFIG_MPC512X
@@ -63,6 +83,13 @@ ifdef CONFIG_MPC5200
 $(obj)ppcstring.o: AFLAGS += -Dmemcpy=__memcpy
 COBJS-y += memcpy_mpc5200.o
 endif
+endif
+
+endif # not minimal
+
+ifdef CONFIG_SPL_BUILD
+COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o
+endif
 
 COBJS  += $(sort $(COBJS-y))
 
@@ -75,12 +102,6 @@ TARGETS += $(LIB)
 all: $(TARGETS)
 
 $(LIB):        $(obj).depend $(OBJS)
-       @if ! $(CROSS_COMPILE)readelf -S $(OBJS) | grep -q '\.fixup.*PROGBITS';\
-       then \
-               echo "ERROR: Your compiler doesn't generate .fixup sections!";\
-               echo "       Upgrade to a recent toolchain."; \
-               exit 1; \
-       fi;
        $(call cmd_link_o_target, $(OBJS))
 
 $(LIBGCC): $(obj).depend $(LGOBJS)
index ac5bd6d4f1599c0b0514a4d4004d17f0c93199af..7088293a3647a6c249369a1e2d436497feb70c8b 100644 (file)
@@ -87,12 +87,6 @@ static void boot_jump_linux(bootm_headers_t *images)
                 *   r8: 0
                 *   r9: 0
                 */
-#if defined(CONFIG_MPC85xx) || defined(CONFIG_440)
- #define EPAPR_MAGIC   (0x45504150)
-#else
- #define EPAPR_MAGIC   (0x65504150)
-#endif
-
                debug ("   Booting using OF flat tree...\n");
                WATCHDOG_RESET ();
                (*kernel) ((bd_t *)of_flat_tree, 0, 0, EPAPR_MAGIC,
diff --git a/arch/powerpc/lib/spl.c b/arch/powerpc/lib/spl.c
new file mode 100644 (file)
index 0000000..502c93b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2012 Stefan Roese <sr@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.
+ */
+#include <common.h>
+#include <config.h>
+#include <spl.h>
+#include <image.h>
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This function jumps to an image with argument. Normally an FDT or ATAGS
+ * image.
+ * arg: Pointer to paramter image in RAM
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+void __noreturn jump_to_image_linux(void *arg)
+{
+       debug("Entering kernel arg pointer: 0x%p\n", arg);
+       typedef void (*image_entry_arg_t)(void *, ulong r4, ulong r5, ulong r6,
+                                         ulong r7, ulong r8, ulong r9)
+               __attribute__ ((noreturn));
+       image_entry_arg_t image_entry =
+               (image_entry_arg_t)spl_image.entry_point;
+
+       image_entry(arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ, 0, 0);
+}
+#endif /* CONFIG_SPL_OS_BOOT */
index 56fd77acea6ee0f4acf6e6d74ac75cb89e6b4f99..24b5ce8e3042e0e498c8f1514aa28bca9b23306c 100644 (file)
@@ -274,8 +274,8 @@ void enable_hlt(void);
 
 static inline void trigger_address_error(void)
 {
+       set_bl_bit();
        __asm__ __volatile__ (
-               "ldc %0, sr\n\t"
                "mov.l @%1, %0"
                :
                : "r" (0x10000000), "r" (0x80000001)
index 7f1fc188cb796b1c5a13b87f098e49b9edea21b8..57324b61749edbeb3fadfe045252d3fd7a8560a5 100644 (file)
@@ -28,12 +28,13 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(CPU).o
 
-START  = start.o start16.o resetvec.o
-COBJS  = interrupts.o cpu.o
+START-y        = start.o
+RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += resetvec.o start16.o
+COBJS  = interrupts.o cpu.o timer.o
 
 SRCS   := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
-START  := $(addprefix $(obj),$(START))
+START  := $(addprefix $(obj),$(START-y) $(RESET_OBJS-))
 
 all:   $(obj).depend $(START) $(LIB)
 
index 13f5f8a2f05fe41cf2475591c25a723b3266aa90..b1d3e959f8f63d4f88570973dc415c03995865c0 100644 (file)
@@ -33,12 +33,13 @@ include $(TOPDIR)/config.mk
 
 LIB    := $(obj)lib$(SOC).o
 
+SOBJS-$(CONFIG_SYS_COREBOOT) += car.o
+COBJS-$(CONFIG_SYS_COREBOOT) += coreboot.o
 COBJS-$(CONFIG_SYS_COREBOOT) += tables.o
 COBJS-$(CONFIG_SYS_COREBOOT) += ipchecksum.o
 COBJS-$(CONFIG_SYS_COREBOOT) += sdram.o
-COBJS-$(CONFIG_SYS_COREBOOT) += sysinfo.o
-
-SOBJS-$(CONFIG_SYS_COREBOOT) += coreboot_car.o
+COBJS-$(CONFIG_SYS_COREBOOT) += timestamp.o
+COBJS-$(CONFIG_PCI) += pci.o
 
 SRCS   := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
similarity index 78%
rename from board/BuS/eb_cpu5282/config.mk
rename to arch/x86/cpu/coreboot/config.mk
index 18fb84eb3b590f7b3edc91fbbb6734a848f3e80a..4858fc3728436a93ac83fc0f8bf18d9ea04bcee5 100644 (file)
@@ -1,7 +1,5 @@
 #
-# (C) Copyright 2000-2003
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-# Coldfire contribution by Bernhard Kuhn <bkuhn@metrowerks.com>
+# Copyright (c) 2012 The Chromium OS Authors.
 #
 # See file CREDITS for list of people who contributed to this
 # project.
@@ -22,6 +20,4 @@
 # MA 02111-1307 USA
 #
 
-ifndef CONFIG_SYS_TEXT_BASE
-CONFIG_SYS_TEXT_BASE = 0xFE000000
-endif
+CONFIG_ARCH_DEVICE_TREE := coreboot
similarity index 55%
rename from board/chromebook-x86/coreboot/coreboot.c
rename to arch/x86/cpu/coreboot/coreboot.c
index 22a643c9d6bc8098200866471c9b784dc5e8b163..9c9431e0d9dc3f869884f6b10d2d4c0bd147d4ef 100644 (file)
 #include <asm/u-boot-x86.h>
 #include <flash.h>
 #include <netdev.h>
+#include <asm/msr.h>
+#include <asm/cache.h>
+#include <asm/io.h>
 #include <asm/arch-coreboot/tables.h>
 #include <asm/arch-coreboot/sysinfo.h>
+#include <asm/arch/timestamp.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-unsigned long monitor_flash_len = CONFIG_SYS_MONITOR_LEN;
-
 /*
  * Miscellaneous platform dependent initializations
  */
@@ -41,6 +43,9 @@ int cpu_init_f(void)
        int ret = get_coreboot_info(&lib_sysinfo);
        if (ret != 0)
                printf("Failed to parse coreboot tables.\n");
+
+       timestamp_init();
+
        return ret;
 }
 
@@ -62,8 +67,29 @@ int board_early_init_r(void)
 
 void show_boot_progress(int val)
 {
-}
+#if MIN_PORT80_KCLOCKS_DELAY
+       static uint32_t prev_stamp;
+       static uint32_t base;
+
+       /*
+        * Scale the time counter reading to avoid using 64 bit arithmetics.
+        * Can't use get_timer() here becuase it could be not yet
+        * initialized or even implemented.
+        */
+       if (!prev_stamp) {
+               base = rdtsc() / 1000;
+               prev_stamp = 0;
+       } else {
+               uint32_t now;
 
+               do {
+                       now = rdtsc() / 1000 - base;
+               } while (now < (prev_stamp + MIN_PORT80_KCLOCKS_DELAY));
+               prev_stamp = now;
+       }
+#endif
+       outb(val, 0x80);
+}
 
 int last_stage_init(void)
 {
@@ -82,6 +108,33 @@ int board_eth_init(bd_t *bis)
        return pci_eth_init(bis);
 }
 
-void setup_pcat_compatibility()
+#define MTRR_TYPE_WP          5
+#define MTRRcap_MSR           0xfe
+#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
+#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
+
+int board_final_cleanup(void)
 {
+       /* Un-cache the ROM so the kernel has one
+        * more MTRR available.
+        *
+        * Coreboot should have assigned this to the
+        * top available variable MTRR.
+        */
+       u8 top_mtrr = (native_read_msr(MTRRcap_MSR) & 0xff) - 1;
+       u8 top_type = native_read_msr(MTRRphysBase_MSR(top_mtrr)) & 0xff;
+
+       /* Make sure this MTRR is the correct Write-Protected type */
+       if (top_type == MTRR_TYPE_WP) {
+               disable_caches();
+               wrmsrl(MTRRphysBase_MSR(top_mtrr), 0);
+               wrmsrl(MTRRphysMask_MSR(top_mtrr), 0);
+               enable_caches();
+       }
+
+       /* Issue SMI to Coreboot to lock down ME and registers */
+       printf("Finalizing Coreboot\n");
+       outb(0xcb, 0xb2);
+
+       return 0;
 }
diff --git a/arch/x86/cpu/coreboot/pci.c b/arch/x86/cpu/coreboot/pci.c
new file mode 100644 (file)
index 0000000..8f94167
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2008,2009
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
+ *
+ * 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 <pci.h>
+#include <asm/pci.h>
+
+static struct pci_controller coreboot_hose;
+
+static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
+                             struct pci_config_table *table)
+{
+       u8 secondary;
+       hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary);
+       hose->last_busno = max(hose->last_busno, secondary);
+       pci_hose_scan_bus(hose, secondary);
+}
+
+static struct pci_config_table pci_coreboot_config_table[] = {
+       /* vendor, device, class, bus, dev, func */
+       { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI,
+               PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge },
+       {}
+};
+
+void pci_init_board(void)
+{
+       coreboot_hose.config_table = pci_coreboot_config_table;
+       coreboot_hose.first_busno = 0;
+       coreboot_hose.last_busno = 0;
+
+       pci_set_region(coreboot_hose.regions + 0, 0x0, 0x0, 0xffffffff,
+               PCI_REGION_MEM);
+       coreboot_hose.region_count = 1;
+
+       pci_setup_type1(&coreboot_hose);
+
+       pci_register_hose(&coreboot_hose);
+
+       pci_hose_scan(&coreboot_hose);
+}
index f8fdac6319eebde8d44a88c51b49dca625538025..76274cb88e3824ea3b066afffd7068c2b97832d8 100644 (file)
@@ -27,8 +27,9 @@
 #include <asm/e820.h>
 #include <asm/u-boot-x86.h>
 #include <asm/global_data.h>
-#include <asm/arch-coreboot/sysinfo.h>
-#include <asm/arch-coreboot/tables.h>
+#include <asm/processor.h>
+#include <asm/arch/sysinfo.h>
+#include <asm/arch/tables.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -51,6 +52,58 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
        return num_entries;
 }
 
+/*
+ * This function looks for the highest region of memory lower than 4GB which
+ * has enough space for U-Boot where U-Boot is aligned on a page boundary. It
+ * overrides the default implementation found elsewhere which simply picks the
+ * end of ram, wherever that may be. The location of the stack, the relocation
+ * address, and how far U-Boot is moved by relocation are set in the global
+ * data structure.
+ */
+int calculate_relocation_address(void)
+{
+       const uint64_t uboot_size = (uintptr_t)&__bss_end -
+                       (uintptr_t)&__text_start;
+       const uint64_t total_size = uboot_size + CONFIG_SYS_MALLOC_LEN +
+               CONFIG_SYS_STACK_SIZE;
+       uintptr_t dest_addr = 0;
+       int i;
+
+       for (i = 0; i < lib_sysinfo.n_memranges; i++) {
+               struct memrange *memrange = &lib_sysinfo.memrange[i];
+               /* Force U-Boot to relocate to a page aligned address. */
+               uint64_t start = roundup(memrange->base, 1 << 12);
+               uint64_t end = memrange->base + memrange->size;
+
+               /* Ignore non-memory regions. */
+               if (memrange->type != CB_MEM_RAM)
+                       continue;
+
+               /* Filter memory over 4GB. */
+               if (end > 0xffffffffULL)
+                       end = 0x100000000ULL;
+               /* Skip this region if it's too small. */
+               if (end - start < total_size)
+                       continue;
+
+               /* Use this address if it's the largest so far. */
+               if (end - uboot_size > dest_addr)
+                       dest_addr = end;
+       }
+
+       /* If no suitable area was found, return an error. */
+       if (!dest_addr)
+               return 1;
+
+       dest_addr -= uboot_size;
+       dest_addr &= ~((1 << 12) - 1);
+       gd->relocaddr = dest_addr;
+       gd->reloc_off = dest_addr - (uintptr_t)&__text_start;
+       gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
+
+       return 0;
+}
+
 int dram_init_f(void)
 {
        int i;
@@ -71,5 +124,20 @@ int dram_init_f(void)
 
 int dram_init(void)
 {
+       int i, j;
+
+       if (CONFIG_NR_DRAM_BANKS) {
+               for (i = 0, j = 0; i < lib_sysinfo.n_memranges; i++) {
+                       struct memrange *memrange = &lib_sysinfo.memrange[i];
+
+                       if (memrange->type == CB_MEM_RAM) {
+                               gd->bd->bi_dram[j].start = memrange->base;
+                               gd->bd->bi_dram[j].size = memrange->size;
+                               j++;
+                               if (j >= CONFIG_NR_DRAM_BANKS)
+                                       break;
+                       }
+               }
+       }
        return 0;
 }
diff --git a/arch/x86/cpu/coreboot/sysinfo.c b/arch/x86/cpu/coreboot/sysinfo.c
deleted file mode 100644 (file)
index 9b3e660..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file is part of the libpayload project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- * Copyright (C) 2009 coresystems GmbH
- *
- * 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.
- * 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 name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-#include <asm/arch-coreboot/sysinfo.h>
-
-/*
- * This needs to be in the .data section so that it's copied over during
- * relocation. By default it's put in the .bss section which is simply filled
- * with zeroes when transitioning from "ROM", which is really RAM, to other
- * RAM.
- */
-struct sysinfo_t lib_sysinfo __attribute__((section(".data")));
index 0e3451bb22306608400f4fc182c5ab615adea814..b116d595550b89c005a8c311ea6cae22280584f8 100644 (file)
  * SUCH DAMAGE.
  */
 
+#include <common.h>
 #include <asm/arch-coreboot/ipchecksum.h>
 #include <asm/arch-coreboot/sysinfo.h>
 #include <asm/arch-coreboot/tables.h>
 
+/*
+ * This needs to be in the .data section so that it's copied over during
+ * relocation. By default it's put in the .bss section which is simply filled
+ * with zeroes when transitioning from "ROM", which is really RAM, to other
+ * RAM.
+ */
+struct sysinfo_t lib_sysinfo __attribute__((section(".data")));
+
 /*
  * Some of this is x86 specific, and the rest of it is generic. Right now,
  * since we only support x86, we'll avoid trying to make lots of infrastructure
@@ -72,22 +81,45 @@ static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info)
 static void cb_parse_serial(unsigned char *ptr, struct sysinfo_t *info)
 {
        struct cb_serial *ser = (struct cb_serial *)ptr;
-       if (ser->type != CB_SERIAL_TYPE_IO_MAPPED)
-               return;
-       info->ser_ioport = ser->baseaddr;
+       info->serial = ser;
 }
 
-static void cb_parse_optiontable(unsigned char *ptr, struct sysinfo_t *info)
+static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info)
 {
-       info->option_table = (struct cb_cmos_option_table *)ptr;
+       struct cb_vbnv *vbnv = (struct cb_vbnv *)ptr;
+
+       info->vbnv_start = vbnv->vbnv_start;
+       info->vbnv_size = vbnv->vbnv_size;
 }
 
-static void cb_parse_checksum(unsigned char *ptr, struct sysinfo_t *info)
+static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info)
 {
-       struct cb_cmos_checksum *cmos_cksum = (struct cb_cmos_checksum *)ptr;
-       info->cmos_range_start = cmos_cksum->range_start;
-       info->cmos_range_end = cmos_cksum->range_end;
-       info->cmos_checksum_location = cmos_cksum->location;
+       int i;
+       struct cb_gpios *gpios = (struct cb_gpios *)ptr;
+
+       info->num_gpios = (gpios->count < SYSINFO_MAX_GPIOS) ?
+                               (gpios->count) : SYSINFO_MAX_GPIOS;
+
+       for (i = 0; i < info->num_gpios; i++)
+               info->gpios[i] = gpios->gpios[i];
+}
+
+static void cb_parse_vdat(unsigned char *ptr, struct sysinfo_t *info)
+{
+       struct cb_vdat *vdat = (struct cb_vdat *) ptr;
+
+       info->vdat_addr = vdat->vdat_addr;
+       info->vdat_size = vdat->vdat_size;
+}
+
+static void cb_parse_tstamp(unsigned char *ptr, struct sysinfo_t *info)
+{
+       info->tstamp_table = ((struct cb_cbmem_tab *)ptr)->cbmem_tab;
+}
+
+static void cb_parse_cbmem_cons(unsigned char *ptr, struct sysinfo_t *info)
+{
+       info->cbmem_cons = ((struct cb_cbmem_tab *)ptr)->cbmem_tab;
 }
 
 static void cb_parse_framebuffer(unsigned char *ptr, struct sysinfo_t *info)
@@ -95,6 +127,11 @@ static void cb_parse_framebuffer(unsigned char *ptr, struct sysinfo_t *info)
        info->framebuffer = (struct cb_framebuffer *)ptr;
 }
 
+static void cb_parse_string(unsigned char *ptr, char **info)
+{
+       *info = (char *)((struct cb_string *)ptr)->string;
+}
+
 static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
 {
        struct cb_header *header;
@@ -125,6 +162,9 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
        /* Now, walk the tables. */
        ptr += header->header_bytes;
 
+       /* Inintialize some fields to sentinel values. */
+       info->vbnv_start = info->vbnv_size = (uint32_t)(-1);
+
        for (i = 0; i < header->table_entries; i++) {
                struct cb_record *rec = (struct cb_record *)ptr;
 
@@ -142,11 +182,35 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
                case CB_TAG_SERIAL:
                        cb_parse_serial(ptr, info);
                        break;
-               case CB_TAG_CMOS_OPTION_TABLE:
-                       cb_parse_optiontable(ptr, info);
+               case CB_TAG_VERSION:
+                       cb_parse_string(ptr, &info->version);
+                       break;
+               case CB_TAG_EXTRA_VERSION:
+                       cb_parse_string(ptr, &info->extra_version);
+                       break;
+               case CB_TAG_BUILD:
+                       cb_parse_string(ptr, &info->build);
+                       break;
+               case CB_TAG_COMPILE_TIME:
+                       cb_parse_string(ptr, &info->compile_time);
+                       break;
+               case CB_TAG_COMPILE_BY:
+                       cb_parse_string(ptr, &info->compile_by);
+                       break;
+               case CB_TAG_COMPILE_HOST:
+                       cb_parse_string(ptr, &info->compile_host);
+                       break;
+               case CB_TAG_COMPILE_DOMAIN:
+                       cb_parse_string(ptr, &info->compile_domain);
+                       break;
+               case CB_TAG_COMPILER:
+                       cb_parse_string(ptr, &info->compiler);
                        break;
-               case CB_TAG_OPTION_CHECKSUM:
-                       cb_parse_checksum(ptr, info);
+               case CB_TAG_LINKER:
+                       cb_parse_string(ptr, &info->linker);
+                       break;
+               case CB_TAG_ASSEMBLER:
+                       cb_parse_string(ptr, &info->assembler);
                        break;
                /*
                 * FIXME we should warn on serial if coreboot set up a
@@ -155,6 +219,21 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
                case CB_TAG_FRAMEBUFFER:
                        cb_parse_framebuffer(ptr, info);
                        break;
+               case CB_TAG_GPIO:
+                       cb_parse_gpios(ptr, info);
+                       break;
+               case CB_TAG_VDAT:
+                       cb_parse_vdat(ptr, info);
+                       break;
+               case CB_TAG_TIMESTAMPS:
+                       cb_parse_tstamp(ptr, info);
+                       break;
+               case CB_TAG_CBMEM_CONSOLE:
+                       cb_parse_cbmem_cons(ptr, info);
+                       break;
+               case CB_TAG_VBNV:
+                       cb_parse_vbnv(ptr, info);
+                       break;
                }
 
                ptr += rec->size;
@@ -166,18 +245,12 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
 /* == Architecture specific == */
 /* This is the x86 specific stuff. */
 
-/* Assume no translation or that memory is identity mapped. */
-static void *phys_to_virt(unsigned long virt)
-{
-       return (void *)(uintptr_t)virt;
-}
-
 int get_coreboot_info(struct sysinfo_t *info)
 {
-       int ret = cb_parse_header(phys_to_virt(0x00000000), 0x1000, info);
+       int ret = cb_parse_header((void *)0x00000000, 0x1000, info);
 
        if (ret != 1)
-               ret = cb_parse_header(phys_to_virt(0x000f0000), 0x1000, info);
+               ret = cb_parse_header((void *)0x000f0000, 0x1000, info);
 
        return (ret == 1) ? 0 : -1;
 }
diff --git a/arch/x86/cpu/coreboot/timestamp.c b/arch/x86/cpu/coreboot/timestamp.c
new file mode 100644 (file)
index 0000000..2ca7a57
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * 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 of the License.
+ *
+ * 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 St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/arch/timestamp.h>
+#include <asm/arch/sysinfo.h>
+#include <linux/compiler.h>
+
+struct timestamp_entry {
+       uint32_t        entry_id;
+       uint64_t        entry_stamp;
+} __packed;
+
+struct timestamp_table {
+       uint64_t        base_time;
+       uint32_t        max_entries;
+       uint32_t        num_entries;
+       struct timestamp_entry entries[0]; /* Variable number of entries */
+} __packed;
+
+static struct timestamp_table *ts_table  __attribute__((section(".data")));
+
+void timestamp_init(void)
+{
+       ts_table = lib_sysinfo.tstamp_table;
+       timer_set_tsc_base(ts_table->base_time);
+       timestamp_add_now(TS_U_BOOT_INITTED);
+}
+
+void timestamp_add(enum timestamp_id id, uint64_t ts_time)
+{
+       struct timestamp_entry *tse;
+
+       if (!ts_table || (ts_table->num_entries == ts_table->max_entries))
+               return;
+
+       tse = &ts_table->entries[ts_table->num_entries++];
+       tse->entry_id = id;
+       tse->entry_stamp = ts_time - ts_table->base_time;
+}
+
+void timestamp_add_now(enum timestamp_id id)
+{
+       timestamp_add(id, rdtsc());
+}
index e9bb0d770a379f6c329085da7217a3ba0dccd165..315e87afeb2120e4dab4929f7a6eac225348cfa6 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <asm/control_regs.h>
 #include <asm/processor.h>
 #include <asm/processor-flags.h>
 #include <asm/interrupt.h>
@@ -90,12 +91,6 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries)
        asm volatile("lgdtl %0\n" : : "m" (gdt));
 }
 
-void init_gd(gd_t *id, u64 *gdt_addr)
-{
-       id->gd_addr = (ulong)id;
-       setup_gdt(id, gdt_addr);
-}
-
 void setup_gdt(gd_t *id, u64 *gdt_addr)
 {
        /* CS: code, read/execute, 4 GB, base 0 */
@@ -121,6 +116,11 @@ void setup_gdt(gd_t *id, u64 *gdt_addr)
        load_fs(X86_GDT_ENTRY_32BIT_FS);
 }
 
+int __weak x86_cleanup_before_linux(void)
+{
+       return 0;
+}
+
 int x86_cpu_init_f(void)
 {
        const u32 em_rst = ~X86_CR0_EM;
@@ -148,16 +148,27 @@ int cpu_init_r(void) __attribute__((weak, alias("x86_cpu_init_r")));
 
 void x86_enable_caches(void)
 {
-       const u32 nw_cd_rst = ~(X86_CR0_NW | X86_CR0_CD);
+       unsigned long cr0;
 
-       /* turn on the cache and disable write through */
-       asm("movl       %%cr0, %%eax\n"
-           "andl       %0, %%eax\n"
-           "movl       %%eax, %%cr0\n"
-           "wbinvd\n" : : "i" (nw_cd_rst) : "eax");
+       cr0 = read_cr0();
+       cr0 &= ~(X86_CR0_NW | X86_CR0_CD);
+       write_cr0(cr0);
+       wbinvd();
 }
 void enable_caches(void) __attribute__((weak, alias("x86_enable_caches")));
 
+void x86_disable_caches(void)
+{
+       unsigned long cr0;
+
+       cr0 = read_cr0();
+       cr0 |= X86_CR0_NW | X86_CR0_CD;
+       wbinvd();
+       write_cr0(cr0);
+       wbinvd();
+}
+void disable_caches(void) __attribute__((weak, alias("x86_disable_caches")));
+
 int x86_init_cache(void)
 {
        enable_caches();
@@ -201,3 +212,17 @@ void __reset_cpu(ulong addr)
        generate_gpf();                 /* start the show */
 }
 void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu")));
+
+int dcache_status(void)
+{
+       return !(read_cr0() & 0x40000000);
+}
+
+/* Define these functions to allow ehch-hcd to function */
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
index 43ec3f8b081fc2bf891fb70bf1e2f0af46793f78..dd30a05a9ddf54a97d69a62e29aa26c7e3bd0106 100644 (file)
  */
 
 #include <common.h>
+#include <asm/cache.h>
+#include <asm/control_regs.h>
 #include <asm/interrupt.h>
 #include <asm/io.h>
 #include <asm/processor-flags.h>
 #include <linux/compiler.h>
+#include <asm/msr.h>
+#include <asm/u-boot-x86.h>
 
 #define DECLARE_INTERRUPT(x) \
        ".globl irq_"#x"\n" \
        "pushl $"#x"\n" \
        "jmp irq_common_entry\n"
 
-/*
- * Volatile isn't enough to prevent the compiler from reordering the
- * read/write functions for the control registers and messing everything up.
- * A memory clobber would solve the problem, but would prevent reordering of
- * all loads stores around it, which can hurt performance. Solution is to
- * use a variable and mimic reads and writes to it to enforce serialisation
- */
-static unsigned long __force_order;
-
-static inline unsigned long read_cr0(void)
-{
-       unsigned long val;
-       asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));
-       return val;
-}
-
-static inline unsigned long read_cr2(void)
-{
-       unsigned long val;
-       asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order));
-       return val;
-}
-
-static inline unsigned long read_cr3(void)
-{
-       unsigned long val;
-       asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));
-       return val;
-}
-
-static inline unsigned long read_cr4(void)
-{
-       unsigned long val;
-       asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));
-       return val;
-}
-
-static inline unsigned long get_debugreg(int regno)
-{
-       unsigned long val = 0;  /* Damn you, gcc! */
-
-       switch (regno) {
-       case 0:
-               asm("mov %%db0, %0" : "=r" (val));
-               break;
-       case 1:
-               asm("mov %%db1, %0" : "=r" (val));
-               break;
-       case 2:
-               asm("mov %%db2, %0" : "=r" (val));
-               break;
-       case 3:
-               asm("mov %%db3, %0" : "=r" (val));
-               break;
-       case 6:
-               asm("mov %%db6, %0" : "=r" (val));
-               break;
-       case 7:
-               asm("mov %%db7, %0" : "=r" (val));
-               break;
-       default:
-               val = 0;
-       }
-       return val;
-}
-
 void dump_regs(struct irq_regs *regs)
 {
        unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
@@ -679,3 +617,32 @@ asm(".globl irq_common_entry\n" \
        DECLARE_INTERRUPT(253) \
        DECLARE_INTERRUPT(254) \
        DECLARE_INTERRUPT(255));
+
+#if defined(CONFIG_INTEL_CORE_ARCH)
+/*
+ * Get the number of CPU time counter ticks since it was read first time after
+ * restart. This yields a free running counter guaranteed to take almost 6
+ * years to wrap around even at 100GHz clock rate.
+ */
+u64 get_ticks(void)
+{
+       static u64 tick_base;
+       u64 now_tick = rdtsc();
+
+       if (!tick_base)
+               tick_base = now_tick;
+
+       return now_tick - tick_base;
+}
+
+#define PLATFORM_INFO_MSR 0xce
+
+unsigned long get_tbclk(void)
+{
+       u32 ratio;
+       u64 platform_info = native_read_msr(PLATFORM_INFO_MSR);
+
+       ratio = (platform_info >> 8) & 0xff;
+       return 100 * 1000 * 1000 * ratio; /* 100MHz times Max Non Turbo ratio */
+}
+#endif
index ee0dabe4bcd049becb3c632ec408c98f32d13fb3..e960e21f6e49d88979b3b502e163f646920dc41d 100644 (file)
@@ -55,8 +55,16 @@ _x86boot_start:
        movl    %eax, %cr0
        wbinvd
 
+       /* Tell 32-bit code it is being entered from an in-RAM copy */
+       movw    $GD_FLG_WARM_BOOT, %bx
+       jmp     1f
 _start:
-       /* This is the 32-bit cold-reset entry point */
+       /*
+        * This is the 32-bit cold-reset entry point. Initialize %bx to 0
+        * in case we're preceeded by some sort of boot stub.
+        */
+       movw    $GD_FLG_COLD_BOOT, %bx
+1:
 
        /* Load the segement registes to match the gdt loaded in start16.S */
        movl    $(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax
@@ -83,13 +91,33 @@ car_init_ret:
         * or fully initialised SDRAM - we really don't care which)
         * starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack
         */
-       movl    $CONFIG_SYS_INIT_SP_ADDR, %esp
 
-       /* Initialise the Global Data Pointer */
-       movl    $CONFIG_SYS_INIT_GD_ADDR, %eax
-       movl    %eax, %edx
-       addl    $GENERATED_GBL_DATA_SIZE, %edx
-       call    init_gd;
+       /* Stack grows down from top of CAR */
+       movl    $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp
+
+       /* Reserve space on stack for global data */
+       subl    $GENERATED_GBL_DATA_SIZE, %esp
+
+       /* Align global data to 16-byte boundary */
+       andl    $0xfffffff0, %esp
+
+       /* Setup first parameter to setup_gdt */
+       movl    %esp, %eax
+
+       /* Reserve space for global descriptor table */
+       subl    $X86_GDT_SIZE, %esp
+
+       /* Align temporary global descriptor table to 16-byte boundary */
+       andl    $0xfffffff0, %esp
+
+       /* Set second parameter to setup_gdt */
+       movl    %esp, %edx
+
+       /* gd->gd_addr = gd (Required to allow gd->xyz to work) */
+       movl    %eax, (%eax)
+
+       /* Setup global descriptor table so gd->xyz works */
+       call    setup_gdt
 
        /* Set parameter to board_init_f() to boot flags */
        xorl    %eax, %eax
@@ -113,9 +141,42 @@ board_init_f_r_trampoline:
         * %eax = Address of top of new stack
         */
 
-       /* Setup stack in RAM */
+       /* Stack grows down from top of SDRAM */
        movl    %eax, %esp
 
+       /* Reserve space on stack for global data */
+       subl    $GENERATED_GBL_DATA_SIZE, %esp
+
+       /* Align global data to 16-byte boundary */
+       andl    $0xfffffff0, %esp
+
+       /* Setup first parameter to memcpy (and setup_gdt) */
+       movl    %esp, %eax
+
+       /* Setup second parameter to memcpy */
+       fs movl 0, %edx
+
+       /* Set third parameter to memcpy */
+       movl    $GENERATED_GBL_DATA_SIZE, %ecx
+
+       /* Copy global data from CAR to SDRAM stack */
+       call    memcpy
+
+       /* Reserve space for global descriptor table */
+       subl    $X86_GDT_SIZE, %esp
+
+       /* Align global descriptor table to 16-byte boundary */
+       andl    $0xfffffff0, %esp
+
+       /* Set second parameter to setup_gdt */
+       movl    %esp, %edx
+
+       /* gd->gd_addr = gd (Required to allow gd->xyz to work) */
+       movl    %eax, (%eax)
+
+       /* Setup global descriptor table so gd->xyz works */
+       call    setup_gdt
+
        /* Re-enter U-Boot by calling board_init_f_r */
        call    board_init_f_r
 
index cc393ff54fccce6efe6cdf84df983bf03cb561ce..603bf1d2d3ecf8a05ae79c54e2bd4dd267800432 100644 (file)
@@ -37,6 +37,9 @@
 .code16
 .globl start16
 start16:
+       /* Set the Cold Boot / Hard Reset flag */
+       movl    $GD_FLG_COLD_BOOT, %ebx
+
        /*
         * First we let the BSP do some early initialization
         * this code have to map the flash to its final position
diff --git a/arch/x86/cpu/timer.c b/arch/x86/cpu/timer.c
new file mode 100644 (file)
index 0000000..149109d
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#include <common.h>
+
+unsigned long timer_get_us(void)
+{
+       printf("timer_get_us used but not implemented.\n");
+       return 0;
+}
index a1ecefafc64326bce747cfab1138c545651a35a8..0c6f0e31d8365309f0c6e19bb5cb04a9a423fdee 100644 (file)
@@ -86,6 +86,8 @@ SECTIONS
        __bios_start = LOADADDR(.bios);
        __bios_size = SIZEOF(.bios);
 
+#ifndef CONFIG_X86_NO_RESET_VECTOR
+
        /*
         * The following expressions place the 16-bit Real-Mode code and
         * Reset Vector at the end of the Flash ROM
@@ -95,4 +97,5 @@ SECTIONS
 
        . = RESET_VEC_LOC;
        .resetvec : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + RESET_VEC_LOC)) { KEEP(*(.resetvec)); }
+#endif
 }
diff --git a/arch/x86/dts/coreboot.dtsi b/arch/x86/dts/coreboot.dtsi
new file mode 100644 (file)
index 0000000..4862a59
--- /dev/null
@@ -0,0 +1,16 @@
+/include/ "skeleton.dtsi"
+
+/ {
+       aliases {
+               console = "/serial";
+       };
+
+       serial {
+               compatible = "ns16550";
+               reg-shift = <1>;
+               io-mapped = <1>;
+               multiplier = <1>;
+               baudrate = <115200>;
+               status = "disabled";
+       };
+};
diff --git a/arch/x86/dts/skeleton.dtsi b/arch/x86/dts/skeleton.dtsi
new file mode 100644 (file)
index 0000000..b41d241
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Skeleton device tree; the bare minimum needed to boot; just include and
+ * add a compatible value.  The bootloader will typically populate the memory
+ * node.
+ */
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       chosen { };
+       aliases { };
+       memory { device_type = "memory"; reg = <0 0>; };
+};
index 5c44e1a47cbbacc0cb46dd1ae79ff619feae29aa..77ae304969ca3fa8d831b51f73e009423f3f1120 100644 (file)
 #ifndef _COREBOOT_SYSINFO_H
 #define _COREBOOT_SYSINFO_H
 
+#include <common.h>
 #include <compiler.h>
+#include <fdt.h>
+#include <asm/arch/tables.h>
 
 /* Allow a maximum of 16 memory range definitions. */
 #define SYSINFO_MAX_MEM_RANGES 16
+/* Allow a maximum of 8 GPIOs */
+#define SYSINFO_MAX_GPIOS 8
 
 struct sysinfo_t {
-       unsigned int cpu_khz;
-       unsigned short ser_ioport;
-       unsigned long ser_base; /* for mmapped serial */
-
        int n_memranges;
-
        struct memrange {
                unsigned long long base;
                unsigned long long size;
                unsigned int type;
        } memrange[SYSINFO_MAX_MEM_RANGES];
 
-       struct cb_cmos_option_table *option_table;
        u32 cmos_range_start;
        u32 cmos_range_end;
        u32 cmos_checksum_location;
+       u32 vbnv_start;
+       u32 vbnv_size;
+
+       char *version;
+       char *extra_version;
+       char *build;
+       char *compile_time;
+       char *compile_by;
+       char *compile_host;
+       char *compile_domain;
+       char *compiler;
+       char *linker;
+       char *assembler;
 
        struct cb_framebuffer *framebuffer;
 
-       unsigned long *mbtable; /** Pointer to the multiboot table */
+       int num_gpios;
+       struct cb_gpio gpios[SYSINFO_MAX_GPIOS];
+
+       void    *vdat_addr;
+       u32     vdat_size;
+       void    *tstamp_table;
+       void    *cbmem_cons;
+
+       struct cb_serial *serial;
 };
 
 extern struct sysinfo_t lib_sysinfo;
index c28697375f783607e9a6cb2e35aff5c8c588509e..ad34a8b0f144fba918fe367c49cb25f57605119b 100644 (file)
@@ -164,6 +164,55 @@ struct cb_framebuffer {
        u8 reserved_mask_size;
 };
 
+#define CB_TAG_GPIO 0x0013
+#define GPIO_MAX_NAME_LENGTH 16
+struct cb_gpio {
+       u32 port;
+       u32 polarity;
+       u32 value;
+       u8 name[GPIO_MAX_NAME_LENGTH];
+};
+
+struct cb_gpios {
+       u32 tag;
+       u32 size;
+
+       u32 count;
+       struct cb_gpio gpios[0];
+};
+
+#define CB_TAG_FDT     0x0014
+struct cb_fdt {
+       uint32_t tag;
+       uint32_t size;  /* size of the entire entry */
+       /* the actual FDT gets placed here */
+};
+
+#define CB_TAG_VDAT    0x0015
+struct cb_vdat {
+       uint32_t tag;
+       uint32_t size;  /* size of the entire entry */
+       void     *vdat_addr;
+       uint32_t vdat_size;
+};
+
+#define CB_TAG_TIMESTAMPS      0x0016
+#define CB_TAG_CBMEM_CONSOLE   0x0017
+#define CB_TAG_MRC_CACHE       0x0018
+struct cb_cbmem_tab {
+       uint32_t tag;
+       uint32_t size;
+       void   *cbmem_tab;
+};
+
+#define CB_TAG_VBNV            0x0019
+struct cb_vbnv {
+       uint32_t tag;
+       uint32_t size;
+       uint32_t vbnv_start;
+       uint32_t vbnv_size;
+};
+
 #define CB_TAG_CMOS_OPTION_TABLE 0x00c8
 struct cb_cmos_option_table {
        u32 tag;
@@ -238,4 +287,29 @@ struct sysinfo_t;
 
 int get_coreboot_info(struct sysinfo_t *info);
 
+#define CBMEM_TOC_RESERVED      512
+#define MAX_CBMEM_ENTRIES       16
+#define CBMEM_MAGIC             0x434f5245
+
+struct cbmem_entry {
+       u32 magic;
+       u32 id;
+       u64 base;
+       u64 size;
+} __packed;
+
+#define CBMEM_ID_FREESPACE      0x46524545
+#define CBMEM_ID_GDT            0x4c474454
+#define CBMEM_ID_ACPI           0x41435049
+#define CBMEM_ID_CBTABLE        0x43425442
+#define CBMEM_ID_PIRQ           0x49525154
+#define CBMEM_ID_MPTABLE        0x534d5054
+#define CBMEM_ID_RESUME         0x5245534d
+#define CBMEM_ID_RESUME_SCRATCH 0x52455343
+#define CBMEM_ID_SMBIOS         0x534d4254
+#define CBMEM_ID_TIMESTAMP      0x54494d45
+#define CBMEM_ID_MRCDATA        0x4d524344
+#define CBMEM_ID_CONSOLE        0x434f4e53
+#define CBMEM_ID_NONE           0x00000000
+
 #endif
diff --git a/arch/x86/include/asm/arch-coreboot/timestamp.h b/arch/x86/include/asm/arch-coreboot/timestamp.h
new file mode 100644 (file)
index 0000000..d104912
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * 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 of the License.
+ *
+ * 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 St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#ifndef __COREBOOT_TIMESTAMP_H__
+#define __COREBOOT_TIMESTAMP_H__
+
+enum timestamp_id {
+       /* coreboot specific timestamp IDs */
+       TS_START_ROMSTAGE = 1,
+       TS_BEFORE_INITRAM = 2,
+       TS_AFTER_INITRAM = 3,
+       TS_END_ROMSTAGE = 4,
+       TS_START_COPYRAM = 8,
+       TS_END_COPYRAM = 9,
+       TS_START_RAMSTAGE = 10,
+       TS_DEVICE_ENUMERATE = 30,
+       TS_DEVICE_CONFIGURE = 40,
+       TS_DEVICE_ENABLE = 50,
+       TS_DEVICE_INITIALIZE = 60,
+       TS_DEVICE_DONE = 70,
+       TS_CBMEM_POST = 75,
+       TS_WRITE_TABLES = 80,
+       TS_LOAD_PAYLOAD = 90,
+       TS_ACPI_WAKE_JUMP = 98,
+       TS_SELFBOOT_JUMP = 99,
+
+       /* U-Boot entry IDs start at 1000 */
+       TS_U_BOOT_INITTED = 1000, /* This is where u-boot starts */
+       TS_U_BOOT_START_KERNEL = 1100, /* Right before jumping to kernel. */
+};
+
+void timestamp_init(void);
+void timestamp_add(enum timestamp_id id, uint64_t ts_time);
+void timestamp_add_now(enum timestamp_id id);
+
+#endif
index c7a38f237a5cf0bcbbcf996ff8ffc01698a62220..5a7e4cba2b2fb48786206331e64222fda5f9f865 100644 (file)
@@ -351,6 +351,11 @@ static __inline__ int ffs(int x)
 }
 #define PLATFORM_FFS
 
+static inline int __ilog2(unsigned int x)
+{
+       return generic_fls(x) - 1;
+}
+
 /**
  * hweightN - returns the hamming weight of a N-bit word
  * @x: the word to weigh
index 87c9e0be42b5a248f8bbe0929a57e4ea5838311e..d4678d4916fb24afbdb2c5bf41d7e536ea59a0e6 100644 (file)
 #define ARCH_DMA_MINALIGN      64
 #endif
 
+static inline void wbinvd(void)
+{
+       asm volatile ("wbinvd" : : : "memory");
+}
+
+static inline void invd(void)
+{
+       asm volatile("invd" : : : "memory");
+}
+
+/* Enable caches and write buffer */
+void enable_caches(void);
+
+/* Disable caches and write buffer */
+void disable_caches(void);
+
 #endif /* __X86_CACHE_H__ */
diff --git a/arch/x86/include/asm/control_regs.h b/arch/x86/include/asm/control_regs.h
new file mode 100644 (file)
index 0000000..aa8be30
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * (C) Copyright 2008-2011
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
+ *
+ * Portions of this file are derived from the Linux kernel source
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * 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 __X86_CONTROL_REGS_H
+#define __X86_CONTROL_REGS_H
+
+/*
+ * The memory clobber prevents the GCC from reordering the read/write order
+ * of CR0
+*/
+static inline unsigned long read_cr0(void)
+{
+       unsigned long val;
+
+       asm volatile ("movl %%cr0, %0" : "=r" (val) : : "memory");
+       return val;
+}
+
+static inline void write_cr0(unsigned long val)
+{
+       asm volatile ("movl %0, %%cr0" : : "r" (val) : "memory");
+}
+
+static inline unsigned long read_cr2(void)
+{
+       unsigned long val;
+
+       asm volatile("mov %%cr2,%0\n\t" : "=r" (val) : : "memory");
+       return val;
+}
+
+static inline unsigned long read_cr3(void)
+{
+       unsigned long val;
+
+       asm volatile("mov %%cr3,%0\n\t" : "=r" (val) : : "memory");
+       return val;
+}
+
+static inline unsigned long read_cr4(void)
+{
+       unsigned long val;
+
+       asm volatile("mov %%cr4,%0\n\t" : "=r" (val) : : "memory");
+       return val;
+}
+
+static inline unsigned long get_debugreg(int regno)
+{
+       unsigned long val = 0;  /* Damn you, gcc! */
+
+       switch (regno) {
+       case 0:
+               asm("mov %%db0, %0" : "=r" (val));
+               break;
+       case 1:
+               asm("mov %%db1, %0" : "=r" (val));
+               break;
+       case 2:
+               asm("mov %%db2, %0" : "=r" (val));
+               break;
+       case 3:
+               asm("mov %%db3, %0" : "=r" (val));
+               break;
+       case 6:
+               asm("mov %%db6, %0" : "=r" (val));
+               break;
+       case 7:
+               asm("mov %%db7, %0" : "=r" (val));
+               break;
+       default:
+               val = 0;
+       }
+       return val;
+}
+
+#endif
index bce999f41ce3ee1f80ac1b03a36eac5f8ff64ee4..dc6402b67dba5425a19d526749ca0d73db35806b 100644 (file)
 
 #ifndef __ASSEMBLY__
 
-typedef        struct global_data {
+#include <asm/u-boot.h>
+
+typedef struct global_data gd_t;
+
+struct global_data {
        /* NOTE: gd_addr MUST be first member of struct global_data! */
-       unsigned long   gd_addr;        /* Location of Global Data */
+       gd_t *gd_addr;  /* Location of Global Data */
        bd_t            *bd;
        unsigned long   flags;
        unsigned int    baudrate;
@@ -52,12 +56,12 @@ typedef     struct global_data {
        unsigned long   relocaddr;      /* Start address of U-Boot in RAM */
        unsigned long   start_addr_sp;  /* start_addr_stackpointer */
        unsigned long   gdt_addr;       /* Location of GDT */
-       unsigned long   new_gd_addr;    /* New location of Global Data */
        phys_size_t     ram_size;       /* RAM size */
        unsigned long   reset_status;   /* reset status register at boot */
+       const void      *fdt_blob;      /* Our device tree, NULL if none */
        void            **jt;           /* jump table */
        char            env_buf[32];    /* buffer for getenv() before reloc. */
-} gd_t;
+};
 
 static inline gd_t *get_fs_gd_ptr(void)
 {
@@ -74,6 +78,12 @@ static inline gd_t *get_fs_gd_ptr(void)
 
 #include <asm-generic/global_data_flags.h>
 
+/*
+ * Our private Global Data Flags
+ */
+#define GD_FLG_COLD_BOOT       0x00100 /* Cold Boot */
+#define GD_FLG_WARM_BOOT       0x00200 /* Warm Boot */
+
 #define DECLARE_GLOBAL_DATA_PTR
 
 #endif /* __ASM_GBL_DATA_H */
similarity index 68%
rename from arch/nios2/include/asm/status_led.h
rename to arch/x86/include/asm/gpio.h
index 20f8d90195530dd7e6cacc5acaa9f8437d363ce4..0a37a85ad1fe42e319fa078d534407dedde6a7d6 100644 (file)
@@ -1,7 +1,5 @@
 /*
- * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
- * Scott McNutt <smcnutt@psyent.com>
- *
+ * Copyright (c) 2012, Google Inc. All rights reserved.
  * See file CREDITS for list of people who contributed to this
  * project.
  *
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  */
-#ifndef __ASM_STATUS_LED_H__
-#define __ASM_STATUS_LED_H__
 
-typedef unsigned led_id_t;
-extern void __led_init (led_id_t mask, int state);
-extern void __led_set (led_id_t mask, int state);
-inline void __led_toggle (led_id_t mask);
+#ifndef _X86_GPIO_H_
+#define _X86_GPIO_H_
+
+#include <asm-generic/gpio.h>
 
-#endif /* __ASM_STATUS_LED_H__ */
+#endif /* _X86_GPIO_H_ */
index 8afb4432906b6d9e3c9431178ddb5b64ced998b7..2f437e034313f9734e05d1c9e9d5389a04cc3d7b 100644 (file)
@@ -29,7 +29,6 @@ int display_dram_config(void);
 int init_baudrate_f(void);
 int calculate_relocation_address(void);
 
-int copy_gd_to_ram_f_r(void);
 int init_cache_f_r(void);
 
 int set_reloc_flag_r(void);
@@ -38,5 +37,6 @@ int init_bd_struct_r(void);
 int flash_init_r(void);
 int status_led_set_r(void);
 int set_load_addr_r(void);
+int init_func_spi(void);
 
 #endif /* !_INIT_HELPERS_H_ */
index 9b757d489e38091700085f93a76293065f66af97..86bac90e8e882650829b7ce9177e5198339237a5 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
+#include <compiler.h>
+
 /*
  * This file contains the definitions for the x86 IO instructions
  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
@@ -36,6 +38,8 @@
 
 #define IO_SPACE_LIMIT 0xffff
 
+#include <asm/types.h>
+
 
 #ifdef __KERNEL__
 
@@ -135,7 +139,7 @@ out:
 #ifdef SLOW_IO_BY_JUMPING
 #define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
 #else
-#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
+#define __SLOW_DOWN_IO "\noutb %%al,$0xed"
 #endif
 
 #ifdef REALLY_SLOW_IO
@@ -218,7 +222,7 @@ static inline void sync(void)
 static inline void *
 map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
 {
-       return (void *)paddr;
+       return (void *)(uintptr_t)paddr;
 }
 
 /*
@@ -231,7 +235,15 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags)
 
 static inline phys_addr_t virt_to_phys(void * vaddr)
 {
-       return (phys_addr_t)(vaddr);
+       return (phys_addr_t)(uintptr_t)(vaddr);
 }
 
+/*
+ * TODO: The kernel offers some more advanced versions of barriers, it might
+ * have some advantages to use them instead of the simple one here.
+ */
+#define dmb()          __asm__ __volatile__ ("" : : : "memory")
+#define __iormb()      dmb()
+#define __iowmb()      dmb()
+
 #endif
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
new file mode 100644 (file)
index 0000000..5017599
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * Taken from the linux kernel file of the same name
+ *
+ * (C) Copyright 2012
+ * Graeme Russ, <graeme.russ@gmail.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
+ */
+
+#ifndef _ASM_X86_MSR_INDEX_H
+#define _ASM_X86_MSR_INDEX_H
+
+/* CPU model specific register (MSR) numbers */
+
+/* x86-64 specific MSRs */
+#define MSR_EFER               0xc0000080 /* extended feature register */
+#define MSR_STAR               0xc0000081 /* legacy mode SYSCALL target */
+#define MSR_LSTAR              0xc0000082 /* long mode SYSCALL target */
+#define MSR_CSTAR              0xc0000083 /* compat mode SYSCALL target */
+#define MSR_SYSCALL_MASK       0xc0000084 /* EFLAGS mask for syscall */
+#define MSR_FS_BASE            0xc0000100 /* 64bit FS base */
+#define MSR_GS_BASE            0xc0000101 /* 64bit GS base */
+#define MSR_KERNEL_GS_BASE     0xc0000102 /* SwapGS GS shadow */
+#define MSR_TSC_AUX            0xc0000103 /* Auxiliary TSC */
+
+/* EFER bits: */
+#define _EFER_SCE              0  /* SYSCALL/SYSRET */
+#define _EFER_LME              8  /* Long mode enable */
+#define _EFER_LMA              10 /* Long mode active (read-only) */
+#define _EFER_NX               11 /* No execute enable */
+#define _EFER_SVME             12 /* Enable virtualization */
+#define _EFER_LMSLE            13 /* Long Mode Segment Limit Enable */
+#define _EFER_FFXSR            14 /* Enable Fast FXSAVE/FXRSTOR */
+
+#define EFER_SCE               (1<<_EFER_SCE)
+#define EFER_LME               (1<<_EFER_LME)
+#define EFER_LMA               (1<<_EFER_LMA)
+#define EFER_NX                        (1<<_EFER_NX)
+#define EFER_SVME              (1<<_EFER_SVME)
+#define EFER_LMSLE             (1<<_EFER_LMSLE)
+#define EFER_FFXSR             (1<<_EFER_FFXSR)
+
+/* Intel MSRs. Some also available on other CPUs */
+#define MSR_IA32_PERFCTR0              0x000000c1
+#define MSR_IA32_PERFCTR1              0x000000c2
+#define MSR_FSB_FREQ                   0x000000cd
+
+#define MSR_NHM_SNB_PKG_CST_CFG_CTL    0x000000e2
+#define NHM_C3_AUTO_DEMOTE             (1UL << 25)
+#define NHM_C1_AUTO_DEMOTE             (1UL << 26)
+#define ATM_LNC_C6_AUTO_DEMOTE         (1UL << 25)
+
+#define MSR_MTRRcap                    0x000000fe
+#define MSR_IA32_BBL_CR_CTL            0x00000119
+#define MSR_IA32_BBL_CR_CTL3           0x0000011e
+
+#define MSR_IA32_SYSENTER_CS           0x00000174
+#define MSR_IA32_SYSENTER_ESP          0x00000175
+#define MSR_IA32_SYSENTER_EIP          0x00000176
+
+#define MSR_IA32_MCG_CAP               0x00000179
+#define MSR_IA32_MCG_STATUS            0x0000017a
+#define MSR_IA32_MCG_CTL               0x0000017b
+
+#define MSR_OFFCORE_RSP_0              0x000001a6
+#define MSR_OFFCORE_RSP_1              0x000001a7
+
+#define MSR_IA32_PEBS_ENABLE           0x000003f1
+#define MSR_IA32_DS_AREA               0x00000600
+#define MSR_IA32_PERF_CAPABILITIES     0x00000345
+
+#define MSR_MTRRfix64K_00000           0x00000250
+#define MSR_MTRRfix16K_80000           0x00000258
+#define MSR_MTRRfix16K_A0000           0x00000259
+#define MSR_MTRRfix4K_C0000            0x00000268
+#define MSR_MTRRfix4K_C8000            0x00000269
+#define MSR_MTRRfix4K_D0000            0x0000026a
+#define MSR_MTRRfix4K_D8000            0x0000026b
+#define MSR_MTRRfix4K_E0000            0x0000026c
+#define MSR_MTRRfix4K_E8000            0x0000026d
+#define MSR_MTRRfix4K_F0000            0x0000026e
+#define MSR_MTRRfix4K_F8000            0x0000026f
+#define MSR_MTRRdefType                        0x000002ff
+
+#define MSR_IA32_CR_PAT                        0x00000277
+
+#define MSR_IA32_DEBUGCTLMSR           0x000001d9
+#define MSR_IA32_LASTBRANCHFROMIP      0x000001db
+#define MSR_IA32_LASTBRANCHTOIP                0x000001dc
+#define MSR_IA32_LASTINTFROMIP         0x000001dd
+#define MSR_IA32_LASTINTTOIP           0x000001de
+
+/* DEBUGCTLMSR bits (others vary by model): */
+#define DEBUGCTLMSR_LBR                        (1UL <<  0)
+#define DEBUGCTLMSR_BTF                        (1UL <<  1)
+#define DEBUGCTLMSR_TR                 (1UL <<  6)
+#define DEBUGCTLMSR_BTS                        (1UL <<  7)
+#define DEBUGCTLMSR_BTINT              (1UL <<  8)
+#define DEBUGCTLMSR_BTS_OFF_OS         (1UL <<  9)
+#define DEBUGCTLMSR_BTS_OFF_USR                (1UL << 10)
+#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11)
+
+#define MSR_IA32_MC0_CTL               0x00000400
+#define MSR_IA32_MC0_STATUS            0x00000401
+#define MSR_IA32_MC0_ADDR              0x00000402
+#define MSR_IA32_MC0_MISC              0x00000403
+
+#define MSR_AMD64_MC0_MASK             0xc0010044
+
+#define MSR_IA32_MCx_CTL(x)            (MSR_IA32_MC0_CTL + 4*(x))
+#define MSR_IA32_MCx_STATUS(x)         (MSR_IA32_MC0_STATUS + 4*(x))
+#define MSR_IA32_MCx_ADDR(x)           (MSR_IA32_MC0_ADDR + 4*(x))
+#define MSR_IA32_MCx_MISC(x)           (MSR_IA32_MC0_MISC + 4*(x))
+
+#define MSR_AMD64_MCx_MASK(x)          (MSR_AMD64_MC0_MASK + (x))
+
+/* These are consecutive and not in the normal 4er MCE bank block */
+#define MSR_IA32_MC0_CTL2              0x00000280
+#define MSR_IA32_MCx_CTL2(x)           (MSR_IA32_MC0_CTL2 + (x))
+
+#define MSR_P6_PERFCTR0                        0x000000c1
+#define MSR_P6_PERFCTR1                        0x000000c2
+#define MSR_P6_EVNTSEL0                        0x00000186
+#define MSR_P6_EVNTSEL1                        0x00000187
+
+/* AMD64 MSRs. Not complete. See the architecture manual for a more
+   complete list. */
+
+#define MSR_AMD64_PATCH_LEVEL          0x0000008b
+#define MSR_AMD64_NB_CFG               0xc001001f
+#define MSR_AMD64_PATCH_LOADER         0xc0010020
+#define MSR_AMD64_OSVW_ID_LENGTH       0xc0010140
+#define MSR_AMD64_OSVW_STATUS          0xc0010141
+#define MSR_AMD64_DC_CFG               0xc0011022
+#define MSR_AMD64_IBSFETCHCTL          0xc0011030
+#define MSR_AMD64_IBSFETCHLINAD                0xc0011031
+#define MSR_AMD64_IBSFETCHPHYSAD       0xc0011032
+#define MSR_AMD64_IBSOPCTL             0xc0011033
+#define MSR_AMD64_IBSOPRIP             0xc0011034
+#define MSR_AMD64_IBSOPDATA            0xc0011035
+#define MSR_AMD64_IBSOPDATA2           0xc0011036
+#define MSR_AMD64_IBSOPDATA3           0xc0011037
+#define MSR_AMD64_IBSDCLINAD           0xc0011038
+#define MSR_AMD64_IBSDCPHYSAD          0xc0011039
+#define MSR_AMD64_IBSCTL               0xc001103a
+#define MSR_AMD64_IBSBRTARGET          0xc001103b
+
+/* Fam 15h MSRs */
+#define MSR_F15H_PERF_CTL              0xc0010200
+#define MSR_F15H_PERF_CTR              0xc0010201
+
+/* Fam 10h MSRs */
+#define MSR_FAM10H_MMIO_CONF_BASE      0xc0010058
+#define FAM10H_MMIO_CONF_ENABLE                (1<<0)
+#define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf
+#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
+#define FAM10H_MMIO_CONF_BASE_MASK     0xfffffffULL
+#define FAM10H_MMIO_CONF_BASE_SHIFT    20
+#define MSR_FAM10H_NODE_ID             0xc001100c
+
+/* K8 MSRs */
+#define MSR_K8_TOP_MEM1                        0xc001001a
+#define MSR_K8_TOP_MEM2                        0xc001001d
+#define MSR_K8_SYSCFG                  0xc0010010
+#define MSR_K8_INT_PENDING_MSG         0xc0010055
+/* C1E active bits in int pending message */
+#define K8_INTP_C1E_ACTIVE_MASK                0x18000000
+#define MSR_K8_TSEG_ADDR               0xc0010112
+#define K8_MTRRFIXRANGE_DRAM_ENABLE    0x00040000 /* MtrrFixDramEn bit    */
+#define K8_MTRRFIXRANGE_DRAM_MODIFY    0x00080000 /* MtrrFixDramModEn bit */
+#define K8_MTRR_RDMEM_WRMEM_MASK       0x18181818 /* Mask: RdMem|WrMem    */
+
+/* K7 MSRs */
+#define MSR_K7_EVNTSEL0                        0xc0010000
+#define MSR_K7_PERFCTR0                        0xc0010004
+#define MSR_K7_EVNTSEL1                        0xc0010001
+#define MSR_K7_PERFCTR1                        0xc0010005
+#define MSR_K7_EVNTSEL2                        0xc0010002
+#define MSR_K7_PERFCTR2                        0xc0010006
+#define MSR_K7_EVNTSEL3                        0xc0010003
+#define MSR_K7_PERFCTR3                        0xc0010007
+#define MSR_K7_CLK_CTL                 0xc001001b
+#define MSR_K7_HWCR                    0xc0010015
+#define MSR_K7_FID_VID_CTL             0xc0010041
+#define MSR_K7_FID_VID_STATUS          0xc0010042
+
+/* K6 MSRs */
+#define MSR_K6_WHCR                    0xc0000082
+#define MSR_K6_UWCCR                   0xc0000085
+#define MSR_K6_EPMR                    0xc0000086
+#define MSR_K6_PSOR                    0xc0000087
+#define MSR_K6_PFIR                    0xc0000088
+
+/* Centaur-Hauls/IDT defined MSRs. */
+#define MSR_IDT_FCR1                   0x00000107
+#define MSR_IDT_FCR2                   0x00000108
+#define MSR_IDT_FCR3                   0x00000109
+#define MSR_IDT_FCR4                   0x0000010a
+
+#define MSR_IDT_MCR0                   0x00000110
+#define MSR_IDT_MCR1                   0x00000111
+#define MSR_IDT_MCR2                   0x00000112
+#define MSR_IDT_MCR3                   0x00000113
+#define MSR_IDT_MCR4                   0x00000114
+#define MSR_IDT_MCR5                   0x00000115
+#define MSR_IDT_MCR6                   0x00000116
+#define MSR_IDT_MCR7                   0x00000117
+#define MSR_IDT_MCR_CTRL               0x00000120
+
+/* VIA Cyrix defined MSRs*/
+#define MSR_VIA_FCR                    0x00001107
+#define MSR_VIA_LONGHAUL               0x0000110a
+#define MSR_VIA_RNG                    0x0000110b
+#define MSR_VIA_BCR2                   0x00001147
+
+/* Transmeta defined MSRs */
+#define MSR_TMTA_LONGRUN_CTRL          0x80868010
+#define MSR_TMTA_LONGRUN_FLAGS         0x80868011
+#define MSR_TMTA_LRTI_READOUT          0x80868018
+#define MSR_TMTA_LRTI_VOLT_MHZ         0x8086801a
+
+/* Intel defined MSRs. */
+#define MSR_IA32_P5_MC_ADDR            0x00000000
+#define MSR_IA32_P5_MC_TYPE            0x00000001
+#define MSR_IA32_TSC                   0x00000010
+#define MSR_IA32_PLATFORM_ID           0x00000017
+#define MSR_IA32_EBL_CR_POWERON                0x0000002a
+#define MSR_EBC_FREQUENCY_ID           0x0000002c
+#define MSR_IA32_FEATURE_CONTROL        0x0000003a
+
+#define FEATURE_CONTROL_LOCKED                         (1<<0)
+#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX       (1<<1)
+#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX      (1<<2)
+
+#define MSR_IA32_APICBASE              0x0000001b
+#define MSR_IA32_APICBASE_BSP          (1<<8)
+#define MSR_IA32_APICBASE_ENABLE       (1<<11)
+#define MSR_IA32_APICBASE_BASE         (0xfffff<<12)
+
+#define MSR_IA32_UCODE_WRITE           0x00000079
+#define MSR_IA32_UCODE_REV             0x0000008b
+
+#define MSR_IA32_PERF_STATUS           0x00000198
+#define MSR_IA32_PERF_CTL              0x00000199
+
+#define MSR_IA32_MPERF                 0x000000e7
+#define MSR_IA32_APERF                 0x000000e8
+
+#define MSR_IA32_THERM_CONTROL         0x0000019a
+#define MSR_IA32_THERM_INTERRUPT       0x0000019b
+
+#define THERM_INT_HIGH_ENABLE          (1 << 0)
+#define THERM_INT_LOW_ENABLE           (1 << 1)
+#define THERM_INT_PLN_ENABLE           (1 << 24)
+
+#define MSR_IA32_THERM_STATUS          0x0000019c
+
+#define THERM_STATUS_PROCHOT           (1 << 0)
+#define THERM_STATUS_POWER_LIMIT       (1 << 10)
+
+#define MSR_THERM2_CTL                 0x0000019d
+
+#define MSR_THERM2_CTL_TM_SELECT       (1ULL << 16)
+
+#define MSR_IA32_MISC_ENABLE           0x000001a0
+
+#define MSR_IA32_TEMPERATURE_TARGET    0x000001a2
+
+#define MSR_IA32_ENERGY_PERF_BIAS      0x000001b0
+
+#define MSR_IA32_PACKAGE_THERM_STATUS          0x000001b1
+
+#define PACKAGE_THERM_STATUS_PROCHOT           (1 << 0)
+#define PACKAGE_THERM_STATUS_POWER_LIMIT       (1 << 10)
+
+#define MSR_IA32_PACKAGE_THERM_INTERRUPT       0x000001b2
+
+#define PACKAGE_THERM_INT_HIGH_ENABLE          (1 << 0)
+#define PACKAGE_THERM_INT_LOW_ENABLE           (1 << 1)
+#define PACKAGE_THERM_INT_PLN_ENABLE           (1 << 24)
+
+/* Thermal Thresholds Support */
+#define THERM_INT_THRESHOLD0_ENABLE    (1 << 15)
+#define THERM_SHIFT_THRESHOLD0        8
+#define THERM_MASK_THRESHOLD0          (0x7f << THERM_SHIFT_THRESHOLD0)
+#define THERM_INT_THRESHOLD1_ENABLE    (1 << 23)
+#define THERM_SHIFT_THRESHOLD1        16
+#define THERM_MASK_THRESHOLD1          (0x7f << THERM_SHIFT_THRESHOLD1)
+#define THERM_STATUS_THRESHOLD0        (1 << 6)
+#define THERM_LOG_THRESHOLD0           (1 << 7)
+#define THERM_STATUS_THRESHOLD1        (1 << 8)
+#define THERM_LOG_THRESHOLD1           (1 << 9)
+
+/* MISC_ENABLE bits: architectural */
+#define MSR_IA32_MISC_ENABLE_FAST_STRING       (1ULL << 0)
+#define MSR_IA32_MISC_ENABLE_TCC               (1ULL << 1)
+#define MSR_IA32_MISC_ENABLE_EMON              (1ULL << 7)
+#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL       (1ULL << 11)
+#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL      (1ULL << 12)
+#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP        (1ULL << 16)
+#define MSR_IA32_MISC_ENABLE_MWAIT             (1ULL << 18)
+#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID       (1ULL << 22)
+#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE      (1ULL << 23)
+#define MSR_IA32_MISC_ENABLE_XD_DISABLE                (1ULL << 34)
+
+/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */
+#define MSR_IA32_MISC_ENABLE_X87_COMPAT                (1ULL << 2)
+#define MSR_IA32_MISC_ENABLE_TM1               (1ULL << 3)
+#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE        (1ULL << 4)
+#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE   (1ULL << 6)
+#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK     (1ULL << 8)
+#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE  (1ULL << 9)
+#define MSR_IA32_MISC_ENABLE_FERR              (1ULL << 10)
+#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX    (1ULL << 10)
+#define MSR_IA32_MISC_ENABLE_TM2               (1ULL << 13)
+#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE  (1ULL << 19)
+#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK    (1ULL << 20)
+#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT       (1ULL << 24)
+#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE  (1ULL << 37)
+#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE     (1ULL << 38)
+#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE   (1ULL << 39)
+
+/* P4/Xeon+ specific */
+#define MSR_IA32_MCG_EAX               0x00000180
+#define MSR_IA32_MCG_EBX               0x00000181
+#define MSR_IA32_MCG_ECX               0x00000182
+#define MSR_IA32_MCG_EDX               0x00000183
+#define MSR_IA32_MCG_ESI               0x00000184
+#define MSR_IA32_MCG_EDI               0x00000185
+#define MSR_IA32_MCG_EBP               0x00000186
+#define MSR_IA32_MCG_ESP               0x00000187
+#define MSR_IA32_MCG_EFLAGS            0x00000188
+#define MSR_IA32_MCG_EIP               0x00000189
+#define MSR_IA32_MCG_RESERVED          0x0000018a
+
+/* Pentium IV performance counter MSRs */
+#define MSR_P4_BPU_PERFCTR0            0x00000300
+#define MSR_P4_BPU_PERFCTR1            0x00000301
+#define MSR_P4_BPU_PERFCTR2            0x00000302
+#define MSR_P4_BPU_PERFCTR3            0x00000303
+#define MSR_P4_MS_PERFCTR0             0x00000304
+#define MSR_P4_MS_PERFCTR1             0x00000305
+#define MSR_P4_MS_PERFCTR2             0x00000306
+#define MSR_P4_MS_PERFCTR3             0x00000307
+#define MSR_P4_FLAME_PERFCTR0          0x00000308
+#define MSR_P4_FLAME_PERFCTR1          0x00000309
+#define MSR_P4_FLAME_PERFCTR2          0x0000030a
+#define MSR_P4_FLAME_PERFCTR3          0x0000030b
+#define MSR_P4_IQ_PERFCTR0             0x0000030c
+#define MSR_P4_IQ_PERFCTR1             0x0000030d
+#define MSR_P4_IQ_PERFCTR2             0x0000030e
+#define MSR_P4_IQ_PERFCTR3             0x0000030f
+#define MSR_P4_IQ_PERFCTR4             0x00000310
+#define MSR_P4_IQ_PERFCTR5             0x00000311
+#define MSR_P4_BPU_CCCR0               0x00000360
+#define MSR_P4_BPU_CCCR1               0x00000361
+#define MSR_P4_BPU_CCCR2               0x00000362
+#define MSR_P4_BPU_CCCR3               0x00000363
+#define MSR_P4_MS_CCCR0                        0x00000364
+#define MSR_P4_MS_CCCR1                        0x00000365
+#define MSR_P4_MS_CCCR2                        0x00000366
+#define MSR_P4_MS_CCCR3                        0x00000367
+#define MSR_P4_FLAME_CCCR0             0x00000368
+#define MSR_P4_FLAME_CCCR1             0x00000369
+#define MSR_P4_FLAME_CCCR2             0x0000036a
+#define MSR_P4_FLAME_CCCR3             0x0000036b
+#define MSR_P4_IQ_CCCR0                        0x0000036c
+#define MSR_P4_IQ_CCCR1                        0x0000036d
+#define MSR_P4_IQ_CCCR2                        0x0000036e
+#define MSR_P4_IQ_CCCR3                        0x0000036f
+#define MSR_P4_IQ_CCCR4                        0x00000370
+#define MSR_P4_IQ_CCCR5                        0x00000371
+#define MSR_P4_ALF_ESCR0               0x000003ca
+#define MSR_P4_ALF_ESCR1               0x000003cb
+#define MSR_P4_BPU_ESCR0               0x000003b2
+#define MSR_P4_BPU_ESCR1               0x000003b3
+#define MSR_P4_BSU_ESCR0               0x000003a0
+#define MSR_P4_BSU_ESCR1               0x000003a1
+#define MSR_P4_CRU_ESCR0               0x000003b8
+#define MSR_P4_CRU_ESCR1               0x000003b9
+#define MSR_P4_CRU_ESCR2               0x000003cc
+#define MSR_P4_CRU_ESCR3               0x000003cd
+#define MSR_P4_CRU_ESCR4               0x000003e0
+#define MSR_P4_CRU_ESCR5               0x000003e1
+#define MSR_P4_DAC_ESCR0               0x000003a8
+#define MSR_P4_DAC_ESCR1               0x000003a9
+#define MSR_P4_FIRM_ESCR0              0x000003a4
+#define MSR_P4_FIRM_ESCR1              0x000003a5
+#define MSR_P4_FLAME_ESCR0             0x000003a6
+#define MSR_P4_FLAME_ESCR1             0x000003a7
+#define MSR_P4_FSB_ESCR0               0x000003a2
+#define MSR_P4_FSB_ESCR1               0x000003a3
+#define MSR_P4_IQ_ESCR0                        0x000003ba
+#define MSR_P4_IQ_ESCR1                        0x000003bb
+#define MSR_P4_IS_ESCR0                        0x000003b4
+#define MSR_P4_IS_ESCR1                        0x000003b5
+#define MSR_P4_ITLB_ESCR0              0x000003b6
+#define MSR_P4_ITLB_ESCR1              0x000003b7
+#define MSR_P4_IX_ESCR0                        0x000003c8
+#define MSR_P4_IX_ESCR1                        0x000003c9
+#define MSR_P4_MOB_ESCR0               0x000003aa
+#define MSR_P4_MOB_ESCR1               0x000003ab
+#define MSR_P4_MS_ESCR0                        0x000003c0
+#define MSR_P4_MS_ESCR1                        0x000003c1
+#define MSR_P4_PMH_ESCR0               0x000003ac
+#define MSR_P4_PMH_ESCR1               0x000003ad
+#define MSR_P4_RAT_ESCR0               0x000003bc
+#define MSR_P4_RAT_ESCR1               0x000003bd
+#define MSR_P4_SAAT_ESCR0              0x000003ae
+#define MSR_P4_SAAT_ESCR1              0x000003af
+#define MSR_P4_SSU_ESCR0               0x000003be
+#define MSR_P4_SSU_ESCR1               0x000003bf /* guess: not in manual */
+
+#define MSR_P4_TBPU_ESCR0              0x000003c2
+#define MSR_P4_TBPU_ESCR1              0x000003c3
+#define MSR_P4_TC_ESCR0                        0x000003c4
+#define MSR_P4_TC_ESCR1                        0x000003c5
+#define MSR_P4_U2L_ESCR0               0x000003b0
+#define MSR_P4_U2L_ESCR1               0x000003b1
+
+#define MSR_P4_PEBS_MATRIX_VERT                0x000003f2
+
+/* Intel Core-based CPU performance counters */
+#define MSR_CORE_PERF_FIXED_CTR0       0x00000309
+#define MSR_CORE_PERF_FIXED_CTR1       0x0000030a
+#define MSR_CORE_PERF_FIXED_CTR2       0x0000030b
+#define MSR_CORE_PERF_FIXED_CTR_CTRL   0x0000038d
+#define MSR_CORE_PERF_GLOBAL_STATUS    0x0000038e
+#define MSR_CORE_PERF_GLOBAL_CTRL      0x0000038f
+#define MSR_CORE_PERF_GLOBAL_OVF_CTRL  0x00000390
+
+/* Geode defined MSRs */
+#define MSR_GEODE_BUSCONT_CONF0                0x00001900
+
+/* Intel VT MSRs */
+#define MSR_IA32_VMX_BASIC              0x00000480
+#define MSR_IA32_VMX_PINBASED_CTLS      0x00000481
+#define MSR_IA32_VMX_PROCBASED_CTLS     0x00000482
+#define MSR_IA32_VMX_EXIT_CTLS          0x00000483
+#define MSR_IA32_VMX_ENTRY_CTLS         0x00000484
+#define MSR_IA32_VMX_MISC               0x00000485
+#define MSR_IA32_VMX_CR0_FIXED0         0x00000486
+#define MSR_IA32_VMX_CR0_FIXED1         0x00000487
+#define MSR_IA32_VMX_CR4_FIXED0         0x00000488
+#define MSR_IA32_VMX_CR4_FIXED1         0x00000489
+#define MSR_IA32_VMX_VMCS_ENUM          0x0000048a
+#define MSR_IA32_VMX_PROCBASED_CTLS2    0x0000048b
+#define MSR_IA32_VMX_EPT_VPID_CAP       0x0000048c
+
+/* AMD-V MSRs */
+
+#define MSR_VM_CR                       0xc0010114
+#define MSR_VM_IGNNE                    0xc0010115
+#define MSR_VM_HSAVE_PA                 0xc0010117
+
+#endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
new file mode 100644 (file)
index 0000000..6030633
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Taken from the linux kernel file of the same name
+ *
+ * (C) Copyright 2012
+ * Graeme Russ, <graeme.russ@gmail.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
+ */
+
+#ifndef _ASM_X86_MSR_H
+#define _ASM_X86_MSR_H
+
+#include <asm/msr-index.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define X86_IOC_RDMSR_REGS     _IOWR('c', 0xA0, __u32[8])
+#define X86_IOC_WRMSR_REGS     _IOWR('c', 0xA1, __u32[8])
+
+#ifdef __KERNEL__
+
+#include <asm/errno.h>
+
+struct msr {
+       union {
+               struct {
+                       u32 l;
+                       u32 h;
+               };
+               u64 q;
+       };
+};
+
+struct msr_info {
+       u32 msr_no;
+       struct msr reg;
+       struct msr *msrs;
+       int err;
+};
+
+struct msr_regs_info {
+       u32 *regs;
+       int err;
+};
+
+static inline unsigned long long native_read_tscp(unsigned int *aux)
+{
+       unsigned long low, high;
+       asm volatile(".byte 0x0f,0x01,0xf9"
+                    : "=a" (low), "=d" (high), "=c" (*aux));
+       return low | ((u64)high << 32);
+}
+
+/*
+ * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
+ * constraint has different meanings. For i386, "A" means exactly
+ * edx:eax, while for x86_64 it doesn't mean rdx:rax or edx:eax. Instead,
+ * it means rax *or* rdx.
+ */
+#ifdef CONFIG_X86_64
+#define DECLARE_ARGS(val, low, high)   unsigned low, high
+#define EAX_EDX_VAL(val, low, high)    ((low) | ((u64)(high) << 32))
+#define EAX_EDX_ARGS(val, low, high)   "a" (low), "d" (high)
+#define EAX_EDX_RET(val, low, high)    "=a" (low), "=d" (high)
+#else
+#define DECLARE_ARGS(val, low, high)   unsigned long long val
+#define EAX_EDX_VAL(val, low, high)    (val)
+#define EAX_EDX_ARGS(val, low, high)   "A" (val)
+#define EAX_EDX_RET(val, low, high)    "=A" (val)
+#endif
+
+static inline unsigned long long native_read_msr(unsigned int msr)
+{
+       DECLARE_ARGS(val, low, high);
+
+       asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+       return EAX_EDX_VAL(val, low, high);
+}
+
+static inline void native_write_msr(unsigned int msr,
+                                   unsigned low, unsigned high)
+{
+       asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+}
+
+extern unsigned long long native_read_tsc(void);
+
+extern int native_rdmsr_safe_regs(u32 regs[8]);
+extern int native_wrmsr_safe_regs(u32 regs[8]);
+
+static inline unsigned long long native_read_pmc(int counter)
+{
+       DECLARE_ARGS(val, low, high);
+
+       asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
+       return EAX_EDX_VAL(val, low, high);
+}
+
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else
+#include <errno.h>
+/*
+ * Access to machine-specific registers (available on 586 and better only)
+ * Note: the rd* operations modify the parameters directly (without using
+ * pointer indirection), this allows gcc to optimize better
+ */
+
+#define rdmsr(msr, val1, val2)                                 \
+do {                                                           \
+       u64 __val = native_read_msr((msr));                     \
+       (void)((val1) = (u32)__val);                            \
+       (void)((val2) = (u32)(__val >> 32));                    \
+} while (0)
+
+static inline void wrmsr(unsigned msr, unsigned low, unsigned high)
+{
+       native_write_msr(msr, low, high);
+}
+
+#define rdmsrl(msr, val)                       \
+       ((val) = native_read_msr((msr)))
+
+#define wrmsrl(msr, val)                                               \
+       native_write_msr((msr), (u32)((u64)(val)), (u32)((u64)(val) >> 32))
+
+/* rdmsr with exception handling */
+#define rdmsr_safe(msr, p1, p2)                                        \
+({                                                             \
+       int __err;                                              \
+       u64 __val = native_read_msr_safe((msr), &__err);        \
+       (*p1) = (u32)__val;                                     \
+       (*p2) = (u32)(__val >> 32);                             \
+       __err;                                                  \
+})
+
+static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
+{
+       u32 gprs[8] = { 0 };
+       int err;
+
+       gprs[1] = msr;
+       gprs[7] = 0x9c5a203a;
+
+       err = native_rdmsr_safe_regs(gprs);
+
+       *p = gprs[0] | ((u64)gprs[2] << 32);
+
+       return err;
+}
+
+static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
+{
+       u32 gprs[8] = { 0 };
+
+       gprs[0] = (u32)val;
+       gprs[1] = msr;
+       gprs[2] = val >> 32;
+       gprs[7] = 0x9c5a203a;
+
+       return native_wrmsr_safe_regs(gprs);
+}
+
+static inline int rdmsr_safe_regs(u32 regs[8])
+{
+       return native_rdmsr_safe_regs(regs);
+}
+
+static inline int wrmsr_safe_regs(u32 regs[8])
+{
+       return native_wrmsr_safe_regs(regs);
+}
+
+#define rdtscl(low)                                            \
+       ((low) = (u32)__native_read_tsc())
+
+#define rdtscll(val)                                           \
+       ((val) = __native_read_tsc())
+
+#define rdpmc(counter, low, high)                      \
+do {                                                   \
+       u64 _l = native_read_pmc((counter));            \
+       (low)  = (u32)_l;                               \
+       (high) = (u32)(_l >> 32);                       \
+} while (0)
+
+#define rdtscp(low, high, aux)                                 \
+do {                                                            \
+       unsigned long long _val = native_read_tscp(&(aux));     \
+       (low) = (u32)_val;                                      \
+       (high) = (u32)(_val >> 32);                             \
+} while (0)
+
+#define rdtscpll(val, aux) (val) = native_read_tscp(&(aux))
+
+#endif /* !CONFIG_PARAVIRT */
+
+
+#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val),                \
+                                            (u32)((val) >> 32))
+
+#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
+
+#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
+
+struct msr *msrs_alloc(void);
+void msrs_free(struct msr *msrs);
+
+#ifdef CONFIG_SMP
+int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
+int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
+int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
+int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
+int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
+int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
+
+#endif  /* CONFIG_SMP */
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_X86_MSR_H */
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
new file mode 100644 (file)
index 0000000..6842da5
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Generic MTRR (Memory Type Range Register) ioctls.
+ * Taken from the Linux kernel
+ *
+ * (C) Copyright 2012
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * Copyright (C) 1997-1999  Richard Gooch <rgooch@atnf.csiro.au>
+ *
+ * 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_MTRR_H
+#define _ASM_X86_MTRR_H
+
+#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
+#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <errno.h>
+
+#define        MTRR_IOCTL_BASE 'M'
+
+struct mtrr_sentry {
+       unsigned long base;     /*  Base address     */
+       unsigned int size;      /*  Size of region   */
+       unsigned int type;      /*  Type of region   */
+};
+
+/*
+ * Warning: this structure has a different order from i386
+ * on x86-64. The 32bit emulation code takes care of that.
+ * But you need to use this for 64bit, otherwise your X server
+ * will break.
+ */
+
+#ifdef __i386__
+struct mtrr_gentry {
+       unsigned int regnum;    /*  Register number  */
+       unsigned long base;     /*  Base address     */
+       unsigned int size;      /*  Size of region   */
+       unsigned int type;      /*  Type of region   */
+};
+
+#else /* __i386__ */
+
+struct mtrr_gentry {
+       unsigned long base;     /*  Base address     */
+       unsigned int size;      /*  Size of region   */
+       unsigned int regnum;    /*  Register number  */
+       unsigned int type;      /*  Type of region   */
+};
+#endif /* !__i386__ */
+
+struct mtrr_var_range {
+       __u32 base_lo;
+       __u32 base_hi;
+       __u32 mask_lo;
+       __u32 mask_hi;
+};
+
+/*
+ * In the Intel processor's MTRR interface, the MTRR type is always held in
+ * an 8 bit field:
+ */
+typedef __u8 mtrr_type;
+
+#define MTRR_NUM_FIXED_RANGES 88
+#define MTRR_MAX_VAR_RANGES 256
+
+struct mtrr_state_type {
+       struct mtrr_var_range var_ranges[MTRR_MAX_VAR_RANGES];
+       mtrr_type fixed_ranges[MTRR_NUM_FIXED_RANGES];
+       unsigned char enabled;
+       unsigned char have_fixed;
+       mtrr_type def_type;
+};
+
+/*  These are the various ioctls  */
+#define MTRRIOC_ADD_ENTRY        _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry)
+#define MTRRIOC_SET_ENTRY        _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry)
+#define MTRRIOC_DEL_ENTRY        _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry)
+#define MTRRIOC_GET_ENTRY        _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry)
+#define MTRRIOC_KILL_ENTRY       _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry)
+#define MTRRIOC_ADD_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry)
+#define MTRRIOC_SET_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry)
+#define MTRRIOC_DEL_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry)
+#define MTRRIOC_GET_PAGE_ENTRY   _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry)
+#define MTRRIOC_KILL_PAGE_ENTRY  _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry)
+
+/*  These are the region types  */
+#define MTRR_TYPE_UNCACHABLE 0
+#define MTRR_TYPE_WRCOMB     1
+/*#define MTRR_TYPE_         2*/
+/*#define MTRR_TYPE_         3*/
+#define MTRR_TYPE_WRTHROUGH  4
+#define MTRR_TYPE_WRPROT     5
+#define MTRR_TYPE_WRBACK     6
+#define MTRR_NUM_TYPES       7
+
+#ifdef __KERNEL__
+
+/*  The following functions are for use by other drivers  */
+# ifdef CONFIG_MTRR
+extern u8 mtrr_type_lookup(u64 addr, u64 end);
+extern void mtrr_save_fixed_ranges(void *);
+extern void mtrr_save_state(void);
+extern int mtrr_add(unsigned long base, unsigned long size,
+                   unsigned int type, bool increment);
+extern int mtrr_add_page(unsigned long base, unsigned long size,
+                        unsigned int type, bool increment);
+extern int mtrr_del(int reg, unsigned long base, unsigned long size);
+extern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
+extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
+extern void mtrr_ap_init(void);
+extern void mtrr_bp_init(void);
+extern void set_mtrr_aps_delayed_init(void);
+extern void mtrr_aps_init(void);
+extern void mtrr_bp_restore(void);
+extern int mtrr_trim_uncached_memory(unsigned long end_pfn);
+extern int amd_special_default_mtrr(void);
+#  else
+static inline u8 mtrr_type_lookup(u64 addr, u64 end)
+{
+       /*
+        * Return no-MTRRs:
+        */
+       return 0xff;
+}
+#define mtrr_save_fixed_ranges(arg) do {} while (0)
+#define mtrr_save_state() do {} while (0)
+static inline int mtrr_del(int reg, unsigned long base, unsigned long size)
+{
+       return -ENODEV;
+}
+static inline int mtrr_del_page(int reg, unsigned long base, unsigned long size)
+{
+       return -ENODEV;
+}
+static inline int mtrr_trim_uncached_memory(unsigned long end_pfn)
+{
+       return 0;
+}
+static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
+{
+}
+
+#define mtrr_ap_init() do {} while (0)
+#define mtrr_bp_init() do {} while (0)
+#define set_mtrr_aps_delayed_init() do {} while (0)
+#define mtrr_aps_init() do {} while (0)
+#define mtrr_bp_restore() do {} while (0)
+#  endif
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+
+struct mtrr_sentry32 {
+       compat_ulong_t base;    /*  Base address     */
+       compat_uint_t size;     /*  Size of region   */
+       compat_uint_t type;     /*  Type of region   */
+};
+
+struct mtrr_gentry32 {
+       compat_ulong_t regnum;  /*  Register number  */
+       compat_uint_t base;     /*  Base address     */
+       compat_uint_t size;     /*  Size of region   */
+       compat_uint_t type;     /*  Type of region   */
+};
+
+#define MTRR_IOCTL_BASE 'M'
+
+#define MTRRIOC32_ADD_ENTRY      _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry32)
+#define MTRRIOC32_SET_ENTRY      _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_ENTRY      _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry32)
+#define MTRRIOC32_GET_ENTRY      _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_ENTRY     _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry32)
+#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry32)
+#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry32)
+#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_PAGE_ENTRY              \
+                                _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry32)
+#endif /* CONFIG_COMPAT */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_X86_MTRR_H */
index 37cc7e3a0f849f59ed561a6ba44a319f00b0798e..6d68ab6c92623e38dfd591f89cf70ce5d888de19 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #ifndef _PCI_I386_H_
-#define _PCI_I386_H_   1
+#define _PCI_I386_H_
 
 #define DEFINE_PCI_DEVICE_TABLE(_table) \
        const struct pci_device_id _table[]
index 6eb518063bd8ec031706f778c83710004952cfb8..17f27cbb68468c31079433dc7cadc1df8b894458 100644 (file)
@@ -41,6 +41,7 @@ enum {
 #else
 /* NOTE: If the above enum is modified, this define must be checked */
 #define X86_GDT_ENTRY_32BIT_DS 3
+#define X86_GDT_NUM_ENTRIES    7
 #endif
 
 #define X86_GDT_SIZE           (X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE)
index 9a40e383eb35afc93ac0b07cbded5530908b4a18..e9fde88f7d4a52a414d7a44d655185f61f3c96b8 100644 (file)
@@ -45,8 +45,8 @@ typedef unsigned long long u64;
 
 typedef u32 dma_addr_t;
 
-typedef unsigned long phys_addr_t;
-typedef unsigned long phys_size_t;
+typedef unsigned long long phys_addr_t;
+typedef unsigned long long phys_size_t;
 
 #endif /* __KERNEL__ */
 
index 878a1ee77b116da67f5b9a43179f395c8daefe95..99062e5955356dc9cd755b7e16ea1eb5d19e093f 100644 (file)
@@ -40,6 +40,7 @@ int cpu_init_f(void);
 void init_gd(gd_t *id, u64 *gdt_addr);
 void setup_gdt(gd_t *id, u64 *gdt_addr);
 int init_cache(void);
+int cleanup_before_linux(void);
 
 /* cpu/.../timer.c */
 void timer_isr(void *);
@@ -62,9 +63,20 @@ u32 isa_map_rom(u32 bus_addr, int size);
 
 /* arch/x86/lib/... */
 int video_bios_init(void);
-int video_init(void);
 
 void   board_init_f_r_trampoline(ulong) __attribute__ ((noreturn));
 void   board_init_f_r(void) __attribute__ ((noreturn));
 
+/* Read the time stamp counter */
+static inline uint64_t rdtsc(void)
+{
+       uint32_t high, low;
+       __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
+       return (((uint64_t)high) << 32) | low;
+}
+
+/* board/... */
+void timer_set_tsc_base(uint64_t new_base);
+uint64_t timer_get_tsc(void);
+
 #endif /* _U_BOOT_I386_H_ */
index da667c50a498c1bad8c29f7134175598be891429..2f45c7b3d749fada710dc8f7605f58f169c25d41 100644 (file)
@@ -36,6 +36,9 @@
 #ifndef _U_BOOT_H_
 #define _U_BOOT_H_     1
 
+#include <config.h>
+#include <compiler.h>
+
 typedef struct bd_info {
        unsigned long   bi_memstart;    /* start of DRAM memory */
        phys_size_t     bi_memsize;     /* size  of DRAM memory in bytes */
index 51836dacca5823b4cc64fbdb04c54c9a8d3f8e4e..0a52cc896c6b9c36b920f7d3fc91fdd3a2c17603 100644 (file)
@@ -25,11 +25,16 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(ARCH).o
 
+ifeq ($(CONFIG_X86_NO_REAL_MODE),)
 SOBJS-$(CONFIG_SYS_PC_BIOS)    += bios.o
 SOBJS-$(CONFIG_SYS_PCI_BIOS)   += bios_pci.o
-SOBJS-$(CONFIG_SYS_X86_REALMODE)       += realmode_switch.o
+COBJS-y        += realmode.o
+SOBJS-y        += realmode_switch.o
 
 COBJS-$(CONFIG_SYS_PC_BIOS)    += bios_setup.o
+COBJS-$(CONFIG_VIDEO_VGA)      += video_bios.o
+endif
+
 COBJS-y        += board.o
 COBJS-y        += bootm.o
 COBJS-y        += cmd_boot.o
@@ -41,12 +46,11 @@ COBJS-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
 COBJS-$(CONFIG_SYS_GENERIC_TIMER) += pcat_timer.o
 COBJS-$(CONFIG_PCI) += pci.o
 COBJS-$(CONFIG_PCI) += pci_type1.o
-COBJS-$(CONFIG_SYS_X86_REALMODE)       += realmode.o
 COBJS-y        += relocate.o
+COBJS-y += physmem.o
 COBJS-y        += string.o
 COBJS-$(CONFIG_SYS_X86_ISR_TIMER)      += timer.o
-COBJS-$(CONFIG_VIDEO)  += video_bios.o
-COBJS-$(CONFIG_VIDEO)  += video.o
+COBJS-$(CONFIG_VIDEO_VGA)      += video.o
 COBJS-$(CONFIG_CMD_ZBOOT)      += zimage.o
 
 SRCS   := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
index e5caf13561b1585cfd36842c15aa0e9156d583c4..22bc26dde90643f1e8a82ae88564624c8f6bdd70 100644 (file)
@@ -36,6 +36,7 @@
 #include <stdio_dev.h>
 #include <asm/u-boot-x86.h>
 #include <asm/relocate.h>
+#include <asm/processor.h>
 
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
@@ -98,10 +99,17 @@ typedef int (init_fnc_t) (void);
 init_fnc_t *init_sequence_f[] = {
        cpu_init_f,
        board_early_init_f,
+#ifdef CONFIG_OF_CONTROL
+       find_fdt,
+       fdtdec_check_fdt,
+#endif
        env_init,
        init_baudrate_f,
        serial_init,
        console_init_f,
+#ifdef CONFIG_OF_CONTROL
+       prepare_fdt,
+#endif
        dram_init_f,
        calculate_relocation_address,
 
@@ -121,7 +129,6 @@ init_fnc_t *init_sequence_f[] = {
  * initialise the CPU caches (to speed up the relocation process)
  */
 init_fnc_t *init_sequence_f_r[] = {
-       copy_gd_to_ram_f_r,
        init_cache_f_r,
        copy_uboot_to_ram,
        clear_bss,
@@ -153,6 +160,9 @@ init_fnc_t *init_sequence_r[] = {
        serial_initialize_r,
 #ifndef CONFIG_SYS_NO_FLASH
        flash_init_r,
+#endif
+#ifdef CONFIG_SPI
+       init_func_spi;
 #endif
        env_relocate_r,
 #ifdef CONFIG_PCI
@@ -164,9 +174,6 @@ init_fnc_t *init_sequence_r[] = {
 #ifdef CONFIG_MISC_INIT_R
        misc_init_r,
 #endif
-#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)
-       pci_init_r,
-#endif
 #if defined(CONFIG_CMD_KGDB)
        kgdb_init_r,
 #endif
index 9ec34ff992baec321687243d25b9b11da4ee51c6..3eec9a61d66a680b81ed6c310f938c6dae880623 100644 (file)
 #include <net.h>
 #include <ide.h>
 #include <serial.h>
+#include <spi.h>
 #include <status_led.h>
 #include <asm/processor.h>
 #include <asm/u-boot-x86.h>
+#include <linux/compiler.h>
 
 #include <asm/init_helpers.h>
 
@@ -71,7 +73,7 @@ int init_baudrate_f(void)
        return 0;
 }
 
-int calculate_relocation_address(void)
+__weak int calculate_relocation_address(void)
 {
        ulong text_start = (ulong)&__text_start;
        ulong bss_end = (ulong)&__bss_end;
@@ -83,51 +85,17 @@ int calculate_relocation_address(void)
         *       requirements
         */
 
-       /* Global Data is at top of available memory */
+       /* Stack is at top of available memory */
        dest_addr = gd->ram_size;
-       dest_addr -= GENERATED_GBL_DATA_SIZE;
-       dest_addr &= ~15;
-       gd->new_gd_addr = dest_addr;
-
-       /* GDT is below Global Data */
-       dest_addr -= X86_GDT_SIZE;
-       dest_addr &= ~15;
-       gd->gdt_addr = dest_addr;
-
-       /* Stack is below GDT */
-       gd->start_addr_sp = dest_addr;
 
-       /* U-Boot is below the stack */
-       dest_addr -= CONFIG_SYS_STACK_SIZE;
+       /* U-Boot is at the top */
        dest_addr -= (bss_end - text_start);
        dest_addr &= ~15;
        gd->relocaddr = dest_addr;
        gd->reloc_off = (dest_addr - text_start);
 
-       return 0;
-}
-
-int copy_gd_to_ram_f_r(void)
-{
-       gd_t *ram_gd;
-
-       /*
-        * Global data is still in temporary memory (the CPU cache).
-        * calculate_relocation_address() has set gd->new_gd_addr to
-        * where the global data lives in RAM but getting it there
-        * safely is a bit tricky due to the 'F-Segment Hack' that
-        * we need to use for x86
-        */
-       ram_gd = (gd_t *)gd->new_gd_addr;
-       memcpy((void *)ram_gd, gd, sizeof(gd_t));
-
-       /*
-        * Reload the Global Descriptor Table so FS points to the
-        * in-RAM copy of Global Data (calculate_relocation_address()
-        * has already calculated the in-RAM location of the GDT)
-        */
-       ram_gd->gd_addr = (ulong)ram_gd;
-       init_gd(ram_gd, (u64 *)gd->gdt_addr);
+       /* Stack is at the bottom, so it can grow down */
+       gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
 
        return 0;
 }
@@ -195,3 +163,40 @@ int set_load_addr_r(void)
 
        return 0;
 }
+
+int init_func_spi(void)
+{
+       puts("SPI:   ");
+       spi_init();
+       puts("ready\n");
+       return 0;
+}
+
+#ifdef CONFIG_OF_CONTROL
+int find_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 */
+       gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE);
+#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;
+}
+
+int prepare_fdt(void)
+{
+       /* For now, put this check after the console is ready */
+       if (fdtdec_prepare_fdt()) {
+               panic("** CONFIG_OF_CONTROL defined but no FDT - please see "
+                       "doc/README.fdt-control");
+       }
+
+       return 0;
+}
+#endif
index 71449fe6fa49d414a1c95a827b768a554caeae08..cca018fa9b06ae174eccb90fea69fb2b4eafa749 100644 (file)
@@ -21,6 +21,7 @@
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <environment.h>
 #include <serial.h>
 #include <kgdb.h>
 #include <scsi.h>
@@ -36,10 +37,35 @@ int serial_initialize_r(void)
        return 0;
 }
 
+/*
+ * 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 not 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", 0);
+#elif defined CONFIG_DELAY_ENVIRONMENT
+       return 0;
+#else
+       return 1;
+#endif
+}
+
 int env_relocate_r(void)
 {
        /* initialize environment */
-       env_relocate();
+       if (should_load_env())
+               env_relocate();
+       else
+               set_default_env(NULL);
 
        return 0;
 }
index 6b3db69447009d711b43e66dedbffbd2e77fd0c1..b0b6637f3a9ff119b150d1bdb1126d6df2f20f34 100644 (file)
@@ -39,7 +39,7 @@ int timer_init(void)
         * Timer 0 is used to increment system_tick 1000 times/sec
         * Timer 1 was used for DRAM refresh in early PC's
         * Timer 2 is used to drive the speaker
-        * (to stasrt a beep: write 3 to port 0x61,
+        * (to start a beep: write 3 to port 0x61,
         * to stop it again: write 0)
         */
        outb(PIT_CMD_CTR0 | PIT_CMD_BOTH | PIT_CMD_MODE2,
diff --git a/arch/x86/lib/physmem.c b/arch/x86/lib/physmem.c
new file mode 100644 (file)
index 0000000..18f0e62
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#include <common.h>
+#include <physmem.h>
+#include <linux/compiler.h>
+
+/* Large pages are 2MB. */
+#define LARGE_PAGE_SIZE ((1 << 20) * 2)
+
+/*
+ * Paging data structures.
+ */
+
+struct pdpe {
+       uint64_t p:1;
+       uint64_t mbz_0:2;
+       uint64_t pwt:1;
+       uint64_t pcd:1;
+       uint64_t mbz_1:4;
+       uint64_t avl:3;
+       uint64_t base:40;
+       uint64_t mbz_2:12;
+};
+
+typedef struct pdpe pdpt_t[512];
+
+struct pde {
+       uint64_t p:1;      /* present */
+       uint64_t rw:1;     /* read/write */
+       uint64_t us:1;     /* user/supervisor */
+       uint64_t pwt:1;    /* page-level writethrough */
+       uint64_t pcd:1;    /* page-level cache disable */
+       uint64_t a:1;      /* accessed */
+       uint64_t d:1;      /* dirty */
+       uint64_t ps:1;     /* page size */
+       uint64_t g:1;      /* global page */
+       uint64_t avl:3;    /* available to software */
+       uint64_t pat:1;    /* page-attribute table */
+       uint64_t mbz_0:8;  /* must be zero */
+       uint64_t base:31;  /* base address */
+};
+
+typedef struct pde pdt_t[512];
+
+static pdpt_t pdpt __aligned(4096);
+static pdt_t pdts[4] __aligned(4096);
+
+/*
+ * Map a virtual address to a physical address and optionally invalidate any
+ * old mapping.
+ *
+ * @param virt         The virtual address to use.
+ * @param phys         The physical address to use.
+ * @param invlpg       Whether to use invlpg to clear any old mappings.
+ */
+static void x86_phys_map_page(uintptr_t virt, phys_addr_t phys, int invlpg)
+{
+       /* Extract the two bit PDPT index and the 9 bit PDT index. */
+       uintptr_t pdpt_idx = (virt >> 30) & 0x3;
+       uintptr_t pdt_idx = (virt >> 21) & 0x1ff;
+
+       /* Set up a handy pointer to the appropriate PDE. */
+       struct pde *pde = &(pdts[pdpt_idx][pdt_idx]);
+
+       memset(pde, 0, sizeof(struct pde));
+       pde->p = 1;
+       pde->rw = 1;
+       pde->us = 1;
+       pde->ps = 1;
+       pde->base = phys >> 21;
+
+       if (invlpg) {
+               /* Flush any stale mapping out of the TLBs. */
+               __asm__ __volatile__(
+                       "invlpg %0\n\t"
+                       :
+                       : "m" (*(uint8_t *)virt)
+               );
+       }
+}
+
+/* Identity map the lower 4GB and turn on paging with PAE. */
+static void x86_phys_enter_paging(void)
+{
+       phys_addr_t page_addr;
+       unsigned i;
+
+       /* Zero out the page tables. */
+       memset(pdpt, 0, sizeof(pdpt));
+       memset(pdts, 0, sizeof(pdts));
+
+       /* Set up the PDPT. */
+       for (i = 0; i < ARRAY_SIZE(pdts); i++) {
+               pdpt[i].p = 1;
+               pdpt[i].base = ((uintptr_t)&pdts[i]) >> 12;
+       }
+
+       /* Identity map everything up to 4GB. */
+       for (page_addr = 0; page_addr < (1ULL << 32);
+                       page_addr += LARGE_PAGE_SIZE) {
+               /* There's no reason to invalidate the TLB with paging off. */
+               x86_phys_map_page(page_addr, page_addr, 0);
+       }
+
+       /* Turn on paging */
+       __asm__ __volatile__(
+               /* Load the page table address */
+               "movl   %0, %%cr3\n\t"
+               /* Enable pae */
+               "movl   %%cr4, %%eax\n\t"
+               "orl    $0x00000020, %%eax\n\t"
+               "movl   %%eax, %%cr4\n\t"
+               /* Enable paging */
+               "movl   %%cr0, %%eax\n\t"
+               "orl    $0x80000000, %%eax\n\t"
+               "movl   %%eax, %%cr0\n\t"
+               :
+               : "r" (pdpt)
+               : "eax"
+       );
+}
+
+/* Disable paging and PAE mode. */
+static void x86_phys_exit_paging(void)
+{
+       /* Turn off paging */
+       __asm__ __volatile__ (
+               /* Disable paging */
+               "movl   %%cr0, %%eax\n\t"
+               "andl   $0x7fffffff, %%eax\n\t"
+               "movl   %%eax, %%cr0\n\t"
+               /* Disable pae */
+               "movl   %%cr4, %%eax\n\t"
+               "andl   $0xffffffdf, %%eax\n\t"
+               "movl   %%eax, %%cr4\n\t"
+               :
+               :
+               : "eax"
+       );
+}
+
+/*
+ * Set physical memory to a particular value when the whole region fits on one
+ * page.
+ *
+ * @param map_addr     The address that starts the physical page.
+ * @param offset       How far into that page to start setting a value.
+ * @param c            The value to set memory to.
+ * @param size         The size in bytes of the area to set.
+ */
+static void x86_phys_memset_page(phys_addr_t map_addr, uintptr_t offset, int c,
+                                unsigned size)
+{
+       /*
+        * U-Boot should be far away from the beginning of memory, so that's a
+        * good place to map our window on top of.
+        */
+       const uintptr_t window = LARGE_PAGE_SIZE;
+
+       /* Make sure the window is below U-Boot. */
+       assert(window + LARGE_PAGE_SIZE <
+              gd->relocaddr - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_STACK_SIZE);
+       /* Map the page into the window and then memset the appropriate part. */
+       x86_phys_map_page(window, map_addr, 1);
+       memset((void *)(window + offset), c, size);
+}
+
+/*
+ * A physical memory anologue to memset with matching parameters and return
+ * value.
+ */
+phys_addr_t arch_phys_memset(phys_addr_t start, int c, phys_size_t size)
+{
+       const phys_addr_t max_addr = (phys_addr_t)~(uintptr_t)0;
+       const phys_addr_t orig_start = start;
+
+       if (!size)
+               return orig_start;
+
+       /* Handle memory below 4GB. */
+       if (start <= max_addr) {
+               phys_size_t low_size = MIN(max_addr + 1 - start, size);
+               void *start_ptr = (void *)(uintptr_t)start;
+
+               assert(((phys_addr_t)(uintptr_t)start) == start);
+               memset(start_ptr, c, low_size);
+               start += low_size;
+               size -= low_size;
+       }
+
+       /* Use paging and PAE to handle memory above 4GB up to 64GB. */
+       if (size) {
+               phys_addr_t map_addr = start & ~(LARGE_PAGE_SIZE - 1);
+               phys_addr_t offset = start - map_addr;
+
+               x86_phys_enter_paging();
+
+               /* Handle the first partial page. */
+               if (offset) {
+                       phys_addr_t end =
+                               MIN(map_addr + LARGE_PAGE_SIZE, start + size);
+                       phys_size_t cur_size = end - start;
+                       x86_phys_memset_page(map_addr, offset, c, cur_size);
+                       size -= cur_size;
+                       map_addr += LARGE_PAGE_SIZE;
+               }
+               /* Handle the complete pages. */
+               while (size > LARGE_PAGE_SIZE) {
+                       x86_phys_memset_page(map_addr, 0, c, LARGE_PAGE_SIZE);
+                       size -= LARGE_PAGE_SIZE;
+                       map_addr += LARGE_PAGE_SIZE;
+               }
+               /* Handle the last partial page. */
+               if (size)
+                       x86_phys_memset_page(map_addr, 0, c, size);
+
+               x86_phys_exit_paging();
+       }
+       return orig_start;
+}
index 200baaba6a2707c28fabc82cb93054158cdff5c0..23edca95269f36a7215f040fc1420e009a942541 100644 (file)
@@ -80,12 +80,12 @@ int do_elf_reloc_fixups(void)
 
                        /* Check that the target points into .text */
                        if (*offset_ptr_ram >= CONFIG_SYS_TEXT_BASE &&
-                                       *offset_ptr_ram <
+                                       *offset_ptr_ram <=
                                        (CONFIG_SYS_TEXT_BASE + size)) {
                                *offset_ptr_ram += gd->reloc_off;
                        }
                }
-       } while (re_src++ < re_end);
+       } while (++re_src < re_end);
 
        return 0;
 }
index fd7032e92c9f40e007348aac3a249e5078284b82..a13424b3e378ce14819ca445afb9109c60874359 100644 (file)
@@ -37,6 +37,7 @@ struct timer_isr_function {
 
 static struct timer_isr_function *first_timer_isr;
 static unsigned long system_ticks;
+static uint64_t base_value;
 
 /*
  * register_timer_isr() allows multiple architecture and board specific
@@ -98,3 +99,19 @@ ulong get_timer(ulong base)
 {
        return system_ticks - base;
 }
+
+void timer_set_tsc_base(uint64_t new_base)
+{
+       base_value = new_base;
+}
+
+uint64_t timer_get_tsc(void)
+{
+       uint64_t time_now;
+
+       time_now = rdtsc();
+       if (!base_value)
+               base_value = time_now;
+
+       return time_now - base_value;
+}
index 3d6b24d6204a67228f93850437013e6df2489c21..20e2416ae16f31f3ae8e441b8ec7b640e3dc00c4 100644 (file)
@@ -222,8 +222,10 @@ int video_init(void)
 
 int drv_video_init(void)
 {
+#ifndef CONFIG_X86_NO_REAL_MODE
        if (video_bios_init())
                return 1;
+#endif
 
        return video_init();
 }
index 22142864c22c052efd5626f26fc3ab04dfb1b630..46af391f29f2a82baebd91acf6e55d638dc7524b 100644 (file)
 #include <asm/realmode.h>
 #include <asm/byteorder.h>
 #include <asm/bootparam.h>
+#ifdef CONFIG_SYS_COREBOOT
+#include <asm/arch/timestamp.h>
+#endif
+#include <linux/compiler.h>
 
 /*
  * Memory lay-out:
@@ -171,7 +175,7 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size,
        else
                *load_address = (void *)ZIMAGE_LOAD_ADDR;
 
-#if defined CONFIG_ZBOOT_32
+#if (defined CONFIG_ZBOOT_32 || defined CONFIG_X86_NO_REAL_MODE)
        printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base);
        memset(setup_base, 0, sizeof(*setup_base));
        setup_base->hdr = params->hdr;
@@ -237,7 +241,7 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
        struct setup_header *hdr = &setup_base->hdr;
        int bootproto = get_boot_protocol(hdr);
 
-#if defined CONFIG_ZBOOT_32
+#if (defined CONFIG_ZBOOT_32 || defined CONFIG_X86_NO_REAL_MODE)
        setup_base->e820_entries = install_e820_map(
                ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
 #endif
@@ -279,10 +283,23 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
        return 0;
 }
 
+/*
+ * Implement a weak default function for boards that optionally
+ * need to clean up the system before jumping to the kernel.
+ */
+__weak void board_final_cleanup(void)
+{
+}
+
 void boot_zimage(void *setup_base, void *load_address)
 {
+       board_final_cleanup();
+
        printf("\nStarting kernel ...\n\n");
 
+#ifdef CONFIG_SYS_COREBOOT
+       timestamp_add_now(TS_U_BOOT_START_KERNEL);
+#endif
 #if defined CONFIG_ZBOOT_32
        /*
         * Set %ebx, %ebp, and %edi to 0, %esi to point to the boot_params
@@ -292,9 +309,9 @@ void boot_zimage(void *setup_base, void *load_address)
         * itself in arch/i386/cpu/cpu.c.
         */
        __asm__ __volatile__ (
-       "movl $0, %%ebp         \n"
-       "cli                    \n"
-       "jmp %[kernel_entry]    \n"
+       "movl $0, %%ebp\n"
+       "cli\n"
+       "jmp *%[kernel_entry]\n"
        :: [kernel_entry]"a"(load_address),
           [boot_params] "S"(setup_base),
           "b"(0), "D"(0)
index 0f14699c5e527186e5c354660132fd240b6dad63..ac860c1348f6ba2e8d6ce881e99d95599b203ef9 100644 (file)
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
-COBJS  = $(BOARD).o cfm_flash.o flash.o
+COBJS  = $(BOARD).o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
diff --git a/board/BuS/eb_cpu5282/cfm_flash.c b/board/BuS/eb_cpu5282/cfm_flash.c
deleted file mode 100644 (file)
index fe03b17..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Basic Flash Driver for Freescale MCF 5281/5282 internal FLASH
- *
- * (C) Copyright 2005 BuS Elektronik GmbH & Co.KG <esw@bus-elektonik.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 <asm/m5282.h>
-#include  "cfm_flash.h"
-
-#if defined(CONFIG_M5281) || defined(CONFIG_M5282)
-
-#if (CONFIG_SYS_CLK>20000000)
-       #define CFM_CLK  (((long) CONFIG_SYS_CLK / (400000 * 8) + 1) | 0x40)
-#else
-       #define CFM_CLK  ((long) CONFIG_SYS_CLK / 400000 + 1)
-#endif
-
-#define cmf_backdoor_address(addr)     (((addr) & 0x0007FFFF) | 0x04000000 | \
-                                        (CONFIG_SYS_MBAR & 0xC0000000))
-
-void cfm_flash_print_info (flash_info_t * info)
-{
-       printf ("Freescale: ");
-       switch (info->flash_id & FLASH_TYPEMASK) {
-       case FREESCALE_ID_MCF5281 & FLASH_TYPEMASK:
-               printf ("MCF5281 internal FLASH\n");
-               break;
-       case FREESCALE_ID_MCF5282 & FLASH_TYPEMASK:
-               printf ("MCF5282 internal FLASH\n");
-               break;
-       default:
-               printf ("Unknown Chip Type\n");
-               break;
-       }
-}
-
-void cfm_flash_init (flash_info_t * info)
-{
-       int sector;
-       ulong protection;
-       MCFCFM_MCR = 0;
-       MCFCFM_CLKD = CFM_CLK;
-       debug ("CFM Clock divider: %ld (%d Hz @ %ld Hz)\n",CFM_CLK,\
-               CONFIG_SYS_CLK / (2* ((CFM_CLK & 0x3F)+1) * (1+((CFM_CLK & 0x40)>>6)*7)),\
-               CONFIG_SYS_CLK);
-       MCFCFM_SACC = 0;
-       MCFCFM_DACC = 0;
-
-       if (MCFCFM_SEC & MCFCFM_SEC_KEYEN)
-               puts("CFM backdoor access is enabled\n");
-       if (MCFCFM_SEC & MCFCFM_SEC_SECSTAT)
-               puts("CFM securety is enabled\n");
-
-       #ifdef CONFIG_M5281
-               info->flash_id = (FREESCALE_MANUFACT & FLASH_VENDMASK) |
-                                (FREESCALE_ID_MCF5281 & FLASH_TYPEMASK);
-               info->size = 256*1024;
-               info->sector_count = 16;
-       #else
-               info->flash_id = (FREESCALE_MANUFACT & FLASH_VENDMASK) |
-                                (FREESCALE_ID_MCF5282 & FLASH_TYPEMASK);
-               info->size = 512*1024;
-               info->sector_count = 32;
-       #endif
-       protection = MCFCFM_PROT;
-       for (sector = 0; sector < info->sector_count; sector++)
-       {
-               if (sector == 0)
-               {
-                       info->start[sector] = CONFIG_SYS_INT_FLASH_BASE;
-               }
-               else
-               {
-                       info->start[sector] = info->start[sector-1] + 0x04000;
-               }
-               info->protect[sector] = protection & 1;
-               protection >>= 1;
-       }
-}
-
-int cfm_flash_readycheck(int checkblank)
-{
-       int     rc;
-       unsigned char state;
-
-       rc      = ERR_OK;
-       while (!(MCFCFM_USTAT & MCFCFM_USTAT_CCIF));
-       state = MCFCFM_USTAT;
-       if (state & MCFCFM_USTAT_ACCERR)
-       {
-               debug ("%s(): CFM access error",__FUNCTION__);
-               rc = ERR_PROG_ERROR;
-       }
-       if (state & MCFCFM_USTAT_PVIOL)
-       {
-               debug ("%s(): CFM protection violation",__FUNCTION__);
-               rc = ERR_PROTECTED;
-       }
-       if (checkblank)
-       {
-               if (!(state & MCFCFM_USTAT_BLANK))
-               {
-                       debug ("%s(): CFM erras error",__FUNCTION__);
-                       rc = ERR_NOT_ERASED;
-               }
-       }
-       MCFCFM_USTAT = state & 0x34; /* reset state */
-       return rc;
-}
-
-/* Erase 16KiB = 8 2KiB pages */
-
-int cfm_flash_erase_sector (flash_info_t * info, int sector)
-{
-       ulong address;
-       int page;
-       int rc;
-       rc= ERR_OK;
-       address = cmf_backdoor_address(info->start[sector]);
-       for (page=0; (page<8) && (rc==ERR_OK); page++)
-       {
-               *(volatile __u32*) address = 0;
-               MCFCFM_CMD = MCFCFM_CMD_PGERS;
-               MCFCFM_USTAT = MCFCFM_USTAT_CBEIF;
-               rc = cfm_flash_readycheck(0);
-               if (rc==ERR_OK)
-               {
-                       *(volatile __u32*) address = 0;
-                       MCFCFM_CMD = MCFCFM_CMD_PGERSVER;
-                       MCFCFM_USTAT = MCFCFM_USTAT_CBEIF;
-                       rc = cfm_flash_readycheck(1);
-               }
-               address += 0x800;
-       }
-       return rc;
-}
-
-int cfm_flash_write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
-{
-       int rc;
-       ulong dest, data;
-
-       rc = ERR_OK;
-       if (addr & 3)
-       {
-               debug ("Byte and Word alignment not supported\n");
-               rc = ERR_ALIGN;
-       }
-       if (cnt & 3)
-       {
-               debug ("Byte and Word transfer not supported\n");
-               rc = ERR_ALIGN;
-       }
-       dest = cmf_backdoor_address(addr);
-       while ((cnt>=4) && (rc == ERR_OK))
-       {
-               data = *((volatile u32 *) src);
-               *(volatile u32*) dest = data;
-               MCFCFM_CMD = MCFCFM_CMD_PGM;
-               MCFCFM_USTAT = MCFCFM_USTAT_CBEIF;
-               rc = cfm_flash_readycheck(0);
-               if (*(volatile u32*) addr != data) rc = ERR_PROG_ERROR;
-               src +=4;
-               dest +=4;
-               addr +=4;
-               cnt -=4;
-       }
-       return rc;
-}
-
-#ifdef CONFIG_SYS_FLASH_PROTECTION
-
-int cfm_flash_protect(flash_info_t * info,long sector,int prot)
-{
-       int rc;
-
-       rc= ERR_OK;
-       if (prot)
-       {
-               MCFCFM_PROT |= (1<<sector);
-               info->protect[sector]=1;
-       }
-       else
-       {
-               MCFCFM_PROT &= ~(1<<sector);
-               info->protect[sector]=0;
-       }
-       return rc;
-}
-
-#endif
-
-#endif
diff --git a/board/BuS/eb_cpu5282/cfm_flash.h b/board/BuS/eb_cpu5282/cfm_flash.h
deleted file mode 100644 (file)
index ed4e794..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Basic Flash Driver for Freescale MCF 5282 internal FLASH
- *
- * (C) Copyright 2005 BuS Elektronik GmbH & Co.KG <esw@bus-elektonik.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 __CFM_FLASH_H_
-#define __CFM_FLASH_H_
-
-#define        FREESCALE_MANUFACT 0xFACFFACF
-#define        FREESCALE_ID_MCF5281 0x5281
-#define        FREESCALE_ID_MCF5282 0x5282
-
-extern void cfm_flash_print_info (flash_info_t * info);
-extern int cfm_flash_erase_sector (flash_info_t * info, int sector);
-extern void cfm_flash_init (flash_info_t * info);
-extern int cfm_flash_write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt);
-#ifdef CONFIG_SYS_FLASH_PROTECTION
-extern int cfm_flash_protect(flash_info_t * info,long sector,int prot);
-#endif
-
-#endif
index d64ad1b705c41eedee97056898f3053d84ee9abb..f73431eff59b4d018236bd04fbe4672c6d697a57 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_VIDEO
 unsigned long display_width;
 unsigned long display_height;
+#endif
 
 /*---------------------------------------------------------------------------*/
 
 int checkboard (void)
 {
-       puts ("Board: MCF-EV1 + MCF-EV23 (BuS Elektronik GmbH & Co. KG)\n");
+       puts("Board: EB+CPU5282 (BuS Elektronik GmbH & Co. KG)\n");
 #if (CONFIG_SYS_TEXT_BASE ==  CONFIG_SYS_INT_FLASH_BASE)
-       puts ("       Boot from Internal FLASH\n");
+       puts("       Boot from Internal FLASH\n");
 #endif
-
        return 0;
 }
 
@@ -55,29 +56,39 @@ phys_size_t initdram (int board_type)
        int size, i;
 
        size = 0;
-       MCFSDRAMC_DCR = MCFSDRAMC_DCR_RTIM_6
-                       | MCFSDRAMC_DCR_RC ((15 * CONFIG_SYS_CLK) >> 4);
+       MCFSDRAMC_DCR = MCFSDRAMC_DCR_RTIM_6 |
+                       MCFSDRAMC_DCR_RC((15 * CONFIG_SYS_CLK / 1000000) >> 4);
+       asm (" nop");
 #ifdef CONFIG_SYS_SDRAM_BASE0
-
-       MCFSDRAMC_DACR0 = MCFSDRAMC_DACR_BASE (CONFIG_SYS_SDRAM_BASE0)
-                       | MCFSDRAMC_DACR_CASL (1)
-                       | MCFSDRAMC_DACR_CBM (3)
-                       | MCFSDRAMC_DACR_PS_16;
+       MCFSDRAMC_DACR0 = MCFSDRAMC_DACR_BASE(CONFIG_SYS_SDRAM_BASE0)|
+               MCFSDRAMC_DACR_CASL(1) | MCFSDRAMC_DACR_CBM(3) |
+               MCFSDRAMC_DACR_PS_32;
+       asm (" nop");
 
        MCFSDRAMC_DMR0 = MCFSDRAMC_DMR_BAM_16M | MCFSDRAMC_DMR_V;
+       asm (" nop");
 
        MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_IP;
+       asm (" nop");
+       for (i = 0; i < 10; i++)
+               asm (" nop");
 
-       *(unsigned short *) (CONFIG_SYS_SDRAM_BASE0) = 0xA5A5;
+       *(unsigned long *)(CONFIG_SYS_SDRAM_BASE0) = 0xA5A5A5A5;
+       asm (" nop");
        MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_RE;
+       asm (" nop");
+
        for (i = 0; i < 2000; i++)
                asm (" nop");
-       mbar_writeLong (MCFSDRAMC_DACR0,
-                       mbar_readLong (MCFSDRAMC_DACR0) | MCFSDRAMC_DACR_IMRS);
-       *(unsigned int *) (CONFIG_SYS_SDRAM_BASE0 + 0x220) = 0xA5A5;
-       size += CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
+
+       MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_IMRS;
+       asm (" nop");
+       /* write SDRAM mode register */
+       *(unsigned long *)(CONFIG_SYS_SDRAM_BASE0 + 0x80440) = 0xA5A5A5A5;
+       asm (" nop");
+       size += CONFIG_SYS_SDRAM_SIZE0 * 1024 * 1024;
 #endif
-#ifdef CONFIG_SYS_SDRAM_BASE1
+#ifdef CONFIG_SYS_SDRAM_BASE1xx
        MCFSDRAMC_DACR1 = MCFSDRAMC_DACR_BASE (CONFIG_SYS_SDRAM_BASE1)
                        | MCFSDRAMC_DACR_CASL (1)
                        | MCFSDRAMC_DACR_CBM (3)
@@ -134,38 +145,74 @@ int testdram (void)
 }
 #endif
 
+#if defined(CONFIG_HW_WATCHDOG)
+
+void hw_watchdog_init(void)
+{
+       char *s;
+       int enable;
+
+       enable = 1;
+       s = getenv("watchdog");
+       if (s != NULL)
+               if ((strncmp(s, "off", 3) == 0) || (strncmp(s, "0", 1) == 0))
+                       enable = 0;
+       if (enable)
+               MCFGPTA_GPTDDR  |= (1<<2);
+       else
+               MCFGPTA_GPTDDR  &= ~(1<<2);
+}
+
+void hw_watchdog_reset(void)
+{
+       MCFGPTA_GPTPORT  ^= (1<<2);
+}
+#endif
+
 int misc_init_r(void)
 {
 #ifdef CONFIG_HW_WATCHDOG
        hw_watchdog_init();
-#endif
-#ifndef CONFIG_VIDEO
-       vcxk_init(16, 16);
 #endif
        return 1;
 }
 
-#if defined(CONFIG_VIDEO)
+void __led_toggle(led_id_t mask)
+{
+       MCFGPTA_GPTPORT ^= (1 << 3);
+}
 
-/*
- ****h* EB+CPU5282-T1/drv_video_init
- * FUNCTION
- ***
- */
+void __led_init(led_id_t mask, int state)
+{
+       __led_set(mask, state);
+       MCFGPTA_GPTDDR  |= (1 << 3);
+}
+
+void __led_set(led_id_t mask, int state)
+{
+       if (state == STATUS_LED_ON)
+               MCFGPTA_GPTPORT |= (1 << 3);
+       else
+               MCFGPTA_GPTPORT &= ~(1 << 3);
+}
+
+#if defined(CONFIG_VIDEO)
 
 int drv_video_init(void)
 {
        char *s;
+#ifdef CONFIG_SPLASH_SCREEN
        unsigned long splash;
-
+#endif
        printf("Init Video as ");
-
-       if ((s = getenv("displaywidth")) != NULL)
+       s = getenv("displaywidth");
+       if (s != NULL)
                display_width = simple_strtoul(s, NULL, 10);
        else
                display_width = 256;
 
-       if ((s = getenv("displayheight")) != NULL)
+       s = getenv("displayheight");
+       if (s != NULL)
                display_height = simple_strtoul(s, NULL, 10);
        else
                display_height = 256;
@@ -178,10 +225,9 @@ int drv_video_init(void)
        vcxk_init(display_width, display_height);
 
 #ifdef CONFIG_SPLASH_SCREEN
-       if ((s = getenv("splashimage")) != NULL) {
-               debug("use splashimage: %s\n", s);
+       s = getenv("splashimage");
+       if (s != NULL) {
                splash = simple_strtoul(s, NULL, 16);
-               debug("use splashimage: %x\n", splash);
                vcxk_acknowledge_wait();
                video_display_bitmap(splash, 0, 0);
        }
diff --git a/board/BuS/eb_cpu5282/flash.c b/board/BuS/eb_cpu5282/flash.c
deleted file mode 100644 (file)
index 8b7f957..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * (C) Copyright 2005
- * BuS Elektronik GmbH & Co.KG <esw@bus-elektonik.de>
- *
- * Based On
- * 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 <common.h>
-#include  "cfm_flash.h"
-
-#define PHYS_FLASH_1 CONFIG_SYS_FLASH_BASE
-#define FLASH_BANK_SIZE 0x200000
-
-flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
-
-void flash_print_info (flash_info_t * info)
-{
-       int i;
-
-       switch (info->flash_id & FLASH_VENDMASK) {
-       case (AMD_MANUFACT & FLASH_VENDMASK):
-               printf ("AMD: ");
-               switch (info->flash_id & FLASH_TYPEMASK) {
-               case (AMD_ID_LV160B & FLASH_TYPEMASK):
-                       printf ("AM29LV160B (16Bit)\n");
-                       break;
-               default:
-                       printf ("Unknown Chip Type\n");
-                       break;
-               }
-               break;
-       case FREESCALE_MANUFACT & FLASH_VENDMASK:
-               cfm_flash_print_info (info);
-               break;
-       default:
-               printf ("Unknown Vendor ");
-               break;
-       }
-
-       puts ("  Size: ");
-       if ((info->size >> 20) > 0)
-       {
-               printf ("%ld MiB",info->size >> 20);
-       }
-       else
-       {
-               printf ("%ld KiB",info->size >> 10);
-       }
-       printf (" in %d Sectors\n", info->sector_count);
-
-       printf ("  Sector Start Addresses:");
-       for (i = 0; i < info->sector_count; i++) {
-               if ((i % 4) == 0) {
-                       printf ("\n    ");
-               }
-               printf ("%02d: %08lX%s  ", i,info->start[i],
-                       info->protect[i] ? " P" : "  ");
-       }
-       printf ("\n\n");
-}
-
-unsigned long flash_init (void)
-{
-       int i, j;
-       ulong size = 0;
-
-       for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
-               ulong flashbase = 0;
-
-               switch (i)
-               {
-               case 1:
-                       flash_info[i].flash_id =
-                               (AMD_MANUFACT & FLASH_VENDMASK) |
-                               (AMD_ID_LV160B & FLASH_TYPEMASK);
-                       flash_info[i].size = FLASH_BANK_SIZE;
-                       flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
-                       memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
-                       flashbase = PHYS_FLASH_1;
-                       for (j = 0; j < flash_info[i].sector_count; j++) {
-                               if (j == 0) {
-                                       /* 1st is 16 KiB */
-                                       flash_info[i].start[j] = flashbase;
-                               }
-                               if ((j >= 1) && (j <= 2)) {
-                               /* 2nd and 3rd are 8 KiB */
-                                       flash_info[i].start[j] =
-                                               flashbase + 0x4000 + 0x2000 * (j - 1);
-                               }
-                               if (j == 3) {
-                                       /* 4th is 32 KiB */
-                                       flash_info[i].start[j] = flashbase + 0x8000;
-                               }
-                               if ((j >= 4) && (j <= 34)) {
-                                       /* rest is 256 KiB */
-                                       flash_info[i].start[j] =
-                                               flashbase + 0x10000 + 0x10000 * (j - 4);
-                               }
-                       }
-                       break;
-               case 0:
-                       cfm_flash_init (&flash_info[i]);
-                       break;
-               default:
-                       panic ("configured to many flash banks!\n");
-               }
-
-               size += flash_info[i].size;
-       }
-
-       flash_protect (FLAG_PROTECT_SET,
-                      CONFIG_SYS_FLASH_BASE,
-                      CONFIG_SYS_FLASH_BASE + 0xffff, &flash_info[0]);
-
-       return size;
-}
-
-#define CMD_READ_ARRAY         0x00F0
-#define CMD_UNLOCK1            0x00AA
-#define CMD_UNLOCK2            0x0055
-#define CMD_ERASE_SETUP                0x0080
-#define CMD_ERASE_CONFIRM      0x0030
-#define CMD_PROGRAM            0x00A0
-#define CMD_UNLOCK_BYPASS      0x0020
-
-#define MEM_FLASH_ADDR1                (*(volatile u16 *)(info->start[0] + (0x00000555<<1)))
-#define MEM_FLASH_ADDR2                (*(volatile u16 *)(info->start[0] + (0x000002AA<<1)))
-
-
-#define BIT_ERASE_DONE         0x0080
-#define BIT_RDY_MASK           0x0080
-#define BIT_PROGRAM_ERROR      0x0020
-#define BIT_TIMEOUT            0x80000000      /* our flag */
-
-#define ERR_READY -1
-
-int amd_flash_erase_sector(flash_info_t * info, int sector)
-{
-       int state;
-       ulong result;
-       ulong start;
-
-       volatile u16 *addr =
-                               (volatile u16 *) (info->start[sector]);
-
-       MEM_FLASH_ADDR1 = CMD_UNLOCK1;
-       MEM_FLASH_ADDR2 = CMD_UNLOCK2;
-       MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
-
-       MEM_FLASH_ADDR1 = CMD_UNLOCK1;
-       MEM_FLASH_ADDR2 = CMD_UNLOCK2;
-       *addr = CMD_ERASE_CONFIRM;
-
-       /* wait until flash is ready */
-       state = 0;
-       start = get_timer(0);
-
-       do {
-               result = *addr;
-
-               /* check timeout */
-               if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
-                       MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
-                       state = ERR_TIMOUT;
-               }
-
-               if (!state && (result & 0xFFFF) & BIT_ERASE_DONE)
-                       state = ERR_READY;
-       }
-       while (!state);
-       if (state == ERR_READY)
-               state = ERR_OK;
-
-       MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
-
-       return state;
-}
-
-int flash_erase (flash_info_t * info, int s_first, int s_last)
-{
-       int iflag, cflag;
-       int sector;
-       int rc;
-
-       rc = ERR_OK;
-
-       if (info->flash_id == FLASH_UNKNOWN)
-       {
-               rc = ERR_UNKNOWN_FLASH_TYPE;
-       } /* (info->flash_id == FLASH_UNKNOWN) */
-
-       if ((s_first < 0) || (s_first > s_last) || s_last >= info->sector_count)
-       {
-               rc = ERR_INVAL;
-       }
-
-       cflag = icache_status ();
-       icache_disable ();
-       iflag = disable_interrupts ();
-
-       for (sector = s_first; (sector <= s_last) && (rc == ERR_OK); sector++) {
-
-               if (info->protect[sector])
-               {
-                       putc('P'); /*  protected sector will not erase */
-               }
-               else
-               {
-                       /* erase on unprotected sector */
-                       puts("E\b");
-                       switch (info->flash_id & FLASH_VENDMASK)
-                       {
-                       case (AMD_MANUFACT & FLASH_VENDMASK):
-                               rc = amd_flash_erase_sector(info,sector);
-                               break;
-                       case (FREESCALE_MANUFACT & FLASH_VENDMASK):
-                               rc = cfm_flash_erase_sector(info,sector);
-                               break;
-                       default:
-                               return ERR_UNKNOWN_FLASH_VENDOR;
-                       }
-                       putc('.');
-               }
-       }
-       if (rc!=ERR_OK)
-       {
-               printf ("\n   ");
-               flash_perror (rc);
-       }
-       else
-       {
-               printf (" done\n");
-       }
-
-       udelay (10000); /* allow flash to settle - wait 10 ms */
-
-       if (iflag)
-               enable_interrupts ();
-
-       if (cflag)
-               icache_enable ();
-
-       return rc;
-}
-
-volatile static int amd_write_word (flash_info_t * info, ulong dest, u16 data)
-{
-       volatile u16 *addr;
-       ulong result;
-       int cflag, iflag;
-       int state;
-       ulong start;
-
-       /*
-        * Check if Flash is (sufficiently) erased
-        */
-       addr = (volatile u16 *) dest;
-
-       result = *addr;
-       if ((result & data) != data)
-               return ERR_NOT_ERASED;
-
-       /*
-        * Disable interrupts which might cause a timeout
-        * here. Remember that our exception vectors are
-        * at address 0 in the flash, and we don't want a
-        * (ticker) exception to happen while the flash
-        * chip is in programming mode.
-        */
-
-       cflag = icache_status ();
-       icache_disable ();
-       iflag = disable_interrupts ();
-
-       MEM_FLASH_ADDR1 = CMD_UNLOCK1;
-       MEM_FLASH_ADDR2 = CMD_UNLOCK2;
-       MEM_FLASH_ADDR1 = CMD_PROGRAM;
-       *addr = data;
-
-       /* arm simple, non interrupt dependent timer */
-       start = get_timer(0);
-
-       /* wait until flash is ready */
-       state = 0;
-       do {
-               result = *addr;
-
-               /* check timeout */
-               if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
-                               state = ERR_TIMOUT;
-               }
-               if (!state && ((result & BIT_RDY_MASK) == (data & BIT_RDY_MASK)))
-                       state = ERR_READY;
-
-       } while (!state);
-
-       *addr = CMD_READ_ARRAY;
-
-       if (state == ERR_READY)
-               state = ERR_OK;
-       if ((*addr != data) && (state != ERR_TIMOUT))
-               state = ERR_PROG_ERROR;
-
-       if (iflag)
-               enable_interrupts ();
-
-       if (cflag)
-               icache_enable ();
-
-       return state;
-}
-
-int amd_flash_write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
-{
-       int rc;
-       ulong dest;
-       u16 data;
-
-       rc = ERR_OK;
-       if (addr & 1)
-       {
-               debug ("Byte alignment not supported\n");
-               rc = ERR_ALIGN;
-       }
-       if (cnt & 1)
-       {
-               debug ("Byte transfer not supported\n");
-               rc = ERR_ALIGN;
-       }
-
-       dest = addr;
-       while ((cnt>=2) && (rc == ERR_OK))
-       {
-               data = *((volatile u16 *) src);
-               rc=amd_write_word (info,dest,data);
-               src +=2;
-               dest +=2;
-               cnt -=2;
-       }
-       return rc;
-}
-
-int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
-{
-       int rc;
-
-       switch (info->flash_id & FLASH_VENDMASK)
-       {
-               case (AMD_MANUFACT & FLASH_VENDMASK):
-                       rc = amd_flash_write_buff(info,src,addr,cnt);
-                       break;
-               case (FREESCALE_MANUFACT & FLASH_VENDMASK):
-                       rc = cfm_flash_write_buff(info,src,addr,cnt);
-                       break;
-               default:
-                       rc = ERR_UNKNOWN_FLASH_VENDOR;
-       }
-       return rc;
-
-}
-int amd_flash_protect(flash_info_t * info,long sector,int prot)
-{
-       int rc;
-       rc= ERR_OK;
-       if (prot)
-       {
-               info->protect[sector]=1;
-       }
-       else
-       {
-               info->protect[sector]=0;
-       }
-       return rc;
-}
-
-#ifdef CONFIG_SYS_FLASH_PROTECTION
-
-int flash_real_protect(flash_info_t * info,long sector,int prot)
-{
-       int rc;
-
-       switch (info->flash_id & FLASH_VENDMASK)
-       {
-               case (AMD_MANUFACT & FLASH_VENDMASK):
-                       rc = amd_flash_protect(info,sector,prot);
-                       break;
-               case (FREESCALE_MANUFACT & FLASH_VENDMASK):
-                       rc = cfm_flash_protect(info,sector,prot);
-                       break;
-               default:
-                       rc = ERR_UNKNOWN_FLASH_VENDOR;
-       }
-       return rc;
-}
-
-#endif
diff --git a/board/a3m071/Makefile b/board/a3m071/Makefile
new file mode 100644 (file)
index 0000000..6f961fb
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB    = $(obj)lib$(BOARD).o
+
+COBJS  := $(BOARD).o
+
+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/a3m071/README b/board/a3m071/README
new file mode 100644 (file)
index 0000000..7698614
--- /dev/null
@@ -0,0 +1,80 @@
+------------------------------------------------------------------------
+A3M071 board support
+------------------------------------------------------------------------
+
+
+SPL NOR flash support:
+----------------------
+To boot fast into the OS (Linux), this board port integrates the SPL
+framework. This means, that a special, stripped-down version of
+U-Boot runs in the beginning. In the case of the A3M071 board, this
+SPL U-Boot version is less than 16 KiB big. This SPL U-Boot can either
+boot the OS (Linux) or a "real", full-blown U-Boot. This detection
+on whether to boot Linux or U-Boot is done by using the "boot_os"
+environment variable. If "boot_os" is set to "yes", Linux will be
+loaded and booted from the SPL U-Boot version. Otherwise, the
+full-blown U-Boot version will be loaded and run.
+
+Enabling Linux booting:
+-----------------------
+From U-Boot:
+=> setenv boot_os yes
+=> saveenv
+
+From Linux:
+$ fw_setenv boot_os yes
+
+Enabling U-Boot booting:
+------------------------
+From U-Boot:
+=> setenv boot_os no
+=> saveenv
+
+From Linux:
+$ fw_setenv boot_os no
+
+
+Preparing Linux image(s) for booting from SPL U-Boot:
+-----------------------------------------------------
+To boot the Linux kernel from the SPL, the DT blob (fdt) needs to get
+prepard/patched first. U-Boot usually inserts some dynamic values into
+the DT binary (blob), e.g. autodetected memory size, MAC addresses,
+clocks speeds etc. To generate this patched DT blob, you can use
+the following command:
+
+1. Load fdt blob to SDRAM:
+=> tftp 1800000 a3m071/a3m071.dtb
+
+2. Set bootargs as desired for Linux booting (e.g. flash_mtd):
+=> run mtdargs addip2 addtty
+
+3. Use "fdt" commands to patch the DT blob:
+=> fdt addr 1800000
+=> fdt boardsetup
+=> fdt chosen
+
+4. Display patched DT blob (optional):
+=> fdt print
+
+5. Save fdt to NOR flash:
+=> erase fc060000 fc07ffff
+=> cp.b 1800000 fc060000 10000
+
+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; \
+       cp.b 1800000 fc060000 10000'
+=> saveenv
+
+After this, only "run upd_fdt" needs to get called to load, patch
+and save the DT blob into NOR flash.
+
+Additionally, the Linux kernel image has to be saved uncompressed in
+its uImage file (and not gzip compressed). This can be done with this
+command:
+
+$ mkimage -A ppc -O linux -T kernel -C none -a 0 -e 0 \
+       -n "Linux Kernel Image" -d vmlinux.bin uImage.uncompressed
+
+------------------------------------------------------------------------
+Stefan Roese, 2012-08-23
diff --git a/board/a3m071/a3m071.c b/board/a3m071/a3m071.c
new file mode 100644 (file)
index 0000000..89ced82
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * (C) Copyright 2003-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2004
+ * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
+ *
+ * (C) Copyright 2006
+ * MicroSys GmbH
+ *
+ * Copyright 2012 Stefan Roese <sr@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 <common.h>
+#include <command.h>
+#include <mpc5xxx.h>
+#include <pci.h>
+#include <miiphy.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+
+#include "mt46v16m16-75.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if !defined(CONFIG_SYS_RAMBOOT) && \
+       (defined(CONFIG_SPL) && defined(CONFIG_SPL_BUILD))
+static void sdram_start(int hi_addr)
+{
+       long hi_addr_bit = hi_addr ? 0x01000000 : 0;
+       long control = SDRAM_CONTROL | hi_addr_bit;
+
+       /* unlock mode register */
+       out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000000);
+
+       /* precharge all banks */
+       out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000002);
+
+#ifdef SDRAM_DDR
+       /* set mode register: extended mode */
+       out_be32((void *)MPC5XXX_SDRAM_MODE, SDRAM_EMODE);
+
+       /* set mode register: reset DLL */
+       out_be32((void *)MPC5XXX_SDRAM_MODE, SDRAM_MODE | 0x04000000);
+#endif
+
+       /* precharge all banks */
+       out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000002);
+
+       /* auto refresh */
+       out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000004);
+
+       /* set mode register */
+       out_be32((void *)MPC5XXX_SDRAM_MODE, SDRAM_MODE);
+
+       /* normal operation */
+       out_be32((void *)MPC5XXX_SDRAM_CTRL, control);
+}
+#endif
+
+/*
+ * ATTENTION: Although partially referenced initdram does NOT make real use
+ * use of CONFIG_SYS_SDRAM_BASE. The code does not work if
+ * CONFIG_SYS_SDRAM_BASE is something else than 0x00000000.
+ */
+phys_size_t initdram(int board_type)
+{
+       ulong dramsize = 0;
+       ulong dramsize2 = 0;
+       uint svr, pvr;
+#if !defined(CONFIG_SYS_RAMBOOT) && \
+       (defined(CONFIG_SPL) && defined(CONFIG_SPL_BUILD))
+       ulong test1, test2;
+
+       /* setup SDRAM chip selects */
+       out_be32((void *)MPC5XXX_SDRAM_CS0CFG, 0x0000001e);     /* 2GB at 0x0 */
+       out_be32((void *)MPC5XXX_SDRAM_CS1CFG, 0x80000000);     /* disabled */
+
+       /* setup config registers */
+       out_be32((void *)MPC5XXX_SDRAM_CONFIG1, SDRAM_CONFIG1);
+       out_be32((void *)MPC5XXX_SDRAM_CONFIG2, SDRAM_CONFIG2);
+
+#ifdef SDRAM_DDR
+       /* set tap delay */
+       out_be32((void *)MPC5XXX_CDM_PORCFG, SDRAM_TAPDELAY);
+#endif
+
+       /* find RAM size using SDRAM CS0 only */
+       sdram_start(0);
+       test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
+       sdram_start(1);
+       test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
+       if (test1 > test2) {
+               sdram_start(0);
+               dramsize = test1;
+       } else {
+               dramsize = test2;
+       }
+
+       /* memory smaller than 1MB is impossible */
+       if (dramsize < (1 << 20))
+               dramsize = 0;
+
+       /* set SDRAM CS0 size according to the amount of RAM found */
+       if (dramsize > 0) {
+               out_be32((void *)MPC5XXX_SDRAM_CS0CFG,
+                        0x13 + __builtin_ffs(dramsize >> 20) - 1);
+       } else {
+               out_be32((void *)MPC5XXX_SDRAM_CS0CFG, 0);      /* disabled */
+       }
+#else /* CONFIG_SYS_RAMBOOT */
+
+       /* retrieve size of memory connected to SDRAM CS0 */
+       dramsize = in_be32((void *)MPC5XXX_SDRAM_CS0CFG) & 0xFF;
+       if (dramsize >= 0x13)
+               dramsize = (1 << (dramsize - 0x13)) << 20;
+       else
+               dramsize = 0;
+
+       /* retrieve size of memory connected to SDRAM CS1 */
+       dramsize2 = in_be32((void *)MPC5XXX_SDRAM_CS1CFG) & 0xFF;
+       if (dramsize2 >= 0x13)
+               dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
+       else
+               dramsize2 = 0;
+
+#endif /* CONFIG_SYS_RAMBOOT */
+
+       /*
+        * On MPC5200B we need to set the special configuration delay in the
+        * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
+        * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
+        *
+        * "The SDelay should be written to a value of 0x00000004. It is
+        * required to account for changes caused by normal wafer processing
+        * parameters."
+        */
+       svr = get_svr();
+       pvr = get_pvr();
+       if ((SVR_MJREV(svr) >= 2) && (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4))
+               out_be32((void *)MPC5XXX_SDRAM_SDELAY, 0x04);
+
+       return dramsize + dramsize2;
+}
+
+static void get_revisions(int *failsavelevel, int *digiboardversion,
+       int *fpgaversion)
+{
+       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;
+       val |= (gpt->gpt3.sr & (1 << (31 - 23))) ? (1 << 1) : 0;
+       val |= (gpt->gpt4.sr & (1 << (31 - 23))) ? (1 << 2) : 0;
+       *digiboardversion = val;
+
+       if (*digiboardversion == 0) {
+               *failsavelevel = 1;     /* digiboard-version ok */
+
+               /* read fpga-version from TMR[5..7] */
+               val = 0;
+               val |= (gpt->gpt5.sr & (1 << (31 - 23))) ? (1) : 0;
+               val |= (gpt->gpt6.sr & (1 << (31 - 23))) ? (1 << 1) : 0;
+               val |= (gpt->gpt7.sr & (1 << (31 - 23))) ? (1 << 2) : 0;
+               *fpgaversion = val;
+
+               if (*fpgaversion == 1)
+                       *failsavelevel = 2;     /* fpga-version ok */
+       }
+}
+
+/*
+ * This function is called from the SPL U-Boot version for
+ * early init stuff, that needs to be done for OS (e.g. Linux)
+ * booting. Doing it later in the real U-Boot would not work
+ * in case that the SPL U-Boot boots Linux directly.
+ */
+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;
+       int digiboardversion;
+       int failsavelevel;
+       int fpgaversion;
+       u32 val;
+
+       get_revisions(&failsavelevel, &digiboardversion, &fpgaversion);
+
+       val = in_be32(&mm->ipbi_ws_ctrl);
+
+       /* first clear bits 19..21 (CS3...5) */
+       val &= ~((1 << 19) | (1 << 20) | (1 << 21));
+       if (failsavelevel == 2) {
+               /* FPGA ok */
+               val |= (1 << 19) | (1 << 21);
+       }
+
+       if (failsavelevel >= 1) {
+               /* at least digiboard-version ok */
+               val |= (1 << 20);
+       }
+
+       /* And write new value back to register */
+       out_be32(&mm->ipbi_ws_ctrl, val);
+
+       /*
+        * No need to change the pin multiplexing (MPC5XXX_GPS_PORT_CONFIG)
+        * as all 3 config versions (failsave level) have the same setup.
+        */
+
+       /*
+        * Setup gpio_wkup_7 as watchdog AS INPUT to disable it - see
+        * ticket #60
+        *
+        * 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));
+
+       /* setup GPIOs for status-leds if needed - see ticket #57 */
+       if (failsavelevel > 0) {
+               /* digiboard-version is OK */
+               /* LED is LOW ACTIVE - so deactivate by set output to 1 */
+               gpio->simple_dvo |= 1 << (31 - 12);
+               gpio->simple_dvo |= 1 << (31 - 13);
+               /* set GPIO direction to output */
+               gpio->simple_ddr |= 1 << (31 - 12);
+               gpio->simple_ddr |= 1 << (31 - 13);
+               /* open drain config is set to "normal output" at reset */
+               /* gpio->simple_ode &=~ ( 1 << (31-12) ); */
+               /* gpio->simple_ode &=~ ( 1 << (31-13) ); */
+               /* enable as GPIO */
+               gpio->simple_gpioe |= 1 << (31 - 12);
+               gpio->simple_gpioe |= 1 << (31 - 13);
+       }
+
+       /* setup fpga irq - see ticket #65 */
+       if (failsavelevel > 1) {
+               /*
+                * The main irq initialisation is done in interrupts.c
+                * mpc5xxx_init_irq
+                */
+               struct mpc5xxx_intr *intr =
+                   (struct mpc5xxx_intr *)(MPC5XXX_ICTL);
+
+               setbits_be32(&intr->ctrl, 0x08C01801);
+
+               /*
+                * The MBAR+0x0524 Bit 21:23 CSe are ignored here due to the
+                * already cleared (intr_ctrl) MBAR+0x0510 ECLR[0] bit above
+                */
+       }
+
+}
+
+int checkboard(void)
+{
+       int digiboardversion;
+       int failsavelevel;
+       int fpgaversion;
+
+       get_revisions(&failsavelevel, &digiboardversion, &fpgaversion);
+
+       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);
+
+       return 0;
+}
+
+/* miscellaneous platform dependent initialisations */
+int misc_init_r(void)
+{
+       /* adjust flash start and offset to detected values */
+       gd->bd->bi_flashstart = flash_info[0].start[0];
+       gd->bd->bi_flashoffset = 0;
+
+       /* adjust mapping */
+       out_be32((void *)MPC5XXX_BOOTCS_START,
+                START_REG(gd->bd->bi_flashstart));
+       out_be32((void *)MPC5XXX_CS0_START, START_REG(gd->bd->bi_flashstart));
+       out_be32((void *)MPC5XXX_BOOTCS_STOP,
+                STOP_REG(gd->bd->bi_flashstart, gd->bd->bi_flashsize));
+       out_be32((void *)MPC5XXX_CS0_STOP,
+                STOP_REG(gd->bd->bi_flashstart, gd->bd->bi_flashsize));
+
+       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_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * A3M071 specific implementation of spl_start_uboot()
+ *
+ * RETURN
+ * 0 if booting into OS is selected (default)
+ * 1 if booting into U-Boot is selected
+ */
+int spl_start_uboot(void)
+{
+       char s[8];
+
+       env_init();
+       getenv_f("boot_os", s, sizeof(s));
+       if ((s != NULL) && (strcmp(s, "yes") == 0))
+               return 0;
+
+       return 1;
+}
+#endif
diff --git a/board/a3m071/mt46v16m16-75.h b/board/a3m071/mt46v16m16-75.h
new file mode 100644 (file)
index 0000000..e49e996
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * (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 */
+#define SDRAM_MODE     0x018D0000
+#define SDRAM_EMODE    0x40090000
+#define SDRAM_CONTROL  0x704f0f00
+#define SDRAM_CONFIG1  0x73722930
+#define SDRAM_CONFIG2  0x47770000
+#define SDRAM_TAPDELAY 0x10000000
+
+#else
+#error CONFIG_MPC5200 not defined
+#endif
index cfcc0dfbe51ef77d901d07f1d73c9d47fc7ffb5b..886baf6c96f57045da105b29cd2419d12d61b794 100644 (file)
@@ -32,9 +32,6 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
-COBJS-y        += coreboot.o
-COBJS-$(CONFIG_PCI) += coreboot_pci.o
-SOBJS-y        += coreboot_start16.o
 SOBJS-y        += coreboot_start.o
 
 SRCS   := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
diff --git a/board/chromebook-x86/coreboot/config.mk b/board/chromebook-x86/coreboot/config.mk
new file mode 100644 (file)
index 0000000..f720851
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * 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.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# 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.
+#
+# Alternatively, this software may be distributed under the terms of the
+# GNU General Public License ("GPL") version 2 as published by the Free
+# Software Foundation.
+#
+
+HOSTCFLAGS_autoconf.mk.dep = -Wno-variadic-macros
diff --git a/board/chromebook-x86/dts/alex.dts b/board/chromebook-x86/dts/alex.dts
new file mode 100644 (file)
index 0000000..cb6a9e4
--- /dev/null
@@ -0,0 +1,24 @@
+/dts-v1/;
+
+/include/ "coreboot.dtsi"
+
+/ {
+        #address-cells = <1>;
+        #size-cells = <1>;
+       model = "Google Alex";
+       compatible = "google,alex", "intel,atom-pineview";
+
+       config {
+              silent_console = <0>;
+       };
+
+        gpio: gpio {};
+
+       serial {
+               reg = <0x3f8 8>;
+               clock-frequency = <115200>;
+       };
+
+        chosen { };
+        memory { device_type = "memory"; reg = <0 0>; };
+};
diff --git a/board/chromebook-x86/dts/link.dts b/board/chromebook-x86/dts/link.dts
new file mode 100644 (file)
index 0000000..af60f59
--- /dev/null
@@ -0,0 +1,24 @@
+/dts-v1/;
+
+/include/ "coreboot.dtsi"
+
+/ {
+        #address-cells = <1>;
+        #size-cells = <1>;
+       model = "Google Link";
+       compatible = "google,link", "intel,celeron-ivybridge";
+
+       config {
+              silent_console = <0>;
+       };
+
+        gpio: gpio {};
+
+       serial {
+               reg = <0x3f8 8>;
+               clock-frequency = <115200>;
+       };
+
+        chosen { };
+        memory { device_type = "memory"; reg = <0 0>; };
+};
index c41f11d60c75a4ed1687a5dca0334ac728262680..a3079dbca367e2b7cb60b5c25a5c50ac8f22bc14 100644 (file)
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
 #include <nand.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <asm/gpio.h>
 #include "qong_fpga.h"
 #include <watchdog.h>
+#include <errno.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -172,10 +173,15 @@ int board_late_init(void)
 {
        u32 val;
        struct pmic *p;
+       int ret;
 
-       pmic_init();
-       p = get_pmic();
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return ret;
 
+       p = pmic_get("FSL_PMIC");
+       if (!p)
+               return -ENODEV;
        /* Enable RTC battery */
        pmic_reg_read(p, REG_POWER_CTL0, &val);
        pmic_reg_write(p, REG_POWER_CTL0, val | COINCHEN);
index 52c22faaa02551b5daddfdd1f0669f451d2cf8b1..89cfaad91f4306c60325bd34faba81c4d0a492a8 100644 (file)
@@ -105,7 +105,7 @@ int checkboard(void)
         * and delay a while before we continue.
         */
        if (mpc85xx_gpio_get(GPIO_RESETS)) {
-               ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+               ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
 
                puts("Debugger detected... extra device reset enabled!\n");
 
index 36f7c4f30f4965e20bad362753c908fcfce90945..75725b49ad8fd662ce6b78d9dae1506e2abd2903 100644 (file)
@@ -53,6 +53,7 @@ COBJS-$(CONFIG_P2020DS)               += ics307_clk.o
 COBJS-$(CONFIG_P3041DS)                += ics307_clk.o
 COBJS-$(CONFIG_P4080DS)                += ics307_clk.o
 COBJS-$(CONFIG_P5020DS)                += ics307_clk.o
+COBJS-$(CONFIG_P5040DS)                += ics307_clk.o
 COBJS-$(CONFIG_VSC_CROSSBAR)    += vsc3316_3308.o
 
 # deal with common files for P-series corenet based devices
@@ -60,6 +61,7 @@ SUBLIB-$(CONFIG_P2041RDB)     += p_corenet/libp_corenet.o
 SUBLIB-$(CONFIG_P3041DS)       += p_corenet/libp_corenet.o
 SUBLIB-$(CONFIG_P4080DS)       += p_corenet/libp_corenet.o
 SUBLIB-$(CONFIG_P5020DS)       += p_corenet/libp_corenet.o
+SUBLIB-$(CONFIG_P5040DS)       += p_corenet/libp_corenet.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS-y))
index 1d4483d8b9d21cce33b01a48476538dbbf457154..a239ee31df938a563def32c9f60f36408e57a0bd 100644 (file)
@@ -45,7 +45,7 @@ typedef struct ngpixis {
        struct {
                u8 sw;
                u8 en;
-       } s[8];
+       } s[9];         /* s[0]..s[7] is SW1..SW8, and s[8] is SW11 */
 } __attribute__ ((packed)) ngpixis_t;
 
 /* Pointer to the PIXIS register set */
index 1fdf8b706bf7b9b3900cb14b1c090072483f6908..d79193af2a9f852b8618fc4ea0856c70aa95caae 100644 (file)
@@ -31,9 +31,11 @@ COBJS-y      += ddr.o
 COBJS-$(CONFIG_P3041DS)        += eth_hydra.o
 COBJS-$(CONFIG_P4080DS)        += eth_p4080.o
 COBJS-$(CONFIG_P5020DS)        += eth_hydra.o
+COBJS-$(CONFIG_P5040DS)        += eth_superhydra.o
 COBJS-$(CONFIG_P3041DS)        += p3041ds_ddr.o
 COBJS-$(CONFIG_P4080DS)        += p4080ds_ddr.o
 COBJS-$(CONFIG_P5020DS)        += p5020ds_ddr.o
+COBJS-$(CONFIG_P5040DS)        += p5040ds_ddr.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS-y))
index a33c936fa00997fd9d387f29a498997a1389d636..21428e3347633eeddaaedf6a7ee619144ea73449 100644 (file)
@@ -45,6 +45,7 @@ int checkboard (void)
        struct cpu_type *cpu = gd->cpu;
        ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
        unsigned int i;
+       static const char * const freq[] = {"100", "125", "156.25", "212.5" };
 
        printf("Board: %sDS, ", cpu->name);
        printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ",
@@ -83,20 +84,28 @@ int checkboard (void)
         * don't match.
         */
        puts("SERDES Reference Clocks: ");
-#if defined(CONFIG_P3041DS) || defined(CONFIG_P5020DS)
+#if defined(CONFIG_P3041DS) || defined(CONFIG_P5020DS) \
+       || defined(CONFIG_P5040DS)
        sw = in_8(&PIXIS_SW(5));
        for (i = 0; i < 3; i++) {
-               static const char *freq[] = {"100", "125", "156.25", "212.5" };
                unsigned int clock = (sw >> (6 - (2 * i))) & 3;
 
                printf("Bank%u=%sMhz ", i+1, freq[clock]);
        }
+#ifdef CONFIG_P5040DS
+       /* On P5040DS, SW11[7:8] determines the Bank 4 frequency */
+       sw = in_8(&PIXIS_SW(9));
+       printf("Bank4=%sMhz ", freq[sw & 3]);
+#endif
        puts("\n");
 #else
        sw = in_8(&PIXIS_SW(3));
-       printf("Bank1=%uMHz ", (sw & 0x40) ? 125 : 100);
-       printf("Bank2=%sMHz ", (sw & 0x20) ? "156.25" : "125");
-       printf("Bank3=%sMHz\n", (sw & 0x10) ? "156.25" : "125");
+       /* SW3[2]: 0 = 100 Mhz, 1 = 125 MHz */
+       /* SW3[3]: 0 = 125 Mhz, 1 = 156.25 MHz */
+       /* SW3[4]: 0 = 125 Mhz, 1 = 156.25 MHz */
+       printf("Bank1=%sMHz ", freq[!!(sw & 0x40)]);
+       printf("Bank2=%sMHz ", freq[1 + !!(sw & 0x20)]);
+       printf("Bank3=%sMHz\n", freq[1 + !!(sw & 0x10)]);
 #endif
 
        return 0;
@@ -168,7 +177,8 @@ int misc_init_r(void)
        unsigned int i;
        u8 sw;
 
-#if defined(CONFIG_P3041DS) || defined(CONFIG_P5020DS)
+#if defined(CONFIG_P3041DS) || defined(CONFIG_P5020DS) \
+       || defined(CONFIG_P5040DS)
        sw = in_8(&PIXIS_SW(5));
        for (i = 0; i < 3; i++) {
                unsigned int clock = (sw >> (6 - (2 * i))) & 3;
index 4a53b8d9337efc9ae96b062328427da0ff0f0faf..da284cde9556aa330acf85adcdf544e6614919fe 100644 (file)
@@ -139,8 +139,8 @@ static const struct board_specific_parameters udimm0[] = {
        {2,  1250,    4,     6,   0xff,    2,  0},
        {2,  1350,    5,     7,   0xff,    2,  0},
        {2,  1666,    5,     8,   0xff,    2,  0},
-       {1,   850,    4,     5,   0xff,    2,  0},
-       {1,   950,    4,     7,   0xff,    2,  0},
+       {1,  1250,    4,     6,   0xff,    2,  0},
+       {1,  1335,    4,     7,   0xff,    2,  0},
        {1,  1666,    4,     8,   0xff,    2,  0},
        {}
 };
diff --git a/board/freescale/corenet_ds/eth_superhydra.c b/board/freescale/corenet_ds/eth_superhydra.c
new file mode 100644 (file)
index 0000000..ef9de25
--- /dev/null
@@ -0,0 +1,722 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ * Author: Srikanth Srinivasan <srikanth.srinivasan@freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This file handles the board muxing between the Fman Ethernet MACs and
+ * the RGMII/SGMII/XGMII PHYs on a Freescale P5040 "Super Hydra" reference
+ * board. The RGMII PHYs are the two on-board 1Gb ports.  The SGMII PHYs are
+ * provided by the standard Freescale four-port SGMII riser card.  The 10Gb
+ * XGMII PHYs are provided via the XAUI riser card.  The P5040 has 2 FMans
+ * and 5 1G interfaces and 10G interface per FMan. Based on the options in
+ * the RCW, we could have upto 3 SGMII cards and 1 XAUI card at a time.
+ *
+ * Muxing is handled via the PIXIS BRDCFG1 register.  The EMI1 bits control
+ * muxing among the RGMII PHYs and the SGMII PHYs.  The value for RGMII is
+ * always the same (0).  The value for SGMII depends on which slot the riser is
+ * inserted in.  The EMI2 bits control muxing for the the XGMII.  Like SGMII,
+ * the value is based on which slot the XAUI is inserted in.
+ *
+ * The SERDES configuration is used to determine where the SGMII and XAUI cards
+ * exist, and also which Fman's MACs are routed to which PHYs.  So for a given
+ * Fman MAC, there is one and only PHY it connects to.  MACs cannot be routed
+ * to PHYs dynamically.
+ *
+ *
+ * This file also updates the device tree in three ways:
+ *
+ * 1) The status of each virtual MDIO node that is referenced by an Ethernet
+ *    node is set to "okay".
+ *
+ * 2) The phy-handle property of each active Ethernet MAC node is set to the
+ *    appropriate PHY node.
+ *
+ * 3) The "mux value" for each virtual MDIO node is set to the correct value,
+ *    if necessary.  Some virtual MDIO nodes do not have configurable mux
+ *    values, so those values are hard-coded in the DTS.  On the HYDRA board,
+ *    the virtual MDIO node for the SGMII card needs to be updated.
+ *
+ * For all this to work, the device tree needs to have the following:
+ *
+ * 1) An alias for each PHY node that an Ethernet node could be routed to.
+ *
+ * 2) An alias for each real and virtual MDIO node that is disabled by default
+ * and might need to be enabled, and also might need to have its mux-value
+ * updated.
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/fsl_serdes.h>
+#include <fm_eth.h>
+#include <fsl_mdio.h>
+#include <malloc.h>
+#include <fdt_support.h>
+#include <asm/fsl_dtsec.h>
+
+#include "../common/ngpixis.h"
+#include "../common/fman.h"
+
+#ifdef CONFIG_FMAN_ENET
+
+#define BRDCFG1_EMI1_SEL_MASK  0x70
+#define BRDCFG1_EMI1_SEL_SLOT1 0x10
+#define BRDCFG1_EMI1_SEL_SLOT2 0x20
+#define BRDCFG1_EMI1_SEL_SLOT5 0x30
+#define BRDCFG1_EMI1_SEL_SLOT6 0x40
+#define BRDCFG1_EMI1_SEL_SLOT7 0x50
+#define BRDCFG1_EMI1_SEL_SLOT3 0x60
+#define BRDCFG1_EMI1_SEL_RGMII 0x00
+#define BRDCFG1_EMI1_EN                0x08
+#define BRDCFG1_EMI2_SEL_MASK  0x06
+#define BRDCFG1_EMI2_SEL_SLOT1 0x00
+#define BRDCFG1_EMI2_SEL_SLOT2 0x02
+
+#define BRDCFG2_REG_GPIO_SEL   0x20
+
+/*
+ * BRDCFG1 mask and value for each MAC
+ *
+ * This array contains the BRDCFG1 values (in mask/val format) that route the
+ * MDIO bus to a particular RGMII or SGMII PHY.
+ */
+static struct {
+       u8 mask;
+       u8 val;
+} mdio_mux[NUM_FM_PORTS];
+
+/*
+ * Mapping of all 18 SERDES lanes to board slots. A value of '0' here means
+ * that the mapping must be determined dynamically, or that the lane maps to
+ * something other than a board slot
+ */
+static u8 lane_to_slot[] = {
+       7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0
+};
+
+/*
+ * Set the board muxing for a given MAC
+ *
+ * The MDIO layer calls this function every time it wants to talk to a PHY.
+ */
+void super_hydra_mux_mdio(u8 mask, u8 val)
+{
+       clrsetbits_8(&pixis->brdcfg1, mask, val);
+}
+
+struct super_hydra_mdio {
+       u8 mask;
+       u8 val;
+       struct mii_dev *realbus;
+};
+
+static int super_hydra_mdio_read(struct mii_dev *bus, int addr, int devad,
+                               int regnum)
+{
+       struct super_hydra_mdio *priv = bus->priv;
+
+       super_hydra_mux_mdio(priv->mask, priv->val);
+
+       return priv->realbus->read(priv->realbus, addr, devad, regnum);
+}
+
+static int super_hydra_mdio_write(struct mii_dev *bus, int addr, int devad,
+                               int regnum, u16 value)
+{
+       struct super_hydra_mdio *priv = bus->priv;
+
+       super_hydra_mux_mdio(priv->mask, priv->val);
+
+       return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
+}
+
+static int super_hydra_mdio_reset(struct mii_dev *bus)
+{
+       struct super_hydra_mdio *priv = bus->priv;
+
+       return priv->realbus->reset(priv->realbus);
+}
+
+static void super_hydra_mdio_set_mux(char *name, u8 mask, u8 val)
+{
+       struct mii_dev *bus = miiphy_get_dev_by_name(name);
+       struct super_hydra_mdio *priv = bus->priv;
+
+       priv->mask = mask;
+       priv->val = val;
+}
+
+static int super_hydra_mdio_init(char *realbusname, char *fakebusname)
+{
+       struct super_hydra_mdio *hmdio;
+       struct mii_dev *bus = mdio_alloc();
+
+       if (!bus) {
+               printf("Failed to allocate Hydra MDIO bus\n");
+               return -1;
+       }
+
+       hmdio = malloc(sizeof(*hmdio));
+       if (!hmdio) {
+               printf("Failed to allocate Hydra private data\n");
+               free(bus);
+               return -1;
+       }
+
+       bus->read = super_hydra_mdio_read;
+       bus->write = super_hydra_mdio_write;
+       bus->reset = super_hydra_mdio_reset;
+       sprintf(bus->name, fakebusname);
+
+       hmdio->realbus = miiphy_get_dev_by_name(realbusname);
+
+       if (!hmdio->realbus) {
+               printf("No bus with name %s\n", realbusname);
+               free(bus);
+               free(hmdio);
+               return -1;
+       }
+
+       bus->priv = hmdio;
+
+       return mdio_register(bus);
+}
+
+/*
+ * Given the following ...
+ *
+ * 1) A pointer to an Fman Ethernet node (as identified by the 'compat'
+ * compatible string and 'addr' physical address)
+ *
+ * 2) An Fman port
+ *
+ * ... update the phy-handle property of the Ethernet node to point to the
+ * right PHY.  This assumes that we already know the PHY for each port.  That
+ * information is stored in mdio_mux[].
+ *
+ * The offset of the Fman Ethernet node is also passed in for convenience, but
+ * it is not used.
+ *
+ * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC.
+ * Inside the Fman, "ports" are things that connect to MACs.  We only call them
+ * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs
+ * and ports are the same thing.
+ */
+void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
+                             enum fm_port port, int offset)
+{
+       enum srds_prtcl device;
+       int lane, slot, phy;
+       char alias[32];
+
+       /* RGMII and XGMII are already mapped correctly in the DTS */
+
+       if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
+               device = serdes_device_from_fm_port(port);
+               lane = serdes_get_first_lane(device);
+               slot = lane_to_slot[lane];
+               phy = fm_info_get_phy_address(port);
+
+               sprintf(alias, "phy_sgmii_slot%u_%x", slot, phy);
+               fdt_set_phy_handle(fdt, compat, addr, alias);
+       }
+}
+
+#define PIXIS_SW2_LANE_23_SEL          0x80
+#define PIXIS_SW2_LANE_45_SEL          0x40
+#define PIXIS_SW2_LANE_67_SEL_MASK     0x30
+#define PIXIS_SW2_LANE_67_SEL_5                0x00
+#define PIXIS_SW2_LANE_67_SEL_6                0x20
+#define PIXIS_SW2_LANE_67_SEL_7                0x10
+#define PIXIS_SW2_LANE_8_SEL           0x08
+#define PIXIS_SW2_LANE_1617_SEL                0x04
+#define PIXIS_SW11_LANE_9_SEL          0x04
+/*
+ * Initialize the lane_to_slot[] array.
+ *
+ * On the P4080DS "Expedition" board, the mapping of SERDES lanes to board
+ * slots is hard-coded.  On the Hydra board, however, the mapping is controlled
+ * by board switch SW2, so the lane_to_slot[] array needs to be dynamically
+ * initialized.
+ */
+static void initialize_lane_to_slot(void)
+{
+       u8 sw2 = in_8(&PIXIS_SW(2));
+       /* SW11 appears in the programming model as SW9 */
+       u8 sw11 = in_8(&PIXIS_SW(9));
+
+       lane_to_slot[2] = (sw2 & PIXIS_SW2_LANE_23_SEL) ? 7 : 4;
+       lane_to_slot[3] = lane_to_slot[2];
+
+       lane_to_slot[4] = (sw2 & PIXIS_SW2_LANE_45_SEL) ? 7 : 6;
+       lane_to_slot[5] = lane_to_slot[4];
+
+       switch (sw2 & PIXIS_SW2_LANE_67_SEL_MASK) {
+       case PIXIS_SW2_LANE_67_SEL_5:
+               lane_to_slot[6] = 5;
+               break;
+       case PIXIS_SW2_LANE_67_SEL_6:
+               lane_to_slot[6] = 6;
+               break;
+       case PIXIS_SW2_LANE_67_SEL_7:
+               lane_to_slot[6] = 7;
+               break;
+       }
+       lane_to_slot[7] = lane_to_slot[6];
+
+       lane_to_slot[8] = (sw2 & PIXIS_SW2_LANE_8_SEL) ? 3 : 0;
+       lane_to_slot[9] = (sw11 & PIXIS_SW11_LANE_9_SEL) ? 0 : 3;
+
+       lane_to_slot[16] = (sw2 & PIXIS_SW2_LANE_1617_SEL) ? 1 : 0;
+       lane_to_slot[17] = lane_to_slot[16];
+}
+
+#endif /* #ifdef CONFIG_FMAN_ENET */
+
+/*
+ * Configure the status for the virtual MDIO nodes
+ *
+ * Rather than create the virtual MDIO nodes from scratch for each active
+ * virtual MDIO, we expect the DTS to have the nodes defined already, and we
+ * only enable the ones that are actually active.
+ *
+ * We assume that the DTS already hard-codes the status for all the
+ * virtual MDIO nodes to "disabled", so all we need to do is enable the
+ * active ones.
+ */
+void fdt_fixup_board_enet(void *fdt)
+{
+#ifdef CONFIG_FMAN_ENET
+       enum fm_port i;
+       int lane, slot;
+
+       for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
+               int idx = i - FM1_DTSEC1;
+
+               switch (fm_info_get_enet_if(i)) {
+               case PHY_INTERFACE_MODE_SGMII:
+                       lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
+                       if (lane >= 0) {
+                               char alias[32];
+
+                               slot = lane_to_slot[lane];
+                               sprintf(alias, "hydra_sg_slot%u", slot);
+                               fdt_status_okay_by_alias(fdt, alias);
+                               debug("Enabled MDIO node %s (slot %i)\n",
+                                     alias, slot);
+                       }
+                       break;
+               case PHY_INTERFACE_MODE_RGMII:
+                       fdt_status_okay_by_alias(fdt, "hydra_rg");
+                       debug("Enabled MDIO node hydra_rg\n");
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       lane = serdes_get_first_lane(XAUI_FM1);
+       if (lane >= 0) {
+               char alias[32];
+
+               slot = lane_to_slot[lane];
+               sprintf(alias, "hydra_xg_slot%u", slot);
+               fdt_status_okay_by_alias(fdt, alias);
+               debug("Enabled MDIO node %s (slot %i)\n", alias, slot);
+       }
+
+#if CONFIG_SYS_NUM_FMAN == 2
+       for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
+               int idx = i - FM2_DTSEC1;
+
+               switch (fm_info_get_enet_if(i)) {
+               case PHY_INTERFACE_MODE_SGMII:
+                       lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
+                       if (lane >= 0) {
+                               char alias[32];
+
+                               slot = lane_to_slot[lane];
+                               sprintf(alias, "hydra_sg_slot%u", slot);
+                               fdt_status_okay_by_alias(fdt, alias);
+                               debug("Enabled MDIO node %s (slot %i)\n",
+                                     alias, slot);
+                       }
+                       break;
+               case PHY_INTERFACE_MODE_RGMII:
+                       fdt_status_okay_by_alias(fdt, "hydra_rg");
+                       debug("Enabled MDIO node hydra_rg\n");
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       lane = serdes_get_first_lane(XAUI_FM2);
+       if (lane >= 0) {
+               char alias[32];
+
+               slot = lane_to_slot[lane];
+               sprintf(alias, "hydra_xg_slot%u", slot);
+               fdt_status_okay_by_alias(fdt, alias);
+               debug("Enabled MDIO node %s (slot %i)\n", alias, slot);
+       }
+#endif /* CONFIG_SYS_NUM_FMAN == 2 */
+#endif /* CONFIG_FMAN_ENET */
+}
+
+/*
+ * Mapping of SerDes Protocol to MDIO MUX value and PHY address.
+ *
+ * Fman 1:
+ *       DTSEC1        |   DTSEC2        |   DTSEC3        |   DTSEC4
+ *       Mux     Phy   |   Mux     Phy   |   Mux     Phy   |   Mux     Phy
+ *       Value   Addr  |   Value   Addr  |   Value   Addr  |   Value   Addr
+ * 0x00  2       1c    |   2       1d    |   2       1e    |   2       1f
+ * 0x01                |                 |   6       1c    |
+ * 0x02                |                 |   3       1c    |   3       1d
+ * 0x03  2       1c    |   2       1d    |   2       1e    |   2       1f
+ * 0x04  2       1c    |   2       1d    |   2       1e    |   2       1f
+ * 0x05                |                 |   3       1c    |   3       1d
+ * 0x06  2       1c    |   2       1d    |   2       1e    |   2       1f
+ * 0x07                |                 |   6       1c    |
+ * 0x11  2       1c    |   2       1d    |   2       1e    |   2       1f
+ * 0x2a  2             |                 |   2       1e    |   2       1f
+ * 0x34  6       1c    |   6       1d    |   4       1e    |   4       1f
+ * 0x35                |                 |   3       1c    |   3       1d
+ * 0x36  6       1c    |   6       1d    |   4       1e    |   4       1f
+ *                     |                 |                 |
+ * Fman  2:            |                 |                 |
+ *       DTSEC1        |   DTSEC2        |   DTSEC3        |   DTSEC4
+ *       EMI1          |   EMI1          |   EMI1          |   EMI1
+ *       Mux     Phy   |   Mux     Phy   |   Mux     Phy   |   Mux     Phy
+ *       Value   Addr  |   Value   Addr  |   Value   Addr  |   Value   Addr
+ * 0x00                |                 |   6       1c    |   6       1d
+ * 0x01                |                 |                 |
+ * 0x02                |                 |   6       1c    |   6       1d
+ * 0x03  3       1c    |   3       1d    |   6       1c    |   6       1d
+ * 0x04  3       1c    |   3       1d    |   6       1c    |   6       1d
+ * 0x05                |                 |   6       1c    |   6       1d
+ * 0x06                |                 |   6       1c    |   6       1d
+ * 0x07                |                 |                 |
+ * 0x11                |                 |                 |
+ * 0x2a                |                 |                 |
+ * 0x34                |                 |                 |
+ * 0x35                |                 |                 |
+ * 0x36                |                 |                 |
+ */
+
+int board_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_FMAN_ENET
+       struct fsl_pq_mdio_info dtsec_mdio_info;
+       struct tgec_mdio_info tgec_mdio_info;
+       unsigned int i, slot;
+       int lane;
+       ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       int srds_prtcl = (in_be32(&gur->rcwsr[4]) &
+                               FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
+
+       printf("Initializing Fman\n");
+
+       initialize_lane_to_slot();
+
+       /* We want to use the PIXIS to configure MUX routing, not GPIOs. */
+       setbits_8(&pixis->brdcfg2, BRDCFG2_REG_GPIO_SEL);
+
+       memset(mdio_mux, 0, sizeof(mdio_mux));
+
+       dtsec_mdio_info.regs =
+               (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
+       dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
+
+       /* Register the real 1G MDIO bus */
+       fsl_pq_mdio_init(bis, &dtsec_mdio_info);
+
+       tgec_mdio_info.regs =
+               (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
+       tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
+
+       /* Register the real 10G MDIO bus */
+       fm_tgec_mdio_init(bis, &tgec_mdio_info);
+
+       /* Register the three virtual MDIO front-ends */
+       super_hydra_mdio_init(DEFAULT_FM_MDIO_NAME,
+                               "SUPER_HYDRA_RGMII_MDIO");
+       super_hydra_mdio_init(DEFAULT_FM_MDIO_NAME,
+                               "SUPER_HYDRA_FM1_SGMII_MDIO");
+       super_hydra_mdio_init(DEFAULT_FM_MDIO_NAME,
+                               "SUPER_HYDRA_FM2_SGMII_MDIO");
+       super_hydra_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME,
+                               "SUPER_HYDRA_FM1_TGEC_MDIO");
+       super_hydra_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME,
+                               "SUPER_HYDRA_FM2_TGEC_MDIO");
+
+       /*
+        * Program the DTSEC PHY addresses assuming that they are all SGMII.
+        * For any DTSEC that's RGMII, we'll override its PHY address later.
+        * We assume that DTSEC5 is only used for RGMII.
+        */
+       fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR);
+       fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR);
+       fm_info_set_phy_address(FM1_10GEC1, CONFIG_SYS_FM2_10GEC1_PHY_ADDR);
+
+#if (CONFIG_SYS_NUM_FMAN == 2)
+       fm_info_set_phy_address(FM2_DTSEC1, CONFIG_SYS_FM2_DTSEC1_PHY_ADDR);
+       fm_info_set_phy_address(FM2_DTSEC2, CONFIG_SYS_FM2_DTSEC2_PHY_ADDR);
+       fm_info_set_phy_address(FM2_DTSEC3, CONFIG_SYS_FM2_DTSEC1_PHY_ADDR);
+       fm_info_set_phy_address(FM2_DTSEC4, CONFIG_SYS_FM2_DTSEC2_PHY_ADDR);
+       fm_info_set_phy_address(FM2_10GEC1, CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
+#endif
+
+       switch (srds_prtcl) {
+       case 0:
+       case 3:
+       case 4:
+       case 6:
+       case 0x11:
+       case 0x2a:
+       case 0x34:
+       case 0x36:
+               fm_info_set_phy_address(FM1_DTSEC3,
+                                       CONFIG_SYS_FM1_DTSEC3_PHY_ADDR);
+               fm_info_set_phy_address(FM1_DTSEC4,
+                                       CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
+               break;
+       case 1:
+       case 2:
+       case 5:
+       case 7:
+       case 0x35:
+               fm_info_set_phy_address(FM1_DTSEC3,
+                                       CONFIG_SYS_FM1_DTSEC1_PHY_ADDR);
+               fm_info_set_phy_address(FM1_DTSEC4,
+                                       CONFIG_SYS_FM1_DTSEC2_PHY_ADDR);
+               break;
+       default:
+               printf("Fman:  Unsupport SerDes Protocol 0x%02x\n", srds_prtcl);
+               break;
+       }
+
+       for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
+               int idx = i - FM1_DTSEC1;
+
+               switch (fm_info_get_enet_if(i)) {
+               case PHY_INTERFACE_MODE_SGMII:
+                       lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
+                       if (lane < 0)
+                               break;
+                       slot = lane_to_slot[lane];
+                       mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
+                       debug("FM1@DTSEC%u expects SGMII in slot %u\n",
+                             idx + 1, slot);
+                       switch (slot) {
+                       case 1:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT1 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 2:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT2 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 3:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT3 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 5:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT5 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 6:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT6 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 7:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT7 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       };
+
+                       super_hydra_mdio_set_mux("SUPER_HYDRA_FM1_SGMII_MDIO",
+                                       mdio_mux[i].mask, mdio_mux[i].val);
+                       fm_info_set_mdio(i,
+                       miiphy_get_dev_by_name("SUPER_HYDRA_FM1_SGMII_MDIO"));
+                       break;
+               case PHY_INTERFACE_MODE_RGMII:
+                       /*
+                        * FM1 DTSEC5 is routed via EC1 to the first on-board
+                        * RGMII port. FM2 DTSEC5 is routed via EC2 to the
+                        * second on-board RGMII port. The other DTSECs cannot
+                        * be routed to RGMII.
+                        */
+                       debug("FM1@DTSEC%u is RGMII at address %u\n",
+                             idx + 1, 0);
+                       fm_info_set_phy_address(i, 0);
+                       mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
+                       mdio_mux[i].val  = BRDCFG1_EMI1_SEL_RGMII |
+                                          BRDCFG1_EMI1_EN;
+                       super_hydra_mdio_set_mux("SUPER_HYDRA_RGMII_MDIO",
+                                       mdio_mux[i].mask, mdio_mux[i].val);
+                       fm_info_set_mdio(i,
+                               miiphy_get_dev_by_name("SUPER_HYDRA_RGMII_MDIO"));
+                       break;
+               case PHY_INTERFACE_MODE_NONE:
+                       fm_info_set_phy_address(i, 0);
+                       break;
+               default:
+                       printf("Fman1: DTSEC%u set to unknown interface %i\n",
+                              idx + 1, fm_info_get_enet_if(i));
+                       fm_info_set_phy_address(i, 0);
+                       break;
+               }
+       }
+
+       /*
+        * For 10G, we only support one XAUI card per Fman.  If present, then we
+        * force its routing and never touch those bits again, which removes the
+        * need for Linux to do any muxing.  This works because of the way
+        * BRDCFG1 is defined, but it's a bit hackish.
+        *
+        * The PHY address for the XAUI card depends on which slot it's in. The
+        * macros we use imply that the PHY address is based on which FM, but
+        * that's not true.  On the P4080DS, FM1 could only use XAUI in slot 5,
+        * and FM2 could only use a XAUI in slot 4.  On the Hydra board, we
+        * check the actual slot and just use the macros as-is, even though
+        * the P3041 and P5020 only have one Fman.
+        */
+       lane = serdes_get_first_lane(XAUI_FM1);
+       if (lane >= 0) {
+               debug("FM1@TGEC1 expects XAUI in slot %u\n", lane_to_slot[lane]);
+               mdio_mux[FM1_10GEC1].mask = BRDCFG1_EMI2_SEL_MASK;
+               mdio_mux[FM1_10GEC1].val = BRDCFG1_EMI2_SEL_SLOT2;
+               super_hydra_mdio_set_mux("SUPER_HYDRA_FM1_TGEC_MDIO",
+                                       mdio_mux[i].mask, mdio_mux[i].val);
+       }
+
+       fm_info_set_mdio(FM1_10GEC1,
+                       miiphy_get_dev_by_name("SUPER_HYDRA_FM1_TGEC_MDIO"));
+
+#if (CONFIG_SYS_NUM_FMAN == 2)
+       for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
+               int idx = i - FM2_DTSEC1;
+
+               switch (fm_info_get_enet_if(i)) {
+               case PHY_INTERFACE_MODE_SGMII:
+                       lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
+                       if (lane < 0)
+                               break;
+                       slot = lane_to_slot[lane];
+                       mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
+                       debug("FM2@DTSEC%u expects SGMII in slot %u\n",
+                             idx + 1, slot);
+                       switch (slot) {
+                       case 1:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT1 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 2:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT2 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 3:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT3 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 5:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT5 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 6:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT6 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       case 7:
+                               mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT7 |
+                                               BRDCFG1_EMI1_EN;
+                               break;
+                       };
+
+                       super_hydra_mdio_set_mux("SUPER_HYDRA_FM2_SGMII_MDIO",
+                                       mdio_mux[i].mask, mdio_mux[i].val);
+                       fm_info_set_mdio(i,
+                       miiphy_get_dev_by_name("SUPER_HYDRA_FM2_SGMII_MDIO"));
+                       break;
+               case PHY_INTERFACE_MODE_RGMII:
+                       /*
+                        * FM1 DTSEC5 is routed via EC1 to the first on-board
+                        * RGMII port. FM2 DTSEC5 is routed via EC2 to the
+                        * second on-board RGMII port. The other DTSECs cannot
+                        * be routed to RGMII.
+                        */
+                       debug("FM2@DTSEC%u is RGMII at address %u\n",
+                             idx + 1, 1);
+                       fm_info_set_phy_address(i, 1);
+                       mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK;
+                       mdio_mux[i].val  = BRDCFG1_EMI1_SEL_RGMII |
+                                       BRDCFG1_EMI1_EN;
+                       super_hydra_mdio_set_mux("SUPER_HYDRA_RGMII_MDIO",
+                                       mdio_mux[i].mask, mdio_mux[i].val);
+                       fm_info_set_mdio(i,
+                       miiphy_get_dev_by_name("SUPER_HYDRA_RGMII_MDIO"));
+                       break;
+               case PHY_INTERFACE_MODE_NONE:
+                       fm_info_set_phy_address(i, 0);
+                       break;
+               default:
+                       printf("Fman2: DTSEC%u set to unknown interface %i\n",
+                               idx + 1, fm_info_get_enet_if(i));
+                       fm_info_set_phy_address(i, 0);
+                       break;
+               }
+       }
+
+       /*
+        * For 10G, we only support one XAUI card per Fman.  If present, then we
+        * force its routing and never touch those bits again, which removes the
+        * need for Linux to do any muxing.  This works because of the way
+        * BRDCFG1 is defined, but it's a bit hackish.
+        *
+        * The PHY address for the XAUI card depends on which slot it's in. The
+        * macros we use imply that the PHY address is based on which FM, but
+        * that's not true.  On the P4080DS, FM1 could only use XAUI in slot 5,
+        * and FM2 could only use a XAUI in slot 4.  On the Hydra board, we
+        * check the actual slot and just use the macros as-is, even though
+        * the P3041 and P5020 only have one Fman.
+        */
+       lane = serdes_get_first_lane(XAUI_FM2);
+       if (lane >= 0) {
+               debug("FM2@TGEC1 expects XAUI in slot %u\n", lane_to_slot[lane]);
+               mdio_mux[FM2_10GEC1].mask = BRDCFG1_EMI2_SEL_MASK;
+               mdio_mux[FM2_10GEC1].val = BRDCFG1_EMI2_SEL_SLOT1;
+               super_hydra_mdio_set_mux("SUPER_HYDRA_FM2_TGEC_MDIO",
+                                       mdio_mux[i].mask, mdio_mux[i].val);
+       }
+
+       fm_info_set_mdio(FM2_10GEC1,
+                       miiphy_get_dev_by_name("SUPER_HYDRA_FM2_TGEC_MDIO"));
+
+#endif
+
+       cpu_eth_init(bis);
+#endif
+
+       return pci_eth_init(bis);
+}
diff --git a/board/freescale/corenet_ds/p5040ds_ddr.c b/board/freescale/corenet_ds/p5040ds_ddr.c
new file mode 100644 (file)
index 0000000..e65de36
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2009-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <asm/fsl_ddr_sdram.h>
+
+fixed_ddr_parm_t fixed_ddr_parm_0[] = {
+       {0, 0, NULL}
+};
+
+fixed_ddr_parm_t fixed_ddr_parm_1[] = {
+       {0, 0, NULL}
+};
index a275d3a074d8fb4fb4b490c8ec7333a06cfb2a73..418c06b655cacaec5961435189b3ae541d1febe0 100644 (file)
@@ -184,7 +184,7 @@ void lbc_sdram_init(void)
 phys_size_t fixed_sdram(void)
 {
   #ifndef CONFIG_SYS_RAMBOOT
-       volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
+       volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC8xxx_DDR_ADDR);
 
        ddr->cs0_bnds = CONFIG_SYS_DDR_CS0_BNDS;
        ddr->cs0_config = CONFIG_SYS_DDR_CS0_CONFIG;
index 285edbce6b46b7206b0b045eb55a88b4675aff30..a4f48bb23432200aeb032ad7f0d81ff1ec407da2 100644 (file)
@@ -389,7 +389,7 @@ void lbc_sdram_init(void)
 phys_size_t fixed_sdram(void)
 {
   #ifndef CONFIG_SYS_RAMBOOT
-       volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
+       volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC8xxx_DDR_ADDR);
 
        ddr->cs0_bnds = CONFIG_SYS_DDR_CS0_BNDS;
        ddr->cs0_config = CONFIG_SYS_DDR_CS0_CONFIG;
index d119c6517f65c7bbdb1f082db3f52ee1aacc5893..0d3b4186251982b8560642f13f80b2f48e023bfa 100644 (file)
@@ -247,7 +247,7 @@ int checkboard (void)
 #if !defined(CONFIG_SPD_EEPROM)
 phys_size_t fixed_sdram(void)
 {
-       volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+       volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
        uint d_init;
 
        out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS);
index 9f8bc53e711c02fd40ed9f2b58b35417a24a277a..bc60632aa0b34662a10243f30c9f6a42f856bbb0 100644 (file)
@@ -30,8 +30,9 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/sys_proto.h>
 #include <watchdog.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
+#include <errno.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -83,10 +84,15 @@ int board_late_init(void)
 {
        u32 val;
        struct pmic *p;
+       int ret;
 
-       pmic_init();
-       p = get_pmic();
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return ret;
 
+       p = pmic_get("FSL_PMIC");
+       if (!p)
+               return -ENODEV;
        /* Enable RTC battery */
        pmic_reg_read(p, REG_POWER_CTL0, &val);
        pmic_reg_write(p, REG_POWER_CTL0, val | COINCHEN);
index 4d8f2f5eea34c1f2c37cd3ab73e62dcabdcf78c2..2aa000f238e43313bf4c2cd30ff0eb9fe0cbd2b7 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/arch/mx35_pins.h>
 #include <asm/arch/iomux.h>
 #include <i2c.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
@@ -228,7 +228,9 @@ int board_init(void)
 static inline int pmic_detect(void)
 {
        unsigned int id;
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("FSL_PMIC");
+       if (!p)
+               return -ENODEV;
 
        pmic_reg_read(p, REG_IDENTIFICATION, &id);
 
@@ -252,10 +254,14 @@ int board_late_init(void)
        u8 val;
        u32 pmic_val;
        struct pmic *p;
+       int ret;
+
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return ret;
 
-       pmic_init();
        if (pmic_detect()) {
-               p = get_pmic();
+               p = pmic_get("FSL_PMIC");
                mxc_request_iomux(MX35_PIN_WATCHDOG_RST, MUX_CONFIG_SION |
                                        MUX_CONFIG_ALT1);
 
index 224eaa3c734fb497cfe66c013bc91e1b189bf723..2310fe137d73644b3738ceaae3732f1adcc1a3b5 100644 (file)
@@ -23,8 +23,10 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
-COBJS  := mx51evk.o
+COBJS-y                        += mx51evk.o
+COBJS-$(CONFIG_VIDEO)  += mx51evk_video.o
 
+COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
 
index 421d8c224444e4ba935f71e6cf9fde39307e385a..d1ef431895a0786f72eb4ae42413202ee9200e97 100644 (file)
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/crm_regs.h>
 #include <asm/arch/clock.h>
+#include <asm/imx-common/mx5_video.h>
 #include <i2c.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mc13892.h>
 #include <usb/ehci-fsl.h>
-#include <linux/fb.h>
-#include <ipu_pixfmt.h>
-
-#define MX51EVK_LCD_3V3                IMX_GPIO_NR(4, 9)
-#define MX51EVK_LCD_5V         IMX_GPIO_NR(4, 10)
-#define MX51EVK_LCD_BACKLIGHT  IMX_GPIO_NR(3, 4)
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -252,9 +247,15 @@ static void power_init(void)
        unsigned int val;
        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
        struct pmic *p;
+       int ret;
+
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return;
 
-       pmic_init();
-       p = get_pmic();
+       p = pmic_get("FSL_PMIC");
+       if (!p)
+               return;
 
        /* Write needed to Power Gate 2 register */
        pmic_reg_read(p, REG_POWER_MISC, &val);
@@ -471,54 +472,6 @@ int board_mmc_init(bd_t *bis)
 }
 #endif
 
-static struct fb_videomode const claa_wvga = {
-       .name           = "CLAA07LC0ACW",
-       .refresh        = 57,
-       .xres           = 800,
-       .yres           = 480,
-       .pixclock       = 37037,
-       .left_margin    = 40,
-       .right_margin   = 60,
-       .upper_margin   = 10,
-       .lower_margin   = 10,
-       .hsync_len      = 20,
-       .vsync_len      = 10,
-       .sync           = 0,
-       .vmode          = FB_VMODE_NONINTERLACED
-};
-
-void lcd_iomux(void)
-{
-       /* DI2_PIN15 */
-       mxc_request_iomux(MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT4);
-
-       /* Pad settings for MX51_PIN_DI2_DISP_CLK */
-       mxc_iomux_set_pad(MX51_PIN_DI2_DISP_CLK, PAD_CTL_HYS_NONE |
-                         PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
-                         PAD_CTL_DRV_MAX | PAD_CTL_SRE_SLOW);
-
-       /* Turn on 3.3V voltage for LCD */
-       mxc_request_iomux(MX51_PIN_CSI2_D12, IOMUX_CONFIG_ALT3);
-       gpio_direction_output(MX51EVK_LCD_3V3, 1);
-
-       /* Turn on 5V voltage for LCD */
-       mxc_request_iomux(MX51_PIN_CSI2_D13, IOMUX_CONFIG_ALT3);
-       gpio_direction_output(MX51EVK_LCD_5V, 1);
-
-       /* Turn on GPIO backlight */
-       mxc_request_iomux(MX51_PIN_DI1_D1_CS, IOMUX_CONFIG_ALT4);
-       mxc_iomux_set_input(MX51_GPIO3_IPP_IND_G_IN_4_SELECT_INPUT,
-                                                       INPUT_CTL_PATH1);
-       gpio_direction_output(MX51EVK_LCD_BACKLIGHT, 1);
-}
-
-void lcd_enable(void)
-{
-       int ret = ipuv3_fb_init(&claa_wvga, 1, IPU_PIX_FMT_RGB565);
-       if (ret)
-               printf("LCD cannot be configured: %d\n", ret);
-}
-
 int board_early_init_f(void)
 {
        setup_iomux_uart();
@@ -526,7 +479,7 @@ int board_early_init_f(void)
 #ifdef CONFIG_USB_EHCI_MX5
        setup_usb_h1();
 #endif
-       lcd_iomux();
+       setup_iomux_lcd();
 
        return 0;
 }
diff --git a/board/freescale/mx51evk/mx51evk_video.c b/board/freescale/mx51evk/mx51evk_video.c
new file mode 100644 (file)
index 0000000..f036cf7
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/list.h>
+#include <asm/gpio.h>
+#include <asm/arch/iomux.h>
+#include <linux/fb.h>
+#include <ipu_pixfmt.h>
+
+#define MX51EVK_LCD_3V3                IMX_GPIO_NR(4, 9)
+#define MX51EVK_LCD_5V         IMX_GPIO_NR(4, 10)
+#define MX51EVK_LCD_BACKLIGHT  IMX_GPIO_NR(3, 4)
+
+static struct fb_videomode const claa_wvga = {
+       .name           = "CLAA07LC0ACW",
+       .refresh        = 57,
+       .xres           = 800,
+       .yres           = 480,
+       .pixclock       = 37037,
+       .left_margin    = 40,
+       .right_margin   = 60,
+       .upper_margin   = 10,
+       .lower_margin   = 10,
+       .hsync_len      = 20,
+       .vsync_len      = 10,
+       .sync           = 0,
+       .vmode          = FB_VMODE_NONINTERLACED
+};
+
+void setup_iomux_lcd(void)
+{
+       /* DI2_PIN15 */
+       mxc_request_iomux(MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT4);
+
+       /* Pad settings for MX51_PIN_DI2_DISP_CLK */
+       mxc_iomux_set_pad(MX51_PIN_DI2_DISP_CLK, PAD_CTL_HYS_NONE |
+                         PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+                         PAD_CTL_DRV_MAX | PAD_CTL_SRE_SLOW);
+
+       /* Turn on 3.3V voltage for LCD */
+       mxc_request_iomux(MX51_PIN_CSI2_D12, IOMUX_CONFIG_ALT3);
+       gpio_direction_output(MX51EVK_LCD_3V3, 1);
+
+       /* Turn on 5V voltage for LCD */
+       mxc_request_iomux(MX51_PIN_CSI2_D13, IOMUX_CONFIG_ALT3);
+       gpio_direction_output(MX51EVK_LCD_5V, 1);
+
+       /* Turn on GPIO backlight */
+       mxc_request_iomux(MX51_PIN_DI1_D1_CS, IOMUX_CONFIG_ALT4);
+       mxc_iomux_set_input(MX51_GPIO3_IPP_IND_G_IN_4_SELECT_INPUT,
+                                                       INPUT_CTL_PATH1);
+       gpio_direction_output(MX51EVK_LCD_BACKLIGHT, 1);
+}
+
+void lcd_enable(void)
+{
+       int ret = ipuv3_fb_init(&claa_wvga, 1, IPU_PIX_FMT_RGB565);
+       if (ret)
+               printf("LCD cannot be configured: %d\n", ret);
+}
index bb4621d62ece80a139b2138a991360867540a8d5..12735014767b9d59908d9f5bc7fab99d0436867e 100644 (file)
@@ -34,7 +34,7 @@
 #include <i2c.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <asm/gpio.h>
 #include <mc13892.h>
@@ -123,9 +123,15 @@ void power_init(void)
 {
        unsigned int val;
        struct pmic *p;
+       int ret;
+
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return;
 
-       pmic_init();
-       p = get_pmic();
+       p = pmic_get("FSL_PMIC");
+       if (!p)
+               return;
 
        /* Set VDDA to 1.25V */
        pmic_reg_read(p, REG_SW_2, &val);
index 8bc69a92c1c0e8a6c05a5084f5dc2ae14a430b86..3be17c5917c37c12dea9afe2496ccf95681afae1 100644 (file)
@@ -22,8 +22,10 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
-COBJS  := mx53loco.o
+COBJS-y                        += mx53loco.o
+COBJS-$(CONFIG_VIDEO)  += mx53loco_video.o
 
+COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS))
 
index a11e8831866cfa143bb18ba0f6aeac3fec71b8a1..81c511cdc187fd22cd4887dd2e0a0e79a88d819d 100644 (file)
 #include <asm/arch/iomux.h>
 #include <asm/arch/clock.h>
 #include <asm/errno.h>
+#include <asm/imx-common/mx5_video.h>
 #include <netdev.h>
 #include <i2c.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
 #include <asm/gpio.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <dialog_pmic.h>
 #include <fsl_pmic.h>
 #include <linux/fb.h>
@@ -344,10 +345,16 @@ static int power_init(void)
        unsigned int val;
        int ret = -1;
        struct pmic *p;
+       int retval;
 
        if (!i2c_probe(CONFIG_SYS_DIALOG_PMIC_I2C_ADDR)) {
-               pmic_dialog_init();
-               p = get_pmic();
+               retval = pmic_dialog_init(I2C_PMIC);
+               if (retval)
+                       return retval;
+
+               p = pmic_get("DIALOG_PMIC");
+               if (!p)
+                       return -ENODEV;
 
                /* Set VDDA to 1.25V */
                val = DA9052_BUCKCORE_BCOREEN | DA_BUCKCORE_VBCORE_1_250V;
@@ -363,8 +370,13 @@ static int power_init(void)
        }
 
        if (!i2c_probe(CONFIG_SYS_FSL_PMIC_I2C_ADDR)) {
-               pmic_init();
-               p = get_pmic();
+               retval = pmic_init(I2C_PMIC);
+               if (retval)
+                       return retval;
+
+               p = pmic_get("DIALOG_PMIC");
+               if (!p)
+                       return -ENODEV;
 
                /* Set VDDGP to 1.25V for 1GHz on SW1 */
                pmic_reg_read(p, REG_SW_0, &val);
@@ -412,74 +424,11 @@ static void clock_1GHz(void)
                printf("CPU:   Switch DDR clock to 400MHz failed\n");
 }
 
-static struct fb_videomode const claa_wvga = {
-       .name           = "CLAA07LC0ACW",
-       .refresh        = 57,
-       .xres           = 800,
-       .yres           = 480,
-       .pixclock       = 37037,
-       .left_margin    = 40,
-       .right_margin   = 60,
-       .upper_margin   = 10,
-       .lower_margin   = 10,
-       .hsync_len      = 20,
-       .vsync_len      = 10,
-       .sync           = 0,
-       .vmode          = FB_VMODE_NONINTERLACED
-};
-
-void lcd_iomux(void)
-{
-       mxc_request_iomux(MX53_PIN_DI0_DISP_CLK, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DI0_PIN15, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DI0_PIN2, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DI0_PIN3, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT0, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT1, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT2, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT3, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT4, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT5, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT6, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT7, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT8, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT9, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT10, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT11, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT12, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT13, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT14, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT15, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT16, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT17, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT18, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT19, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT20, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT21, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT22, IOMUX_CONFIG_ALT0);
-       mxc_request_iomux(MX53_PIN_DISP0_DAT23, IOMUX_CONFIG_ALT0);
-
-       /* Turn on GPIO backlight */
-       mxc_request_iomux(MX53_PIN_EIM_D24, IOMUX_CONFIG_ALT1);
-       gpio_direction_output(MX53LOCO_LCD_POWER, 1);
-
-       /* Turn on display contrast */
-       mxc_request_iomux(MX53_PIN_GPIO_1, IOMUX_CONFIG_ALT1);
-       gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_1), 1);
-}
-
-void lcd_enable(void)
-{
-       int ret = ipuv3_fb_init(&claa_wvga, 0, IPU_PIX_FMT_RGB565);
-       if (ret)
-               printf("LCD cannot be configured: %d\n", ret);
-}
-
 int board_early_init_f(void)
 {
        setup_iomux_uart();
        setup_iomux_fec();
-       lcd_iomux();
+       setup_iomux_lcd();
 
        return 0;
 }
diff --git a/board/freescale/mx53loco/mx53loco_video.c b/board/freescale/mx53loco/mx53loco_video.c
new file mode 100644 (file)
index 0000000..69991e8
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/list.h>
+#include <asm/gpio.h>
+#include <asm/arch/iomux.h>
+#include <linux/fb.h>
+#include <ipu_pixfmt.h>
+
+#define MX53LOCO_LCD_POWER             IMX_GPIO_NR(3, 24)
+
+static struct fb_videomode const claa_wvga = {
+       .name           = "CLAA07LC0ACW",
+       .refresh        = 57,
+       .xres           = 800,
+       .yres           = 480,
+       .pixclock       = 37037,
+       .left_margin    = 40,
+       .right_margin   = 60,
+       .upper_margin   = 10,
+       .lower_margin   = 10,
+       .hsync_len      = 20,
+       .vsync_len      = 10,
+       .sync           = 0,
+       .vmode          = FB_VMODE_NONINTERLACED
+};
+
+void setup_iomux_lcd(void)
+{
+       mxc_request_iomux(MX53_PIN_DI0_DISP_CLK, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DI0_PIN15, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DI0_PIN2, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DI0_PIN3, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT0, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT1, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT2, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT3, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT4, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT5, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT6, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT7, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT8, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT9, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT10, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT11, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT12, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT13, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT14, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT15, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT16, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT17, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT18, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT19, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT20, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT21, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT22, IOMUX_CONFIG_ALT0);
+       mxc_request_iomux(MX53_PIN_DISP0_DAT23, IOMUX_CONFIG_ALT0);
+
+       /* Turn on GPIO backlight */
+       mxc_request_iomux(MX53_PIN_EIM_D24, IOMUX_CONFIG_ALT1);
+       gpio_direction_output(MX53LOCO_LCD_POWER, 1);
+
+       /* Turn on display contrast */
+       mxc_request_iomux(MX53_PIN_GPIO_1, IOMUX_CONFIG_ALT1);
+       gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_1), 1);
+}
+
+void lcd_enable(void)
+{
+       int ret = ipuv3_fb_init(&claa_wvga, 0, IPU_PIX_FMT_RGB565);
+       if (ret)
+               printf("LCD cannot be configured: %d\n", ret);
+}
index eb11f3fe12af036d3a4c71c14a30d56eb4ed9f4f..9110767a141341e1336f8f3ecb6e3c0ceccf8a4b 100644 (file)
@@ -74,7 +74,7 @@ int checkboard(void)
 phys_size_t fixed_sdram(void)
 {
 #ifndef CONFIG_SYS_RAMBOOT
-       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
 
        set_next_law(0, LAW_SIZE_2G, LAW_TRGT_IF_DDR_1);
 
index 0dcf7d1ab17e7262fc1db420261acfb37743cef0..5b45d72f511252e838be98bbfe16b2fdc28f9b05 100644 (file)
@@ -24,11 +24,27 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+
+COBJS-y        += spl_minimal.o tlb.o law.o
+
+else
+
 COBJS-y        += $(BOARD).o
 COBJS-y        += ddr.o
 COBJS-y        += law.o
 COBJS-y        += tlb.o
 
+endif
+
 SRCS   := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS-y))
 SOBJS  := $(addprefix $(obj),$(SOBJS))
index 88ba56f457e92522b189423d1a462632acdcc304..9355536b35d072a3a84f045db39fa5cf25045b7a 100644 (file)
@@ -206,6 +206,7 @@ int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
 }
 #endif /* CONFIG_SYS_DDR_RAW_TIMING */
 
+#ifdef CONFIG_SYS_DDR_CS0_BNDS
 /* Fixed sdram init -- doesn't use serial presence detect. */
 phys_size_t fixed_sdram(void)
 {
@@ -260,6 +261,7 @@ phys_size_t fixed_sdram(void)
 
        return ddr_size;
 }
+#endif
 
 void fsl_ddr_board_options(memctl_options_t *popts,
                                dimm_params_t *pdimm,
index 0da8300c6f56fa52acd066070e79f693544ea0ed..cb5e7b7c0c0212054a04edb1388dd52d10136c2d 100644 (file)
@@ -32,7 +32,7 @@ struct law_entry law_table[] = {
 #endif
        SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_64M, LAW_TRGT_IF_LBC),
 #ifdef CONFIG_SYS_NAND_BASE_PHYS
-       SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC),
+       SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_32K, LAW_TRGT_IF_LBC),
 #endif
 };
 
index aa39260ca7ed084589a444f52e9ac546dbdb0058..5b5b86c822e968db065913406700462d5f66af16 100644 (file)
@@ -177,7 +177,7 @@ void board_gpio_init(void)
         */
 
        setbits_be32(&pgpio->gpdir, 0x02130000);
-#ifndef CONFIG_SYS_RAMBOOT
+#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SPL)
        /* init DDR3 reset signal */
        setbits_be32(&pgpio->gpdir, 0x00200000);
        setbits_be32(&pgpio->gpodr, 0x00200000);
similarity index 93%
rename from nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c
rename to board/freescale/p1_p2_rdb_pc/spl_minimal.c
index 4c140c1572f0de4330e7c931a9c084d863f7a62d..09019e98af2118181507973e3d0c852448cf5b3a 100644 (file)
 #include <ns16550.h>
 #include <asm/io.h>
 #include <nand.h>
+#include <linux/compiler.h>
 #include <asm/fsl_law.h>
 #include <asm/fsl_ddr_sdram.h>
 #include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_SYS_INIT_L2_ADDR
 /*
  * Fixed sdram init -- doesn't use serial presence detect.
  */
-void sdram_init(void)
+static void sdram_init(void)
 {
-       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
 
        __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds);
        __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config);
@@ -71,6 +73,7 @@ void sdram_init(void)
 
        set_next_law(0, CONFIG_SYS_SDRAM_SIZE_LAW, LAW_TRGT_IF_DDR_1);
 }
+#endif
 
 void board_init_f(ulong bootflag)
 {
@@ -101,15 +104,16 @@ void board_init_f(ulong bootflag)
        __raw_writel(0x00000000, &pgpio->gpdir);
 #endif
 
+#ifndef CONFIG_SYS_INIT_L2_ADDR
        /* Initialize the DDR3 */
        sdram_init();
+#endif
 
        /* copy code to RAM and jump to it - this should not return */
        /* NOTE - code has to be copied out of NAND buffer before
         * other blocks can be read.
         */
-       relocate_code(CONFIG_SYS_NAND_U_BOOT_RELOC_SP, 0,
-                       CONFIG_SYS_NAND_U_BOOT_RELOC);
+       relocate_code(CONFIG_SPL_RELOC_STACK, 0, CONFIG_SPL_RELOC_TEXT_BASE);
 }
 
 void board_init_r(gd_t *gd, ulong dest_addr)
index 6d2246387a6967b17644e2c39417723802a909e0..3e4dffd237df76f908add7249696af5fdc06a941 100644 (file)
@@ -53,7 +53,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 1, BOOKE_PAGESZ_1M, 1),
 
-#ifndef CONFIG_NAND_SPL
+#ifndef CONFIG_SPL_BUILD
        /* W**G* - Flash/promjet, localbus */
        /* This will be changed to *I*G* after relocation to RAM. */
        SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
@@ -85,7 +85,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
        SET_TLB_ENTRY(1, CONFIG_SYS_PMC_BASE, CONFIG_SYS_PMC_BASE_PHYS,
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 10, BOOKE_PAGESZ_64K, 1),
-#endif
+#endif /* not SPL */
 
 #ifdef CONFIG_SYS_NAND_BASE
        /* *I*G - NAND */
@@ -94,7 +94,17 @@ struct fsl_e_tlb_entry tlb_table[] = {
                        0, 7, BOOKE_PAGESZ_1M, 1),
 #endif
 
-#ifdef CONFIG_SYS_RAMBOOT
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
+#ifdef CONFIG_SYS_INIT_L2_ADDR
+       /* L2SRAM */
+       SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L2_ADDR, CONFIG_SYS_INIT_L2_ADDR_PHYS,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 8, BOOKE_PAGESZ_256K, 1),
+       SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L2_ADDR + 0x40000,
+                     CONFIG_SYS_INIT_L2_ADDR_PHYS + 0x40000,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 12, BOOKE_PAGESZ_256K, 1),
+#else
        /* *I*G - eSDHC/eSPI/NAND boot */
        SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE,
                        MAS3_SX|MAS3_SW|MAS3_SR, 0,
@@ -106,9 +116,9 @@ struct fsl_e_tlb_entry tlb_table[] = {
                        CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000,
                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                        0, 9, BOOKE_PAGESZ_1G, 1),
-#endif
-#endif
-
+#endif /* P1020MBG */
+#endif /* not L2 SRAM */
+#endif /* RAMBOOT/SPL */
 };
 
 int num_tlb_entries = ARRAY_SIZE(tlb_table);
index 3188f59e4b670752356a37ecd60e24ebbdfd5c3a..d4a445108ad8eb55a9f1b9668676f0645dcb4065 100644 (file)
@@ -84,7 +84,7 @@ int checkboard(void)
 
 phys_size_t fixed_sdram(void)
 {
-       volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+       volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
        uint d_init;
 
        ddr->cs0_config = CONFIG_SYS_DDR_CS0_CONFIG;
index c2b2823ef9dab8fe146af8c5ada34b9fe08fa86a..69d41db530d0ce5b9a5244adfd64dacc798dc6c2 100644 (file)
@@ -33,7 +33,7 @@
 #include <i2c.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mc13892.h>
 
@@ -173,9 +173,15 @@ static void power_init(void)
        unsigned int val;
        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
        struct pmic *p;
+       int ret;
+
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return;
 
-       pmic_init();
-       p = get_pmic();
+       p = pmic_get("FSL_PMIC");
+       if (!p)
+               return;
 
        /* Write needed to Power Gate 2 register */
        pmic_reg_read(p, REG_POWER_MISC, &val);
index 143fcefedf55e710c055d92d859eebc2ec225724..0c2cb795dd66448bb44e64fce3703609acaef16d 100644 (file)
 #include <common.h>
 #include <netdev.h>
 #include <command.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mc13783.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
+#include <errno.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -195,14 +196,21 @@ int board_mmc_init(bd_t *bis)
 {
        u32 val;
        struct pmic *p;
+       int ret;
 
        /*
        * this is the first driver to use the pmic, so call
        * pmic_init() here. board_late_init() is too late for
        * the MMC driver.
        */
-       pmic_init();
-       p = get_pmic();
+
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return ret;
+
+       p = pmic_get("FSL_PMIC");
+       if (!p)
+               return -ENODEV;
 
        /* configure pins for SDHC1 only */
        mx31_gpio_mux(IOMUX_MODE(MUX_CTL_SD1_CLK, MUX_CTL_FUNC));
index 6ee2128aab8e6738539266dea07ef016ee6218f7..8cfb4e6620dade4577bca5c1e02d3944d3d3fc65 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009-2012
  * Wojciech Dubowik <wojciech.dubowik@neratec.com>
- * Luka Perkov <uboot@lukaperkov.net>
+ * Luka Perkov <luka@openwrt.org>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
index 2fb3e5ed8f23eb94626f7b20cd3b40c0a9efbe9a..8b6fe1bcadb56bf6f296c61b899111472e4c55ff 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2009-2012
  * Wojciech Dubowik <wojciech.dubowik@neratec.com>
- * Luka Perkov <uboot@lukaperkov.net>
+ * Luka Perkov <luka@openwrt.org>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
index 6c9dfe3d31d3e6b2fc3ab2d687c5c6cf0b9778eb..4b64dab5925121fb97f7e68bb731d91fd95c99a0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # (C) Copyright 2009-2012
 # Wojciech Dubowik <wojciech.dubowik@neratec.com>
-# Luka Perkov <uboot@lukaperkov.net>
+# Luka Perkov <luka@openwrt.org>
 #
 # See file CREDITS for list of people who contributed to this
 # project.
index d316f33cd11dfdf4b49b9c1c01fd3f25bd226d47..0b3721ed854004f9110d2a4a490f71dc7f060cc0 100644 (file)
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/omap_musb.h>
+#include <asm/arch/am35x_def.h>
 #include <asm/arch/mem.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/mmc_host_def.h>
+#include <asm/arch/musb.h>
 #include <asm/mach-types.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
 #include <i2c.h>
+#include <netdev.h>
 #include "am3517evm.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -50,6 +58,52 @@ int board_init(void)
        return 0;
 }
 
+#ifdef CONFIG_USB_MUSB_AM35X
+static struct musb_hdrc_config musb_config = {
+       .multipoint     = 1,
+       .dyn_fifo       = 1,
+       .num_eps        = 16,
+       .ram_bits       = 12,
+};
+
+static struct omap_musb_board_data musb_board_data = {
+       .set_phy_power          = am35x_musb_phy_power,
+       .clear_irq              = am35x_musb_clear_irq,
+       .reset                  = am35x_musb_reset,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#if defined(CONFIG_MUSB_HOST)
+       .mode           = MUSB_HOST,
+#elif defined(CONFIG_MUSB_GADGET)
+       .mode           = MUSB_PERIPHERAL,
+#else
+#error "Please define either CONFIG_MUSB_HOST or CONFIG_MUSB_GADGET"
+#endif
+       .config         = &musb_config,
+       .power          = 250,
+       .platform_ops   = &am35x_ops,
+       .board_data     = &musb_board_data,
+};
+
+static void am3517_evm_musb_init(void)
+{
+       /*
+        * Set up USB clock/mode in the DEVCONF2 register.
+        * USB2.0 PHY reference clock is 13 MHz
+        */
+       clrsetbits_le32(&am35x_scm_general_regs->devconf2,
+                       CONF2_REFFREQ | CONF2_OTGMODE | CONF2_PHY_GPIOMODE,
+                       CONF2_REFFREQ_13MHZ | CONF2_SESENDEN |
+                       CONF2_VBDTCTEN | CONF2_DATPOL);
+
+       musb_register(&musb_plat, &musb_board_data,
+                       (void *)AM35XX_IPSS_USBOTGSS_BASE);
+}
+#else
+#define am3517_evm_musb_init() do {} while (0)
+#endif
+
 /*
  * Routine: misc_init_r
  * Description: Init i2c, ethernet, etc... (done here so udelay works)
@@ -62,6 +116,8 @@ int misc_init_r(void)
 
        dieid_num_r();
 
+       am3517_evm_musb_init();
+
        return 0;
 }
 
@@ -83,3 +139,21 @@ int board_mmc_init(bd_t *bis)
        return 0;
 }
 #endif
+
+#if defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)
+int board_eth_init(bd_t *bis)
+{
+       int rv, n = 0;
+
+       rv = cpu_eth_init(bis);
+       if (rv > 0)
+               n += rv;
+
+       rv = usb_eth_initialize(bis);
+       if (rv > 0)
+               n += rv;
+
+       return n;
+}
+#endif
+
index b7e6e4107c5be88049fe7133cf3d705cdfc112bf..5f0f3961d319ad2ab037403e26b243f2debe43c3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2011-2012
  * Gerald Kerma <dreagle@doukki.net>
- * Luka Perkov <uboot@lukaperkov.net>
+ * Luka Perkov <luka@openwrt.org>
  * Simon Baatz <gmbnomis@gmail.com>
  *
  * See file CREDITS for list of people who contributed to this
index 0118c2b69acc18d7c25fc31195c39d5e9e6009d0..3315696dda91c5f48eb32eee17e0cbb5762fc381 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2011-2012
  * Gerald Kerma <dreagle@doukki.net>
  * Simon Baatz <gmbnomis@gmail.com>
- * Luka Perkov <uboot@lukaperkov.net>
+ * Luka Perkov <luka@openwrt.org>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
index bd594ebd5d7752fa63d86e1e2bdea6511c8ee005..bade627ccf57d7581e828c809e8c2798d2ee8061 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright (C) 2011-2012
 # Gerald Kerma <dreagle@doukki.net>
 # Simon Baatz <gmbnomis@gmail.com>
-# Luka Perkov <uboot@lukaperkov.net>
+# Luka Perkov <luka@openwrt.org>
 #
 # See file CREDITS for list of people who contributed to this
 # project.
index e8fb1ea4130a740480cd685c0cb09d9c9d732d51..ff76963925fab27b6c545cdb096b51e110775744 100644 (file)
 #include <common.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <usb/s3c_udc.h>
 #include <asm/arch/cpu.h>
-#include <max8998_pmic.h>
+#include <power/max8998_pmic.h>
 DECLARE_GLOBAL_DATA_PTR;
 
 static struct s5pc110_gpio *s5pc110_gpio;
@@ -41,9 +41,17 @@ int board_init(void)
        gd->bd->bi_arch_number = MACH_TYPE_GONI;
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
-#if defined(CONFIG_PMIC)
-       pmic_init();
-#endif
+       return 0;
+}
+
+int power_init_board(void)
+{
+       int ret;
+
+       ret = pmic_init(I2C_5);
+       if (ret)
+               return ret;
+
        return 0;
 }
 
@@ -108,7 +116,9 @@ static int s5pc1xx_phy_control(int on)
 {
        int ret;
        static int status;
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("MAX8998_PMIC");
+       if (!p)
+               return -ENODEV;
 
        if (pmic_probe(p))
                return -1;
index e11a8922fca98983c9b4c4841f66a6a3786bf199..e540190984740da822678724a71ffed0764b1cb2 100644 (file)
 #include <asm/arch/mipi_dsim.h>
 #include <asm/arch/watchdog.h>
 #include <asm/arch/power.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <usb/s3c_udc.h>
-#include <max8997_pmic.h>
+#include <power/max8997_pmic.h>
 #include <libtizen.h>
+#include <power/max8997_muic.h>
+#include <power/battery.h>
+#include <power/max17042_fg.h>
 
 #include "setup.h"
 
@@ -68,10 +71,6 @@ int board_init(void)
        check_hw_revision();
        printf("HW Revision:\t0x%x\n", board_rev);
 
-#if defined(CONFIG_PMIC)
-       pmic_init();
-#endif
-
        return 0;
 }
 
@@ -90,6 +89,275 @@ void i2c_init_board(void)
        s5p_gpio_direction_output(&gpio2->y4, 1, 1);
 }
 
+static void trats_low_power_mode(void)
+{
+       struct exynos4_clock *clk =
+           (struct exynos4_clock *)samsung_get_base_clock();
+       struct exynos4_power *pwr =
+           (struct exynos4_power *)samsung_get_base_power();
+
+       /* Power down CORE1 */
+       /* LOCAL_PWR_CFG [1:0] 0x3 EN, 0x0 DIS */
+       writel(0x0, &pwr->arm_core1_configuration);
+
+       /* Change the APLL frequency */
+       /* ENABLE (1 enable) | LOCKED (1 locked)  */
+       /* [31]              | [29]               */
+       /* FSEL      | MDIV          | PDIV            | SDIV */
+       /* [27]      | [25:16]       | [13:8]          | [2:0]      */
+       writel(0xa0c80604, &clk->apll_con0);
+
+       /* Change CPU0 clock divider */
+       /* CORE2_RATIO  | APLL_RATIO   | PCLK_DBG_RATIO | ATB_RATIO  */
+       /* [30:28]      | [26:24]      | [22:20]        | [18:16]    */
+       /* PERIPH_RATIO | COREM1_RATIO | COREM0_RATIO   | CORE_RATIO */
+       /* [14:12]      | [10:8]       | [6:4]          | [2:0]      */
+       writel(0x00000100, &clk->div_cpu0);
+
+       /* CLK_DIV_STAT_CPU0 - wait until clock gets stable (0 = stable) */
+       while (readl(&clk->div_stat_cpu0) & 0x1111111)
+               continue;
+
+       /* Change clock divider ratio for DMC */
+       /* DMCP_RATIO                  | DMCD_RATIO  */
+       /* [22:20]                     | [18:16]     */
+       /* DMC_RATIO | DPHY_RATIO | ACP_PCLK_RATIO   | ACP_RATIO */
+       /* [14:12]   | [10:8]     | [6:4]            | [2:0]     */
+       writel(0x13113117, &clk->div_dmc0);
+
+       /* CLK_DIV_STAT_DMC0 - wait until clock gets stable (0 = stable) */
+       while (readl(&clk->div_stat_dmc0) & 0x11111111)
+               continue;
+
+       /* Turn off unnecessary power domains */
+       writel(0x0, &pwr->xxti_configuration);  /* XXTI */
+       writel(0x0, &pwr->cam_configuration);   /* CAM */
+       writel(0x0, &pwr->tv_configuration);    /* TV */
+       writel(0x0, &pwr->mfc_configuration);   /* MFC */
+       writel(0x0, &pwr->g3d_configuration);   /* G3D */
+       writel(0x0, &pwr->gps_configuration);   /* GPS */
+       writel(0x0, &pwr->gps_alive_configuration);     /* GPS_ALIVE */
+
+       /* Turn off unnecessary clocks */
+       writel(0x0, &clk->gate_ip_cam); /* CAM */
+       writel(0x0, &clk->gate_ip_tv);          /* TV */
+       writel(0x0, &clk->gate_ip_mfc); /* MFC */
+       writel(0x0, &clk->gate_ip_g3d); /* G3D */
+       writel(0x0, &clk->gate_ip_image);       /* IMAGE */
+       writel(0x0, &clk->gate_ip_gps); /* GPS */
+}
+
+static int pmic_init_max8997(void)
+{
+       struct pmic *p = pmic_get("MAX8997_PMIC");
+       int i = 0, ret = 0;
+       u32 val;
+
+       if (pmic_probe(p))
+               return -1;
+
+       /* BUCK1 VARM: 1.2V */
+       val = (1200000 - 650000) / 25000;
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK1DVS1, val);
+       val = ENBUCK | ACTIVE_DISCHARGE;                /* DVS OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK1CTRL, val);
+
+       /* BUCK2 VINT: 1.1V */
+       val = (1100000 - 650000) / 25000;
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK2DVS1, val);
+       val = ENBUCK | ACTIVE_DISCHARGE;                /* DVS OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK2CTRL, val);
+
+
+       /* BUCK3 G3D: 1.1V - OFF */
+       ret |= pmic_reg_read(p, MAX8997_REG_BUCK3CTRL, &val);
+       val &= ~ENBUCK;
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK3CTRL, val);
+
+       val = (1100000 - 750000) / 50000;
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK3DVS, val);
+
+       /* BUCK4 CAMISP: 1.2V - OFF */
+       ret |= pmic_reg_read(p, MAX8997_REG_BUCK4CTRL, &val);
+       val &= ~ENBUCK;
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK4CTRL, val);
+
+       val = (1200000 - 650000) / 25000;
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK4DVS, val);
+
+       /* BUCK5 VMEM: 1.2V */
+       val = (1200000 - 650000) / 25000;
+       for (i = 0; i < 8; i++)
+               ret |= pmic_reg_write(p, MAX8997_REG_BUCK5DVS1 + i, val);
+
+       val = ENBUCK | ACTIVE_DISCHARGE;                /* DVS OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK5CTRL, val);
+
+       /* BUCK6 CAM AF: 2.8V */
+       /* No Voltage Setting Register */
+       /* GNSLCT 3.0X */
+       val = GNSLCT;
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK6CTRL, val);
+
+       /* BUCK7 VCC_SUB: 2.0V */
+       val = (2000000 - 750000) / 50000;
+       ret |= pmic_reg_write(p, MAX8997_REG_BUCK7DVS, val);
+
+       /* LDO1 VADC: 3.3V */
+       val = max8997_reg_ldo(3300000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO1CTRL, val);
+
+       /* LDO1 Disable active discharging */
+       ret |= pmic_reg_read(p, MAX8997_REG_LDO1CONFIG, &val);
+       val &= ~LDO_ADE;
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO1CONFIG, val);
+
+       /* LDO2 VALIVE: 1.1V */
+       val = max8997_reg_ldo(1100000) | EN_LDO;
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO2CTRL, val);
+
+       /* LDO3 VUSB/MIPI: 1.1V */
+       val = max8997_reg_ldo(1100000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO3CTRL, val);
+
+       /* LDO4 VMIPI: 1.8V */
+       val = max8997_reg_ldo(1800000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO4CTRL, val);
+
+       /* LDO5 VHSIC: 1.2V */
+       val = max8997_reg_ldo(1200000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO5CTRL, val);
+
+       /* LDO6 VCC_1.8V_PDA: 1.8V */
+       val = max8997_reg_ldo(1800000) | EN_LDO;
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO6CTRL, val);
+
+       /* LDO7 CAM_ISP: 1.8V */
+       val = max8997_reg_ldo(1800000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO7CTRL, val);
+
+       /* LDO8 VDAC/VUSB: 3.3V */
+       val = max8997_reg_ldo(3300000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO8CTRL, val);
+
+       /* LDO9 VCC_2.8V_PDA: 2.8V */
+       val = max8997_reg_ldo(2800000) | EN_LDO;
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO9CTRL, val);
+
+       /* LDO10 VPLL: 1.1V */
+       val = max8997_reg_ldo(1100000) | EN_LDO;
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO10CTRL, val);
+
+       /* LDO11 TOUCH: 2.8V */
+       val = max8997_reg_ldo(2800000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO11CTRL, val);
+
+       /* LDO12 VTCAM: 1.8V */
+       val = max8997_reg_ldo(1800000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO12CTRL, val);
+
+       /* LDO13 VCC_3.0_LCD: 3.0V */
+       val = max8997_reg_ldo(3000000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO13CTRL, val);
+
+       /* LDO14 MOTOR: 3.0V */
+       val = max8997_reg_ldo(3000000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO14CTRL, val);
+
+       /* LDO15 LED_A: 2.8V */
+       val = max8997_reg_ldo(2800000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO15CTRL, val);
+
+       /* LDO16 CAM_SENSOR: 1.8V */
+       val = max8997_reg_ldo(1800000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO16CTRL, val);
+
+       /* LDO17 VTF: 2.8V */
+       val = max8997_reg_ldo(2800000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO17CTRL, val);
+
+       /* LDO18 TOUCH_LED 3.3V */
+       val = max8997_reg_ldo(3300000) | DIS_LDO;       /* OFF */
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO18CTRL, val);
+
+       /* LDO21 VDDQ: 1.2V */
+       val = max8997_reg_ldo(1200000) | EN_LDO;
+       ret |= pmic_reg_write(p, MAX8997_REG_LDO21CTRL, val);
+
+       /* SAFEOUT for both 1 and 2: 4.9V, Active discharge, Enable */
+       val = (SAFEOUT_4_90V << 0) | (SAFEOUT_4_90V << 2) |
+               ACTDISSAFEO1 | ACTDISSAFEO2 | ENSAFEOUT1 | ENSAFEOUT2;
+       ret |= pmic_reg_write(p, MAX8997_REG_SAFEOUTCTRL, val);
+
+       if (ret) {
+               puts("MAX8997 PMIC setting error!\n");
+               return -1;
+       }
+       return 0;
+}
+
+int power_init_board(void)
+{
+       int chrg, ret;
+       struct power_battery *pb;
+       struct pmic *p_fg, *p_chrg, *p_muic, *p_bat;
+
+       ret = pmic_init(I2C_5);
+       ret |= pmic_init_max8997();
+       ret |= power_fg_init(I2C_9);
+       ret |= power_muic_init(I2C_5);
+       ret |= power_bat_init(0);
+       if (ret)
+               return ret;
+
+       p_fg = pmic_get("MAX17042_FG");
+       if (!p_fg) {
+               puts("MAX17042_FG: Not found\n");
+               return -ENODEV;
+       }
+
+       p_chrg = pmic_get("MAX8997_PMIC");
+       if (!p_chrg) {
+               puts("MAX8997_PMIC: Not found\n");
+               return -ENODEV;
+       }
+
+       p_muic = pmic_get("MAX8997_MUIC");
+       if (!p_muic) {
+               puts("MAX8997_MUIC: Not found\n");
+               return -ENODEV;
+       }
+
+       p_bat = pmic_get("BAT_TRATS");
+       if (!p_bat) {
+               puts("BAT_TRATS: Not found\n");
+               return -ENODEV;
+       }
+
+       p_fg->parent =  p_bat;
+       p_chrg->parent = p_bat;
+       p_muic->parent = p_bat;
+
+       p_bat->low_power_mode = trats_low_power_mode;
+       p_bat->pbat->battery_init(p_bat, p_fg, p_chrg, p_muic);
+
+       pb = p_bat->pbat;
+       chrg = p_muic->chrg->chrg_type(p_muic);
+       debug("CHARGER TYPE: %d\n", chrg);
+
+       if (!p_chrg->chrg->chrg_bat_present(p_chrg)) {
+               puts("No battery detected\n");
+               return -1;
+       }
+
+       p_fg->fg->fg_battery_check(p_fg, p_bat);
+
+       if (pb->bat->state == CHARGE && chrg == CHARGER_USB)
+               puts("CHARGE Battery !\n");
+
+       return 0;
+}
+
 int dram_init(void)
 {
        gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) +
@@ -238,7 +506,9 @@ static int s5pc210_phy_control(int on)
 {
        int ret = 0;
        u32 val = 0;
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("MAX8997_PMIC");
+       if (!p)
+               return -ENODEV;
 
        if (pmic_probe(p))
                return -1;
@@ -413,7 +683,9 @@ static void lcd_reset(void)
 static int lcd_power(void)
 {
        int ret = 0;
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("MAX8997_PMIC");
+       if (!p)
+               return -ENODEV;
 
        if (pmic_probe(p))
                return 0;
@@ -473,7 +745,9 @@ static struct mipi_dsim_lcd_device mipi_lcd_device = {
 static int mipi_power(void)
 {
        int ret = 0;
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("MAX8997_PMIC");
+       if (!p)
+               return -ENODEV;
 
        if (pmic_probe(p))
                return 0;
index 90fff5cf5e181af64cfd56b53937d64daac916bd..36a047217c57cbdac1b07196fbb137bf0eb7f2d1 100644 (file)
 #include <asm/arch/adc.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <usb/s3c_udc.h>
 #include <asm/arch/cpu.h>
-#include <max8998_pmic.h>
+#include <power/max8998_pmic.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -58,16 +58,23 @@ int board_init(void)
        gd->bd->bi_arch_number = MACH_TYPE_UNIVERSAL_C210;
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
-#if defined(CONFIG_PMIC)
-       pmic_init();
-#endif
-
        check_hw_revision();
        printf("HW Revision:\t0x%x\n", board_rev);
 
        return 0;
 }
 
+int power_init_board(void)
+{
+       int ret;
+
+       ret = pmic_init(I2C_5);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 int dram_init(void)
 {
        gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) +
@@ -112,7 +119,9 @@ static unsigned short get_adc_value(int channel)
 static int adc_power_control(int on)
 {
        int ret;
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("MAX8998_PMIC");
+       if (!p)
+               return -ENODEV;
 
        if (pmic_probe(p))
                return -1;
@@ -280,7 +289,9 @@ int board_mmc_init(bd_t *bis)
 static int s5pc210_phy_control(int on)
 {
        int ret = 0;
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("MAX8998_PMIC");
+       if (!p)
+               return -ENODEV;
 
        if (pmic_probe(p))
                return -1;
index 45ec485c50b88a48a2bebdea1b80ff47508e8248..95085611336af8d32c5940306bcd6d40958fe9d6 100644 (file)
@@ -91,7 +91,7 @@ void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
  */
 phys_size_t fixed_sdram(void)
 {
-       volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
+       volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC8xxx_DDR_ADDR);
 
        out_be32(&ddr->cs0_bnds,        0x0000007f);
        out_be32(&ddr->cs1_bnds,        0x008000ff);
index c8235f4a9b4a29dd384dc8c8cf677ab879d27793..8a9ce790f147e36adb634d60eebae9c31b0140ad 100644 (file)
@@ -41,7 +41,7 @@
  */
 phys_size_t fixed_sdram(void)
 {
-       volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
+       volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC8xxx_DDR_ADDR);
 
        /*
         * Disable memory controller.
index b56a801a4d040965e0aa682dc314dcd2a87e2a08..f0eca54c9e9626bcdd187e60d6b8b03501831f34 100644 (file)
@@ -379,9 +379,14 @@ static struct cpsw_platform_data cpsw_data = {
        .host_port_num          = 0,
        .version                = CPSW_CTRL_VERSION_2,
 };
+#endif
 
+#if defined(CONFIG_DRIVER_TI_CPSW) || \
+       (defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
 int board_eth_init(bd_t *bis)
 {
+       int rv, n = 0;
+#ifdef CONFIG_DRIVER_TI_CPSW
        uint8_t mac_addr[6];
        uint32_t mac_hi, mac_lo;
 
@@ -400,7 +405,7 @@ int board_eth_init(bd_t *bis)
                if (is_valid_ether_addr(mac_addr))
                        eth_setenv_enetaddr("ethaddr", mac_addr);
                else
-                       return -1;
+                       goto try_usbether;
        }
 
        if (board_is_bone() || board_is_bone_lt() || board_is_idk()) {
@@ -413,6 +418,20 @@ int board_eth_init(bd_t *bis)
                                PHY_INTERFACE_MODE_RGMII;
        }
 
-       return cpsw_register(&cpsw_data);
+       rv = cpsw_register(&cpsw_data);
+       if (rv < 0)
+               printf("Error %d registering CPSW switch\n", rv);
+       else
+               n += rv;
+#endif
+try_usbether:
+#if defined(CONFIG_USB_ETHER) && !defined(CONFIG_SPL_BUILD)
+       rv = usb_eth_initialize(bis);
+       if (rv < 0)
+               printf("Error %d registering USB_ETHER\n", rv);
+       else
+               n += rv;
+#endif
+       return n;
 }
 #endif
index 6175e1d1ac031ed1d5a41c3ff407d5027a00fc9e..f20ebed4524298c4d5bb777dd732f7ae509d1b1c 100644 (file)
 #include <asm/arch/sys_proto.h>
 #include <asm/gpio.h>
 #include <asm/mach-types.h>
+#include <asm/omap_musb.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
 #include "beagle.h"
 #include <command.h>
 
@@ -285,6 +290,33 @@ static void beagle_dvi_pup(void)
 }
 #endif
 
+#ifdef CONFIG_USB_MUSB_OMAP2PLUS
+static struct musb_hdrc_config musb_config = {
+       .multipoint     = 1,
+       .dyn_fifo       = 1,
+       .num_eps        = 16,
+       .ram_bits       = 12,
+};
+
+static struct omap_musb_board_data musb_board_data = {
+       .interface_type = MUSB_INTERFACE_ULPI,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#if defined(CONFIG_MUSB_HOST)
+       .mode           = MUSB_HOST,
+#elif defined(CONFIG_MUSB_GADGET)
+       .mode           = MUSB_PERIPHERAL,
+#else
+#error "Please define either CONFIG_MUSB_HOST or CONFIG_MUSB_GADGET"
+#endif
+       .config         = &musb_config,
+       .power          = 100,
+       .platform_ops   = &omap2430_ops,
+       .board_data     = &musb_board_data,
+};
+#endif
+
 /*
  * Routine: misc_init_r
  * Description: Configure board specific parts
@@ -466,6 +498,10 @@ int misc_init_r(void)
        omap3_dss_enable();
 #endif
 
+#ifdef CONFIG_USB_MUSB_OMAP2PLUS
+       musb_register(&musb_plat, &musb_board_data, (void *)MUSB_BASE);
+#endif
+
        return 0;
 }
 
@@ -513,3 +549,10 @@ int ehci_hcd_stop(int index)
 }
 
 #endif /* CONFIG_USB_EHCI */
+
+#if defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)
+int board_eth_init(bd_t *bis)
+{
+       return usb_eth_initialize(bis);
+}
+#endif
index abdd1aac2b5dd9bda98fb0a664506b4e6ed54d68..a471fec23dd791d2198495a4a3a5aff4afc3f57a 100644 (file)
@@ -34,7 +34,7 @@
 #include <asm/arch/sys_proto.h>
 #include <i2c.h>
 #include <mmc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_esdhc.h>
 #include <fsl_pmic.h>
 #include <mc13892.h>
@@ -306,9 +306,15 @@ static void power_init_mx51(void)
 {
        unsigned int val;
        struct pmic *p;
+       int ret;
+
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return;
 
-       pmic_init();
-       p = get_pmic();
+       p = pmic_get("FSL_PMIC");
+       if (!p)
+               return;
 
        /* Write needed to Power Gate 2 register */
        pmic_reg_read(p, REG_POWER_MISC, &val);
index 286749f3c910e2f409fd741220d7c0b5c885fcf0..66a0d35450a0be722082354ff7dac7fce2e8560d 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/arch/mx35_pins.h>
 #include <asm/arch/iomux.h>
 #include <i2c.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mc13892.h>
 #include <mmc.h>
@@ -178,12 +178,16 @@ int board_init(void)
 {
        struct pmic *p;
        u32 val;
+       int ret;
 
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
-       pmic_init();
-       p = get_pmic();
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return ret;
+
+       p = pmic_get("FSL_PMIC");
 
        /*
         * Set switchers in Auto in NORMAL mode & STANDBY mode
index 6f21af08215687ec8d24d567d1153bba5cc4abe9..388e4a4461d2bb6b8403ae7d8730e743197c4bf7 100644 (file)
@@ -100,6 +100,7 @@ at91sam9rlek_dataflash       arm         arm926ejs   at91sam9rlek        atmel
 at91sam9rlek_nandflash       arm         arm926ejs   at91sam9rlek        atmel          at91        at91sam9rlek:AT91SAM9RL,SYS_USE_NANDFLASH
 at91sam9x5ek_nandflash       arm         arm926ejs   at91sam9x5ek        atmel          at91        at91sam9x5ek:AT91SAM9X5,SYS_USE_NANDFLASH
 at91sam9x5ek_spiflash        arm         arm926ejs   at91sam9x5ek        atmel          at91        at91sam9x5ek:AT91SAM9X5,SYS_USE_SPIFLASH
+at91sam9x5ek_mmc             arm         arm926ejs   at91sam9x5ek        atmel          at91        at91sam9x5ek:AT91SAM9X5,SYS_USE_MMC
 at91sam9xeek_dataflash_cs0   arm         arm926ejs   at91sam9260ek       atmel          at91        at91sam9260ek:AT91SAM9XE,SYS_USE_DATAFLASH_CS0
 at91sam9xeek_dataflash_cs1   arm         arm926ejs   at91sam9260ek       atmel          at91        at91sam9260ek:AT91SAM9XE,SYS_USE_DATAFLASH_CS1
 at91sam9xeek_nandflash       arm         arm926ejs   at91sam9260ek       atmel          at91        at91sam9260ek:AT91SAM9XE,SYS_USE_NANDFLASH
@@ -374,7 +375,7 @@ M5235EVB                     m68k        mcf523x     m5235evb            freesca
 M5235EVB_Flash32             m68k        mcf523x     m5235evb            freescale      -           M5235EVB:NORFLASH_PS32BIT,SYS_TEXT_BASE=0xFFC00000
 cobra5272                    m68k        mcf52x2     cobra5272           -
 idmr                         m68k        mcf52x2
-eb_cpu5282                   m68k        mcf52x2     eb_cpu5282          BuS            -           eb_cpu5282:SYS_TEXT_BASE=0xFFE00000
+eb_cpu5282                   m68k        mcf52x2     eb_cpu5282          BuS            -           eb_cpu5282:SYS_TEXT_BASE=0xFF000000
 eb_cpu5282_internal          m68k        mcf52x2     eb_cpu5282          BuS            -           eb_cpu5282:SYS_TEXT_BASE=0xF0000000
 TASREG                       m68k        mcf52x2     tasreg              esd
 M5208EVBE                    m68k        mcf52x2     m5208evbe           freescale
@@ -474,6 +475,7 @@ mpc5121ads                   powerpc     mpc512x     mpc5121ads          freesca
 mpc5121ads_rev2              powerpc     mpc512x     mpc5121ads          freescale      -           mpc5121ads:MPC5121ADS_REV2
 cmi_mpc5xx                   powerpc     mpc5xx      cmi
 PATI                         powerpc     mpc5xx      pati                mpl
+a3m071                       powerpc     mpc5xxx     a3m071
 a4m072                       powerpc     mpc5xxx     a4m072
 BC3450                       powerpc     mpc5xxx     bc3450
 canmb                        powerpc     mpc5xxx
@@ -850,6 +852,7 @@ P5020DS_SDCARD                   powerpc     mpc85xx     corenet_ds          freescale
 P5020DS_SECURE_BOOT          powerpc     mpc85xx     corenet_ds          freescale      -           P5020DS:SECURE_BOOT
 P5020DS_SPIFLASH            powerpc     mpc85xx     corenet_ds          freescale      -           P5020DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000
 P5020DS_SRIO_PCIE_BOOT          powerpc     mpc85xx     corenet_ds          freescale      -           P5020DS:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000
+P5040DS                      powerpc     mpc85xx     corenet_ds          freescale
 BSC9131RDB_SPIFLASH          powerpc     mpc85xx     bsc9131rdb          freescale      -           BSC9131RDB:BSC9131RDB,SPIFLASH
 stxgp3                       powerpc     mpc85xx     stxgp3              stx
 stxssa                       powerpc     mpc85xx     stxssa              stx            -           stxssa
@@ -1099,7 +1102,7 @@ gr_cpci_ax2000               sparc       leon3       -                   gaisler
 gr_ep2s60                    sparc       leon3       -                   gaisler
 grsim                        sparc       leon3       -                   gaisler
 gr_xc3s_1500                 sparc       leon3       -                   gaisler
-coreboot-x86                 x86         x86        coreboot            chromebook-x86 coreboot    coreboot:SYS_TEXT_BASE=0xFC0000
+coreboot-x86                 x86         x86        coreboot            chromebook-x86 coreboot    coreboot:SYS_TEXT_BASE=0x01110000
 eNET                         x86         x86        eNET                -              sc520       eNET:SYS_TEXT_BASE=0x38040000
 eNET_SRAM                    x86         x86        eNET                -              sc520       eNET:SYS_TEXT_BASE=0x19000000
 # Target                     ARCH        CPU         Board name          Vendor                SoC         Options
index 9e433222115ae16fb9a12cfb1a60807bf9229c70..c29a7d82e3318673a605f6cac79bab1e4e8e0ba0 100644 (file)
@@ -195,6 +195,9 @@ COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
 endif
 
 ifdef CONFIG_SPL_BUILD
+COBJS-y += cmd_nvedit.o
+COBJS-y += env_common.o
+COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
 COBJS-$(CONFIG_SPL_NET_SUPPORT) += cmd_nvedit.o
 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_common.o
index 4f827f893d665d66963a7f32aeaea4f00222d9d2..1df12cdda07d04f80632190c09b841e85a774b45 100644 (file)
 #include <errno.h>
 #include <bouncebuf.h>
 
-static int addr_aligned(void *data, size_t len)
+static int addr_aligned(struct bounce_buffer *state)
 {
        const ulong align_mask = ARCH_DMA_MINALIGN - 1;
 
        /* Check if start is aligned */
-       if ((ulong)data & align_mask) {
-               debug("Unaligned start address %p\n", data);
+       if ((ulong)state->user_buffer & align_mask) {
+               debug("Unaligned buffer address %p\n", state->user_buffer);
                return 0;
        }
 
-       data += len;
-
-       /* Check if end is aligned */
-       if ((ulong)data & align_mask) {
-               debug("Unaligned end address %p\n", data);
+       /* Check if length is aligned */
+       if (state->len != state->len_aligned) {
+               debug("Unaligned buffer length %d\n", state->len);
                return 0;
        }
 
@@ -49,44 +47,53 @@ static int addr_aligned(void *data, size_t len)
        return 1;
 }
 
-int bounce_buffer_start(void **data, size_t len, void **backup, uint8_t flags)
+int bounce_buffer_start(struct bounce_buffer *state, void *data,
+                       size_t len, unsigned int flags)
 {
-       void *tmp;
-       size_t alen;
-
-       if (addr_aligned(*data, len)) {
-               *backup = NULL;
-               return 0;
+       state->user_buffer = data;
+       state->bounce_buffer = data;
+       state->len = len;
+       state->len_aligned = roundup(len, ARCH_DMA_MINALIGN);
+       state->flags = flags;
+
+       if (!addr_aligned(state)) {
+               state->bounce_buffer = memalign(ARCH_DMA_MINALIGN,
+                                               state->len_aligned);
+               if (!state->bounce_buffer)
+                       return -ENOMEM;
+
+               if (state->flags & GEN_BB_READ)
+                       memcpy(state->bounce_buffer, state->user_buffer,
+                               state->len);
        }
 
-       alen = roundup(len, ARCH_DMA_MINALIGN);
-       tmp = memalign(ARCH_DMA_MINALIGN, alen);
-
-       if (!tmp)
-               return -ENOMEM;
-
-       if (flags & GEN_BB_READ)
-               memcpy(tmp, *data, len);
-
-       *backup = *data;
-       *data = tmp;
+       /*
+        * Flush data to RAM so DMA reads can pick it up,
+        * and any CPU writebacks don't race with DMA writes
+        */
+       flush_dcache_range((unsigned long)state->bounce_buffer,
+                               (unsigned long)(state->bounce_buffer) +
+                                       state->len_aligned);
 
        return 0;
 }
 
-int bounce_buffer_stop(void **data, size_t len, void **backup, uint8_t flags)
+int bounce_buffer_stop(struct bounce_buffer *state)
 {
-       void *tmp = *data;
+       if (state->flags & GEN_BB_WRITE) {
+               /* Invalidate cache so that CPU can see any newly DMA'd data */
+               invalidate_dcache_range((unsigned long)state->bounce_buffer,
+                                       (unsigned long)(state->bounce_buffer) +
+                                               state->len_aligned);
+       }
 
-       /* The buffer was already aligned, since "backup" is NULL. */
-       if (!*backup)
+       if (state->bounce_buffer == state->user_buffer)
                return 0;
 
-       if (flags & GEN_BB_WRITE)
-               memcpy(*backup, *data, len);
+       if (state->flags & GEN_BB_WRITE)
+               memcpy(state->user_buffer, state->bounce_buffer, state->len);
 
-       *data = *backup;
-       free(tmp);
+       free(state->bounce_buffer);
 
        return 0;
 }
index b8809e3bf5409bd154f2ced0a193392794ac32df..5a52edde31dff8c4083baa449302ffab1b906cb4 100644 (file)
@@ -31,6 +31,7 @@
 #include <command.h>
 #include <asm/byteorder.h>
 #include <malloc.h>
+#include <video.h>
 
 static int bmp_info (ulong addr);
 
@@ -238,9 +239,7 @@ int bmp_display(ulong addr, int x, int y)
 #if defined(CONFIG_LCD)
        ret = lcd_display_bitmap((ulong)bmp, x, y);
 #elif defined(CONFIG_VIDEO)
-       extern int video_display_bitmap (ulong, int, int);
-
-       ret = video_display_bitmap ((unsigned long)bmp, x, y);
+       ret = video_display_bitmap((unsigned long)bmp, x, y);
 #else
 # error bmp_display() requires CONFIG_LCD or CONFIG_VIDEO
 #endif
index d256ddfaa6f017a944aef86ff42c5cc86de915aa..4dbe952bb0f56b92f40b0a67dd594f83d987e804 100644 (file)
@@ -949,8 +949,19 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
                         * node
                         */
                        bootstage_mark(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
+#ifdef CONFIG_FIT_BEST_MATCH
+                       if (fit_uname_config)
+                               cfg_noffset =
+                                       fit_conf_get_node(fit_hdr,
+                                                         fit_uname_config);
+                       else
+                               cfg_noffset =
+                                       fit_conf_find_compat(fit_hdr,
+                                                            gd->fdt_blob);
+#else
                        cfg_noffset = fit_conf_get_node(fit_hdr,
                                                        fit_uname_config);
+#endif
                        if (cfg_noffset < 0) {
                                bootstage_error(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
                                return NULL;
index d83b3ba69b7269dd0eb52bcfb455779d8aec2637..7f5ab43c7f5d92f4af1e799ae42e2ffcbe9f3786 100644 (file)
@@ -140,7 +140,7 @@ int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 U_BOOT_CMD(
        led, 3, 1, do_led,
-       "led\t- ["
+       "["
 #ifdef CONFIG_BOARD_SPECIFIC_LED
 #ifdef STATUS_LED_BIT
        "0|"
@@ -167,6 +167,6 @@ U_BOOT_CMD(
 #ifdef STATUS_LED_BLUE
        "blue|"
 #endif
-       "all] [on|off|toggle]\n",
-       "led [led_name] [on|off|toggle] sets or clears led(s)\n"
+       "all] [on|off|toggle]",
+       "[led_name] [on|off|toggle] sets or clears led(s)"
 );
index 62a1c224d36329a126425819de847acde8d24fa0..7dacd5114ce1416bf1cb5c9af5589cd62530becd 100644 (file)
@@ -144,7 +144,7 @@ static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 U_BOOT_CMD(
        mmcinfo, 1, 0, do_mmcinfo,
        "display MMC info",
-       "- dislay info of the current MMC device"
+       "- display info of the current MMC device"
 );
 
 static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
@@ -250,14 +250,13 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                return 0;
        }
 
-       if (strcmp(argv[1], "read") == 0)
+       state = MMC_INVALID;
+       if (argc == 5 && strcmp(argv[1], "read") == 0)
                state = MMC_READ;
-       else if (strcmp(argv[1], "write") == 0)
+       else if (argc == 5 && strcmp(argv[1], "write") == 0)
                state = MMC_WRITE;
-       else if (strcmp(argv[1], "erase") == 0)
+       else if (argc == 4 && strcmp(argv[1], "erase") == 0)
                state = MMC_ERASE;
-       else
-               state = MMC_INVALID;
 
        if (state != MMC_INVALID) {
                struct mmc *mmc = find_mmc_device(curr_device);
index 4b1606972b2d3b701b44b9e5080548d1815b6d83..1568594ca4109c0944292fb2ea7762fa343e7e76 100644 (file)
@@ -700,6 +700,25 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                return ret == 0 ? 0 : 1;
        }
 
+#ifdef CONFIG_CMD_NAND_TORTURE
+       if (strcmp(cmd, "torture") == 0) {
+               if (argc < 3)
+                       goto usage;
+
+               if (!str2off(argv[2], &off)) {
+                       puts("Offset is not a valid number\n");
+                       return 1;
+               }
+
+               printf("\nNAND torture: device %d offset 0x%llx size 0x%x\n",
+                       dev, off, nand->erasesize);
+               ret = nand_torture(nand, off);
+               printf(" %s\n", ret ? "Failed" : "Passed");
+
+               return ret == 0 ? 0 : 1;
+       }
+#endif
+
        if (strcmp(cmd, "markbad") == 0) {
                argc -= 2;
                argv += 2;
@@ -810,6 +829,9 @@ static char nand_help_text[] =
        "nand erase.chip [clean] - erase entire chip'\n"
        "nand bad - show bad blocks\n"
        "nand dump[.oob] off - dump page\n"
+#ifdef CONFIG_CMD_NAND_TORTURE
+       "nand torture off - torture block at offset\n"
+#endif
        "nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
        "    really clean NAND erasing bad blocks (UNSAFE)\n"
        "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
index 8ad0b2305827c0a1696a8de852a88e4c9337dfbd..dacdc2d5b1c2da32437cb40715c98740e8eda061 100644 (file)
@@ -192,7 +192,7 @@ static void usb_display_desc(struct usb_device *dev)
 
 }
 
-static void usb_display_conf_desc(struct usb_configuration_descriptor *config,
+static void usb_display_conf_desc(struct usb_config_descriptor *config,
                                  struct usb_device *dev)
 {
        printf("   Configuration: %d\n", config->bConfigurationValue);
index df642e656ca23271ff1fa05b0afd3b8c1e50090a..e93b6e89cf9da48a130c265a83b575eba4a0c737 100644 (file)
@@ -3049,6 +3049,133 @@ int fit_check_format(const void *fit)
        return 1;
 }
 
+
+/**
+ * fit_conf_find_compat
+ * @fit: pointer to the FIT format image header
+ * @fdt: pointer to the device tree to compare against
+ *
+ * fit_conf_find_compat() attempts to find the configuration whose fdt is the
+ * most compatible with the passed in device tree.
+ *
+ * Example:
+ *
+ * / o image-tree
+ *   |-o images
+ *   | |-o fdt@1
+ *   | |-o fdt@2
+ *   |
+ *   |-o configurations
+ *     |-o config@1
+ *     | |-fdt = fdt@1
+ *     |
+ *     |-o config@2
+ *       |-fdt = fdt@2
+ *
+ * / o U-Boot fdt
+ *   |-compatible = "foo,bar", "bim,bam"
+ *
+ * / o kernel fdt1
+ *   |-compatible = "foo,bar",
+ *
+ * / o kernel fdt2
+ *   |-compatible = "bim,bam", "baz,biz"
+ *
+ * Configuration 1 would be picked because the first string in U-Boot's
+ * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
+ * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
+ *
+ * returns:
+ *     offset to the configuration to use if one was found
+ *     -1 otherwise
+ */
+int fit_conf_find_compat(const void *fit, const void *fdt)
+{
+       int ndepth = 0;
+       int noffset, confs_noffset, images_noffset;
+       const void *fdt_compat;
+       int fdt_compat_len;
+       int best_match_offset = 0;
+       int best_match_pos = 0;
+
+       confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
+       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+       if (confs_noffset < 0 || images_noffset < 0) {
+               debug("Can't find configurations or images nodes.\n");
+               return -1;
+       }
+
+       fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
+       if (!fdt_compat) {
+               debug("Fdt for comparison has no \"compatible\" property.\n");
+               return -1;
+       }
+
+       /*
+        * Loop over the configurations in the FIT image.
+        */
+       for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
+                       (noffset >= 0) && (ndepth > 0);
+                       noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               const void *kfdt;
+               const char *kfdt_name;
+               int kfdt_noffset;
+               const char *cur_fdt_compat;
+               int len;
+               size_t size;
+               int i;
+
+               if (ndepth > 1)
+                       continue;
+
+               kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
+               if (!kfdt_name) {
+                       debug("No fdt property found.\n");
+                       continue;
+               }
+               kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
+                                                 kfdt_name);
+               if (kfdt_noffset < 0) {
+                       debug("No image node named \"%s\" found.\n",
+                             kfdt_name);
+                       continue;
+               }
+               /*
+                * Get a pointer to this configuration's fdt.
+                */
+               if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) {
+                       debug("Failed to get fdt \"%s\".\n", kfdt_name);
+                       continue;
+               }
+
+               len = fdt_compat_len;
+               cur_fdt_compat = fdt_compat;
+               /*
+                * Look for a match for each U-Boot compatibility string in
+                * turn in this configuration's fdt.
+                */
+               for (i = 0; len > 0 &&
+                    (!best_match_offset || best_match_pos > i); i++) {
+                       int cur_len = strlen(cur_fdt_compat) + 1;
+
+                       if (!fdt_node_check_compatible(kfdt, 0,
+                                                      cur_fdt_compat)) {
+                               best_match_offset = noffset;
+                               best_match_pos = i;
+                               break;
+                       }
+                       len -= cur_len;
+                       cur_fdt_compat += cur_len;
+               }
+       }
+       if (!best_match_offset) {
+               debug("No match found.\n");
+               return -1;
+       }
+
+       return best_match_offset;
+}
+
 /**
  * fit_conf_get_node - get node offset for configuration of a given unit name
  * @fit: pointer to the FIT format image header
index b6be8002d201692535602677ae2d002b8618e088..4c83a8bf0355d2912840e06046b7f0c2a4aaed80 100644 (file)
@@ -642,6 +642,138 @@ static void splash_align_axis(int *axis, unsigned long panel_size,
 }
 #endif
 
+
+#ifdef CONFIG_LCD_BMP_RLE8
+
+#define BMP_RLE8_ESCAPE                0
+#define BMP_RLE8_EOL           0
+#define BMP_RLE8_EOBMP         1
+#define BMP_RLE8_DELTA         2
+
+static void draw_unencoded_bitmap(ushort **fbp, uchar *bmap, ushort *cmap,
+                                 int cnt)
+{
+       while (cnt > 0) {
+               *(*fbp)++ = cmap[*bmap++];
+               cnt--;
+       }
+}
+
+static void draw_encoded_bitmap(ushort **fbp, ushort c, int cnt)
+{
+       ushort *fb = *fbp;
+       int cnt_8copy = cnt >> 3;
+
+       cnt -= cnt_8copy << 3;
+       while (cnt_8copy > 0) {
+               *fb++ = c;
+               *fb++ = c;
+               *fb++ = c;
+               *fb++ = c;
+               *fb++ = c;
+               *fb++ = c;
+               *fb++ = c;
+               *fb++ = c;
+               cnt_8copy--;
+       }
+       while (cnt > 0) {
+               *fb++ = c;
+               cnt--;
+       }
+       (*fbp) = fb;
+}
+
+/*
+ * Do not call this function directly, must be called from
+ * lcd_display_bitmap.
+ */
+static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb,
+                                   int x_off, int y_off)
+{
+       uchar *bmap;
+       ulong width, height;
+       ulong cnt, runlen;
+       int x, y;
+       int decode = 1;
+
+       width = le32_to_cpu(bmp->header.width);
+       height = le32_to_cpu(bmp->header.height);
+       bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset);
+
+       x = 0;
+       y = height - 1;
+
+       while (decode) {
+               if (bmap[0] == BMP_RLE8_ESCAPE) {
+                       switch (bmap[1]) {
+                       case BMP_RLE8_EOL:
+                               /* end of line */
+                               bmap += 2;
+                               x = 0;
+                               y--;
+                               /* 16bpix, 2-byte per pixel, width should *2 */
+                               fb -= (width * 2 + lcd_line_length);
+                               break;
+                       case BMP_RLE8_EOBMP:
+                               /* end of bitmap */
+                               decode = 0;
+                               break;
+                       case BMP_RLE8_DELTA:
+                               /* delta run */
+                               x += bmap[2];
+                               y -= bmap[3];
+                               /* 16bpix, 2-byte per pixel, x should *2 */
+                               fb = (uchar *) (lcd_base + (y + y_off - 1)
+                                       * lcd_line_length + (x + x_off) * 2);
+                               bmap += 4;
+                               break;
+                       default:
+                               /* unencoded run */
+                               runlen = bmap[1];
+                               bmap += 2;
+                               if (y < height) {
+                                       if (x < width) {
+                                               if (x + runlen > width)
+                                                       cnt = width - x;
+                                               else
+                                                       cnt = runlen;
+                                               draw_unencoded_bitmap(
+                                                       (ushort **)&fb,
+                                                       bmap, cmap, cnt);
+                                       }
+                                       x += runlen;
+                               }
+                               bmap += runlen;
+                               if (runlen & 1)
+                                       bmap++;
+                       }
+               } else {
+                       /* encoded run */
+                       if (y < height) {
+                               runlen = bmap[0];
+                               if (x < width) {
+                                       /* aggregate the same code */
+                                       while (bmap[0] == 0xff &&
+                                              bmap[2] != BMP_RLE8_ESCAPE &&
+                                              bmap[1] == bmap[3]) {
+                                               runlen += bmap[2];
+                                               bmap += 2;
+                                       }
+                                       if (x + runlen > width)
+                                               cnt = width - x;
+                                       else
+                                               cnt = runlen;
+                                       draw_encoded_bitmap((ushort **)&fb,
+                                               cmap[bmap[1]], cnt);
+                               }
+                               x += runlen;
+                       }
+                       bmap += 2;
+               }
+       }
+}
+#endif
+
 #if defined(CONFIG_MPC823) || defined(CONFIG_MCC200)
 #define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++)
 #else
@@ -675,7 +807,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
        uchar *fb;
        bmp_image_t *bmp=(bmp_image_t *)bmp_image;
        uchar *bmap;
-       ushort padded_line;
+       ushort padded_width;
        unsigned long width, height, byte_width;
        unsigned long pwidth = panel_info.vl_col;
        unsigned colors, bpix, bmp_bpix;
@@ -762,7 +894,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
        }
 #endif
 
-       padded_line = (width&0x3) ? ((width&~0x3)+4) : (width);
+       padded_width = (width&0x3) ? ((width&~0x3)+4) : (width);
 
 #ifdef CONFIG_SPLASH_SCREEN_ALIGN
        splash_align_axis(&x, pwidth, width);
@@ -781,6 +913,18 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
        switch (bmp_bpix) {
        case 1: /* pass through */
        case 8:
+#ifdef CONFIG_LCD_BMP_RLE8
+               if (le32_to_cpu(bmp->header.compression) == BMP_BI_RLE8) {
+                       if (bpix != 16) {
+                               /* TODO implement render code for bpix != 16 */
+                               printf("Error: only support 16 bpix");
+                               return 1;
+                       }
+                       lcd_display_rle8_bitmap(bmp, cmap_base, fb, x, y);
+                       break;
+               }
+#endif
+
                if (bpix != 16)
                        byte_width = width;
                else
@@ -796,7 +940,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                                        fb += sizeof(uint16_t) / sizeof(*fb);
                                }
                        }
-                       bmap += (width - padded_line);
+                       bmap += (padded_width - width);
                        fb   -= (byte_width + lcd_line_length);
                }
                break;
@@ -808,7 +952,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                        for (j = 0; j < width; j++)
                                fb_put_word(&fb, &bmap);
 
-                       bmap += (padded_line - width) * 2;
+                       bmap += (padded_width - width) * 2;
                        fb   -= (width * 2 + lcd_line_length);
                }
                break;
@@ -885,5 +1029,31 @@ static void *lcd_logo(void)
 #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
 }
 
+void lcd_position_cursor(unsigned col, unsigned row)
+{
+       console_col = min(col, CONSOLE_COLS - 1);
+       console_row = min(row, CONSOLE_ROWS - 1);
+}
+
+int lcd_get_pixel_width(void)
+{
+       return panel_info.vl_col;
+}
+
+int lcd_get_pixel_height(void)
+{
+       return panel_info.vl_row;
+}
+
+int lcd_get_screen_rows(void)
+{
+       return CONSOLE_ROWS;
+}
+
+int lcd_get_screen_columns(void)
+{
+       return CONSOLE_COLS;
+}
+
 /************************************************************************/
 /************************************************************************/
index 592ce077d214d20243c57209c0e046037c7d69c1..5362781f18700ee7e98547e07a5f673635b52666 100644 (file)
@@ -30,6 +30,7 @@
 #include <common.h>
 #include <watchdog.h>
 #include <command.h>
+#include <fdtdec.h>
 #include <malloc.h>
 #include <version.h>
 #ifdef CONFIG_MODEM_SUPPORT
 #include <hush.h>
 #endif
 
+#ifdef CONFIG_OF_CONTROL
+#include <fdtdec.h>
+#endif
+
+#ifdef CONFIG_OF_LIBFDT
+#include <fdt_support.h>
+#endif /* CONFIG_OF_LIBFDT */
+
 #include <post.h>
 #include <linux/ctype.h>
 #include <menu.h>
 
-#if defined(CONFIG_SILENT_CONSOLE) || defined(CONFIG_POST) || defined(CONFIG_CMDLINE_EDITING)
 DECLARE_GLOBAL_DATA_PTR;
-#endif
 
 /*
  * Board-specific Platform code can reimplement show_boot_progress () if needed
@@ -274,6 +281,73 @@ int abortboot(int bootdelay)
 # endif        /* CONFIG_AUTOBOOT_KEYED */
 #endif /* CONFIG_BOOTDELAY >= 0  */
 
+/*
+ * Runs the given boot command securely.  Specifically:
+ * - Doesn't run the command with the shell (run_command or parse_string_outer),
+ *   since that's a lot of code surface that an attacker might exploit.
+ *   Because of this, we don't do any argument parsing--the secure boot command
+ *   has to be a full-fledged u-boot command.
+ * - Doesn't check for keypresses before booting, since that could be a
+ *   security hole; also disables Ctrl-C.
+ * - Doesn't allow the command to return.
+ *
+ * Upon any failures, this function will drop into an infinite loop after
+ * printing the error message to console.
+ */
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \
+       defined(CONFIG_OF_CONTROL)
+static void secure_boot_cmd(char *cmd)
+{
+       cmd_tbl_t *cmdtp;
+       int rc;
+
+       if (!cmd) {
+               printf("## Error: Secure boot command not specified\n");
+               goto err;
+       }
+
+       /* Disable Ctrl-C just in case some command is used that checks it. */
+       disable_ctrlc(1);
+
+       /* Find the command directly. */
+       cmdtp = find_cmd(cmd);
+       if (!cmdtp) {
+               printf("## Error: \"%s\" not defined\n", cmd);
+               goto err;
+       }
+
+       /* Run the command, forcing no flags and faking argc and argv. */
+       rc = (cmdtp->cmd)(cmdtp, 0, 1, &cmd);
+
+       /* Shouldn't ever return from boot command. */
+       printf("## Error: \"%s\" returned (code %d)\n", cmd, rc);
+
+err:
+       /*
+        * Not a whole lot to do here.  Rebooting won't help much, since we'll
+        * just end up right back here.  Just loop.
+        */
+       hang();
+}
+
+static void process_fdt_options(const void *blob)
+{
+       ulong addr;
+
+       /* Add an env variable to point to a kernel payload, if available */
+       addr = fdtdec_get_config_int(gd->fdt_blob, "kernel-offset", 0);
+       if (addr)
+               setenv_addr("kernaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
+
+       /* Add an env variable to point to a root disk, if available */
+       addr = fdtdec_get_config_int(gd->fdt_blob, "rootdisk-offset", 0);
+       if (addr)
+               setenv_addr("rootaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
+}
+#endif /* CONFIG_OF_CONTROL */
+
+
 /****************************************************************************/
 
 void main_loop (void)
@@ -284,7 +358,10 @@ void main_loop (void)
        int rc = 1;
        int flag;
 #endif
-
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \
+               defined(CONFIG_OF_CONTROL)
+       char *env;
+#endif
 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
        char *s;
        int bootdelay;
@@ -380,6 +457,23 @@ void main_loop (void)
        else
 #endif /* CONFIG_BOOTCOUNT_LIMIT */
                s = getenv ("bootcmd");
+#ifdef CONFIG_OF_CONTROL
+       /* Allow the fdt to override the boot command */
+       env = fdtdec_get_config_string(gd->fdt_blob, "bootcmd");
+       if (env)
+               s = env;
+
+       process_fdt_options(gd->fdt_blob);
+
+       /*
+        * If the bootsecure option was chosen, use secure_boot_cmd().
+        * Always use 'env' in this case, since bootsecure requres that the
+        * bootcmd was specified in the FDT too.
+        */
+       if (fdtdec_get_config_int(gd->fdt_blob, "bootsecure", 0))
+               secure_boot_cmd(env);
+
+#endif /* CONFIG_OF_CONTROL */
 
        debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
 
@@ -404,6 +498,10 @@ 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 f068abd8f84b7a437bc227009de9df83acda2847..ff9ba7b0a59ef5cff6fddbb7771da8b6d63e26ee 100644 (file)
@@ -74,6 +74,16 @@ __weak int spl_start_uboot(void)
 }
 #endif
 
+/*
+ * Weak default function for board specific cleanup/preparation before
+ * Linux boot. Some boards/platforms might not need it, so just provide
+ * an empty stub here.
+ */
+__weak void spl_board_prepare_for_linux(void)
+{
+       /* Nothing to do! */
+}
+
 void spl_parse_image_header(const struct image_header *header)
 {
        u32 header_size = sizeof(struct image_header);
@@ -155,7 +165,13 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
                        CONFIG_SYS_SPL_MALLOC_SIZE);
 #endif
 
+#ifndef CONFIG_PPC
+       /*
+        * timer_init() does not exist on PPC systems. The timer is initialized
+        * and enabled (decrementer) in interrupt_init() here.
+        */
        timer_init();
+#endif
 
 #ifdef CONFIG_SPL_BOARD_INIT
        spl_board_init();
index 605ff3fde3ea30e1f631043ea5003557360689c0..9f48e5f5034da70cda786d8569a7287780868c9c 100644 (file)
@@ -237,6 +237,8 @@ int stdio_init (void)
 #ifdef CONFIG_JTAG_CONSOLE
        drv_jtag_console_init ();
 #endif
-
+#ifdef CONFIG_CBMEM_CONSOLE
+       cbmemc_init();
+#endif
        return (0);
 }
index 50b81752ebca7300599da7580629614d84e0d696..ac9b4ca8d58bfe8dd3cd941c7fb094a4b9d819e7 100644 (file)
@@ -492,9 +492,9 @@ int usb_get_configuration_no(struct usb_device *dev,
 {
        int result;
        unsigned int tmp;
-       struct usb_configuration_descriptor *config;
+       struct usb_config_descriptor *config;
 
-       config = (struct usb_configuration_descriptor *)&buffer[0];
+       config = (struct usb_config_descriptor *)&buffer[0];
        result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9);
        if (result < 9) {
                if (result < 0)
index 19f01db1caa299f8217b778b12772fd789fc013f..4efbcfe90d369fdc60028640c74efba05d3442b6 100644 (file)
@@ -93,6 +93,15 @@ static const unsigned char usb_kbd_num_keypad[] = {
        '.', 0, 0, 0, '='
 };
 
+/*
+ * map arrow keys to ^F/^B ^N/^P, can't really use the proper
+ * ANSI sequence for arrow keys because the queuing code breaks
+ * when a single keypress expands to 3 queue elements
+ */
+static const unsigned char usb_kbd_arrow[] = {
+       0x6, 0x2, 0xe, 0x10
+};
+
 /*
  * NOTE: It's important for the NUM, CAPS, SCROLL-lock bits to be in this
  *       order. See usb_kbd_setled() function!
@@ -112,7 +121,7 @@ struct usb_kbd_pdata {
        uint32_t        usb_out_pointer;
        uint8_t         usb_kbd_buffer[USB_KBD_BUFFER_LEN];
 
-       uint8_t         new[8];
+       uint8_t         *new;
        uint8_t         old[8];
 
        uint8_t         flags;
@@ -224,6 +233,10 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode,
                        keycode = usb_kbd_numkey[scancode - 0x1e];
        }
 
+       /* Arrow keys */
+       if ((scancode >= 0x4f) && (scancode <= 0x52))
+               keycode = usb_kbd_arrow[scancode - 0x4f];
+
        /* Numeric keypad */
        if ((scancode >= 0x54) && (scancode <= 0x67))
                keycode = usb_kbd_num_keypad[scancode - 0x54];
@@ -435,6 +448,9 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
        /* Clear private data */
        memset(data, 0, sizeof(struct usb_kbd_pdata));
 
+       /* allocate input buffer aligned and sized to USB DMA alignment */
+       data->new = memalign(USB_DMA_MINALIGN, roundup(8, USB_DMA_MINALIGN));
+
        /* Insert private data into USB device structure */
        dev->privptr = data;
 
index 4646f682d2c8b6c7f05bf0dc5ea9fba1c8b4f791..7bdc90eff701183934874195356c36e6d5a4ab5f 100644 (file)
@@ -199,7 +199,7 @@ void dev_print (block_dev_desc_t *dev_desc)
                break;
        }
        puts ("\n");
-       if ((dev_desc->lba * dev_desc->blksz)>0L) {
+       if (dev_desc->lba > 0L && dev_desc->blksz > 0L) {
                ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
                lbaint_t lba;
 
index da88b3241984c45bf5c8970ca7f818e54c4d9a18..521e8bc0e9b7144e0e378ab2808ccaccbb3d8ce3 100644 (file)
@@ -8,7 +8,7 @@
 
 include $(TOPDIR)/config.mk
 
-DOCBOOKS := linker_lists.xml stdio.xml
+DOCBOOKS := fs.xml linker_lists.xml stdio.xml
 
 ###
 # The build process is as follows (targets):
index 5a4b591a89a2795993d94627a3ca43038c2b14ab..f9b023f28413b6b0d3c0f6183220cda7b066e866 100644 (file)
@@ -26,7 +26,7 @@ Major Config Switches during various boot Modes
 ----------------------------------------------
 
 NOR boot
-               !defined(CONFIG_SYS_RAMBOOT)
+               !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SPL)
 NOR boot Secure
                !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT)
 RAMBOOT(SD, SPI & NAND boot)
index c130189587b81a21b1d51aa20cf11112b8eb89b3..a1a511c5339cbc8f9b6d71e1b13cf7e609fa9156 100644 (file)
@@ -108,6 +108,9 @@ Configuration Options:
    CONFIG_CMD_NAND
       Enables NAND support and commmands.
 
+   CONFIG_CMD_NAND_TORTURE
+      Enables the torture command (see description of this command below).
+
    CONFIG_MTD_NAND_ECC_JFFS2
       Define this if you want the Error Correction Code information in
       the out-of-band data to be formatted to match the JFFS2 file system.
@@ -213,6 +216,24 @@ Miscellaneous and testing commands:
   DANGEROUS!!! Factory set bad blocks will be lost. Use only
   to remove artificial bad blocks created with the "markbad" command.
 
+  "torture offset"
+  Torture block to determine if it is still reliable.
+  Enabled by the CONFIG_CMD_NAND_TORTURE configuration option.
+  This command returns 0 if the block is still reliable, else 1.
+  If the block is detected as unreliable, it is up to the user to decide to
+  mark this block as bad.
+  The analyzed block is put through 3 erase / write cycles (or less if the block
+  is detected as unreliable earlier).
+  This command can be used in scripts, e.g. together with the markbad command to
+  automate retries and handling of possibly newly detected bad blocks if the
+  nand write command fails.
+  It can also be used manually by users having seen some NAND errors in logs to
+  search the root cause of these errors.
+  The underlying nand_torture() function is also useful for code willing to
+  automate actions following a nand->write() error. This would e.g. be required
+  in order to program or update safely firmware to NAND, especially for the UBI
+  part of such firmware.
+
 
 NAND locking command (for chips with active LOCKPRE pin)
 
index ed0839836ea15fb400185b395e2da183fb85bff0..25fe69aa5c4cbc31593bdd2d0b8cd8ca4398090d 100644 (file)
@@ -79,6 +79,6 @@ Adjust the baud rate on \fITTY\fP. Default rate is 115200.
 
 Daniel Stodden <daniel.stodden@gmail.com>
 .br
-Luka Perkov <uboot@lukaperkov.net>
+Luka Perkov <luka@openwrt.org>
 .br
 David Purdy <david.c.purdy@gmail.com>
index d50ac3bfefd12b70dd898a4a1d18ae25b8b1f99d..2d97b4f1e4d521796af31646480671465d6a0d1d 100644 (file)
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
 LIB    := $(obj)libgpio.o
 
 COBJS-$(CONFIG_AT91_GPIO)      += at91_gpio.o
+COBJS-$(CONFIG_INTEL_ICH6_GPIO)        += intel_ich6_gpio.o
 COBJS-$(CONFIG_KIRKWOOD_GPIO)  += kw_gpio.o
 COBJS-$(CONFIG_MARVELL_GPIO)   += mvgpio.o
 COBJS-$(CONFIG_MARVELL_MFP)    += mvmfp.o
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
new file mode 100644 (file)
index 0000000..6fed01f
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * 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
+ */
+
+/*
+ * This is a GPIO driver for Intel ICH6 and later. The x86 GPIOs are accessed
+ * through the PCI bus. Each PCI device has 256 bytes of configuration space,
+ * consisting of a standard header and a device-specific set of registers. PCI
+ * bus 0, device 31, function 0 gives us access to the chipset GPIOs (among
+ * other things). Within the PCI configuration space, the GPIOBASE register
+ * tells us where in the device's I/O region we can find more registers to
+ * actually access the GPIOs.
+ *
+ * PCI bus/device/function 0:1f:0  => PCI config registers
+ *   PCI config register "GPIOBASE"
+ *     PCI I/O space + [GPIOBASE]  => start of GPIO registers
+ *       GPIO registers => gpio pin function, direction, value
+ *
+ *
+ * Danger Will Robinson! Bank 0 (GPIOs 0-31) seems to be fairly stable. Most
+ * ICH versions have more, but the decoding the matrix that describes them is
+ * absurdly complex and constantly changing. We'll provide Bank 1 and Bank 2,
+ * but they will ONLY work for certain unspecified chipsets because the offset
+ * from GPIOBASE changes randomly. Even then, many GPIOs are unimplemented or
+ * reserved or subject to arcane restrictions.
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+
+/* Where in config space is the register that points to the GPIO registers? */
+#define PCI_CFG_GPIOBASE 0x48
+
+#define NUM_BANKS 3
+
+/* Within the I/O space, where are the registers to control the GPIOs? */
+static struct {
+       u8 use_sel;
+       u8 io_sel;
+       u8 lvl;
+} gpio_bank[NUM_BANKS] = {
+       { 0x00, 0x04, 0x0c },           /* Bank 0 */
+       { 0x30, 0x34, 0x38 },           /* Bank 1 */
+       { 0x40, 0x44, 0x48 }            /* Bank 2 */
+};
+
+static pci_dev_t dev;                  /* handle for 0:1f:0 */
+static u32 gpiobase;                   /* offset into I/O space */
+static int found_it_once;              /* valid GPIO device? */
+static u32 lock[NUM_BANKS];            /* "lock" for access to pins */
+
+static int bad_arg(int num, int *bank, int *bitnum)
+{
+       int i = num / 32;
+       int j = num % 32;
+
+       if (num < 0 || i > NUM_BANKS) {
+               debug("%s: bogus gpio num: %d\n", __func__, num);
+               return -1;
+       }
+       *bank = i;
+       *bitnum = j;
+       return 0;
+}
+
+static int mark_gpio(int bank, int bitnum)
+{
+       if (lock[bank] & (1UL << bitnum)) {
+               debug("%s: %d.%d already marked\n", __func__, bank, bitnum);
+               return -1;
+       }
+       lock[bank] |= (1 << bitnum);
+       return 0;
+}
+
+static void clear_gpio(int bank, int bitnum)
+{
+       lock[bank] &= ~(1 << bitnum);
+}
+
+static int notmine(int num, int *bank, int *bitnum)
+{
+       if (bad_arg(num, bank, bitnum))
+               return -1;
+       return !(lock[*bank] & (1UL << *bitnum));
+}
+
+static int gpio_init(void)
+{
+       u8 tmpbyte;
+       u16 tmpword;
+       u32 tmplong;
+
+       /* Have we already done this? */
+       if (found_it_once)
+               return 0;
+
+       /* Where should it be? */
+       dev = PCI_BDF(0, 0x1f, 0);
+
+       /* Is the device present? */
+       pci_read_config_word(dev, PCI_VENDOR_ID, &tmpword);
+       if (tmpword != PCI_VENDOR_ID_INTEL) {
+               debug("%s: wrong VendorID\n", __func__);
+               return -1;
+       }
+
+       pci_read_config_word(dev, PCI_DEVICE_ID, &tmpword);
+       debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword);
+       /*
+        * We'd like to validate the Device ID too, but pretty much any
+        * value is either a) correct with slight differences, or b)
+        * correct but undocumented. We'll have to check a bunch of other
+        * things instead...
+        */
+
+       /* I/O should already be enabled (it's a RO bit). */
+       pci_read_config_word(dev, PCI_COMMAND, &tmpword);
+       if (!(tmpword & PCI_COMMAND_IO)) {
+               debug("%s: device IO not enabled\n", __func__);
+               return -1;
+       }
+
+       /* Header Type must be normal (bits 6-0 only; see spec.) */
+       pci_read_config_byte(dev, PCI_HEADER_TYPE, &tmpbyte);
+       if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) {
+               debug("%s: invalid Header type\n", __func__);
+               return -1;
+       }
+
+       /* Base Class must be a bridge device */
+       pci_read_config_byte(dev, PCI_CLASS_CODE, &tmpbyte);
+       if (tmpbyte != PCI_CLASS_CODE_BRIDGE) {
+               debug("%s: invalid class\n", __func__);
+               return -1;
+       }
+       /* Sub Class must be ISA */
+       pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &tmpbyte);
+       if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) {
+               debug("%s: invalid subclass\n", __func__);
+               return -1;
+       }
+
+       /* Programming Interface must be 0x00 (no others exist) */
+       pci_read_config_byte(dev, PCI_CLASS_PROG, &tmpbyte);
+       if (tmpbyte != 0x00) {
+               debug("%s: invalid interface type\n", __func__);
+               return -1;
+       }
+
+       /*
+        * GPIOBASE moved to its current offset with ICH6, but prior to
+        * that it was unused (or undocumented). Check that it looks
+        * okay: not all ones or zeros, and mapped to I/O space (bit 0).
+        */
+       pci_read_config_dword(dev, PCI_CFG_GPIOBASE, &tmplong);
+       if (tmplong == 0x00000000 || tmplong == 0xffffffff ||
+           !(tmplong & 0x00000001)) {
+               debug("%s: unexpected GPIOBASE value\n", __func__);
+               return -1;
+       }
+
+       /*
+        * Okay, I guess we're looking at the right device. The actual
+        * GPIO registers are in the PCI device's I/O space, starting
+        * at the offset that we just read. Bit 0 indicates that it's
+        * an I/O address, not a memory address, so mask that off.
+        */
+       gpiobase = tmplong & 0xfffffffe;
+
+       /* Finally. These are the droids we're looking for. */
+       found_it_once = 1;
+       return 0;
+}
+
+int gpio_request(unsigned num, const char *label /* UNUSED */)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+
+       /* Is the hardware ready? */
+       if (gpio_init())
+               return -1;
+
+       if (bad_arg(num, &i, &j))
+               return -1;
+
+       /*
+        * Make sure that the GPIO pin we want isn't already in use for some
+        * built-in hardware function. We have to check this for every
+        * requested pin.
+        */
+       tmplong = inl(gpiobase + gpio_bank[i].use_sel);
+       if (!(tmplong & (1UL << j))) {
+               debug("%s: gpio %d is reserved for internal use\n", __func__,
+                     num);
+               return -1;
+       }
+
+       return mark_gpio(i, j);
+}
+
+int gpio_free(unsigned num)
+{
+       int i = 0, j = 0;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       clear_gpio(i, j);
+       return 0;
+}
+
+int gpio_direction_input(unsigned num)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       tmplong = inl(gpiobase + gpio_bank[i].io_sel);
+       tmplong |= (1UL << j);
+       outl(gpiobase + gpio_bank[i].io_sel, tmplong);
+       return 0;
+}
+
+int gpio_direction_output(unsigned num, int value)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       tmplong = inl(gpiobase + gpio_bank[i].io_sel);
+       tmplong &= ~(1UL << j);
+       outl(gpiobase + gpio_bank[i].io_sel, tmplong);
+       return 0;
+}
+
+int gpio_get_value(unsigned num)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+       int r;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       tmplong = inl(gpiobase + gpio_bank[i].lvl);
+       r = (tmplong & (1UL << j)) ? 1 : 0;
+       return r;
+}
+
+int gpio_set_value(unsigned num, int value)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       tmplong = inl(gpiobase + gpio_bank[i].lvl);
+       if (value)
+               tmplong |= (1UL << j);
+       else
+               tmplong &= ~(1UL << j);
+       outl(gpiobase + gpio_bank[i].lvl, tmplong);
+       return 0;
+}
index 271463cf142b25c1096cb46dbbb5a7b5fa338abb..8cdc3b649ca34a963efe314da8731642914a684b 100644 (file)
@@ -27,20 +27,13 @@ LIB := $(obj)libmisc.o
 
 COBJS-$(CONFIG_ALI152X) += ali512x.o
 COBJS-$(CONFIG_DS4510)  += ds4510.o
-COBJS-$(CONFIG_FSL_LAW) += fsl_law.o
+COBJS-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o
 COBJS-$(CONFIG_GPIO_LED) += gpio_led.o
 COBJS-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
 COBJS-$(CONFIG_NS87308) += ns87308.o
 COBJS-$(CONFIG_PDSP188x) += pdsp188x.o
 COBJS-$(CONFIG_STATUS_LED) += status_led.o
 COBJS-$(CONFIG_TWL4030_LED) += twl4030_led.o
-COBJS-$(CONFIG_PMIC) += pmic_core.o
-COBJS-$(CONFIG_DIALOG_PMIC) += pmic_dialog.o
-COBJS-$(CONFIG_PMIC_FSL) += pmic_fsl.o
-COBJS-$(CONFIG_PMIC_I2C) += pmic_i2c.o
-COBJS-$(CONFIG_PMIC_SPI) += pmic_spi.o
-COBJS-$(CONFIG_PMIC_MAX8998) += pmic_max8998.o
-COBJS-$(CONFIG_PMIC_MAX8997) += pmic_max8997.o
 
 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/misc/cbmem_console.c b/drivers/misc/cbmem_console.c
new file mode 100644 (file)
index 0000000..80a84fd
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * 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 of the License.
+ *
+ * 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 St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <common.h>
+
+#ifndef CONFIG_SYS_COREBOOT
+#error This driver requires coreboot
+#endif
+
+#include <asm/arch/sysinfo.h>
+
+struct cbmem_console {
+       u32 buffer_size;
+       u32 buffer_cursor;
+       u8  buffer_body[0];
+}  __attribute__ ((__packed__));
+
+static struct cbmem_console *cbmem_console_p;
+
+void cbmemc_putc(char data)
+{
+       int cursor;
+
+       cursor = cbmem_console_p->buffer_cursor++;
+       if (cursor < cbmem_console_p->buffer_size)
+               cbmem_console_p->buffer_body[cursor] = data;
+}
+
+void cbmemc_puts(const char *str)
+{
+       char c;
+
+       while ((c = *str++) != 0)
+               cbmemc_putc(c);
+}
+
+int cbmemc_init(void)
+{
+       int rc;
+       struct stdio_dev cons_dev;
+       cbmem_console_p = lib_sysinfo.cbmem_cons;
+
+       memset(&cons_dev, 0, sizeof(cons_dev));
+
+       strcpy(cons_dev.name, "cbmem");
+       cons_dev.flags = DEV_FLAGS_OUTPUT; /* Output only */
+       cons_dev.putc  = cbmemc_putc;
+       cons_dev.puts  = cbmemc_puts;
+
+       rc = stdio_register(&cons_dev);
+
+       return (rc == 0) ? 1 : rc;
+}
diff --git a/drivers/misc/pmic_core.c b/drivers/misc/pmic_core.c
deleted file mode 100644 (file)
index 5d62a56..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics
- * Lukasz Majewski <l.majewski@samsung.com>
- *
- * (C) Copyright 2010
- * Stefano Babic, DENX Software Engineering, sbabic@denx.de
- *
- * (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <linux/types.h>
-#include <pmic.h>
-
-static struct pmic pmic;
-
-int check_reg(u32 reg)
-{
-       if (reg >= pmic.number_of_regs) {
-               printf("<reg num> = %d is invalid. Should be less than %d\n",
-                      reg, pmic.number_of_regs);
-               return -1;
-       }
-       return 0;
-}
-
-int pmic_set_output(struct pmic *p, u32 reg, int out, int on)
-{
-       u32 val;
-
-       if (pmic_reg_read(p, reg, &val))
-               return -1;
-
-       if (on)
-               val |= out;
-       else
-               val &= ~out;
-
-       if (pmic_reg_write(p, reg, val))
-               return -1;
-
-       return 0;
-}
-
-static void pmic_show_info(struct pmic *p)
-{
-       printf("PMIC: %s\n", p->name);
-}
-
-static void pmic_dump(struct pmic *p)
-{
-       int i, ret;
-       u32 val;
-
-       pmic_show_info(p);
-       for (i = 0; i < p->number_of_regs; i++) {
-               ret = pmic_reg_read(p, i, &val);
-               if (ret)
-                       puts("PMIC: Registers dump failed\n");
-
-               if (!(i % 8))
-                       printf("\n0x%02x: ", i);
-
-               printf("%08x ", val);
-       }
-       puts("\n");
-}
-
-struct pmic *get_pmic(void)
-{
-       return &pmic;
-}
-
-int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       u32 ret, reg, val;
-       char *cmd;
-
-       struct pmic *p = &pmic;
-
-       /* at least two arguments please */
-       if (argc < 2)
-               return cmd_usage(cmdtp);
-
-       cmd = argv[1];
-       if (strcmp(cmd, "dump") == 0) {
-               pmic_dump(p);
-               return 0;
-       }
-
-       if (strcmp(cmd, "read") == 0) {
-               if (argc < 3)
-                       return cmd_usage(cmdtp);
-
-               reg = simple_strtoul(argv[2], NULL, 16);
-
-               ret = pmic_reg_read(p, reg, &val);
-
-               if (ret)
-                       puts("PMIC: Register read failed\n");
-
-               printf("\n0x%02x: 0x%08x\n", reg, val);
-
-               return 0;
-       }
-
-       if (strcmp(cmd, "write") == 0) {
-               if (argc < 4)
-                       return cmd_usage(cmdtp);
-
-               reg = simple_strtoul(argv[2], NULL, 16);
-               val = simple_strtoul(argv[3], NULL, 16);
-
-               pmic_reg_write(p, reg, val);
-
-               return 0;
-       }
-
-       /* No subcommand found */
-       return 1;
-}
-
-U_BOOT_CMD(
-       pmic,   CONFIG_SYS_MAXARGS, 1, do_pmic,
-       "PMIC",
-       "dump - dump PMIC registers\n"
-       "pmic read <reg> - read register\n"
-       "pmic write <reg> <value> - write register"
-);
index a1dd7302bfc732122fe6620ded02b46dd8c817fd..65791aa218449039439faf578ca0d4e899680f7b 100644 (file)
@@ -47,6 +47,7 @@ COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
 COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
 COBJS-$(CONFIG_DWMMC) += dw_mmc.o
+COBJS-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o
 
 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
new file mode 100644 (file)
index 0000000..72a31b7
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2012 SAMSUNG Electronics
+ * Jaehoon Chung <jh80.chung@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 <common.h>
+#include <malloc.h>
+#include <dwmmc.h>
+#include <asm/arch/dwmmc.h>
+#include <asm/arch/clk.h>
+
+static char *EXYNOS_NAME = "EXYNOS DWMMC";
+
+static void exynos_dwmci_clksel(struct dwmci_host *host)
+{
+       u32 val;
+       val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) |
+               DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(0);
+
+       dwmci_writel(host, DWMCI_CLKSEL, val);
+}
+
+int exynos_dwmci_init(u32 regbase, int bus_width, int index)
+{
+       struct dwmci_host *host = NULL;
+       host = malloc(sizeof(struct dwmci_host));
+       if (!host) {
+               printf("dwmci_host malloc fail!\n");
+               return 1;
+       }
+
+       host->name = EXYNOS_NAME;
+       host->ioaddr = (void *)regbase;
+       host->buswidth = bus_width;
+       host->clksel = exynos_dwmci_clksel;
+       host->dev_index = index;
+
+       add_dwmci(host, 52000000, 400000);
+
+       return 0;
+}
+
index 5ffd8c59e6ebfed812e459a422477c6b3d92b4e2..72e8ce6da423018e8714be88fd4a3722fd49dca6 100644 (file)
@@ -868,7 +868,7 @@ static void mmc_set_bus_width(struct mmc *mmc, uint width)
 
 static int mmc_startup(struct mmc *mmc)
 {
-       int err, width;
+       int err;
        uint mult, freq;
        u64 cmult, csize, capacity;
        struct mmc_cmd cmd;
@@ -1087,21 +1087,44 @@ static int mmc_startup(struct mmc *mmc)
                else
                        mmc->tran_speed = 25000000;
        } else {
-               width = ((mmc->host_caps & MMC_MODE_MASK_WIDTH_BITS) >>
-                        MMC_MODE_WIDTH_BITS_SHIFT);
-               for (; width >= 0; width--) {
-                       /* Set the card to use 4 bit*/
+               int idx;
+
+               /* An array of possible bus widths in order of preference */
+               static unsigned ext_csd_bits[] = {
+                       EXT_CSD_BUS_WIDTH_8,
+                       EXT_CSD_BUS_WIDTH_4,
+                       EXT_CSD_BUS_WIDTH_1,
+               };
+
+               /* An array to map CSD bus widths to host cap bits */
+               static unsigned ext_to_hostcaps[] = {
+                       [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
+                       [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
+               };
+
+               /* An array to map chosen bus width to an integer */
+               static unsigned widths[] = {
+                       8, 4, 1,
+               };
+
+               for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
+                       unsigned int extw = ext_csd_bits[idx];
+
+                       /*
+                        * Check to make sure the controller supports
+                        * this bus width, if it's more than 1
+                        */
+                       if (extw != EXT_CSD_BUS_WIDTH_1 &&
+                                       !(mmc->host_caps & ext_to_hostcaps[extw]))
+                               continue;
+
                        err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
-                                       EXT_CSD_BUS_WIDTH, width);
+                                       EXT_CSD_BUS_WIDTH, extw);
 
                        if (err)
                                continue;
 
-                       if (!width) {
-                               mmc_set_bus_width(mmc, 1);
-                               break;
-                       } else
-                               mmc_set_bus_width(mmc, 4 * width);
+                       mmc_set_bus_width(mmc, widths[idx]);
 
                        err = mmc_send_ext_csd(mmc, test_csd);
                        if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
@@ -1115,7 +1138,7 @@ static int mmc_startup(struct mmc *mmc)
                                 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
                                        &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
 
-                               mmc->card_caps |= width;
+                               mmc->card_caps |= ext_to_hostcaps[extw];
                                break;
                        }
                }
@@ -1135,13 +1158,15 @@ static int mmc_startup(struct mmc *mmc)
        mmc->block_dev.type = 0;
        mmc->block_dev.blksz = mmc->read_bl_len;
        mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
-       sprintf(mmc->block_dev.vendor, "Man %06x Snr %08x", mmc->cid[0] >> 8,
-                       (mmc->cid[2] << 8) | (mmc->cid[3] >> 24));
-       sprintf(mmc->block_dev.product, "%c%c%c%c%c", mmc->cid[0] & 0xff,
-                       (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
-                       (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
-       sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28,
-                       (mmc->cid[2] >> 24) & 0xf);
+       sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
+               mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
+               (mmc->cid[3] >> 16) & 0xffff);
+       sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
+               (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
+               (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
+               (mmc->cid[2] >> 24) & 0xff);
+       sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
+               (mmc->cid[2] >> 16) & 0xf);
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
        init_part(&mmc->block_dev);
 #endif
index 109acbf6234bf3eb29e4caf9ba18f5c4294e784e..024df592f2256bd7f846683fd1f8d3ff61baa529 100644 (file)
@@ -96,11 +96,11 @@ static int mxsmmc_send_cmd_pio(struct mxsmmc_priv *priv, struct mmc_data *data)
 static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
 {
        uint32_t data_count = data->blocksize * data->blocks;
-       uint32_t cache_data_count = roundup(data_count, ARCH_DMA_MINALIGN);
        int dmach;
        struct mxs_dma_desc *desc = priv->desc;
-       void *addr, *backup;
-       uint8_t flags;
+       void *addr;
+       unsigned int flags;
+       struct bounce_buffer bbstate;
 
        memset(desc, 0, sizeof(struct mxs_dma_desc));
        desc->address = (dma_addr_t)desc;
@@ -115,19 +115,9 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
                flags = GEN_BB_READ;
        }
 
-       bounce_buffer_start(&addr, data_count, &backup, flags);
+       bounce_buffer_start(&bbstate, addr, data_count, flags);
 
-       priv->desc->cmd.address = (dma_addr_t)addr;
-
-       if (data->flags & MMC_DATA_WRITE) {
-               /* Flush data to DRAM so DMA can pick them up */
-               flush_dcache_range((uint32_t)addr,
-                       (uint32_t)(addr) + cache_data_count);
-       }
-
-       /* Invalidate the area, so no writeback into the RAM races with DMA */
-       invalidate_dcache_range((uint32_t)priv->desc->cmd.address,
-                       (uint32_t)(priv->desc->cmd.address + cache_data_count));
+       priv->desc->cmd.address = (dma_addr_t)bbstate.bounce_buffer;
 
        priv->desc->cmd.data |= MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM |
                                (data_count << MXS_DMA_DESC_BYTES_OFFSET);
@@ -135,17 +125,11 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
        dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->id;
        mxs_dma_desc_append(dmach, priv->desc);
        if (mxs_dma_go(dmach)) {
-               bounce_buffer_stop(&addr, data_count, &backup, flags);
+               bounce_buffer_stop(&bbstate);
                return COMM_ERR;
        }
 
-       /* The data arrived into DRAM, invalidate cache over them */
-       if (data->flags & MMC_DATA_READ) {
-               invalidate_dcache_range((uint32_t)addr,
-                       (uint32_t)(addr) + cache_data_count);
-       }
-
-       bounce_buffer_stop(&addr, data_count, &backup, flags);
+       bounce_buffer_stop(&bbstate);
 
        return 0;
 }
index 7845f873ac9009295768c102fd4024d75f85c565..b9cbe34f1f12f728471514ceac568576fe696b9c 100644 (file)
@@ -340,6 +340,9 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
                return;
        }
 
+       if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
+               sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+
        pwr |= SDHCI_POWER_ON;
 
        sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
index 8fea6a6bfb2cc0a9aa7c85c1b191e1972612233c..b141eafc7bb16ae0cdeeb704068b92b1e15a4983 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <bouncebuf.h>
 #include <common.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
@@ -66,14 +67,17 @@ static void tegra_get_setup(struct mmc_host *host, int dev_index)
        host->reg = (struct tegra_mmc *)host->base;
 }
 
-static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data)
+static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data,
+                               struct bounce_buffer *bbstate)
 {
        unsigned char ctrl;
 
-       debug("data->dest: %08X, data->blocks: %u, data->blocksize: %u\n",
-       (u32)data->dest, data->blocks, data->blocksize);
 
-       writel((u32)data->dest, &host->reg->sysad);
+       debug("buf: %p (%p), data->blocks: %u, data->blocksize: %u\n",
+               bbstate->bounce_buffer, bbstate->user_buffer, data->blocks,
+               data->blocksize);
+
+       writel((u32)bbstate->bounce_buffer, &host->reg->sysad);
        /*
         * DMASEL[4:3]
         * 00 = Selects SDMA
@@ -114,14 +118,6 @@ static void mmc_set_transfer_mode(struct mmc_host *host, struct mmc_data *data)
        if (data->flags & MMC_DATA_READ)
                mode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;
 
-       if (data->flags & MMC_DATA_WRITE) {
-               if ((uintptr_t)data->src & (ARCH_DMA_MINALIGN - 1))
-                       printf("Warning: unaligned write to %p may fail\n",
-                              data->src);
-               flush_dcache_range((ulong)data->src, (ulong)data->src +
-                       data->blocks * data->blocksize);
-       }
-
        writew(mode, &host->reg->trnmod);
 }
 
@@ -156,8 +152,8 @@ static int mmc_wait_inhibit(struct mmc_host *host,
        return 0;
 }
 
-static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
-                       struct mmc_data *data)
+static int mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd,
+                       struct mmc_data *data, struct bounce_buffer *bbstate)
 {
        struct mmc_host *host = (struct mmc_host *)mmc->priv;
        int flags, i;
@@ -172,7 +168,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                return result;
 
        if (data)
-               mmc_prepare_data(host, data);
+               mmc_prepare_data(host, data, bbstate);
 
        debug("cmd->arg: %08x\n", cmd->cmdarg);
        writel(cmd->cmdarg, &host->reg->argument);
@@ -322,20 +318,42 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                        }
                }
                writel(mask, &host->reg->norintsts);
-               if (data->flags & MMC_DATA_READ) {
-                       if ((uintptr_t)data->dest & (ARCH_DMA_MINALIGN - 1))
-                               printf("Warning: unaligned read from %p "
-                                       "may fail\n", data->dest);
-                       invalidate_dcache_range((ulong)data->dest,
-                               (ulong)data->dest +
-                                       data->blocks * data->blocksize);
-               }
        }
 
        udelay(1000);
        return 0;
 }
 
+static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+                       struct mmc_data *data)
+{
+       void *buf;
+       unsigned int bbflags;
+       size_t len;
+       struct bounce_buffer bbstate;
+       int ret;
+
+       if (data) {
+               if (data->flags & MMC_DATA_READ) {
+                       buf = data->dest;
+                       bbflags = GEN_BB_WRITE;
+               } else {
+                       buf = (void *)data->src;
+                       bbflags = GEN_BB_READ;
+               }
+               len = data->blocks * data->blocksize;
+
+               bounce_buffer_start(&bbstate, buf, len, bbflags);
+       }
+
+       ret = mmc_send_cmd_bounced(mmc, cmd, data, &bbstate);
+
+       if (data)
+               bounce_buffer_stop(&bbstate);
+
+       return ret;
+}
+
 static void mmc_change_clock(struct mmc_host *host, uint clock)
 {
        int div;
index beb99cacb6636291e4c91a65f79710214e31cb35..28e52bd08ea72153020584f63f4fa74497ed545d 100644 (file)
@@ -26,21 +26,33 @@ include $(TOPDIR)/config.mk
 LIB    := $(obj)libnand.o
 
 ifdef CONFIG_CMD_NAND
+
 ifdef CONFIG_SPL_BUILD
-ifdef CONFIG_SPL_NAND_SIMPLE
-COBJS-y += nand_spl_simple.o
-endif
-ifdef CONFIG_SPL_NAND_LOAD
-COBJS-y        += nand_spl_load.o
+
+ifdef CONFIG_SPL_NAND_DRIVERS
+NORMAL_DRIVERS=y
 endif
-else
+
+COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
+COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
+COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
+COBJS-$(CONFIG_SPL_NAND_BASE) += nand_base.o
+
+else # not spl
+
+NORMAL_DRIVERS=y
+
 COBJS-y += nand.o
 COBJS-y += nand_bbt.o
 COBJS-y += nand_ids.o
 COBJS-y += nand_util.o
-endif
 COBJS-y += nand_ecc.o
 COBJS-y += nand_base.o
+
+endif # not spl
+
+ifdef NORMAL_DRIVERS
+
 COBJS-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
 
 COBJS-$(CONFIG_NAND_ATMEL) += atmel_nand.o
@@ -65,7 +77,13 @@ COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
 COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
-endif
+
+else  # minimal SPL drivers
+
+COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
+
+endif # drivers
+endif # nand
 
 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
index 9076ad4cdc36ac517ef1658f91a0955c2223ab16..834a8a64983f35d01abdb1383cd928fbb155b6ff 100644 (file)
@@ -748,7 +748,7 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr)
 
        /* set up nand options */
        nand->options = NAND_NO_READRDY | NAND_NO_AUTOINCR |
-                       NAND_USE_FLASH_BBT;
+                       NAND_USE_FLASH_BBT | NAND_NO_SUBPAGE_WRITE;
 
        nand->controller = &elbc_ctrl->controller;
        nand->priv = priv;
diff --git a/drivers/mtd/nand/fsl_elbc_spl.c b/drivers/mtd/nand/fsl_elbc_spl.c
new file mode 100644 (file)
index 0000000..50ff4fe
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * NAND boot for Freescale Enhanced Local Bus Controller, Flash Control Machine
+ *
+ * (C) Copyright 2006-2008
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * Copyright (c) 2008 Freescale Semiconductor, Inc.
+ * Author: Scott Wood <scottwood@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/fsl_lbc.h>
+#include <nand.h>
+
+#define WINDOW_SIZE 8192
+
+static void nand_wait(void)
+{
+       fsl_lbc_t *regs = LBC_BASE_ADDR;
+
+       for (;;) {
+               uint32_t status = in_be32(&regs->ltesr);
+
+               if (status == 1)
+                       return;
+
+               if (status & 1) {
+                       puts("read failed (ltesr)\n");
+                       for (;;);
+               }
+       }
+}
+
+static int nand_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
+{
+       fsl_lbc_t *regs = LBC_BASE_ADDR;
+       uchar *buf = (uchar *)CONFIG_SYS_NAND_BASE;
+       const int large = CONFIG_SYS_NAND_OR_PRELIM & OR_FCM_PGS;
+       const int block_shift = large ? 17 : 14;
+       const int block_size = 1 << block_shift;
+       const int page_size = large ? 2048 : 512;
+       const int bad_marker = large ? page_size + 0 : page_size + 5;
+       int fmr = (15 << FMR_CWTO_SHIFT) | (2 << FMR_AL_SHIFT) | 2;
+       int pos = 0;
+       char *dst = vdst;
+
+       if (offs & (block_size - 1)) {
+               puts("bad offset\n");
+               for (;;);
+       }
+
+       if (large) {
+               fmr |= FMR_ECCM;
+               out_be32(&regs->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) |
+                                    (NAND_CMD_READSTART << FCR_CMD1_SHIFT));
+               out_be32(&regs->fir,
+                        (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+                        (FIR_OP_CA  << FIR_OP1_SHIFT) |
+                        (FIR_OP_PA  << FIR_OP2_SHIFT) |
+                        (FIR_OP_CW1 << FIR_OP3_SHIFT) |
+                        (FIR_OP_RBW << FIR_OP4_SHIFT));
+       } else {
+               out_be32(&regs->fcr, NAND_CMD_READ0 << FCR_CMD0_SHIFT);
+               out_be32(&regs->fir,
+                        (FIR_OP_CW0 << FIR_OP0_SHIFT) |
+                        (FIR_OP_CA  << FIR_OP1_SHIFT) |
+                        (FIR_OP_PA  << FIR_OP2_SHIFT) |
+                        (FIR_OP_RBW << FIR_OP3_SHIFT));
+       }
+
+       out_be32(&regs->fbcr, 0);
+       clrsetbits_be32(&regs->bank[0].br, BR_DECC, BR_DECC_CHK_GEN);
+
+       while (pos < uboot_size) {
+               int i = 0;
+               out_be32(&regs->fbar, offs >> block_shift);
+
+               do {
+                       int j;
+                       unsigned int page_offs = (offs & (block_size - 1)) << 1;
+
+                       out_be32(&regs->ltesr, ~0);
+                       out_be32(&regs->lteatr, 0);
+                       out_be32(&regs->fpar, page_offs);
+                       out_be32(&regs->fmr, fmr);
+                       out_be32(&regs->lsor, 0);
+                       nand_wait();
+
+                       page_offs %= WINDOW_SIZE;
+
+                       /*
+                        * If either of the first two pages are marked bad,
+                        * continue to the next block.
+                        */
+                       if (i++ < 2 && buf[page_offs + bad_marker] != 0xff) {
+                               puts("skipping\n");
+                               offs = (offs + block_size) & ~(block_size - 1);
+                               pos &= ~(block_size - 1);
+                               break;
+                       }
+
+                       for (j = 0; j < page_size; j++)
+                               dst[pos + j] = buf[page_offs + j];
+
+                       pos += page_size;
+                       offs += page_size;
+               } while ((offs & (block_size - 1)) && (pos < uboot_size));
+       }
+
+       return 0;
+}
+
+/*
+ * The main entry for NAND booting. It's necessary that SDRAM is already
+ * configured and available since this code loads the main U-Boot image
+ * from NAND into SDRAM and starts it from there.
+ */
+void nand_boot(void)
+{
+       __attribute__((noreturn)) void (*uboot)(void);
+       /*
+        * Load U-Boot image from NAND into RAM
+        */
+       nand_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+                       CONFIG_SYS_NAND_U_BOOT_SIZE,
+                       (void *)CONFIG_SYS_NAND_U_BOOT_DST);
+
+#ifdef CONFIG_NAND_ENV_DST
+       nand_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
+                       (void *)CONFIG_NAND_ENV_DST);
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+       nand_load_image(CONFIG_ENV_OFFSET_REDUND, CONFIG_ENV_SIZE,
+                       (void *)CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE);
+#endif
+#endif
+
+#ifdef CONFIG_SPL_FLUSH_IMAGE
+       /*
+        * Clean d-cache and invalidate i-cache, to
+        * make sure that no stale data is executed.
+        */
+       flush_cache(CONFIG_SYS_NAND_U_BOOT_DST, CONFIG_SYS_NAND_U_BOOT_SIZE);
+#endif
+
+       puts("transfering control\n");
+       /*
+        * Jump to U-Boot image
+        */
+       uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
+       (*uboot)();
+}
index b3b7c705e189a9fdfb61ba45c517d1de1fc03bed..0878bece675bd3267d044919dbf0c870d966042b 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/errno.h>
 #include <asm/fsl_ifc.h>
 
+#define FSL_IFC_V1_1_0 0x01010000
 #define MAX_BANKS      4
 #define ERR_BYTE       0xFF /* Value returned for read bytes
                                when read failed */
@@ -738,11 +739,66 @@ static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
 {
 }
 
+static void fsl_ifc_sram_init(void)
+{
+       struct fsl_ifc *ifc = ifc_ctrl->regs;
+       uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
+       long long end_tick;
+
+       cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT;
+
+       /* Save CSOR and CSOR_ext */
+       csor = in_be32(&ifc_ctrl->regs->csor_cs[cs].csor);
+       csor_ext = in_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext);
+
+       /* chage PageSize 8K and SpareSize 1K*/
+       csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
+       out_be32(&ifc_ctrl->regs->csor_cs[cs].csor, csor_8k);
+       out_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, 0x0000400);
+
+       /* READID */
+       out_be32(&ifc->ifc_nand.nand_fir0,
+                       (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) |
+                       (IFC_FIR_OP_UA  << IFC_NAND_FIR0_OP1_SHIFT) |
+                       (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT));
+       out_be32(&ifc->ifc_nand.nand_fcr0,
+                       NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT);
+       out_be32(&ifc->ifc_nand.row3, 0x0);
+
+       out_be32(&ifc->ifc_nand.nand_fbcr, 0x0);
+
+       /* Program ROW0/COL0 */
+       out_be32(&ifc->ifc_nand.row0, 0x0);
+       out_be32(&ifc->ifc_nand.col0, 0x0);
+
+       /* set the chip select for NAND Transaction */
+       out_be32(&ifc->ifc_nand.nand_csel, ifc_ctrl->cs_nand);
+
+       /* start read seq */
+       out_be32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
+
+       /* wait for NAND Machine complete flag or timeout */
+       end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
+
+       while (end_tick > get_ticks()) {
+               ifc_ctrl->status = in_be32(&ifc->ifc_nand.nand_evter_stat);
+
+               if (ifc_ctrl->status & IFC_NAND_EVTER_STAT_OPC)
+                       break;
+       }
+
+       out_be32(&ifc->ifc_nand.nand_evter_stat, ifc_ctrl->status);
+
+       /* Restore CSOR and CSOR_ext */
+       out_be32(&ifc_ctrl->regs->csor_cs[cs].csor, csor);
+       out_be32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, csor_ext);
+}
+
 int board_nand_init(struct nand_chip *nand)
 {
        struct fsl_ifc_mtd *priv;
        struct nand_ecclayout *layout;
-       uint32_t cspr = 0, csor = 0;
+       uint32_t cspr = 0, csor = 0, ver = 0;
 
        if (!ifc_ctrl) {
                fsl_ifc_ctrl_init();
@@ -797,7 +853,7 @@ int board_nand_init(struct nand_chip *nand)
 
        /* set up nand options */
        nand->options = NAND_NO_READRDY | NAND_NO_AUTOINCR |
-                       NAND_USE_FLASH_BBT;
+                       NAND_USE_FLASH_BBT | NAND_NO_SUBPAGE_WRITE;
 
        if (cspr & CSPR_PORT_SIZE_16) {
                nand->read_byte = fsl_ifc_read_byte16;
@@ -861,5 +917,9 @@ int board_nand_init(struct nand_chip *nand)
                nand->ecc.mode = NAND_ECC_SOFT;
        }
 
+       ver = in_be32(&ifc_ctrl->regs->ifc_rev);
+       if (ver == FSL_IFC_V1_1_0)
+               fsl_ifc_sram_init();
+
        return 0;
 }
index d3b71a50adc00303e8c4d598da15b116d954fdf5..a2d06be99fcf4f3f0882671a514b36b4afecb7a3 100644 (file)
@@ -1245,7 +1245,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                        if (unlikely(ops->mode == MTD_OOB_RAW))
                                ret = chip->ecc.read_page_raw(mtd, chip,
                                                              bufpoi, page);
-                       else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
+                       else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
+                           !oob)
                                ret = chip->ecc.read_subpage(mtd, chip,
                                                        col, bytes, bufpoi);
                        else
@@ -1256,7 +1257,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 
                        /* Transfer not aligned data */
                        if (!aligned) {
-                               if (!NAND_SUBPAGE_READ(chip) && !oob &&
+                               if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
                                    !(mtd->ecc_stats.failed - stats.failed))
                                        chip->pagebuf = realpage;
                                memcpy(buf, chip->buffers->databuf + col, bytes);
@@ -3150,6 +3151,10 @@ int nand_scan_tail(struct mtd_info *mtd)
        /* Invalidate the pagebuffer reference */
        chip->pagebuf = -1;
 
+       /* Large page NAND with SOFT_ECC should support subpage reads */
+       if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
+               chip->options |= NAND_SUBPAGE_READ;
+
        /* Fill in remaining MTD driver data */
        mtd->type = MTD_NANDFLASH;
        mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
index c4752a7cbf8ad0eca0f717522cb5ce919acc6919..2ba0c5ef95604a32859e959822168a46f310c524 100644 (file)
@@ -50,8 +50,8 @@
 #include <nand.h>
 #include <jffs2/jffs2.h>
 
-typedef struct erase_info erase_info_t;
-typedef struct mtd_info          mtd_info_t;
+typedef struct erase_info      erase_info_t;
+typedef struct mtd_info                mtd_info_t;
 
 /* support only for native endian JFFS2 */
 #define cpu_to_je16(x) (x)
@@ -59,7 +59,7 @@ typedef struct mtd_info         mtd_info_t;
 
 /**
  * nand_erase_opts: - erase NAND flash with support for various options
- *                   (jffs2 formating)
+ *                   (jffs2 formatting)
  *
  * @param meminfo      NAND device to erase
  * @param opts         options,  @see struct nand_erase_options
@@ -80,8 +80,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
        struct mtd_oob_ops oob_opts;
        struct nand_chip *chip = meminfo->priv;
 
-       if ((opts->offset & (meminfo->writesize - 1)) != 0) {
-               printf("Attempt to erase non page aligned data\n");
+       if ((opts->offset & (meminfo->erasesize - 1)) != 0) {
+               printf("Attempt to erase non block-aligned data\n");
                return -1;
        }
 
@@ -94,8 +94,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
        erase_length = lldiv(opts->length + meminfo->erasesize - 1,
                             meminfo->erasesize);
 
-       cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
-       cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
+       cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+       cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
        cleanmarker.totlen = cpu_to_je32(8);
 
        /* scrub option allows to erase badblock. To prevent internal
@@ -118,7 +118,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
             erased_length < erase_length;
             erase.addr += meminfo->erasesize) {
 
-               WATCHDOG_RESET ();
+               WATCHDOG_RESET();
 
                if (!opts->scrub && bbtest) {
                        int ret = meminfo->block_isbad(meminfo, erase.addr);
@@ -259,7 +259,7 @@ int nand_lock(struct mtd_info *mtd, int tight)
  *                        flash
  *
  * @param mtd          nand mtd instance
- * @param offset       page address to query (muss be page aligned!)
+ * @param offset       page address to query (must be page-aligned!)
  *
  * @return             -1 in case of error
  *                     >0 lock status:
@@ -281,7 +281,7 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset)
 
 
        if ((offset & (mtd->writesize - 1)) != 0) {
-               printf ("nand_get_lock_status: "
+               printf("nand_get_lock_status: "
                        "Start address must be beginning of "
                        "nand page!\n");
                ret = -1;
@@ -332,20 +332,20 @@ int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length,
        /* check the WP bit */
        chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
        if (!(chip->read_byte(mtd) & NAND_STATUS_WP)) {
-               printf ("nand_unlock: Device is write protected!\n");
+               printf("nand_unlock: Device is write protected!\n");
                ret = -1;
                goto out;
        }
 
        if ((start & (mtd->erasesize - 1)) != 0) {
-               printf ("nand_unlock: Start address must be beginning of "
+               printf("nand_unlock: Start address must be beginning of "
                        "nand block!\n");
                ret = -1;
                goto out;
        }
 
        if (length == 0 || (length & (mtd->erasesize - 1)) != 0) {
-               printf ("nand_unlock: Length must be a multiple of nand block "
+               printf("nand_unlock: Length must be a multiple of nand block "
                        "size %08x!\n", mtd->erasesize);
                ret = -1;
                goto out;
@@ -485,7 +485,7 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
                pages = nand->erasesize / nand->writesize;
                blocksize = (pages * nand->oobsize) + nand->erasesize;
                if (*length % (nand->writesize + nand->oobsize)) {
-                       printf ("Attempt to write incomplete page"
+                       printf("Attempt to write incomplete page"
                                " in yaffs mode\n");
                        return -EINVAL;
                }
@@ -507,25 +507,25 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
         * partition boundary).  So don't try to handle that.
         */
        if ((offset & (nand->writesize - 1)) != 0) {
-               printf ("Attempt to write non page aligned data\n");
+               printf("Attempt to write non page-aligned data\n");
                *length = 0;
                return -EINVAL;
        }
 
        need_skip = check_skip_len(nand, offset, *length);
        if (need_skip < 0) {
-               printf ("Attempt to write outside the flash area\n");
+               printf("Attempt to write outside the flash area\n");
                *length = 0;
                return -EINVAL;
        }
 
        if (!need_skip && !(flags & WITH_DROP_FFS)) {
-               rval = nand_write (nand, offset, length, buffer);
+               rval = nand_write(nand, offset, length, buffer);
                if (rval == 0)
                        return 0;
 
                *length = 0;
-               printf ("NAND write to offset %llx failed %d\n",
+               printf("NAND write to offset %llx failed %d\n",
                        offset, rval);
                return rval;
        }
@@ -534,10 +534,10 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
                size_t block_offset = offset & (nand->erasesize - 1);
                size_t write_size, truncated_write_size;
 
-               WATCHDOG_RESET ();
+               WATCHDOG_RESET();
 
-               if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
-                       printf ("Skip bad block 0x%08llx\n",
+               if (nand_block_isbad(nand, offset & ~(nand->erasesize - 1))) {
+                       printf("Skip bad block 0x%08llx\n",
                                offset & ~(nand->erasesize - 1));
                        offset += nand->erasesize - block_offset;
                        continue;
@@ -592,7 +592,7 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
                }
 
                if (rval != 0) {
-                       printf ("NAND write to offset %llx failed %d\n",
+                       printf("NAND write to offset %llx failed %d\n",
                                offset, rval);
                        *length -= left_to_write;
                        return rval;
@@ -608,13 +608,13 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
  * nand_read_skip_bad:
  *
  * Read image from NAND flash.
- * Blocks that are marked bad are skipped and the next block is readen
+ * Blocks that are marked bad are skipped and the next block is read
  * instead as long as the image is short enough to fit even after skipping the
  * bad blocks.
  *
  * @param nand NAND device
  * @param offset offset in flash
- * @param length buffer length, on return holds remaining bytes to read
+ * @param length buffer length, on return holds number of read bytes
  * @param buffer buffer to write to
  * @return 0 in case of success
  */
@@ -627,25 +627,25 @@ int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
        int need_skip;
 
        if ((offset & (nand->writesize - 1)) != 0) {
-               printf ("Attempt to read non page aligned data\n");
+               printf("Attempt to read non page-aligned data\n");
                *length = 0;
                return -EINVAL;
        }
 
        need_skip = check_skip_len(nand, offset, *length);
        if (need_skip < 0) {
-               printf ("Attempt to read outside the flash area\n");
+               printf("Attempt to read outside the flash area\n");
                *length = 0;
                return -EINVAL;
        }
 
        if (!need_skip) {
-               rval = nand_read (nand, offset, length, buffer);
+               rval = nand_read(nand, offset, length, buffer);
                if (!rval || rval == -EUCLEAN)
                        return 0;
 
                *length = 0;
-               printf ("NAND read from offset %llx failed %d\n",
+               printf("NAND read from offset %llx failed %d\n",
                        offset, rval);
                return rval;
        }
@@ -654,10 +654,10 @@ int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
                size_t block_offset = offset & (nand->erasesize - 1);
                size_t read_length;
 
-               WATCHDOG_RESET ();
+               WATCHDOG_RESET();
 
-               if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
-                       printf ("Skipping bad block 0x%08llx\n",
+               if (nand_block_isbad(nand, offset & ~(nand->erasesize - 1))) {
+                       printf("Skipping bad block 0x%08llx\n",
                                offset & ~(nand->erasesize - 1));
                        offset += nand->erasesize - block_offset;
                        continue;
@@ -668,9 +668,9 @@ int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
                else
                        read_length = nand->erasesize - block_offset;
 
-               rval = nand_read (nand, offset, &read_length, p_buffer);
+               rval = nand_read(nand, offset, &read_length, p_buffer);
                if (rval && rval != -EUCLEAN) {
-                       printf ("NAND read from offset %llx failed %d\n",
+                       printf("NAND read from offset %llx failed %d\n",
                                offset, rval);
                        *length -= left_to_read;
                        return rval;
@@ -683,3 +683,125 @@ int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 
        return 0;
 }
+
+#ifdef CONFIG_CMD_NAND_TORTURE
+
+/**
+ * check_pattern:
+ *
+ * Check if buffer contains only a certain byte pattern.
+ *
+ * @param buf buffer to check
+ * @param patt the pattern to check
+ * @param size buffer size in bytes
+ * @return 1 if there are only patt bytes in buf
+ *         0 if something else was found
+ */
+static int check_pattern(const u_char *buf, u_char patt, int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++)
+               if (buf[i] != patt)
+                       return 0;
+       return 1;
+}
+
+/**
+ * nand_torture:
+ *
+ * Torture a block of NAND flash.
+ * This is useful to determine if a block that caused a write error is still
+ * good or should be marked as bad.
+ *
+ * @param nand NAND device
+ * @param offset offset in flash
+ * @return 0 if the block is still good
+ */
+int nand_torture(nand_info_t *nand, loff_t offset)
+{
+       u_char patterns[] = {0xa5, 0x5a, 0x00};
+       struct erase_info instr = {
+               .mtd = nand,
+               .addr = offset,
+               .len = nand->erasesize,
+       };
+       size_t retlen;
+       int err, ret = -1, i, patt_count;
+       u_char *buf;
+
+       if ((offset & (nand->erasesize - 1)) != 0) {
+               puts("Attempt to torture a block at a non block-aligned offset\n");
+               return -EINVAL;
+       }
+
+       if (offset + nand->erasesize > nand->size) {
+               puts("Attempt to torture a block outside the flash area\n");
+               return -EINVAL;
+       }
+
+       patt_count = ARRAY_SIZE(patterns);
+
+       buf = malloc(nand->erasesize);
+       if (buf == NULL) {
+               puts("Out of memory for erase block buffer\n");
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < patt_count; i++) {
+               err = nand->erase(nand, &instr);
+               if (err) {
+                       printf("%s: erase() failed for block at 0x%llx: %d\n",
+                               nand->name, instr.addr, err);
+                       goto out;
+               }
+
+               /* Make sure the block contains only 0xff bytes */
+               err = nand->read(nand, offset, nand->erasesize, &retlen, buf);
+               if ((err && err != -EUCLEAN) || retlen != nand->erasesize) {
+                       printf("%s: read() failed for block at 0x%llx: %d\n",
+                               nand->name, instr.addr, err);
+                       goto out;
+               }
+
+               err = check_pattern(buf, 0xff, nand->erasesize);
+               if (!err) {
+                       printf("Erased block at 0x%llx, but a non-0xff byte was found\n",
+                               offset);
+                       ret = -EIO;
+                       goto out;
+               }
+
+               /* Write a pattern and check it */
+               memset(buf, patterns[i], nand->erasesize);
+               err = nand->write(nand, offset, nand->erasesize, &retlen, buf);
+               if (err || retlen != nand->erasesize) {
+                       printf("%s: write() failed for block at 0x%llx: %d\n",
+                               nand->name, instr.addr, err);
+                       goto out;
+               }
+
+               err = nand->read(nand, offset, nand->erasesize, &retlen, buf);
+               if ((err && err != -EUCLEAN) || retlen != nand->erasesize) {
+                       printf("%s: read() failed for block at 0x%llx: %d\n",
+                               nand->name, instr.addr, err);
+                       goto out;
+               }
+
+               err = check_pattern(buf, patterns[i], nand->erasesize);
+               if (!err) {
+                       printf("Pattern 0x%.2x checking failed for block at "
+                                       "0x%llx\n", patterns[i], offset);
+                       ret = -EIO;
+                       goto out;
+               }
+       }
+
+       ret = 0;
+
+out:
+       free(buf);
+       return ret;
+}
+
+#endif
index 7a1fcdd81fbe4009dad08f373feb27672e6542f6..7fbb50a562347ab5bca287979c681414d667bcf6 100644 (file)
@@ -44,6 +44,7 @@ COBJS-$(CONFIG_PPC_P2041) += p5020.o
 COBJS-$(CONFIG_PPC_P3041) += p5020.o
 COBJS-$(CONFIG_PPC_P4080) += p4080.o
 COBJS-$(CONFIG_PPC_P5020) += p5020.o
+COBJS-$(CONFIG_PPC_P5040) += p5040.o
 COBJS-$(CONFIG_PPC_T4240) += t4240.o
 COBJS-$(CONFIG_PPC_B4860) += b4860.o
 endif
diff --git a/drivers/net/fm/p5040.c b/drivers/net/fm/p5040.c
new file mode 100644 (file)
index 0000000..bc6b4ba
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+u32 port_to_devdisr[] = {
+       [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
+       [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
+       [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
+       [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4,
+       [FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5,
+       [FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1,
+       [FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1,
+       [FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2,
+       [FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3,
+       [FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4,
+       [FM2_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC2_5,
+       [FM2_10GEC1] = FSL_CORENET_DEVDISR2_10GEC2,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+       ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       u32 devdisr2 = in_be32(&gur->devdisr2);
+
+       return port_to_devdisr[port] & devdisr2;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+       ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+       /* don't allow disabling of DTSEC1 as its needed for MDIO */
+       if (port == FM1_DTSEC1)
+               return;
+
+       setbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+       ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       u32 rcwsr11 = in_be32(&gur->rcwsr[11]);
+
+       if (is_device_disabled(port))
+               return PHY_INTERFACE_MODE_NONE;
+
+       if ((port == FM1_10GEC1) && (is_serdes_configured(XAUI_FM1)))
+               return PHY_INTERFACE_MODE_XGMII;
+
+       if ((port == FM2_10GEC1) && (is_serdes_configured(XAUI_FM2)))
+               return PHY_INTERFACE_MODE_XGMII;
+
+       /* handle RGMII first */
+       if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) ==
+               FSL_CORENET_RCWSR11_EC1_FM1_DTSEC5_RGMII))
+               return PHY_INTERFACE_MODE_RGMII;
+
+       if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) ==
+               FSL_CORENET_RCWSR11_EC1_FM1_DTSEC5_MII))
+               return PHY_INTERFACE_MODE_MII;
+
+       if ((port == FM2_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+               FSL_CORENET_RCWSR11_EC2_FM2_DTSEC5_RGMII))
+               return PHY_INTERFACE_MODE_RGMII;
+
+       if ((port == FM2_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+               FSL_CORENET_RCWSR11_EC2_FM2_DTSEC5_MII))
+               return PHY_INTERFACE_MODE_MII;
+
+       switch (port) {
+       case FM1_DTSEC1:
+       case FM1_DTSEC2:
+       case FM1_DTSEC3:
+       case FM1_DTSEC4:
+       case FM1_DTSEC5:
+               if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1))
+                       return PHY_INTERFACE_MODE_SGMII;
+               break;
+       case FM2_DTSEC1:
+       case FM2_DTSEC2:
+       case FM2_DTSEC3:
+       case FM2_DTSEC4:
+       case FM2_DTSEC5:
+               if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1))
+                       return PHY_INTERFACE_MODE_SGMII;
+               break;
+       default:
+               return PHY_INTERFACE_MODE_NONE;
+       }
+
+       return PHY_INTERFACE_MODE_NONE;
+}
index 48ae16374dc5c8cfa0391ebdd927c69abb5ee0a9..77ac1f7c7b9a1a8452c064dc6abfd39fb3785ec8 100644 (file)
@@ -470,6 +470,28 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info)
                }
 #endif
 
+#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
+               if (enabled == 0) {
+                       serdes_corenet_t *srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
+                       temp32 = in_be32(&srds_regs->srdspccr0);
+
+                       if ((temp32 >> 28) == 3) {
+                               int i;
+
+                               out_be32(&srds_regs->srdspccr0, 2 << 28);
+                               setbits_be32(&pci->pdb_stat, 0x08000000);
+                               in_be32(&pci->pdb_stat);
+                               udelay(100);
+                               clrbits_be32(&pci->pdb_stat, 0x08000000);
+                               asm("sync;isync");
+                               for (i=0; i < 100 && ltssm < PCI_LTSSM_L0; i++) {
+                                       pci_hose_read_config_word(hose, dev, PCI_LTSSM, &ltssm);
+                                       udelay(1000);
+                               }
+                               enabled = ltssm >= PCI_LTSSM_L0;
+                       }
+               }
+#endif
                if (!enabled) {
                        /* Let the user know there's no PCIe link */
                        printf("no link, regs @ 0x%lx\n", pci_info->regs);
index 6bf388cb7d59036fd2922eb51dd89d09328af05d..8c7190156c302b60b9f5b8601bc7e4e7a0594b73 100644 (file)
@@ -23,7 +23,7 @@
 
 include $(TOPDIR)/config.mk
 
-LIB    := $(obj)libpower.o
+LIB    := $(obj)libpower.o
 
 COBJS-$(CONFIG_FTPMU010_POWER) += ftpmu010.o
 COBJS-$(CONFIG_TPS6586X_POWER) += tps6586x.o
@@ -31,9 +31,15 @@ COBJS-$(CONFIG_TWL4030_POWER)        += twl4030.o
 COBJS-$(CONFIG_TWL6030_POWER)  += twl6030.o
 COBJS-$(CONFIG_TWL6035_POWER)  += twl6035.o
 
+COBJS-$(CONFIG_POWER) += power_core.o
+COBJS-$(CONFIG_DIALOG_POWER) += power_dialog.o
+COBJS-$(CONFIG_POWER_FSL) += power_fsl.o
+COBJS-$(CONFIG_POWER_I2C) += power_i2c.o
+COBJS-$(CONFIG_POWER_SPI) += power_spi.o
+
 COBJS  := $(COBJS-y)
-SRCS   := $(COBJS:.o=.c)
-OBJS   := $(addprefix $(obj),$(COBJS))
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
 
 all:   $(LIB)
 
diff --git a/drivers/power/battery/Makefile b/drivers/power/battery/Makefile
new file mode 100644 (file)
index 0000000..b176701
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2012 Samsung Electronics
+# Lukasz Majewski <l.majewski@samsung.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libbattery.o
+
+COBJS-$(CONFIG_POWER_BATTERY_TRATS) += bat_trats.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
+
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+########################################################################
diff --git a/drivers/power/battery/bat_trats.c b/drivers/power/battery/bat_trats.c
new file mode 100644 (file)
index 0000000..ca0d214
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <power/pmic.h>
+#include <power/battery.h>
+#include <power/max8997_pmic.h>
+#include <errno.h>
+
+static struct battery battery_trats;
+
+static int power_battery_charge(struct pmic *bat)
+{
+       struct power_battery *p_bat = bat->pbat;
+       struct battery *battery = p_bat->bat;
+       int k;
+
+       if (bat->chrg->chrg_state(p_bat->chrg, CHARGER_ENABLE, 450))
+               return -1;
+
+       for (k = 0; bat->chrg->chrg_bat_present(p_bat->chrg) &&
+                    bat->chrg->chrg_type(p_bat->muic) &&
+                    battery->state_of_chrg < 100; k++) {
+               udelay(10000000);
+               puts(".");
+               bat->fg->fg_battery_update(p_bat->fg, bat);
+
+               if (k == 100) {
+                       debug(" %d [V]", battery->voltage_uV);
+                       puts("\n");
+                       k = 0;
+               }
+
+       }
+
+       bat->chrg->chrg_state(p_bat->chrg, CHARGER_DISABLE, 0);
+
+       return 0;
+}
+
+static int power_battery_init_trats(struct pmic *bat_,
+                                   struct pmic *fg_,
+                                   struct pmic *chrg_,
+                                   struct pmic *muic_)
+{
+       bat_->pbat->fg = fg_;
+       bat_->pbat->chrg = chrg_;
+       bat_->pbat->muic = muic_;
+
+       bat_->fg = fg_->fg;
+       bat_->chrg = chrg_->chrg;
+       bat_->chrg->chrg_type = muic_->chrg->chrg_type;
+       return 0;
+}
+
+static struct power_battery power_bat_trats = {
+       .bat = &battery_trats,
+       .battery_init = power_battery_init_trats,
+       .battery_charge = power_battery_charge,
+};
+
+int power_bat_init(unsigned char bus)
+{
+       static const char name[] = "BAT_TRATS";
+       struct pmic *p = pmic_alloc();
+
+       if (!p) {
+               printf("%s: POWER allocation error!\n", __func__);
+               return -ENOMEM;
+       }
+
+       debug("Board BAT init\n");
+
+       p->interface = PMIC_NONE;
+       p->name = name;
+       p->bus = bus;
+
+       p->pbat = &power_bat_trats;
+       return 0;
+}
diff --git a/drivers/power/fuel_gauge/Makefile b/drivers/power/fuel_gauge/Makefile
new file mode 100644 (file)
index 0000000..da15414
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2012 Samsung Electronics
+# Lukasz Majewski <l.majewski@samsung.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libfuel_gauge.o
+
+COBJS-$(CONFIG_POWER_FG_MAX17042) += fg_max17042.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
+
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+########################################################################
diff --git a/drivers/power/fuel_gauge/fg_max17042.c b/drivers/power/fuel_gauge/fg_max17042.c
new file mode 100644 (file)
index 0000000..9b7c184
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <power/pmic.h>
+#include <power/max17042_fg.h>
+#include <i2c.h>
+#include <power/max8997_pmic.h>
+#include <power/power_chrg.h>
+#include <power/battery.h>
+#include <power/fg_battery_cell_params.h>
+#include <errno.h>
+
+static int fg_write_regs(struct pmic *p, u8 addr, u16 *data, int num)
+{
+       int ret = 0;
+       int i;
+
+       for (i = 0; i < num; i++, addr++)
+               ret |= pmic_reg_write(p, addr, *(data + i));
+
+       return ret;
+}
+
+static int fg_read_regs(struct pmic *p, u8 addr, u16 *data, int num)
+{
+       int ret = 0;
+       int i;
+
+       for (i = 0; i < num; i++, addr++)
+               ret |= pmic_reg_read(p, addr, (u32 *) (data + i));
+
+       return ret;
+}
+
+static int fg_write_and_verify(struct pmic *p, u8 addr, u16 data)
+{
+       unsigned int val = data;
+       int ret = 0;
+
+       ret |= pmic_reg_write(p, addr, val);
+       ret |= pmic_reg_read(p, addr, &val);
+
+       if (ret)
+               return ret;
+
+       if (((u16) val) == data)
+               return 0;
+
+       return -1;
+}
+
+static void por_fuelgauge_init(struct pmic *p)
+{
+       u16 r_data0[16], r_data1[16], r_data2[16];
+       u32 rewrite_count = 5, i = 0;
+       unsigned int val;
+       int ret = 0;
+
+       /* Delay 500 ms */
+       mdelay(500);
+       /* Initilize Configuration */
+       pmic_reg_write(p, MAX17042_CONFIG, 0x2310);
+
+rewrite_model:
+       /* Unlock Model Access */
+       pmic_reg_write(p, MAX17042_MLOCKReg1, MODEL_UNLOCK1);
+       pmic_reg_write(p, MAX17042_MLOCKReg2, MODEL_UNLOCK2);
+
+       /* Write/Read/Verify the Custom Model */
+       ret |= fg_write_regs(p, MAX17042_MODEL1, cell_character0,
+                            ARRAY_SIZE(cell_character0));
+       ret |= fg_write_regs(p, MAX17042_MODEL2, cell_character1,
+                            ARRAY_SIZE(cell_character1));
+       ret |= fg_write_regs(p, MAX17042_MODEL3, cell_character2,
+                            ARRAY_SIZE(cell_character2));
+
+       if (ret) {
+               printf("%s: Cell parameters write failed!\n", __func__);
+               return;
+       }
+
+       ret |= fg_read_regs(p, MAX17042_MODEL1, r_data0, ARRAY_SIZE(r_data0));
+       ret |= fg_read_regs(p, MAX17042_MODEL2, r_data1, ARRAY_SIZE(r_data1));
+       ret |= fg_read_regs(p, MAX17042_MODEL3, r_data2, ARRAY_SIZE(r_data2));
+
+       if (ret)
+               printf("%s: Cell parameters read failed!\n", __func__);
+
+       for (i = 0; i < 16; i++) {
+               if ((cell_character0[i] != r_data0[i])
+                   || (cell_character1[i] != r_data1[i])
+                   || (cell_character2[i] != r_data2[i]))
+                       goto rewrite_model;
+               }
+
+       /* Lock model access */
+       pmic_reg_write(p, MAX17042_MLOCKReg1, MODEL_LOCK1);
+       pmic_reg_write(p, MAX17042_MLOCKReg2, MODEL_LOCK2);
+
+       /* Verify the model access is locked */
+       ret |= fg_read_regs(p, MAX17042_MODEL1, r_data0, ARRAY_SIZE(r_data0));
+       ret |= fg_read_regs(p, MAX17042_MODEL2, r_data1, ARRAY_SIZE(r_data1));
+       ret |= fg_read_regs(p, MAX17042_MODEL3, r_data2, ARRAY_SIZE(r_data2));
+
+       if (ret) {
+               printf("%s: Cell parameters read failed!\n", __func__);
+               return;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(r_data0); i++) {
+               /* Check if model locked */
+               if (r_data0[i] || r_data1[i] || r_data2[i]) {
+                       /* Rewrite model data - prevent from endless loop */
+                       if (rewrite_count--) {
+                               puts("FG - Lock model access failed!\n");
+                               goto rewrite_model;
+                       }
+               }
+       }
+
+       /* Write Custom Parameters */
+       fg_write_and_verify(p, MAX17042_RCOMP0, RCOMP0);
+       fg_write_and_verify(p, MAX17042_TEMPCO, TempCo);
+
+       /* Delay at least 350mS */
+       mdelay(350);
+
+       /* Initialization Complete */
+       pmic_reg_read(p, MAX17042_STATUS, &val);
+       /* Write and Verify Status with POR bit Cleared */
+       fg_write_and_verify(p, MAX17042_STATUS, val & ~MAX17042_POR);
+
+       /* Delay at least 350 ms */
+       mdelay(350);
+}
+
+static int power_update_battery(struct pmic *p, struct pmic *bat)
+{
+       struct power_battery *pb = bat->pbat;
+       unsigned int val;
+       int ret = 0;
+
+       if (pmic_probe(p)) {
+               puts("Can't find max17042 fuel gauge\n");
+               return -1;
+       }
+
+       ret |= pmic_reg_read(p, MAX17042_VFSOC, &val);
+       pb->bat->state_of_chrg = (val >> 8);
+
+       pmic_reg_read(p, MAX17042_VCELL, &val);
+       debug("vfsoc: 0x%x\n", val);
+       pb->bat->voltage_uV = ((val & 0xFFUL) >> 3) + ((val & 0xFF00) >> 3);
+       pb->bat->voltage_uV = (pb->bat->voltage_uV * 625);
+
+       pmic_reg_read(p, 0x05, &val);
+       pb->bat->capacity = val >> 2;
+
+       return ret;
+}
+
+static int power_check_battery(struct pmic *p, struct pmic *bat)
+{
+       struct power_battery *pb = bat->pbat;
+       unsigned int val;
+       int ret = 0;
+
+       if (pmic_probe(p)) {
+               puts("Can't find max17042 fuel gauge\n");
+               return -1;
+       }
+
+       ret |= pmic_reg_read(p, MAX17042_STATUS, &val);
+       debug("fg status: 0x%x\n", val);
+
+       if (val == MAX17042_POR)
+               por_fuelgauge_init(p);
+
+       ret |= pmic_reg_read(p, MAX17042_VERSION, &val);
+       pb->bat->version = val;
+
+       power_update_battery(p, bat);
+       debug("fg ver: 0x%x\n", pb->bat->version);
+       printf("BAT: state_of_charge(SOC):%d%%\n",
+              pb->bat->state_of_chrg);
+
+       printf("     voltage: %d.%6.6d [V] (expected to be %d [mAh])\n",
+              pb->bat->voltage_uV / 1000000,
+              pb->bat->voltage_uV % 1000000,
+              pb->bat->capacity);
+
+       if (pb->bat->voltage_uV > 3850000)
+               pb->bat->state = EXT_SOURCE;
+       else if (pb->bat->voltage_uV < 3600000 || pb->bat->state_of_chrg < 5)
+               pb->bat->state = CHARGE;
+       else
+               pb->bat->state = NORMAL;
+
+       return ret;
+}
+
+static struct power_fg power_fg_ops = {
+       .fg_battery_check = power_check_battery,
+       .fg_battery_update = power_update_battery,
+};
+
+int power_fg_init(unsigned char bus)
+{
+       static const char name[] = "MAX17042_FG";
+       struct pmic *p = pmic_alloc();
+
+       if (!p) {
+               printf("%s: POWER allocation error!\n", __func__);
+               return -ENOMEM;
+       }
+
+       debug("Board Fuel Gauge init\n");
+
+       p->name = name;
+       p->interface = PMIC_I2C;
+       p->number_of_regs = FG_NUM_OF_REGS;
+       p->hw.i2c.addr = MAX17042_I2C_ADDR;
+       p->hw.i2c.tx_num = 2;
+       p->sensor_byte_order = PMIC_SENSOR_BYTE_ORDER_BIG;
+       p->bus = bus;
+
+       p->fg = &power_fg_ops;
+       return 0;
+}
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
new file mode 100644 (file)
index 0000000..e19a9a8
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2012 Samsung Electronics
+# Lukasz Majewski <l.majewski@samsung.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libpmic.o
+
+COBJS-$(CONFIG_POWER_MAX8998) += pmic_max8998.o
+COBJS-$(CONFIG_POWER_MAX8997) += pmic_max8997.o
+COBJS-$(CONFIG_POWER_MUIC_MAX8997) += muic_max8997.o
+
+COBJS  := $(COBJS-y)
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
+
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+########################################################################
diff --git a/drivers/power/pmic/muic_max8997.c b/drivers/power/pmic/muic_max8997.c
new file mode 100644 (file)
index 0000000..d5095c8
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <power/pmic.h>
+#include <power/power_chrg.h>
+#include <power/max8997_muic.h>
+#include <i2c.h>
+#include <errno.h>
+
+static int power_chrg_get_type(struct pmic *p)
+{
+       unsigned int val;
+       unsigned char charge_type, charger;
+
+       if (pmic_probe(p))
+               return CHARGER_NO;
+
+       pmic_reg_read(p, MAX8997_MUIC_STATUS2, &val);
+       charge_type = val & MAX8997_MUIC_CHG_MASK;
+
+       switch (charge_type) {
+       case MAX8997_MUIC_CHG_NO:
+               charger = CHARGER_NO;
+               break;
+       case MAX8997_MUIC_CHG_USB:
+       case MAX8997_MUIC_CHG_USB_D:
+               charger = CHARGER_USB;
+               break;
+       case MAX8997_MUIC_CHG_TA:
+       case MAX8997_MUIC_CHG_TA_1A:
+               charger = CHARGER_TA;
+               break;
+       case MAX8997_MUIC_CHG_TA_500:
+               charger = CHARGER_TA_500;
+               break;
+       default:
+               charger = CHARGER_UNKNOWN;
+               break;
+       }
+
+       return charger;
+}
+
+static struct power_chrg power_chrg_muic_ops = {
+       .chrg_type = power_chrg_get_type,
+};
+
+int power_muic_init(unsigned int bus)
+{
+       static const char name[] = "MAX8997_MUIC";
+       struct pmic *p = pmic_alloc();
+
+       if (!p) {
+               printf("%s: POWER allocation error!\n", __func__);
+               return -ENOMEM;
+       }
+
+       debug("Board Micro USB Interface Controller init\n");
+
+       p->name = name;
+       p->interface = PMIC_I2C;
+       p->number_of_regs = MUIC_NUM_OF_REGS;
+       p->hw.i2c.addr = MAX8997_MUIC_I2C_ADDR;
+       p->hw.i2c.tx_num = 1;
+       p->bus = bus;
+
+       p->chrg = &power_chrg_muic_ops;
+       return 0;
+}
diff --git a/drivers/power/pmic/pmic_max8997.c b/drivers/power/pmic/pmic_max8997.c
new file mode 100644 (file)
index 0000000..4e5c6d6
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <power/pmic.h>
+#include <power/max8997_pmic.h>
+#include <i2c.h>
+#include <errno.h>
+
+unsigned char max8997_reg_ldo(int uV)
+{
+       unsigned char ret;
+       if (uV <= 800000)
+               return 0;
+       if (uV >= 3950000)
+               return MAX8997_LDO_MAX_VAL;
+       ret = (uV - 800000) / 50000;
+       if (ret > MAX8997_LDO_MAX_VAL) {
+               printf("MAX8997 LDO SETTING ERROR (%duV) -> %u\n", uV, ret);
+               ret = MAX8997_LDO_MAX_VAL;
+       }
+
+       return ret;
+}
+
+static int pmic_charger_state(struct pmic *p, int state, int current)
+{
+       unsigned char fc;
+       u32 val = 0;
+
+       if (pmic_probe(p))
+               return -1;
+
+       if (state == CHARGER_DISABLE) {
+               puts("Disable the charger.\n");
+               pmic_reg_read(p, MAX8997_REG_MBCCTRL2, &val);
+               val &= ~(MBCHOSTEN | VCHGR_FC);
+               pmic_reg_write(p, MAX8997_REG_MBCCTRL2, val);
+
+               return -1;
+       }
+
+       if (current < CHARGER_MIN_CURRENT || current > CHARGER_MAX_CURRENT) {
+               printf("%s: Wrong charge current: %d [mA]\n",
+                      __func__, current);
+               return -1;
+       }
+
+       fc = (current - CHARGER_MIN_CURRENT) / CHARGER_CURRENT_RESOLUTION;
+       fc = fc & 0xf; /* up to 950 mA */
+
+       printf("Enable the charger @ %d [mA]\n", fc * CHARGER_CURRENT_RESOLUTION
+              + CHARGER_MIN_CURRENT);
+
+       val = fc | MBCICHFCSET;
+       pmic_reg_write(p, MAX8997_REG_MBCCTRL4, val);
+
+       pmic_reg_read(p, MAX8997_REG_MBCCTRL2, &val);
+       val = MBCHOSTEN | VCHGR_FC; /* enable charger & fast charge */
+       pmic_reg_write(p, MAX8997_REG_MBCCTRL2, val);
+
+       return 0;
+}
+
+static int pmic_charger_bat_present(struct pmic *p)
+{
+       u32 val;
+
+       if (pmic_probe(p))
+               return -1;
+
+       pmic_reg_read(p, MAX8997_REG_STATUS4, &val);
+
+       return !(val & DETBAT);
+}
+
+static struct power_chrg power_chrg_pmic_ops = {
+       .chrg_bat_present = pmic_charger_bat_present,
+       .chrg_state = pmic_charger_state,
+};
+
+int pmic_init(unsigned char bus)
+{
+       static const char name[] = "MAX8997_PMIC";
+       struct pmic *p = pmic_alloc();
+
+       if (!p) {
+               printf("%s: POWER allocation error!\n", __func__);
+               return -ENOMEM;
+       }
+
+       debug("Board PMIC init\n");
+
+       p->name = name;
+       p->interface = PMIC_I2C;
+       p->number_of_regs = PMIC_NUM_OF_REGS;
+       p->hw.i2c.addr = MAX8997_I2C_ADDR;
+       p->hw.i2c.tx_num = 1;
+       p->bus = bus;
+
+       p->chrg = &power_chrg_pmic_ops;
+       return 0;
+}
similarity index 82%
rename from drivers/misc/pmic_max8998.c
rename to drivers/power/pmic/pmic_max8998.c
index cc69fd708032f3ab423728f35e0a3a1c5c813f74..452e1c8d86279642a78182603c98935d33916523 100644 (file)
  */
 
 #include <common.h>
-#include <pmic.h>
-#include <max8998_pmic.h>
+#include <power/pmic.h>
+#include <power/max8998_pmic.h>
+#include <errno.h>
 
-int pmic_init(void)
+int pmic_init(unsigned char bus)
 {
-       struct pmic *p = get_pmic();
        static const char name[] = "MAX8998_PMIC";
+       struct pmic *p = pmic_alloc();
+
+       if (!p) {
+               printf("%s: POWER allocation error!\n", __func__);
+               return -ENOMEM;
+       }
 
        puts("Board PMIC init\n");
 
@@ -37,7 +43,7 @@ int pmic_init(void)
        p->number_of_regs = PMIC_NUM_OF_REGS;
        p->hw.i2c.addr = MAX8998_I2C_ADDR;
        p->hw.i2c.tx_num = 1;
-       p->bus = I2C_PMIC;
+       p->bus = bus;
 
        return 0;
 }
diff --git a/drivers/power/power_core.c b/drivers/power/power_core.c
new file mode 100644 (file)
index 0000000..90df2c5
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ * Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * (C) Copyright 2010
+ * Stefano Babic, DENX Software Engineering, sbabic@denx.de
+ *
+ * (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <power/pmic.h>
+
+static LIST_HEAD(pmic_list);
+
+int check_reg(struct pmic *p, u32 reg)
+{
+       if (reg >= p->number_of_regs) {
+               printf("<reg num> = %d is invalid. Should be less than %d\n",
+                      reg, p->number_of_regs);
+               return -1;
+       }
+
+       return 0;
+}
+
+int pmic_set_output(struct pmic *p, u32 reg, int out, int on)
+{
+       u32 val;
+
+       if (pmic_reg_read(p, reg, &val))
+               return -1;
+
+       if (on)
+               val |= out;
+       else
+               val &= ~out;
+
+       if (pmic_reg_write(p, reg, val))
+               return -1;
+
+       return 0;
+}
+
+static void pmic_show_info(struct pmic *p)
+{
+       printf("PMIC: %s\n", p->name);
+}
+
+static int pmic_dump(struct pmic *p)
+{
+       int i, ret;
+       u32 val;
+
+       if (!p) {
+               puts("Wrong PMIC name!\n");
+               return -1;
+       }
+
+       pmic_show_info(p);
+       for (i = 0; i < p->number_of_regs; i++) {
+               ret = pmic_reg_read(p, i, &val);
+               if (ret)
+                       puts("PMIC: Registers dump failed\n");
+
+               if (!(i % 8))
+                       printf("\n0x%02x: ", i);
+
+               printf("%08x ", val);
+       }
+       puts("\n");
+       return 0;
+}
+
+struct pmic *pmic_alloc(void)
+{
+       struct pmic *p;
+
+       p = calloc(sizeof(*p), 1);
+       if (!p) {
+               printf("%s: No available memory for allocation!\n", __func__);
+               return NULL;
+       }
+
+       list_add_tail(&p->list, &pmic_list);
+
+       debug("%s: new pmic struct: 0x%p\n", __func__, p);
+
+       return p;
+}
+
+struct pmic *pmic_get(const char *s)
+{
+       struct pmic *p;
+
+       list_for_each_entry(p, &pmic_list, list) {
+               if (strcmp(p->name, s) == 0) {
+                       debug("%s: pmic %s -> 0x%p\n", __func__, p->name, p);
+                       return p;
+               }
+       }
+
+       return NULL;
+}
+
+const char *power_get_interface(int interface)
+{
+       const char *power_interface[] = {"I2C", "SPI", "|+|-|"};
+       return power_interface[interface];
+}
+
+static void pmic_list_names(void)
+{
+       struct pmic *p;
+
+       puts("PMIC devices:\n");
+       list_for_each_entry(p, &pmic_list, list) {
+               printf("name: %s bus: %s_%d\n", p->name,
+                      power_get_interface(p->interface), p->bus);
+       }
+}
+
+int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       u32 ret, reg, val;
+       char *cmd, *name;
+       struct pmic *p;
+
+       /* at least two arguments please */
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       if (strcmp(argv[1], "list") == 0) {
+               pmic_list_names();
+               return CMD_RET_SUCCESS;
+       }
+
+       name = argv[1];
+       cmd = argv[2];
+
+       debug("%s: name: %s cmd: %s\n", __func__, name, cmd);
+       p = pmic_get(name);
+       if (!p)
+               return CMD_RET_FAILURE;
+
+       if (strcmp(cmd, "dump") == 0) {
+               if (pmic_dump(p))
+                       return CMD_RET_FAILURE;
+               return CMD_RET_SUCCESS;
+       }
+
+       if (strcmp(cmd, "read") == 0) {
+               if (argc < 4)
+                       return CMD_RET_USAGE;
+
+               reg = simple_strtoul(argv[3], NULL, 16);
+               ret = pmic_reg_read(p, reg, &val);
+
+               if (ret)
+                       puts("PMIC: Register read failed\n");
+
+               printf("\n0x%02x: 0x%08x\n", reg, val);
+
+               return CMD_RET_SUCCESS;
+       }
+
+       if (strcmp(cmd, "write") == 0) {
+               if (argc < 5)
+                       return CMD_RET_USAGE;
+
+               reg = simple_strtoul(argv[3], NULL, 16);
+               val = simple_strtoul(argv[4], NULL, 16);
+               pmic_reg_write(p, reg, val);
+
+               return CMD_RET_SUCCESS;
+       }
+
+       if (strcmp(cmd, "bat") == 0) {
+               if (argc < 4)
+                       return CMD_RET_USAGE;
+
+               if (strcmp(argv[3], "state") == 0)
+                       p->fg->fg_battery_check(p->pbat->fg, p);
+
+               if (strcmp(argv[3], "charge") == 0) {
+                       if (p->pbat) {
+                               printf("PRINT BAT charge %s\n", p->name);
+                               if (p->low_power_mode)
+                                       p->low_power_mode();
+                               if (p->pbat->battery_charge)
+                                       p->pbat->battery_charge(p);
+                       }
+               }
+
+               return CMD_RET_SUCCESS;
+       }
+
+       /* No subcommand found */
+       return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+       pmic,   CONFIG_SYS_MAXARGS, 1, do_pmic,
+       "PMIC",
+       "list - list available PMICs\n"
+       "pmic name dump - dump named PMIC registers\n"
+       "pmic name read <reg> - read register\n"
+       "pmic name write <reg> <value> - write register\n"
+       "pmic name bat state - write register\n"
+       "pmic name bat charge - write register\n"
+);
similarity index 81%
rename from drivers/misc/pmic_dialog.c
rename to drivers/power/power_dialog.c
index e97af1d1d01a3020516f83fa7ef3b6ccee2ec9a2..d7ebd1583e8303495f4641e06d80cf4a83a91072 100644 (file)
  */
 
 #include <common.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <dialog_pmic.h>
+#include <errno.h>
 
-int pmic_dialog_init(void)
+int pmic_dialog_init(unsigned char bus)
 {
-       struct pmic *p = get_pmic();
        static const char name[] = "DIALOG_PMIC";
+       struct pmic *p = pmic_alloc();
+
+       if (!p) {
+               printf("%s: POWER allocation error!\n", __func__);
+               return -ENOMEM;
+       }
 
        p->name = name;
        p->number_of_regs = DIALOG_NUM_OF_REGS;
@@ -31,7 +37,7 @@ int pmic_dialog_init(void)
        p->interface = PMIC_I2C;
        p->hw.i2c.addr = CONFIG_SYS_DIALOG_PMIC_I2C_ADDR;
        p->hw.i2c.tx_num = 1;
-       p->bus = I2C_PMIC;
+       p->bus = bus;
 
        return 0;
 }
similarity index 83%
rename from drivers/misc/pmic_fsl.c
rename to drivers/power/power_fsl.c
index c8d4c8d9ecf6e429470485738da6385075e96915..a663831589fdfe05a5756c592cd4ae5fcfc0fd6e 100644 (file)
@@ -23,8 +23,9 @@
 
 #include <common.h>
 #include <spi.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
+#include <errno.h>
 
 #if defined(CONFIG_PMIC_FSL_MC13892)
 #define FSL_PMIC_I2C_LENGTH    3
 #define FSL_PMIC_I2C_LENGTH    1
 #endif
 
-#if defined(CONFIG_PMIC_SPI)
+#if defined(CONFIG_POWER_SPI)
 static u32 pmic_spi_prepare_tx(u32 reg, u32 *val, u32 write)
 {
        return (write << 31) | (reg << 25) | (*val & 0x00FFFFFF);
 }
 #endif
 
-int pmic_init(void)
+int pmic_init(unsigned char bus)
 {
-       struct pmic *p = get_pmic();
        static const char name[] = "FSL_PMIC";
+       struct pmic *p = pmic_alloc();
+
+       if (!p) {
+               printf("%s: POWER allocation error!\n", __func__);
+               return -ENOMEM;
+       }
 
        p->name = name;
        p->number_of_regs = PMIC_NUM_OF_REGS;
 
-#if defined(CONFIG_PMIC_SPI)
+#if defined(CONFIG_POWER_SPI)
        p->interface = PMIC_SPI;
        p->bus = CONFIG_FSL_PMIC_BUS;
        p->hw.spi.cs = CONFIG_FSL_PMIC_CS;
@@ -56,13 +62,13 @@ int pmic_init(void)
        p->hw.spi.bitlen = CONFIG_FSL_PMIC_BITLEN;
        p->hw.spi.flags = SPI_XFER_BEGIN | SPI_XFER_END;
        p->hw.spi.prepare_tx = pmic_spi_prepare_tx;
-#elif defined(CONFIG_PMIC_I2C)
+#elif defined(CONFIG_POWER_I2C)
        p->interface = PMIC_I2C;
        p->hw.i2c.addr = CONFIG_SYS_FSL_PMIC_I2C_ADDR;
        p->hw.i2c.tx_num = FSL_PMIC_I2C_LENGTH;
-       p->bus = I2C_PMIC;
+       p->bus = bus;
 #else
-#error "You must select CONFIG_PMIC_SPI or CONFIG_PMIC_I2C"
+#error "You must select CONFIG_POWER_SPI or CONFIG_PMIC_I2C"
 #endif
 
        return 0;
similarity index 62%
rename from drivers/misc/pmic_i2c.c
rename to drivers/power/power_i2c.c
index 95a3365b9fc72a481ded1937d4293b1fb6cb4042..3e5a784cf539cc942dcf87b5ee0bfad487f49053 100644 (file)
 
 #include <common.h>
 #include <linux/types.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <i2c.h>
+#include <compiler.h>
 
 int pmic_reg_write(struct pmic *p, u32 reg, u32 val)
 {
        unsigned char buf[4] = { 0 };
 
-       if (check_reg(reg))
+       if (check_reg(p, reg))
                return -1;
 
        switch (pmic_i2c_tx_num) {
        case 3:
-               buf[0] = (val >> 16) & 0xff;
-               buf[1] = (val >> 8) & 0xff;
-               buf[2] = val & 0xff;
+               if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) {
+                       buf[2] = (cpu_to_le32(val) >> 16) & 0xff;
+                       buf[1] = (cpu_to_le32(val) >> 8) & 0xff;
+                       buf[0] = cpu_to_le32(val) & 0xff;
+               } else {
+                       buf[0] = (cpu_to_le32(val) >> 16) & 0xff;
+                       buf[1] = (cpu_to_le32(val) >> 8) & 0xff;
+                       buf[2] = cpu_to_le32(val) & 0xff;
+               }
+               break;
+       case 2:
+               if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) {
+                       buf[1] = (cpu_to_le32(val) >> 8) & 0xff;
+                       buf[0] = cpu_to_le32(val) & 0xff;
+               } else {
+                       buf[0] = (cpu_to_le32(val) >> 8) & 0xff;
+                       buf[1] = cpu_to_le32(val) & 0xff;
+               }
                break;
        case 1:
-               buf[0] = val & 0xff;
+               buf[0] = cpu_to_le32(val) & 0xff;
                break;
        default:
                printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num);
@@ -63,7 +79,7 @@ int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
        unsigned char buf[4] = { 0 };
        u32 ret_val = 0;
 
-       if (check_reg(reg))
+       if (check_reg(p, reg))
                return -1;
 
        if (i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num))
@@ -71,10 +87,21 @@ int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
 
        switch (pmic_i2c_tx_num) {
        case 3:
-               ret_val = buf[0] << 16 | buf[1] << 8 | buf[2];
+               if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG)
+                       ret_val = le32_to_cpu(buf[2] << 16
+                                             | buf[1] << 8 | buf[0]);
+               else
+                       ret_val = le32_to_cpu(buf[0] << 16 |
+                                             buf[1] << 8 | buf[2]);
+               break;
+       case 2:
+               if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG)
+                       ret_val = le32_to_cpu(buf[1] << 8 | buf[0]);
+               else
+                       ret_val = le32_to_cpu(buf[0] << 8 | buf[1]);
                break;
        case 1:
-               ret_val = buf[0];
+               ret_val = le32_to_cpu(buf[0]);
                break;
        default:
                printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num);
@@ -88,7 +115,7 @@ int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
 int pmic_probe(struct pmic *p)
 {
        I2C_SET_BUS(p->bus);
-       debug("PMIC:%s probed!\n", p->name);
+       debug("Bus: %d PMIC:%s probed!\n", p->bus, p->name);
        if (i2c_probe(pmic_i2c_addr)) {
                printf("Can't find PMIC:%s\n", p->name);
                return -1;
similarity index 97%
rename from drivers/misc/pmic_spi.c
rename to drivers/power/power_spi.c
index 5a0dd22e29078c6a4b0b8e9fc7d2ad2867ece25e..27488ea5d929b6cd50c27b62b79396f0c8470cc1 100644 (file)
@@ -28,7 +28,7 @@
 
 #include <common.h>
 #include <linux/types.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <spi.h>
 
 static struct spi_slave *slave;
@@ -59,7 +59,7 @@ static u32 pmic_reg(struct pmic *p, u32 reg, u32 *val, u32 write)
                        return -1;
        }
 
-       if (check_reg(reg))
+       if (check_reg(p, reg))
                return -1;
 
        if (spi_claim_bus(slave))
index 70ea8a15898116a553d70d7150588331b859cf46..e79f4621d3f9e8157e5861b3382a91181031b4dc 100644 (file)
 #include <common.h>
 #include <rtc.h>
 #include <spi.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 
 int rtc_get(struct rtc_time *rtc)
 {
        u32 day1, day2, time;
        int tim, i = 0;
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("FSL_PMIC");
        int ret;
 
+       if (!p)
+               return -1;
        do {
                ret = pmic_reg_read(p, REG_RTC_DAY, &day1);
                if (ret < 0)
@@ -61,7 +63,9 @@ int rtc_get(struct rtc_time *rtc)
 int rtc_set(struct rtc_time *rtc)
 {
        u32 time, day;
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("FSL_PMIC");
+       if (!p)
+               return -1;
 
        time = mktime(rtc->tm_year, rtc->tm_mon, rtc->tm_mday,
                      rtc->tm_hour, rtc->tm_min, rtc->tm_sec);
index 9027781445f447efc63483294b2bf564947842df..bbd91ca247df995d2b5d11e865ea7ba391574239 100644 (file)
@@ -36,6 +36,9 @@
 
 void NS16550_init(NS16550_t com_port, int baud_divisor)
 {
+       while (!(serial_in(&com_port->lsr) & UART_LSR_TEMT))
+               ;
+
        serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
 #if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
                                        defined(CONFIG_AM33XX)
index c1c0134bcb3fdd8ec7e6c8a93e9f463291b5b9ca..fc01a3c5164b03bdd94e5de0f7ea8ba08e77dc60 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <serial.h>
 
+#ifndef CONFIG_NS16550_MIN_FUNCTIONS
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #if !defined(CONFIG_CONS_INDEX)
@@ -304,3 +306,5 @@ void ns16550_serial_initialize(void)
        serial_register(&eserial6_device);
 #endif
 }
+
+#endif /* !CONFIG_NS16550_MIN_FUNCTIONS */
index b331be794badb8f5d84710ba693348ca9600bc2e..dfdba9f64eb8031144d6be6b2722f070df3cf047 100644 (file)
@@ -163,8 +163,8 @@ static int pl01x_serial_init(void)
        }
 #endif
        /* Finally, enable the UART */
-       writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE,
-              &regs->pl011_cr);
+       writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE |
+              UART_PL011_CR_RTS, &regs->pl011_cr);
 
        return 0;
 }
index 3c931d0212703f90cc2b099f023a5bcabad029d5..ee1f2d768a14f936d3979f5c12bfdff0ba2aac99 100644 (file)
@@ -117,6 +117,14 @@ static int serial_rx_fifo_level(void)
        return scif_rxfill(&sh_sci);
 }
 
+static void handle_error(void)
+{
+       sci_in(&sh_sci, SCxSR);
+       sci_out(&sh_sci, SCxSR, SCxSR_ERROR_CLEAR(&sh_sci));
+       sci_in(&sh_sci, SCLSR);
+       sci_out(&sh_sci, SCLSR, 0x00);
+}
+
 void serial_raw_putc(const char c)
 {
        while (1) {
@@ -138,16 +146,14 @@ static void sh_serial_putc(const char c)
 
 static int sh_serial_tstc(void)
 {
+       if (sci_in(&sh_sci, SCxSR) & SCIF_ERRORS) {
+               handle_error();
+               return 0;
+       }
+
        return serial_rx_fifo_level() ? 1 : 0;
 }
 
-void handle_error(void)
-{
-       sci_in(&sh_sci, SCxSR);
-       sci_out(&sh_sci, SCxSR, SCxSR_ERROR_CLEAR(&sh_sci));
-       sci_in(&sh_sci, SCLSR);
-       sci_out(&sh_sci, SCLSR, 0x00);
-}
 
 int serial_getc_check(void)
 {
index f88d0c190c4ef9a5c0a7ac50bc4c2036e264f1d9..f9163a80ed17cbcf912f0e4baf2a9b39fc6705e5 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/string.h>
 
 #include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
 #include <linux/usb/gadget.h>
 
 
index b656c8b9f481f984dad8b291d0323a100d4d03f8..5b8776e0b70b4e479cdb48aebfa8dacf22b9cf97 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <common.h>
 #include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
 #include <asm/errno.h>
 #include <linux/usb/gadget.h>
 #include <asm/unaligned.h>
index 8b24e00e2715a4b493be67899a1197870354e667..de880ffeb8a6e9c1821ce88ada68134f214fa410 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/errno.h>
 #include <linux/netdevice.h>
 #include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
 #include <linux/usb/cdc.h>
 #include <linux/usb/gadget.h>
 #include <net.h>
index 3ec4c65e7485c955843911b25157488d1a498a94..10547e3279b6aadac2cc376ea2d5efd281147ad2 100644 (file)
@@ -25,7 +25,6 @@
 #include <malloc.h>
 
 #include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/composite.h>
 
index 02cae0fc7586134cb8ba5ca07bba640b336a95b6..e5701422fa3de2e4cb48244fa65b4e63441356d1 100644 (file)
 #endif
 
 /* Mentor high speed "dual role" controller, in peripheral role */
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-#define gadget_is_musbhdrc(g)  (!strcmp("musb_hdrc", (g)->name))
+#ifdef CONFIG_MUSB_GADGET
+#define gadget_is_musbhdrc(g)  (!strcmp("musb-hdrc", (g)->name))
 #else
 #define gadget_is_musbhdrc(g)  0
 #endif
index 3fdfdf7af08ec8a0d85031d16768f822fb609175..f9d24e3dfdc02ab6a613a3a1a1ad964bf364aad6 100644 (file)
@@ -37,7 +37,6 @@
 #include <malloc.h>
 
 #include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
 #include <linux/usb/gadget.h>
 
 #include <asm/byteorder.h>
index 4dbe060d6f2359c377be128e6e0a344218836a01..95555cf96b9c3a1f1b52482c54c5ae9830ae3a2a 100644 (file)
@@ -13,7 +13,6 @@
 #include <common.h>
 #include <asm/errno.h>
 #include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
 #include <linux/usb/gadget.h>
 
 #include <asm/unaligned.h>
index d90e94d8109d02065b88afc3c3fd0fca0824f5c7..7f98a6354ac4227515cb412f8ed5abde3ed63cdb 100644 (file)
@@ -210,6 +210,18 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
        return 0;
 }
 
+static inline u8 ehci_encode_speed(enum usb_device_speed speed)
+{
+       #define QH_HIGH_SPEED   2
+       #define QH_FULL_SPEED   0
+       #define QH_LOW_SPEED    1
+       if (speed == USB_SPEED_HIGH)
+               return QH_HIGH_SPEED;
+       if (speed == USB_SPEED_LOW)
+               return QH_LOW_SPEED;
+       return QH_FULL_SPEED;
+}
+
 static int
 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                   int length, struct devrequest *req)
@@ -318,12 +330,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
         * - qh_overlay.qt_altnext
         */
        qh->qh_link = cpu_to_hc32((uint32_t)&ctrl->qh_list | QH_LINK_TYPE_QH);
-       c = usb_pipespeed(pipe) != USB_SPEED_HIGH && !usb_pipeendpoint(pipe);
+       c = (dev->speed != USB_SPEED_HIGH) && !usb_pipeendpoint(pipe);
        maxpacket = usb_maxpacket(dev, pipe);
        endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) |
                QH_ENDPT1_MAXPKTLEN(maxpacket) | QH_ENDPT1_H(0) |
                QH_ENDPT1_DTC(QH_ENDPT1_DTC_DT_FROM_QTD) |
-               QH_ENDPT1_EPS(usb_pipespeed(pipe)) |
+               QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) |
                QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) |
                QH_ENDPT1_DEVADDR(usb_pipedevice(pipe));
        qh->qh_endpt1 = cpu_to_hc32(endpt);
index 19e16a4a804bbacf9efdee693ba9174f6ec6024b..289018c4f6aa3504f91311402720d95a52f74765 100644 (file)
@@ -617,7 +617,7 @@ static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
        int epnum = usb_pipeendpoint(pipe);
        int max = usb_maxpacket(dev, pipe);
        int dir_out = usb_pipeout(pipe);
-       int speed_low = usb_pipeslow(pipe);
+       int speed_low = (dev->speed == USB_SPEED_LOW);
        int i, done = 0, stat, timeout, cc;
 
        /* 500 frames or 0.5s timeout when function is busy and NAKs transactions for a while */
index c2106adbd3bae5b6e709425b8440553c1b2c1be6..bdbe250b01e917a6cf51a386bc18d453416df0a4 100644 (file)
@@ -803,7 +803,7 @@ static ed_t *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe,
                        | (usb_pipeisoc(pipe)? 0x8000: 0)
                        | (usb_pipecontrol(pipe)? 0: \
                                           (usb_pipeout(pipe)? 0x800: 0x1000))
-                       | usb_pipeslow(pipe) << 13
+                       | (usb_dev->speed == USB_SPEED_LOW) << 13
                        | usb_maxpacket(usb_dev, pipe) << 16);
 
        if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
index 03cd4c3d2a2f60801ccb31ad5ac22cd85ef836ed..dde076403494ae33b2df8450380f817cf01f8f51 100644 (file)
@@ -620,7 +620,7 @@ static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe)
                              | (usb_pipeisoc(pipe) ? 0x8000 : 0)
                              | (usb_pipecontrol(pipe) ? 0 :
                                 (usb_pipeout(pipe) ? 0x800 : 0x1000))
-                             | usb_pipeslow(pipe) << 13 |
+                             | (usb_dev->speed == USB_SPEED_LOW) << 13 |
                              usb_maxpacket(usb_dev, pipe) << 16);
 
        return ed_ret;
index 2a4e7ff4b3720b9e1eb92acb7768f3d6ca940667..b503b356ce57f50c73cdcb7b2ebe58479542f241 100644 (file)
@@ -31,9 +31,6 @@
 #endif
 
 static const char hcd_name[] = "r8a66597_hcd";
-static unsigned short clock = CONFIG_R8A66597_XTAL;
-static unsigned short vif = CONFIG_R8A66597_LDRV;
-static unsigned short endian = CONFIG_R8A66597_ENDIAN;
 static struct r8a66597 gr8a66597;
 
 static void get_hub_data(struct usb_device *dev, u16 *hub_devnum, u16 *hubport)
@@ -96,7 +93,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
                }
        } while ((tmp & USBE) != USBE);
        r8a66597_bclr(r8a66597, USBE, SYSCFG0);
-       r8a66597_mdfy(r8a66597, clock, XTAL, SYSCFG0);
+       r8a66597_mdfy(r8a66597, CONFIG_R8A66597_XTAL, XTAL, SYSCFG0);
 
        i = 0;
        r8a66597_bset(r8a66597, XCKE, SYSCFG0);
@@ -162,7 +159,7 @@ static int enable_controller(struct r8a66597 *r8a66597)
        if (ret < 0)
                return ret;
 
-       r8a66597_bset(r8a66597, vif & LDRV, PINCFG);
+       r8a66597_bset(r8a66597, CONFIG_R8A66597_LDRV & LDRV, PINCFG);
        r8a66597_bset(r8a66597, USBE, SYSCFG0);
 
        r8a66597_bset(r8a66597, INTL, SOFCFG);
@@ -170,9 +167,9 @@ static int enable_controller(struct r8a66597 *r8a66597)
        r8a66597_write(r8a66597, 0, INTENB1);
        r8a66597_write(r8a66597, 0, INTENB2);
 
-       r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL);
-       r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL);
-       r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL);
+       r8a66597_bset(r8a66597, CONFIG_R8A66597_ENDIAN & BIGEND, CFIFOSEL);
+       r8a66597_bset(r8a66597, CONFIG_R8A66597_ENDIAN & BIGEND, D0FIFOSEL);
+       r8a66597_bset(r8a66597, CONFIG_R8A66597_ENDIAN & BIGEND, D1FIFOSEL);
        r8a66597_bset(r8a66597, TRNENSEL, SOFCFG);
 
        for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
@@ -673,7 +670,6 @@ static int r8a66597_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
        int stat = 0;
        __u16 bmRType_bReq;
        __u16 wValue;
-       __u16 wIndex;
        __u16 wLength;
        unsigned char data[32];
 
@@ -686,7 +682,6 @@ static int r8a66597_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
 
        bmRType_bReq  = cmd->requesttype | (cmd->request << 8);
        wValue        = cpu_to_le16 (cmd->value);
-       wIndex        = cpu_to_le16 (cmd->index);
        wLength       = cpu_to_le16 (cmd->length);
 
        switch (bmRType_bReq) {
@@ -908,7 +903,7 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
        return 0;
 }
 
-int usb_lowlevel_init(int index, void **controller))
+int usb_lowlevel_init(int index, void **controller)
 {
        struct r8a66597 *r8a66597 = &gr8a66597;
 
index 283061604693efa58e422f09ae95537ae4d52931..417f1a8aba1bf2e9833ee6b6e29267bd7b10b4cc 100644 (file)
@@ -234,7 +234,7 @@ static int sl811_send_packet(struct usb_device *dev, unsigned long pipe, __u8 *b
        __u16 status = 0;
        int err = 0, time_start = get_timer(0);
        int need_preamble = !(rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED) &&
-               usb_pipeslow(pipe);
+               (dev->speed == USB_SPEED_LOW);
 
        if (len > 239)
                return -1;
diff --git a/drivers/usb/musb-new/Makefile b/drivers/usb/musb-new/Makefile
new file mode 100644 (file)
index 0000000..c23bef1
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# for USB OTG silicon based on Mentor Graphics INVENTRA designs
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    := $(obj)libusb_musb-new.o
+
+COBJS-$(CONFIG_MUSB_GADGET) += musb_gadget.o musb_gadget_ep0.o musb_core.o
+COBJS-$(CONFIG_MUSB_GADGET) += musb_uboot.o
+COBJS-$(CONFIG_MUSB_HOST) += musb_host.o musb_core.o musb_uboot.o
+COBJS-$(CONFIG_USB_MUSB_DSPS) += musb_dsps.o
+COBJS-$(CONFIG_USB_MUSB_AM35X) += am35x.o
+COBJS-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o
+
+CFLAGS_NO_WARN := $(call cc-option,-Wno-unused-variable) \
+                       $(call cc-option,-Wno-unused-but-set-variable) \
+                       $(call cc-option,-Wno-unused-label)
+CFLAGS += $(CFLAGS_NO_WARN)
+
+COBJS  := $(sort $(COBJS-y))
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+all:   $(LIB)
+
+#$(LIB):       $(OBJS)
+$(LIB):        $(obj).depend $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
+
diff --git a/drivers/usb/musb-new/am35x.c b/drivers/usb/musb-new/am35x.c
new file mode 100644 (file)
index 0000000..57c9bd3
--- /dev/null
@@ -0,0 +1,709 @@
+/*
+ * Texas Instruments AM35x "glue layer"
+ *
+ * Copyright (c) 2010, by Texas Instruments
+ *
+ * Based on the DA8xx "glue layer" code.
+ * Copyright (c) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file is part of the Inventra Controller Driver for Linux.
+ *
+ * The Inventra Controller Driver for Linux 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.
+ *
+ * The Inventra Controller Driver for Linux 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 The Inventra Controller Driver for Linux ; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define __UBOOT__
+#ifndef __UBOOT__
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/usb.h>
+#else
+#include <common.h>
+#include <asm/omap_musb.h>
+#include "linux-compat.h"
+#endif
+
+#include "musb_core.h"
+
+/*
+ * AM35x specific definitions
+ */
+/* USB 2.0 OTG module registers */
+#define USB_REVISION_REG       0x00
+#define USB_CTRL_REG           0x04
+#define USB_STAT_REG           0x08
+#define USB_EMULATION_REG      0x0c
+/* 0x10 Reserved */
+#define USB_AUTOREQ_REG                0x14
+#define USB_SRP_FIX_TIME_REG   0x18
+#define USB_TEARDOWN_REG       0x1c
+#define EP_INTR_SRC_REG                0x20
+#define EP_INTR_SRC_SET_REG    0x24
+#define EP_INTR_SRC_CLEAR_REG  0x28
+#define EP_INTR_MASK_REG       0x2c
+#define EP_INTR_MASK_SET_REG   0x30
+#define EP_INTR_MASK_CLEAR_REG 0x34
+#define EP_INTR_SRC_MASKED_REG 0x38
+#define CORE_INTR_SRC_REG      0x40
+#define CORE_INTR_SRC_SET_REG  0x44
+#define CORE_INTR_SRC_CLEAR_REG        0x48
+#define CORE_INTR_MASK_REG     0x4c
+#define CORE_INTR_MASK_SET_REG 0x50
+#define CORE_INTR_MASK_CLEAR_REG 0x54
+#define CORE_INTR_SRC_MASKED_REG 0x58
+/* 0x5c Reserved */
+#define USB_END_OF_INTR_REG    0x60
+
+/* Control register bits */
+#define AM35X_SOFT_RESET_MASK  1
+
+/* USB interrupt register bits */
+#define AM35X_INTR_USB_SHIFT   16
+#define AM35X_INTR_USB_MASK    (0x1ff << AM35X_INTR_USB_SHIFT)
+#define AM35X_INTR_DRVVBUS     0x100
+#define AM35X_INTR_RX_SHIFT    16
+#define AM35X_INTR_TX_SHIFT    0
+#define AM35X_TX_EP_MASK       0xffff          /* EP0 + 15 Tx EPs */
+#define AM35X_RX_EP_MASK       0xfffe          /* 15 Rx EPs */
+#define AM35X_TX_INTR_MASK     (AM35X_TX_EP_MASK << AM35X_INTR_TX_SHIFT)
+#define AM35X_RX_INTR_MASK     (AM35X_RX_EP_MASK << AM35X_INTR_RX_SHIFT)
+
+#define USB_MENTOR_CORE_OFFSET 0x400
+
+struct am35x_glue {
+       struct device           *dev;
+       struct platform_device  *musb;
+       struct clk              *phy_clk;
+       struct clk              *clk;
+};
+#define glue_to_musb(g)                platform_get_drvdata(g->musb)
+
+/*
+ * am35x_musb_enable - enable interrupts
+ */
+static void am35x_musb_enable(struct musb *musb)
+{
+       void __iomem *reg_base = musb->ctrl_base;
+       u32 epmask;
+
+       /* Workaround: setup IRQs through both register sets. */
+       epmask = ((musb->epmask & AM35X_TX_EP_MASK) << AM35X_INTR_TX_SHIFT) |
+              ((musb->epmask & AM35X_RX_EP_MASK) << AM35X_INTR_RX_SHIFT);
+
+       musb_writel(reg_base, EP_INTR_MASK_SET_REG, epmask);
+       musb_writel(reg_base, CORE_INTR_MASK_SET_REG, AM35X_INTR_USB_MASK);
+
+       /* Force the DRVVBUS IRQ so we can start polling for ID change. */
+       if (is_otg_enabled(musb))
+               musb_writel(reg_base, CORE_INTR_SRC_SET_REG,
+                           AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT);
+}
+
+/*
+ * am35x_musb_disable - disable HDRC and flush interrupts
+ */
+static void am35x_musb_disable(struct musb *musb)
+{
+       void __iomem *reg_base = musb->ctrl_base;
+
+       musb_writel(reg_base, CORE_INTR_MASK_CLEAR_REG, AM35X_INTR_USB_MASK);
+       musb_writel(reg_base, EP_INTR_MASK_CLEAR_REG,
+                        AM35X_TX_INTR_MASK | AM35X_RX_INTR_MASK);
+       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+       musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
+}
+
+#ifndef __UBOOT__
+#define portstate(stmt)                stmt
+
+static void am35x_musb_set_vbus(struct musb *musb, int is_on)
+{
+       WARN_ON(is_on && is_peripheral_active(musb));
+}
+
+#define        POLL_SECONDS    2
+
+static struct timer_list otg_workaround;
+
+static void otg_timer(unsigned long _musb)
+{
+       struct musb             *musb = (void *)_musb;
+       void __iomem            *mregs = musb->mregs;
+       u8                      devctl;
+       unsigned long           flags;
+
+       /*
+        * We poll because AM35x's won't expose several OTG-critical
+        * status change events (from the transceiver) otherwise.
+        */
+       devctl = musb_readb(mregs, MUSB_DEVCTL);
+       dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
+               otg_state_string(musb->xceiv->state));
+
+       spin_lock_irqsave(&musb->lock, flags);
+       switch (musb->xceiv->state) {
+       case OTG_STATE_A_WAIT_BCON:
+               devctl &= ~MUSB_DEVCTL_SESSION;
+               musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+               devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+               if (devctl & MUSB_DEVCTL_BDEVICE) {
+                       musb->xceiv->state = OTG_STATE_B_IDLE;
+                       MUSB_DEV_MODE(musb);
+               } else {
+                       musb->xceiv->state = OTG_STATE_A_IDLE;
+                       MUSB_HST_MODE(musb);
+               }
+               break;
+       case OTG_STATE_A_WAIT_VFALL:
+               musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+               musb_writel(musb->ctrl_base, CORE_INTR_SRC_SET_REG,
+                           MUSB_INTR_VBUSERROR << AM35X_INTR_USB_SHIFT);
+               break;
+       case OTG_STATE_B_IDLE:
+               if (!is_peripheral_enabled(musb))
+                       break;
+
+               devctl = musb_readb(mregs, MUSB_DEVCTL);
+               if (devctl & MUSB_DEVCTL_BDEVICE)
+                       mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
+               else
+                       musb->xceiv->state = OTG_STATE_A_IDLE;
+               break;
+       default:
+               break;
+       }
+       spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout)
+{
+       static unsigned long last_timer;
+
+       if (!is_otg_enabled(musb))
+               return;
+
+       if (timeout == 0)
+               timeout = jiffies + msecs_to_jiffies(3);
+
+       /* Never idle if active, or when VBUS timeout is not set as host */
+       if (musb->is_active || (musb->a_wait_bcon == 0 &&
+                               musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
+               dev_dbg(musb->controller, "%s active, deleting timer\n",
+                       otg_state_string(musb->xceiv->state));
+               del_timer(&otg_workaround);
+               last_timer = jiffies;
+               return;
+       }
+
+       if (time_after(last_timer, timeout) && timer_pending(&otg_workaround)) {
+               dev_dbg(musb->controller, "Longer idle timer already pending, ignoring...\n");
+               return;
+       }
+       last_timer = timeout;
+
+       dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
+               otg_state_string(musb->xceiv->state),
+               jiffies_to_msecs(timeout - jiffies));
+       mod_timer(&otg_workaround, timeout);
+}
+#endif
+
+static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
+{
+       struct musb  *musb = hci;
+       void __iomem *reg_base = musb->ctrl_base;
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+       struct usb_otg *otg = musb->xceiv->otg;
+#else
+       struct omap_musb_board_data *data =
+               (struct omap_musb_board_data *)musb->controller;
+#endif
+       unsigned long flags;
+       irqreturn_t ret = IRQ_NONE;
+       u32 epintr, usbintr;
+
+#ifdef __UBOOT__
+       /*
+        * It seems that on AM35X interrupt registers can be updated
+        * before core registers. This confuses the code.
+        * As a workaround add a small delay here.
+        */
+       udelay(10);
+#endif
+       spin_lock_irqsave(&musb->lock, flags);
+
+       /* Get endpoint interrupts */
+       epintr = musb_readl(reg_base, EP_INTR_SRC_MASKED_REG);
+
+       if (epintr) {
+               musb_writel(reg_base, EP_INTR_SRC_CLEAR_REG, epintr);
+
+               musb->int_rx =
+                       (epintr & AM35X_RX_INTR_MASK) >> AM35X_INTR_RX_SHIFT;
+               musb->int_tx =
+                       (epintr & AM35X_TX_INTR_MASK) >> AM35X_INTR_TX_SHIFT;
+       }
+
+       /* Get usb core interrupts */
+       usbintr = musb_readl(reg_base, CORE_INTR_SRC_MASKED_REG);
+       if (!usbintr && !epintr)
+               goto eoi;
+
+       if (usbintr) {
+               musb_writel(reg_base, CORE_INTR_SRC_CLEAR_REG, usbintr);
+
+               musb->int_usb =
+                       (usbintr & AM35X_INTR_USB_MASK) >> AM35X_INTR_USB_SHIFT;
+       }
+#ifndef __UBOOT__
+       /*
+        * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
+        * AM35x's missing ID change IRQ.  We need an ID change IRQ to
+        * switch appropriately between halves of the OTG state machine.
+        * Managing DEVCTL.SESSION per Mentor docs requires that we know its
+        * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
+        * Also, DRVVBUS pulses for SRP (but not at 5V) ...
+        */
+       if (usbintr & (AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT)) {
+               int drvvbus = musb_readl(reg_base, USB_STAT_REG);
+               void __iomem *mregs = musb->mregs;
+               u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
+               int err;
+
+               err = is_host_enabled(musb) && (musb->int_usb &
+                                               MUSB_INTR_VBUSERROR);
+               if (err) {
+                       /*
+                        * The Mentor core doesn't debounce VBUS as needed
+                        * to cope with device connect current spikes. This
+                        * means it's not uncommon for bus-powered devices
+                        * to get VBUS errors during enumeration.
+                        *
+                        * This is a workaround, but newer RTL from Mentor
+                        * seems to allow a better one: "re"-starting sessions
+                        * without waiting for VBUS to stop registering in
+                        * devctl.
+                        */
+                       musb->int_usb &= ~MUSB_INTR_VBUSERROR;
+                       musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
+                       mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
+                       WARNING("VBUS error workaround (delay coming)\n");
+               } else if (is_host_enabled(musb) && drvvbus) {
+                       MUSB_HST_MODE(musb);
+                       otg->default_a = 1;
+                       musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+                       portstate(musb->port1_status |= USB_PORT_STAT_POWER);
+                       del_timer(&otg_workaround);
+               } else {
+                       musb->is_active = 0;
+                       MUSB_DEV_MODE(musb);
+                       otg->default_a = 0;
+                       musb->xceiv->state = OTG_STATE_B_IDLE;
+                       portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
+               }
+
+               /* NOTE: this must complete power-on within 100 ms. */
+               dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
+                               drvvbus ? "on" : "off",
+                               otg_state_string(musb->xceiv->state),
+                               err ? " ERROR" : "",
+                               devctl);
+               ret = IRQ_HANDLED;
+       }
+#endif
+
+       if (musb->int_tx || musb->int_rx || musb->int_usb)
+               ret |= musb_interrupt(musb);
+
+eoi:
+       /* EOI needs to be written for the IRQ to be re-asserted. */
+       if (ret == IRQ_HANDLED || epintr || usbintr) {
+               /* clear level interrupt */
+               if (data->clear_irq)
+                       data->clear_irq();
+               /* write EOI */
+               musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
+       }
+
+#ifndef __UBOOT__
+       /* Poll for ID change */
+       if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE)
+               mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
+#endif
+
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return ret;
+}
+
+#ifndef __UBOOT__
+static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode)
+{
+       struct device *dev = musb->controller;
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+       int     retval = 0;
+
+       if (data->set_mode)
+               data->set_mode(musb_mode);
+       else
+               retval = -EIO;
+
+       return retval;
+}
+#endif
+
+static int am35x_musb_init(struct musb *musb)
+{
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+#else
+       struct omap_musb_board_data *data =
+               (struct omap_musb_board_data *)musb->controller;
+#endif
+       void __iomem *reg_base = musb->ctrl_base;
+       u32 rev;
+
+       musb->mregs += USB_MENTOR_CORE_OFFSET;
+
+       /* Returns zero if e.g. not clocked */
+       rev = musb_readl(reg_base, USB_REVISION_REG);
+       if (!rev)
+               return -ENODEV;
+
+#ifndef __UBOOT__
+       usb_nop_xceiv_register();
+       musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv))
+               return -ENODEV;
+
+       if (is_host_enabled(musb))
+               setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
+#endif
+
+       /* Reset the musb */
+       if (data->reset)
+               data->reset();
+
+       /* Reset the controller */
+       musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK);
+
+       /* Start the on-chip PHY and its PLL. */
+       if (data->set_phy_power)
+               data->set_phy_power(1);
+
+       msleep(5);
+
+       musb->isr = am35x_musb_interrupt;
+
+       /* clear level interrupt */
+       if (data->clear_irq)
+               data->clear_irq();
+
+       return 0;
+}
+
+static int am35x_musb_exit(struct musb *musb)
+{
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+#else
+       struct omap_musb_board_data *data =
+               (struct omap_musb_board_data *)musb->controller;
+#endif
+
+#ifndef __UBOOT__
+       if (is_host_enabled(musb))
+               del_timer_sync(&otg_workaround);
+#endif
+
+       /* Shutdown the on-chip PHY and its PLL. */
+       if (data->set_phy_power)
+               data->set_phy_power(0);
+
+#ifndef __UBOOT__
+       usb_put_phy(musb->xceiv);
+       usb_nop_xceiv_unregister();
+#endif
+
+       return 0;
+}
+
+/* AM35x supports only 32bit read operation */
+void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
+{
+       void __iomem *fifo = hw_ep->fifo;
+       u32             val;
+       int             i;
+
+       /* Read for 32bit-aligned destination address */
+       if (likely((0x03 & (unsigned long) dst) == 0) && len >= 4) {
+               readsl(fifo, dst, len >> 2);
+               dst += len & ~0x03;
+               len &= 0x03;
+       }
+       /*
+        * Now read the remaining 1 to 3 byte or complete length if
+        * unaligned address.
+        */
+       if (len > 4) {
+               for (i = 0; i < (len >> 2); i++) {
+                       *(u32 *) dst = musb_readl(fifo, 0);
+                       dst += 4;
+               }
+               len &= 0x03;
+       }
+       if (len > 0) {
+               val = musb_readl(fifo, 0);
+               memcpy(dst, &val, len);
+       }
+}
+
+#ifndef __UBOOT__
+static const struct musb_platform_ops am35x_ops = {
+#else
+const struct musb_platform_ops am35x_ops = {
+#endif
+       .init           = am35x_musb_init,
+       .exit           = am35x_musb_exit,
+
+       .enable         = am35x_musb_enable,
+       .disable        = am35x_musb_disable,
+
+#ifndef __UBOOT__
+       .set_mode       = am35x_musb_set_mode,
+       .try_idle       = am35x_musb_try_idle,
+
+       .set_vbus       = am35x_musb_set_vbus,
+#endif
+};
+
+#ifndef __UBOOT__
+static u64 am35x_dmamask = DMA_BIT_MASK(32);
+
+static int __devinit am35x_probe(struct platform_device *pdev)
+{
+       struct musb_hdrc_platform_data  *pdata = pdev->dev.platform_data;
+       struct platform_device          *musb;
+       struct am35x_glue               *glue;
+
+       struct clk                      *phy_clk;
+       struct clk                      *clk;
+
+       int                             ret = -ENOMEM;
+
+       glue = kzalloc(sizeof(*glue), GFP_KERNEL);
+       if (!glue) {
+               dev_err(&pdev->dev, "failed to allocate glue context\n");
+               goto err0;
+       }
+
+       musb = platform_device_alloc("musb-hdrc", -1);
+       if (!musb) {
+               dev_err(&pdev->dev, "failed to allocate musb device\n");
+               goto err1;
+       }
+
+       phy_clk = clk_get(&pdev->dev, "fck");
+       if (IS_ERR(phy_clk)) {
+               dev_err(&pdev->dev, "failed to get PHY clock\n");
+               ret = PTR_ERR(phy_clk);
+               goto err2;
+       }
+
+       clk = clk_get(&pdev->dev, "ick");
+       if (IS_ERR(clk)) {
+               dev_err(&pdev->dev, "failed to get clock\n");
+               ret = PTR_ERR(clk);
+               goto err3;
+       }
+
+       ret = clk_enable(phy_clk);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to enable PHY clock\n");
+               goto err4;
+       }
+
+       ret = clk_enable(clk);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to enable clock\n");
+               goto err5;
+       }
+
+       musb->dev.parent                = &pdev->dev;
+       musb->dev.dma_mask              = &am35x_dmamask;
+       musb->dev.coherent_dma_mask     = am35x_dmamask;
+
+       glue->dev                       = &pdev->dev;
+       glue->musb                      = musb;
+       glue->phy_clk                   = phy_clk;
+       glue->clk                       = clk;
+
+       pdata->platform_ops             = &am35x_ops;
+
+       platform_set_drvdata(pdev, glue);
+
+       ret = platform_device_add_resources(musb, pdev->resource,
+                       pdev->num_resources);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add resources\n");
+               goto err6;
+       }
+
+       ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add platform_data\n");
+               goto err6;
+       }
+
+       ret = platform_device_add(musb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register musb device\n");
+               goto err6;
+       }
+
+       return 0;
+
+err6:
+       clk_disable(clk);
+
+err5:
+       clk_disable(phy_clk);
+
+err4:
+       clk_put(clk);
+
+err3:
+       clk_put(phy_clk);
+
+err2:
+       platform_device_put(musb);
+
+err1:
+       kfree(glue);
+
+err0:
+       return ret;
+}
+
+static int __devexit am35x_remove(struct platform_device *pdev)
+{
+       struct am35x_glue       *glue = platform_get_drvdata(pdev);
+
+       platform_device_del(glue->musb);
+       platform_device_put(glue->musb);
+       clk_disable(glue->clk);
+       clk_disable(glue->phy_clk);
+       clk_put(glue->clk);
+       clk_put(glue->phy_clk);
+       kfree(glue);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int am35x_suspend(struct device *dev)
+{
+       struct am35x_glue       *glue = dev_get_drvdata(dev);
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+
+       /* Shutdown the on-chip PHY and its PLL. */
+       if (data->set_phy_power)
+               data->set_phy_power(0);
+
+       clk_disable(glue->phy_clk);
+       clk_disable(glue->clk);
+
+       return 0;
+}
+
+static int am35x_resume(struct device *dev)
+{
+       struct am35x_glue       *glue = dev_get_drvdata(dev);
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+       int                     ret;
+
+       /* Start the on-chip PHY and its PLL. */
+       if (data->set_phy_power)
+               data->set_phy_power(1);
+
+       ret = clk_enable(glue->phy_clk);
+       if (ret) {
+               dev_err(dev, "failed to enable PHY clock\n");
+               return ret;
+       }
+
+       ret = clk_enable(glue->clk);
+       if (ret) {
+               dev_err(dev, "failed to enable clock\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct dev_pm_ops am35x_pm_ops = {
+       .suspend        = am35x_suspend,
+       .resume         = am35x_resume,
+};
+
+#define DEV_PM_OPS     &am35x_pm_ops
+#else
+#define DEV_PM_OPS     NULL
+#endif
+
+static struct platform_driver am35x_driver = {
+       .probe          = am35x_probe,
+       .remove         = __devexit_p(am35x_remove),
+       .driver         = {
+               .name   = "musb-am35x",
+               .pm     = DEV_PM_OPS,
+       },
+};
+
+MODULE_DESCRIPTION("AM35x MUSB Glue Layer");
+MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
+MODULE_LICENSE("GPL v2");
+
+static int __init am35x_init(void)
+{
+       return platform_driver_register(&am35x_driver);
+}
+module_init(am35x_init);
+
+static void __exit am35x_exit(void)
+{
+       platform_driver_unregister(&am35x_driver);
+}
+module_exit(am35x_exit);
+#endif
diff --git a/drivers/usb/musb-new/linux-compat.h b/drivers/usb/musb-new/linux-compat.h
new file mode 100644 (file)
index 0000000..5c126ef
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef __LINUX_COMPAT_H__
+#define __LINUX_COMPAT_H__
+
+#include <malloc.h>
+#include <linux/list.h>
+#include <linux/compat.h>
+
+#define __init
+#define __devinit
+#define __devinitdata
+#define __devinitconst
+#define __iomem
+#define __deprecated
+
+typedef enum { false = 0, true = 1 } bool;
+
+struct unused {};
+typedef struct unused unused_t;
+
+typedef int irqreturn_t;
+typedef unused_t spinlock_t;
+
+struct work_struct {};
+
+struct timer_list {};
+struct notifier_block {};
+
+typedef unsigned long dmaaddr_t;
+
+#define spin_lock_init(lock) do {} while (0)
+#define spin_lock(lock) do {} while (0)
+#define spin_unlock(lock) do {} while (0)
+#define spin_lock_irqsave(lock, flags) do {} while (0)
+#define spin_unlock_irqrestore(lock, flags) do {} while (0)
+
+#define setup_timer(timer, func, data) do {} while (0)
+#define del_timer_sync(timer) do {} while (0)
+#define schedule_work(work) do {} while (0)
+#define INIT_WORK(work, fun) do {} while (0)
+
+#define cpu_relax() do {} while (0)
+
+#define pr_debug(fmt, args...) debug(fmt, ##args)
+#define dev_dbg(dev, fmt, args...)             \
+       debug(fmt, ##args)
+#define dev_vdbg(dev, fmt, args...)            \
+       debug(fmt, ##args)
+#define dev_info(dev, fmt, args...)            \
+       printf(fmt, ##args)
+#define dev_err(dev, fmt, args...)             \
+       printf(fmt, ##args)
+#define printk printf
+
+#define WARN(condition, fmt, args...) ({       \
+       int ret_warn = !!condition;             \
+       if (ret_warn)                           \
+               printf(fmt, ##args);            \
+       ret_warn; })
+
+#define KERN_DEBUG
+#define KERN_NOTICE
+#define KERN_WARNING
+#define KERN_ERR
+
+#define kfree(ptr) free(ptr)
+
+#define pm_runtime_get_sync(dev) do {} while (0)
+#define pm_runtime_put(dev) do {} while (0)
+#define pm_runtime_put_sync(dev) do {} while (0)
+#define pm_runtime_use_autosuspend(dev) do {} while (0)
+#define pm_runtime_set_autosuspend_delay(dev, delay) do {} while (0)
+#define pm_runtime_enable(dev) do {} while (0)
+
+#define MODULE_DESCRIPTION(desc)
+#define MODULE_AUTHOR(author)
+#define MODULE_LICENSE(license)
+#define MODULE_ALIAS(alias)
+#define module_param(name, type, perm)
+#define MODULE_PARM_DESC(name, desc)
+#define EXPORT_SYMBOL_GPL(name)
+
+#define writesl(a, d, s) __raw_writesl((unsigned long)a, d, s)
+#define readsl(a, d, s) __raw_readsl((unsigned long)a, d, s)
+#define writesw(a, d, s) __raw_writesw((unsigned long)a, d, s)
+#define readsw(a, d, s) __raw_readsw((unsigned long)a, d, s)
+#define writesb(a, d, s) __raw_writesb((unsigned long)a, d, s)
+#define readsb(a, d, s) __raw_readsb((unsigned long)a, d, s)
+
+#define IRQ_NONE 0
+#define IRQ_HANDLED 0
+
+#define dev_set_drvdata(dev, data) do {} while (0)
+
+#define disable_irq_wake(irq) do {} while (0)
+#define enable_irq_wake(irq) -EINVAL
+#define free_irq(irq, data) do {} while (0)
+#define request_irq(nr, f, flags, nm, data) 0
+
+#define device_init_wakeup(dev, a) do {} while (0)
+
+#define platform_data device_data
+
+#ifndef wmb
+#define wmb()                  asm volatile (""   : : : "memory")
+#endif
+
+#define msleep(a)      udelay(a * 1000)
+
+/*
+ * Map U-Boot config options to Linux ones
+ */
+#ifdef CONFIG_OMAP34XX
+#define CONFIG_SOC_OMAP3430
+#endif
+
+#endif /* __LINUX_COMPAT_H__ */
diff --git a/drivers/usb/musb-new/musb_core.c b/drivers/usb/musb-new/musb_core.c
new file mode 100644 (file)
index 0000000..040a5c0
--- /dev/null
@@ -0,0 +1,2497 @@
+/*
+ * MUSB OTG driver core code
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+/*
+ * Inventra (Multipoint) Dual-Role Controller Driver for Linux.
+ *
+ * This consists of a Host Controller Driver (HCD) and a peripheral
+ * controller driver implementing the "Gadget" API; OTG support is
+ * in the works.  These are normal Linux-USB controller drivers which
+ * use IRQs and have no dedicated thread.
+ *
+ * This version of the driver has only been used with products from
+ * Texas Instruments.  Those products integrate the Inventra logic
+ * with other DMA, IRQ, and bus modules, as well as other logic that
+ * needs to be reflected in this driver.
+ *
+ *
+ * NOTE:  the original Mentor code here was pretty much a collection
+ * of mechanisms that don't seem to have been fully integrated/working
+ * for *any* Linux kernel version.  This version aims at Linux 2.6.now,
+ * Key open issues include:
+ *
+ *  - Lack of host-side transaction scheduling, for all transfer types.
+ *    The hardware doesn't do it; instead, software must.
+ *
+ *    This is not an issue for OTG devices that don't support external
+ *    hubs, but for more "normal" USB hosts it's a user issue that the
+ *    "multipoint" support doesn't scale in the expected ways.  That
+ *    includes DaVinci EVM in a common non-OTG mode.
+ *
+ *      * Control and bulk use dedicated endpoints, and there's as
+ *        yet no mechanism to either (a) reclaim the hardware when
+ *        peripherals are NAKing, which gets complicated with bulk
+ *        endpoints, or (b) use more than a single bulk endpoint in
+ *        each direction.
+ *
+ *        RESULT:  one device may be perceived as blocking another one.
+ *
+ *      * Interrupt and isochronous will dynamically allocate endpoint
+ *        hardware, but (a) there's no record keeping for bandwidth;
+ *        (b) in the common case that few endpoints are available, there
+ *        is no mechanism to reuse endpoints to talk to multiple devices.
+ *
+ *        RESULT:  At one extreme, bandwidth can be overcommitted in
+ *        some hardware configurations, no faults will be reported.
+ *        At the other extreme, the bandwidth capabilities which do
+ *        exist tend to be severely undercommitted.  You can't yet hook
+ *        up both a keyboard and a mouse to an external USB hub.
+ */
+
+/*
+ * This gets many kinds of configuration information:
+ *     - Kconfig for everything user-configurable
+ *     - platform_device for addressing, irq, and platform_data
+ *     - platform_data is mostly for board-specific informarion
+ *       (plus recentrly, SOC or family details)
+ *
+ * Most of the conditional compilation will (someday) vanish.
+ */
+
+#define __UBOOT__
+#ifndef __UBOOT__
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/prefetch.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#else
+#include <common.h>
+#include <usb.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
+#include <asm/io.h>
+#include "linux-compat.h"
+#include "usb-compat.h"
+#endif
+
+#include "musb_core.h"
+
+#define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON)
+
+
+#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
+#define DRIVER_DESC "Inventra Dual-Role USB Controller Driver"
+
+#define MUSB_VERSION "6.0"
+
+#define DRIVER_INFO DRIVER_DESC ", v" MUSB_VERSION
+
+#define MUSB_DRIVER_NAME "musb-hdrc"
+const char musb_driver_name[] = MUSB_DRIVER_NAME;
+
+MODULE_DESCRIPTION(DRIVER_INFO);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MUSB_DRIVER_NAME);
+
+
+#ifndef __UBOOT__
+/*-------------------------------------------------------------------------*/
+
+static inline struct musb *dev_to_musb(struct device *dev)
+{
+       return dev_get_drvdata(dev);
+}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#ifndef __UBOOT__
+#ifndef CONFIG_BLACKFIN
+static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
+{
+       void __iomem *addr = phy->io_priv;
+       int     i = 0;
+       u8      r;
+       u8      power;
+       int     ret;
+
+       pm_runtime_get_sync(phy->io_dev);
+
+       /* Make sure the transceiver is not in low power mode */
+       power = musb_readb(addr, MUSB_POWER);
+       power &= ~MUSB_POWER_SUSPENDM;
+       musb_writeb(addr, MUSB_POWER, power);
+
+       /* REVISIT: musbhdrc_ulpi_an.pdf recommends setting the
+        * ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM.
+        */
+
+       musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
+       musb_writeb(addr, MUSB_ULPI_REG_CONTROL,
+                       MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);
+
+       while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
+                               & MUSB_ULPI_REG_CMPLT)) {
+               i++;
+               if (i == 10000) {
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
+
+       }
+       r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
+       r &= ~MUSB_ULPI_REG_CMPLT;
+       musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
+
+       ret = musb_readb(addr, MUSB_ULPI_REG_DATA);
+
+out:
+       pm_runtime_put(phy->io_dev);
+
+       return ret;
+}
+
+static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
+{
+       void __iomem *addr = phy->io_priv;
+       int     i = 0;
+       u8      r = 0;
+       u8      power;
+       int     ret = 0;
+
+       pm_runtime_get_sync(phy->io_dev);
+
+       /* Make sure the transceiver is not in low power mode */
+       power = musb_readb(addr, MUSB_POWER);
+       power &= ~MUSB_POWER_SUSPENDM;
+       musb_writeb(addr, MUSB_POWER, power);
+
+       musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
+       musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data);
+       musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ);
+
+       while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
+                               & MUSB_ULPI_REG_CMPLT)) {
+               i++;
+               if (i == 10000) {
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
+       }
+
+       r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
+       r &= ~MUSB_ULPI_REG_CMPLT;
+       musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
+
+out:
+       pm_runtime_put(phy->io_dev);
+
+       return ret;
+}
+#else
+#define musb_ulpi_read         NULL
+#define musb_ulpi_write                NULL
+#endif
+
+static struct usb_phy_io_ops musb_ulpi_access = {
+       .read = musb_ulpi_read,
+       .write = musb_ulpi_write,
+};
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if !defined(CONFIG_USB_MUSB_TUSB6010) && !defined(CONFIG_USB_MUSB_BLACKFIN)
+
+/*
+ * Load an endpoint's FIFO
+ */
+void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
+{
+       struct musb *musb = hw_ep->musb;
+       void __iomem *fifo = hw_ep->fifo;
+
+       prefetch((u8 *)src);
+
+       dev_dbg(musb->controller, "%cX ep%d fifo %p count %d buf %p\n",
+                       'T', hw_ep->epnum, fifo, len, src);
+
+       /* we can't assume unaligned reads work */
+       if (likely((0x01 & (unsigned long) src) == 0)) {
+               u16     index = 0;
+
+               /* best case is 32bit-aligned source address */
+               if ((0x02 & (unsigned long) src) == 0) {
+                       if (len >= 4) {
+                               writesl(fifo, src + index, len >> 2);
+                               index += len & ~0x03;
+                       }
+                       if (len & 0x02) {
+                               musb_writew(fifo, 0, *(u16 *)&src[index]);
+                               index += 2;
+                       }
+               } else {
+                       if (len >= 2) {
+                               writesw(fifo, src + index, len >> 1);
+                               index += len & ~0x01;
+                       }
+               }
+               if (len & 0x01)
+                       musb_writeb(fifo, 0, src[index]);
+       } else  {
+               /* byte aligned */
+               writesb(fifo, src, len);
+       }
+}
+
+#if !defined(CONFIG_USB_MUSB_AM35X)
+/*
+ * Unload an endpoint's FIFO
+ */
+void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
+{
+       struct musb *musb = hw_ep->musb;
+       void __iomem *fifo = hw_ep->fifo;
+
+       dev_dbg(musb->controller, "%cX ep%d fifo %p count %d buf %p\n",
+                       'R', hw_ep->epnum, fifo, len, dst);
+
+       /* we can't assume unaligned writes work */
+       if (likely((0x01 & (unsigned long) dst) == 0)) {
+               u16     index = 0;
+
+               /* best case is 32bit-aligned destination address */
+               if ((0x02 & (unsigned long) dst) == 0) {
+                       if (len >= 4) {
+                               readsl(fifo, dst, len >> 2);
+                               index = len & ~0x03;
+                       }
+                       if (len & 0x02) {
+                               *(u16 *)&dst[index] = musb_readw(fifo, 0);
+                               index += 2;
+                       }
+               } else {
+                       if (len >= 2) {
+                               readsw(fifo, dst, len >> 1);
+                               index = len & ~0x01;
+                       }
+               }
+               if (len & 0x01)
+                       dst[index] = musb_readb(fifo, 0);
+       } else  {
+               /* byte aligned */
+               readsb(fifo, dst, len);
+       }
+}
+#endif
+
+#endif /* normal PIO */
+
+
+/*-------------------------------------------------------------------------*/
+
+/* for high speed test mode; see USB 2.0 spec 7.1.20 */
+static const u8 musb_test_packet[53] = {
+       /* implicit SYNC then DATA0 to start */
+
+       /* JKJKJKJK x9 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* JJKKJJKK x8 */
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       /* JJJJKKKK x8 */
+       0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
+       /* JJJJJJJKKKKKKK x8 */
+       0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* JJJJJJJK x8 */
+       0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd,
+       /* JKKKKKKK x10, JK */
+       0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e
+
+       /* implicit CRC16 then EOP to end */
+};
+
+void musb_load_testpacket(struct musb *musb)
+{
+       void __iomem    *regs = musb->endpoints[0].regs;
+
+       musb_ep_select(musb->mregs, 0);
+       musb_write_fifo(musb->control_ep,
+                       sizeof(musb_test_packet), musb_test_packet);
+       musb_writew(regs, MUSB_CSR0, MUSB_CSR0_TXPKTRDY);
+}
+
+#ifndef __UBOOT__
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Handles OTG hnp timeouts, such as b_ase0_brst
+ */
+void musb_otg_timer_func(unsigned long data)
+{
+       struct musb     *musb = (struct musb *)data;
+       unsigned long   flags;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       switch (musb->xceiv->state) {
+       case OTG_STATE_B_WAIT_ACON:
+               dev_dbg(musb->controller, "HNP: b_wait_acon timeout; back to b_peripheral\n");
+               musb_g_disconnect(musb);
+               musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+               musb->is_active = 0;
+               break;
+       case OTG_STATE_A_SUSPEND:
+       case OTG_STATE_A_WAIT_BCON:
+               dev_dbg(musb->controller, "HNP: %s timeout\n",
+                       otg_state_string(musb->xceiv->state));
+               musb_platform_set_vbus(musb, 0);
+               musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
+               break;
+       default:
+               dev_dbg(musb->controller, "HNP: Unhandled mode %s\n",
+                       otg_state_string(musb->xceiv->state));
+       }
+       musb->ignore_disconnect = 0;
+       spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+/*
+ * Stops the HNP transition. Caller must take care of locking.
+ */
+void musb_hnp_stop(struct musb *musb)
+{
+       struct usb_hcd  *hcd = musb_to_hcd(musb);
+       void __iomem    *mbase = musb->mregs;
+       u8      reg;
+
+       dev_dbg(musb->controller, "HNP: stop from %s\n", otg_state_string(musb->xceiv->state));
+
+       switch (musb->xceiv->state) {
+       case OTG_STATE_A_PERIPHERAL:
+               musb_g_disconnect(musb);
+               dev_dbg(musb->controller, "HNP: back to %s\n",
+                       otg_state_string(musb->xceiv->state));
+               break;
+       case OTG_STATE_B_HOST:
+               dev_dbg(musb->controller, "HNP: Disabling HR\n");
+               hcd->self.is_b_host = 0;
+               musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+               MUSB_DEV_MODE(musb);
+               reg = musb_readb(mbase, MUSB_POWER);
+               reg |= MUSB_POWER_SUSPENDM;
+               musb_writeb(mbase, MUSB_POWER, reg);
+               /* REVISIT: Start SESSION_REQUEST here? */
+               break;
+       default:
+               dev_dbg(musb->controller, "HNP: Stopping in unknown state %s\n",
+                       otg_state_string(musb->xceiv->state));
+       }
+
+       /*
+        * When returning to A state after HNP, avoid hub_port_rebounce(),
+        * which cause occasional OPT A "Did not receive reset after connect"
+        * errors.
+        */
+       musb->port1_status &= ~(USB_PORT_STAT_C_CONNECTION << 16);
+}
+#endif
+
+/*
+ * Interrupt Service Routine to record USB "global" interrupts.
+ * Since these do not happen often and signify things of
+ * paramount importance, it seems OK to check them individually;
+ * the order of the tests is specified in the manual
+ *
+ * @param musb instance pointer
+ * @param int_usb register contents
+ * @param devctl
+ * @param power
+ */
+
+static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
+                               u8 devctl, u8 power)
+{
+#ifndef __UBOOT__
+       struct usb_otg *otg = musb->xceiv->otg;
+#endif
+       irqreturn_t handled = IRQ_NONE;
+
+       dev_dbg(musb->controller, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
+               int_usb);
+
+#ifndef __UBOOT__
+       /* in host mode, the peripheral may issue remote wakeup.
+        * in peripheral mode, the host may resume the link.
+        * spurious RESUME irqs happen too, paired with SUSPEND.
+        */
+       if (int_usb & MUSB_INTR_RESUME) {
+               handled = IRQ_HANDLED;
+               dev_dbg(musb->controller, "RESUME (%s)\n", otg_state_string(musb->xceiv->state));
+
+               if (devctl & MUSB_DEVCTL_HM) {
+                       void __iomem *mbase = musb->mregs;
+
+                       switch (musb->xceiv->state) {
+                       case OTG_STATE_A_SUSPEND:
+                               /* remote wakeup?  later, GetPortStatus
+                                * will stop RESUME signaling
+                                */
+
+                               if (power & MUSB_POWER_SUSPENDM) {
+                                       /* spurious */
+                                       musb->int_usb &= ~MUSB_INTR_SUSPEND;
+                                       dev_dbg(musb->controller, "Spurious SUSPENDM\n");
+                                       break;
+                               }
+
+                               power &= ~MUSB_POWER_SUSPENDM;
+                               musb_writeb(mbase, MUSB_POWER,
+                                               power | MUSB_POWER_RESUME);
+
+                               musb->port1_status |=
+                                               (USB_PORT_STAT_C_SUSPEND << 16)
+                                               | MUSB_PORT_STAT_RESUME;
+                               musb->rh_timer = jiffies
+                                               + msecs_to_jiffies(20);
+
+                               musb->xceiv->state = OTG_STATE_A_HOST;
+                               musb->is_active = 1;
+                               usb_hcd_resume_root_hub(musb_to_hcd(musb));
+                               break;
+                       case OTG_STATE_B_WAIT_ACON:
+                               musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+                               musb->is_active = 1;
+                               MUSB_DEV_MODE(musb);
+                               break;
+                       default:
+                               WARNING("bogus %s RESUME (%s)\n",
+                                       "host",
+                                       otg_state_string(musb->xceiv->state));
+                       }
+               } else {
+                       switch (musb->xceiv->state) {
+                       case OTG_STATE_A_SUSPEND:
+                               /* possibly DISCONNECT is upcoming */
+                               musb->xceiv->state = OTG_STATE_A_HOST;
+                               usb_hcd_resume_root_hub(musb_to_hcd(musb));
+                               break;
+                       case OTG_STATE_B_WAIT_ACON:
+                       case OTG_STATE_B_PERIPHERAL:
+                               /* disconnect while suspended?  we may
+                                * not get a disconnect irq...
+                                */
+                               if ((devctl & MUSB_DEVCTL_VBUS)
+                                               != (3 << MUSB_DEVCTL_VBUS_SHIFT)
+                                               ) {
+                                       musb->int_usb |= MUSB_INTR_DISCONNECT;
+                                       musb->int_usb &= ~MUSB_INTR_SUSPEND;
+                                       break;
+                               }
+                               musb_g_resume(musb);
+                               break;
+                       case OTG_STATE_B_IDLE:
+                               musb->int_usb &= ~MUSB_INTR_SUSPEND;
+                               break;
+                       default:
+                               WARNING("bogus %s RESUME (%s)\n",
+                                       "peripheral",
+                                       otg_state_string(musb->xceiv->state));
+                       }
+               }
+       }
+
+       /* see manual for the order of the tests */
+       if (int_usb & MUSB_INTR_SESSREQ) {
+               void __iomem *mbase = musb->mregs;
+
+               if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS
+                               && (devctl & MUSB_DEVCTL_BDEVICE)) {
+                       dev_dbg(musb->controller, "SessReq while on B state\n");
+                       return IRQ_HANDLED;
+               }
+
+               dev_dbg(musb->controller, "SESSION_REQUEST (%s)\n",
+                       otg_state_string(musb->xceiv->state));
+
+               /* IRQ arrives from ID pin sense or (later, if VBUS power
+                * is removed) SRP.  responses are time critical:
+                *  - turn on VBUS (with silicon-specific mechanism)
+                *  - go through A_WAIT_VRISE
+                *  - ... to A_WAIT_BCON.
+                * a_wait_vrise_tmout triggers VBUS_ERROR transitions
+                */
+               musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
+               musb->ep0_stage = MUSB_EP0_START;
+               musb->xceiv->state = OTG_STATE_A_IDLE;
+               MUSB_HST_MODE(musb);
+               musb_platform_set_vbus(musb, 1);
+
+               handled = IRQ_HANDLED;
+       }
+
+       if (int_usb & MUSB_INTR_VBUSERROR) {
+               int     ignore = 0;
+
+               /* During connection as an A-Device, we may see a short
+                * current spikes causing voltage drop, because of cable
+                * and peripheral capacitance combined with vbus draw.
+                * (So: less common with truly self-powered devices, where
+                * vbus doesn't act like a power supply.)
+                *
+                * Such spikes are short; usually less than ~500 usec, max
+                * of ~2 msec.  That is, they're not sustained overcurrent
+                * errors, though they're reported using VBUSERROR irqs.
+                *
+                * Workarounds:  (a) hardware: use self powered devices.
+                * (b) software:  ignore non-repeated VBUS errors.
+                *
+                * REVISIT:  do delays from lots of DEBUG_KERNEL checks
+                * make trouble here, keeping VBUS < 4.4V ?
+                */
+               switch (musb->xceiv->state) {
+               case OTG_STATE_A_HOST:
+                       /* recovery is dicey once we've gotten past the
+                        * initial stages of enumeration, but if VBUS
+                        * stayed ok at the other end of the link, and
+                        * another reset is due (at least for high speed,
+                        * to redo the chirp etc), it might work OK...
+                        */
+               case OTG_STATE_A_WAIT_BCON:
+               case OTG_STATE_A_WAIT_VRISE:
+                       if (musb->vbuserr_retry) {
+                               void __iomem *mbase = musb->mregs;
+
+                               musb->vbuserr_retry--;
+                               ignore = 1;
+                               devctl |= MUSB_DEVCTL_SESSION;
+                               musb_writeb(mbase, MUSB_DEVCTL, devctl);
+                       } else {
+                               musb->port1_status |=
+                                         USB_PORT_STAT_OVERCURRENT
+                                       | (USB_PORT_STAT_C_OVERCURRENT << 16);
+                       }
+                       break;
+               default:
+                       break;
+               }
+
+               dev_dbg(musb->controller, "VBUS_ERROR in %s (%02x, %s), retry #%d, port1 %08x\n",
+                               otg_state_string(musb->xceiv->state),
+                               devctl,
+                               ({ char *s;
+                               switch (devctl & MUSB_DEVCTL_VBUS) {
+                               case 0 << MUSB_DEVCTL_VBUS_SHIFT:
+                                       s = "<SessEnd"; break;
+                               case 1 << MUSB_DEVCTL_VBUS_SHIFT:
+                                       s = "<AValid"; break;
+                               case 2 << MUSB_DEVCTL_VBUS_SHIFT:
+                                       s = "<VBusValid"; break;
+                               /* case 3 << MUSB_DEVCTL_VBUS_SHIFT: */
+                               default:
+                                       s = "VALID"; break;
+                               }; s; }),
+                               VBUSERR_RETRY_COUNT - musb->vbuserr_retry,
+                               musb->port1_status);
+
+               /* go through A_WAIT_VFALL then start a new session */
+               if (!ignore)
+                       musb_platform_set_vbus(musb, 0);
+               handled = IRQ_HANDLED;
+       }
+
+       if (int_usb & MUSB_INTR_SUSPEND) {
+               dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x power %02x\n",
+                       otg_state_string(musb->xceiv->state), devctl, power);
+               handled = IRQ_HANDLED;
+
+               switch (musb->xceiv->state) {
+               case OTG_STATE_A_PERIPHERAL:
+                       /* We also come here if the cable is removed, since
+                        * this silicon doesn't report ID-no-longer-grounded.
+                        *
+                        * We depend on T(a_wait_bcon) to shut us down, and
+                        * hope users don't do anything dicey during this
+                        * undesired detour through A_WAIT_BCON.
+                        */
+                       musb_hnp_stop(musb);
+                       usb_hcd_resume_root_hub(musb_to_hcd(musb));
+                       musb_root_disconnect(musb);
+                       musb_platform_try_idle(musb, jiffies
+                                       + msecs_to_jiffies(musb->a_wait_bcon
+                                               ? : OTG_TIME_A_WAIT_BCON));
+
+                       break;
+               case OTG_STATE_B_IDLE:
+                       if (!musb->is_active)
+                               break;
+               case OTG_STATE_B_PERIPHERAL:
+                       musb_g_suspend(musb);
+                       musb->is_active = is_otg_enabled(musb)
+                                       && otg->gadget->b_hnp_enable;
+                       if (musb->is_active) {
+                               musb->xceiv->state = OTG_STATE_B_WAIT_ACON;
+                               dev_dbg(musb->controller, "HNP: Setting timer for b_ase0_brst\n");
+                               mod_timer(&musb->otg_timer, jiffies
+                                       + msecs_to_jiffies(
+                                                       OTG_TIME_B_ASE0_BRST));
+                       }
+                       break;
+               case OTG_STATE_A_WAIT_BCON:
+                       if (musb->a_wait_bcon != 0)
+                               musb_platform_try_idle(musb, jiffies
+                                       + msecs_to_jiffies(musb->a_wait_bcon));
+                       break;
+               case OTG_STATE_A_HOST:
+                       musb->xceiv->state = OTG_STATE_A_SUSPEND;
+                       musb->is_active = is_otg_enabled(musb)
+                                       && otg->host->b_hnp_enable;
+                       break;
+               case OTG_STATE_B_HOST:
+                       /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
+                       dev_dbg(musb->controller, "REVISIT: SUSPEND as B_HOST\n");
+                       break;
+               default:
+                       /* "should not happen" */
+                       musb->is_active = 0;
+                       break;
+               }
+       }
+#endif
+
+       if (int_usb & MUSB_INTR_CONNECT) {
+               struct usb_hcd *hcd = musb_to_hcd(musb);
+
+               handled = IRQ_HANDLED;
+               musb->is_active = 1;
+
+               musb->ep0_stage = MUSB_EP0_START;
+
+               /* flush endpoints when transitioning from Device Mode */
+               if (is_peripheral_active(musb)) {
+                       /* REVISIT HNP; just force disconnect */
+               }
+               musb_writew(musb->mregs, MUSB_INTRTXE, musb->epmask);
+               musb_writew(musb->mregs, MUSB_INTRRXE, musb->epmask & 0xfffe);
+               musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7);
+#ifndef __UBOOT__
+               musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED
+                                       |USB_PORT_STAT_HIGH_SPEED
+                                       |USB_PORT_STAT_ENABLE
+                                       );
+               musb->port1_status |= USB_PORT_STAT_CONNECTION
+                                       |(USB_PORT_STAT_C_CONNECTION << 16);
+
+               /* high vs full speed is just a guess until after reset */
+               if (devctl & MUSB_DEVCTL_LSDEV)
+                       musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
+
+               /* indicate new connection to OTG machine */
+               switch (musb->xceiv->state) {
+               case OTG_STATE_B_PERIPHERAL:
+                       if (int_usb & MUSB_INTR_SUSPEND) {
+                               dev_dbg(musb->controller, "HNP: SUSPEND+CONNECT, now b_host\n");
+                               int_usb &= ~MUSB_INTR_SUSPEND;
+                               goto b_host;
+                       } else
+                               dev_dbg(musb->controller, "CONNECT as b_peripheral???\n");
+                       break;
+               case OTG_STATE_B_WAIT_ACON:
+                       dev_dbg(musb->controller, "HNP: CONNECT, now b_host\n");
+b_host:
+                       musb->xceiv->state = OTG_STATE_B_HOST;
+                       hcd->self.is_b_host = 1;
+                       musb->ignore_disconnect = 0;
+                       del_timer(&musb->otg_timer);
+                       break;
+               default:
+                       if ((devctl & MUSB_DEVCTL_VBUS)
+                                       == (3 << MUSB_DEVCTL_VBUS_SHIFT)) {
+                               musb->xceiv->state = OTG_STATE_A_HOST;
+                               hcd->self.is_b_host = 0;
+                       }
+                       break;
+               }
+
+               /* poke the root hub */
+               MUSB_HST_MODE(musb);
+               if (hcd->status_urb)
+                       usb_hcd_poll_rh_status(hcd);
+               else
+                       usb_hcd_resume_root_hub(hcd);
+
+               dev_dbg(musb->controller, "CONNECT (%s) devctl %02x\n",
+                               otg_state_string(musb->xceiv->state), devctl);
+#endif
+       }
+
+#ifndef __UBOOT__
+       if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) {
+               dev_dbg(musb->controller, "DISCONNECT (%s) as %s, devctl %02x\n",
+                               otg_state_string(musb->xceiv->state),
+                               MUSB_MODE(musb), devctl);
+               handled = IRQ_HANDLED;
+
+               switch (musb->xceiv->state) {
+               case OTG_STATE_A_HOST:
+               case OTG_STATE_A_SUSPEND:
+                       usb_hcd_resume_root_hub(musb_to_hcd(musb));
+                       musb_root_disconnect(musb);
+                       if (musb->a_wait_bcon != 0 && is_otg_enabled(musb))
+                               musb_platform_try_idle(musb, jiffies
+                                       + msecs_to_jiffies(musb->a_wait_bcon));
+                       break;
+               case OTG_STATE_B_HOST:
+                       /* REVISIT this behaves for "real disconnect"
+                        * cases; make sure the other transitions from
+                        * from B_HOST act right too.  The B_HOST code
+                        * in hnp_stop() is currently not used...
+                        */
+                       musb_root_disconnect(musb);
+                       musb_to_hcd(musb)->self.is_b_host = 0;
+                       musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+                       MUSB_DEV_MODE(musb);
+                       musb_g_disconnect(musb);
+                       break;
+               case OTG_STATE_A_PERIPHERAL:
+                       musb_hnp_stop(musb);
+                       musb_root_disconnect(musb);
+                       /* FALLTHROUGH */
+               case OTG_STATE_B_WAIT_ACON:
+                       /* FALLTHROUGH */
+               case OTG_STATE_B_PERIPHERAL:
+               case OTG_STATE_B_IDLE:
+                       musb_g_disconnect(musb);
+                       break;
+               default:
+                       WARNING("unhandled DISCONNECT transition (%s)\n",
+                               otg_state_string(musb->xceiv->state));
+                       break;
+               }
+       }
+
+       /* mentor saves a bit: bus reset and babble share the same irq.
+        * only host sees babble; only peripheral sees bus reset.
+        */
+       if (int_usb & MUSB_INTR_RESET) {
+               handled = IRQ_HANDLED;
+               if (is_host_capable() && (devctl & MUSB_DEVCTL_HM) != 0) {
+                       /*
+                        * Looks like non-HS BABBLE can be ignored, but
+                        * HS BABBLE is an error condition. For HS the solution
+                        * is to avoid babble in the first place and fix what
+                        * caused BABBLE. When HS BABBLE happens we can only
+                        * stop the session.
+                        */
+                       if (devctl & (MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV))
+                               dev_dbg(musb->controller, "BABBLE devctl: %02x\n", devctl);
+                       else {
+                               ERR("Stopping host session -- babble\n");
+                               musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+                       }
+               } else if (is_peripheral_capable()) {
+                       dev_dbg(musb->controller, "BUS RESET as %s\n",
+                               otg_state_string(musb->xceiv->state));
+                       switch (musb->xceiv->state) {
+                       case OTG_STATE_A_SUSPEND:
+                               /* We need to ignore disconnect on suspend
+                                * otherwise tusb 2.0 won't reconnect after a
+                                * power cycle, which breaks otg compliance.
+                                */
+                               musb->ignore_disconnect = 1;
+                               musb_g_reset(musb);
+                               /* FALLTHROUGH */
+                       case OTG_STATE_A_WAIT_BCON:     /* OPT TD.4.7-900ms */
+                               /* never use invalid T(a_wait_bcon) */
+                               dev_dbg(musb->controller, "HNP: in %s, %d msec timeout\n",
+                                       otg_state_string(musb->xceiv->state),
+                                       TA_WAIT_BCON(musb));
+                               mod_timer(&musb->otg_timer, jiffies
+                                       + msecs_to_jiffies(TA_WAIT_BCON(musb)));
+                               break;
+                       case OTG_STATE_A_PERIPHERAL:
+                               musb->ignore_disconnect = 0;
+                               del_timer(&musb->otg_timer);
+                               musb_g_reset(musb);
+                               break;
+                       case OTG_STATE_B_WAIT_ACON:
+                               dev_dbg(musb->controller, "HNP: RESET (%s), to b_peripheral\n",
+                                       otg_state_string(musb->xceiv->state));
+                               musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+                               musb_g_reset(musb);
+                               break;
+                       case OTG_STATE_B_IDLE:
+                               musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+                               /* FALLTHROUGH */
+                       case OTG_STATE_B_PERIPHERAL:
+                               musb_g_reset(musb);
+                               break;
+                       default:
+                               dev_dbg(musb->controller, "Unhandled BUS RESET as %s\n",
+                                       otg_state_string(musb->xceiv->state));
+                       }
+               }
+       }
+#endif
+
+#if 0
+/* REVISIT ... this would be for multiplexing periodic endpoints, or
+ * supporting transfer phasing to prevent exceeding ISO bandwidth
+ * limits of a given frame or microframe.
+ *
+ * It's not needed for peripheral side, which dedicates endpoints;
+ * though it _might_ use SOF irqs for other purposes.
+ *
+ * And it's not currently needed for host side, which also dedicates
+ * endpoints, relies on TX/RX interval registers, and isn't claimed
+ * to support ISO transfers yet.
+ */
+       if (int_usb & MUSB_INTR_SOF) {
+               void __iomem *mbase = musb->mregs;
+               struct musb_hw_ep       *ep;
+               u8 epnum;
+               u16 frame;
+
+               dev_dbg(musb->controller, "START_OF_FRAME\n");
+               handled = IRQ_HANDLED;
+
+               /* start any periodic Tx transfers waiting for current frame */
+               frame = musb_readw(mbase, MUSB_FRAME);
+               ep = musb->endpoints;
+               for (epnum = 1; (epnum < musb->nr_endpoints)
+                                       && (musb->epmask >= (1 << epnum));
+                               epnum++, ep++) {
+                       /*
+                        * FIXME handle framecounter wraps (12 bits)
+                        * eliminate duplicated StartUrb logic
+                        */
+                       if (ep->dwWaitFrame >= frame) {
+                               ep->dwWaitFrame = 0;
+                               pr_debug("SOF --> periodic TX%s on %d\n",
+                                       ep->tx_channel ? " DMA" : "",
+                                       epnum);
+                               if (!ep->tx_channel)
+                                       musb_h_tx_start(musb, epnum);
+                               else
+                                       cppi_hostdma_start(musb, epnum);
+                       }
+               }               /* end of for loop */
+       }
+#endif
+
+       schedule_work(&musb->irq_work);
+
+       return handled;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+* Program the HDRC to start (enable interrupts, dma, etc.).
+*/
+void musb_start(struct musb *musb)
+{
+       void __iomem    *regs = musb->mregs;
+       u8              devctl = musb_readb(regs, MUSB_DEVCTL);
+
+       dev_dbg(musb->controller, "<== devctl %02x\n", devctl);
+
+       /*  Set INT enable registers, enable interrupts */
+       musb_writew(regs, MUSB_INTRTXE, musb->epmask);
+       musb_writew(regs, MUSB_INTRRXE, musb->epmask & 0xfffe);
+       musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
+
+       musb_writeb(regs, MUSB_TESTMODE, 0);
+
+       /* put into basic highspeed mode and start session */
+       musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
+                                               | MUSB_POWER_HSENAB
+                                               /* ENSUSPEND wedges tusb */
+                                               /* | MUSB_POWER_ENSUSPEND */
+                                               );
+
+       musb->is_active = 0;
+       devctl = musb_readb(regs, MUSB_DEVCTL);
+       devctl &= ~MUSB_DEVCTL_SESSION;
+
+       if (is_otg_enabled(musb)) {
+#ifndef __UBOOT__
+               /* session started after:
+                * (a) ID-grounded irq, host mode;
+                * (b) vbus present/connect IRQ, peripheral mode;
+                * (c) peripheral initiates, using SRP
+                */
+               if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
+                       musb->is_active = 1;
+               else
+                       devctl |= MUSB_DEVCTL_SESSION;
+#endif
+
+       } else if (is_host_enabled(musb)) {
+               /* assume ID pin is hard-wired to ground */
+               devctl |= MUSB_DEVCTL_SESSION;
+
+       } else /* peripheral is enabled */ {
+               if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
+                       musb->is_active = 1;
+       }
+       musb_platform_enable(musb);
+       musb_writeb(regs, MUSB_DEVCTL, devctl);
+}
+
+
+static void musb_generic_disable(struct musb *musb)
+{
+       void __iomem    *mbase = musb->mregs;
+       u16     temp;
+
+       /* disable interrupts */
+       musb_writeb(mbase, MUSB_INTRUSBE, 0);
+       musb_writew(mbase, MUSB_INTRTXE, 0);
+       musb_writew(mbase, MUSB_INTRRXE, 0);
+
+       /* off */
+       musb_writeb(mbase, MUSB_DEVCTL, 0);
+
+       /*  flush pending interrupts */
+       temp = musb_readb(mbase, MUSB_INTRUSB);
+       temp = musb_readw(mbase, MUSB_INTRTX);
+       temp = musb_readw(mbase, MUSB_INTRRX);
+
+}
+
+/*
+ * Make the HDRC stop (disable interrupts, etc.);
+ * reversible by musb_start
+ * called on gadget driver unregister
+ * with controller locked, irqs blocked
+ * acts as a NOP unless some role activated the hardware
+ */
+void musb_stop(struct musb *musb)
+{
+       /* stop IRQs, timers, ... */
+       musb_platform_disable(musb);
+       musb_generic_disable(musb);
+       dev_dbg(musb->controller, "HDRC disabled\n");
+
+       /* FIXME
+        *  - mark host and/or peripheral drivers unusable/inactive
+        *  - disable DMA (and enable it in HdrcStart)
+        *  - make sure we can musb_start() after musb_stop(); with
+        *    OTG mode, gadget driver module rmmod/modprobe cycles that
+        *  - ...
+        */
+       musb_platform_try_idle(musb, 0);
+}
+
+#ifndef __UBOOT__
+static void musb_shutdown(struct platform_device *pdev)
+{
+       struct musb     *musb = dev_to_musb(&pdev->dev);
+       unsigned long   flags;
+
+       pm_runtime_get_sync(musb->controller);
+
+       musb_gadget_cleanup(musb);
+
+       spin_lock_irqsave(&musb->lock, flags);
+       musb_platform_disable(musb);
+       musb_generic_disable(musb);
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       if (!is_otg_enabled(musb) && is_host_enabled(musb))
+               usb_remove_hcd(musb_to_hcd(musb));
+       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+       musb_platform_exit(musb);
+
+       pm_runtime_put(musb->controller);
+       /* FIXME power down */
+}
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * The silicon either has hard-wired endpoint configurations, or else
+ * "dynamic fifo" sizing.  The driver has support for both, though at this
+ * writing only the dynamic sizing is very well tested.   Since we switched
+ * away from compile-time hardware parameters, we can no longer rely on
+ * dead code elimination to leave only the relevant one in the object file.
+ *
+ * We don't currently use dynamic fifo setup capability to do anything
+ * more than selecting one of a bunch of predefined configurations.
+ */
+#if defined(CONFIG_USB_MUSB_TUSB6010)                  \
+       || defined(CONFIG_USB_MUSB_TUSB6010_MODULE)     \
+       || defined(CONFIG_USB_MUSB_OMAP2PLUS)           \
+       || defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE)    \
+       || defined(CONFIG_USB_MUSB_AM35X)               \
+       || defined(CONFIG_USB_MUSB_AM35X_MODULE)        \
+       || defined(CONFIG_USB_MUSB_DSPS)                \
+       || defined(CONFIG_USB_MUSB_DSPS_MODULE)
+static ushort __devinitdata fifo_mode = 4;
+#elif defined(CONFIG_USB_MUSB_UX500)                   \
+       || defined(CONFIG_USB_MUSB_UX500_MODULE)
+static ushort __devinitdata fifo_mode = 5;
+#else
+static ushort __devinitdata fifo_mode = 2;
+#endif
+
+/* "modprobe ... fifo_mode=1" etc */
+module_param(fifo_mode, ushort, 0);
+MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration");
+
+/*
+ * tables defining fifo_mode values.  define more if you like.
+ * for host side, make sure both halves of ep1 are set up.
+ */
+
+/* mode 0 - fits in 2KB */
+static struct musb_fifo_cfg __devinitdata mode_0_cfg[] = {
+{ .hw_ep_num = 1, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num = 1, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, },
+{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, },
+{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, },
+};
+
+/* mode 1 - fits in 4KB */
+static struct musb_fifo_cfg __devinitdata mode_1_cfg[] = {
+{ .hw_ep_num = 1, .style = FIFO_TX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
+{ .hw_ep_num = 1, .style = FIFO_RX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
+{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, },
+{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, },
+{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, },
+};
+
+/* mode 2 - fits in 4KB */
+static struct musb_fifo_cfg __devinitdata mode_2_cfg[] = {
+{ .hw_ep_num = 1, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num = 1, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num = 2, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num = 2, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, },
+{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, },
+};
+
+/* mode 3 - fits in 4KB */
+static struct musb_fifo_cfg __devinitdata mode_3_cfg[] = {
+{ .hw_ep_num = 1, .style = FIFO_TX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
+{ .hw_ep_num = 1, .style = FIFO_RX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
+{ .hw_ep_num = 2, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num = 2, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, },
+{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, },
+};
+
+/* mode 4 - fits in 16KB */
+static struct musb_fifo_cfg __devinitdata mode_4_cfg[] = {
+{ .hw_ep_num =  1, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  1, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  2, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  2, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  3, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  3, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  4, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  4, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  5, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  5, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  6, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  6, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  7, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  7, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  8, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  8, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  9, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  9, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num = 10, .style = FIFO_TX,   .maxpacket = 256, },
+{ .hw_ep_num = 10, .style = FIFO_RX,   .maxpacket = 64, },
+{ .hw_ep_num = 11, .style = FIFO_TX,   .maxpacket = 256, },
+{ .hw_ep_num = 11, .style = FIFO_RX,   .maxpacket = 64, },
+{ .hw_ep_num = 12, .style = FIFO_TX,   .maxpacket = 256, },
+{ .hw_ep_num = 12, .style = FIFO_RX,   .maxpacket = 64, },
+{ .hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 4096, },
+{ .hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024, },
+{ .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, },
+};
+
+/* mode 5 - fits in 8KB */
+static struct musb_fifo_cfg __devinitdata mode_5_cfg[] = {
+{ .hw_ep_num =  1, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  1, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  2, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  2, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  3, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  3, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  4, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  4, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  5, .style = FIFO_TX,   .maxpacket = 512, },
+{ .hw_ep_num =  5, .style = FIFO_RX,   .maxpacket = 512, },
+{ .hw_ep_num =  6, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num =  6, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num =  7, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num =  7, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num =  8, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num =  8, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num =  9, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num =  9, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num = 10, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num = 10, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num = 11, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num = 11, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num = 12, .style = FIFO_TX,   .maxpacket = 32, },
+{ .hw_ep_num = 12, .style = FIFO_RX,   .maxpacket = 32, },
+{ .hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 512, },
+{ .hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024, },
+{ .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, },
+};
+
+/*
+ * configure a fifo; for non-shared endpoints, this may be called
+ * once for a tx fifo and once for an rx fifo.
+ *
+ * returns negative errno or offset for next fifo.
+ */
+static int __devinit
+fifo_setup(struct musb *musb, struct musb_hw_ep  *hw_ep,
+               const struct musb_fifo_cfg *cfg, u16 offset)
+{
+       void __iomem    *mbase = musb->mregs;
+       int     size = 0;
+       u16     maxpacket = cfg->maxpacket;
+       u16     c_off = offset >> 3;
+       u8      c_size;
+
+       /* expect hw_ep has already been zero-initialized */
+
+       size = ffs(max(maxpacket, (u16) 8)) - 1;
+       maxpacket = 1 << size;
+
+       c_size = size - 3;
+       if (cfg->mode == BUF_DOUBLE) {
+               if ((offset + (maxpacket << 1)) >
+                               (1 << (musb->config->ram_bits + 2)))
+                       return -EMSGSIZE;
+               c_size |= MUSB_FIFOSZ_DPB;
+       } else {
+               if ((offset + maxpacket) > (1 << (musb->config->ram_bits + 2)))
+                       return -EMSGSIZE;
+       }
+
+       /* configure the FIFO */
+       musb_writeb(mbase, MUSB_INDEX, hw_ep->epnum);
+
+       /* EP0 reserved endpoint for control, bidirectional;
+        * EP1 reserved for bulk, two unidirection halves.
+        */
+       if (hw_ep->epnum == 1)
+               musb->bulk_ep = hw_ep;
+       /* REVISIT error check:  be sure ep0 can both rx and tx ... */
+       switch (cfg->style) {
+       case FIFO_TX:
+               musb_write_txfifosz(mbase, c_size);
+               musb_write_txfifoadd(mbase, c_off);
+               hw_ep->tx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
+               hw_ep->max_packet_sz_tx = maxpacket;
+               break;
+       case FIFO_RX:
+               musb_write_rxfifosz(mbase, c_size);
+               musb_write_rxfifoadd(mbase, c_off);
+               hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
+               hw_ep->max_packet_sz_rx = maxpacket;
+               break;
+       case FIFO_RXTX:
+               musb_write_txfifosz(mbase, c_size);
+               musb_write_txfifoadd(mbase, c_off);
+               hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
+               hw_ep->max_packet_sz_rx = maxpacket;
+
+               musb_write_rxfifosz(mbase, c_size);
+               musb_write_rxfifoadd(mbase, c_off);
+               hw_ep->tx_double_buffered = hw_ep->rx_double_buffered;
+               hw_ep->max_packet_sz_tx = maxpacket;
+
+               hw_ep->is_shared_fifo = true;
+               break;
+       }
+
+       /* NOTE rx and tx endpoint irqs aren't managed separately,
+        * which happens to be ok
+        */
+       musb->epmask |= (1 << hw_ep->epnum);
+
+       return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0));
+}
+
+static struct musb_fifo_cfg __devinitdata ep0_cfg = {
+       .style = FIFO_RXTX, .maxpacket = 64,
+};
+
+static int __devinit ep_config_from_table(struct musb *musb)
+{
+       const struct musb_fifo_cfg      *cfg;
+       unsigned                i, n;
+       int                     offset;
+       struct musb_hw_ep       *hw_ep = musb->endpoints;
+
+       if (musb->config->fifo_cfg) {
+               cfg = musb->config->fifo_cfg;
+               n = musb->config->fifo_cfg_size;
+               goto done;
+       }
+
+       switch (fifo_mode) {
+       default:
+               fifo_mode = 0;
+               /* FALLTHROUGH */
+       case 0:
+               cfg = mode_0_cfg;
+               n = ARRAY_SIZE(mode_0_cfg);
+               break;
+       case 1:
+               cfg = mode_1_cfg;
+               n = ARRAY_SIZE(mode_1_cfg);
+               break;
+       case 2:
+               cfg = mode_2_cfg;
+               n = ARRAY_SIZE(mode_2_cfg);
+               break;
+       case 3:
+               cfg = mode_3_cfg;
+               n = ARRAY_SIZE(mode_3_cfg);
+               break;
+       case 4:
+               cfg = mode_4_cfg;
+               n = ARRAY_SIZE(mode_4_cfg);
+               break;
+       case 5:
+               cfg = mode_5_cfg;
+               n = ARRAY_SIZE(mode_5_cfg);
+               break;
+       }
+
+       printk(KERN_DEBUG "%s: setup fifo_mode %d\n",
+                       musb_driver_name, fifo_mode);
+
+
+done:
+       offset = fifo_setup(musb, hw_ep, &ep0_cfg, 0);
+       /* assert(offset > 0) */
+
+       /* NOTE:  for RTL versions >= 1.400 EPINFO and RAMINFO would
+        * be better than static musb->config->num_eps and DYN_FIFO_SIZE...
+        */
+
+       for (i = 0; i < n; i++) {
+               u8      epn = cfg->hw_ep_num;
+
+               if (epn >= musb->config->num_eps) {
+                       pr_debug("%s: invalid ep %d\n",
+                                       musb_driver_name, epn);
+                       return -EINVAL;
+               }
+               offset = fifo_setup(musb, hw_ep + epn, cfg++, offset);
+               if (offset < 0) {
+                       pr_debug("%s: mem overrun, ep %d\n",
+                                       musb_driver_name, epn);
+                       return -EINVAL;
+               }
+               epn++;
+               musb->nr_endpoints = max(epn, musb->nr_endpoints);
+       }
+
+       printk(KERN_DEBUG "%s: %d/%d max ep, %d/%d memory\n",
+                       musb_driver_name,
+                       n + 1, musb->config->num_eps * 2 - 1,
+                       offset, (1 << (musb->config->ram_bits + 2)));
+
+       if (!musb->bulk_ep) {
+               pr_debug("%s: missing bulk\n", musb_driver_name);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+
+/*
+ * ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false
+ * @param musb the controller
+ */
+static int __devinit ep_config_from_hw(struct musb *musb)
+{
+       u8 epnum = 0;
+       struct musb_hw_ep *hw_ep;
+       void *mbase = musb->mregs;
+       int ret = 0;
+
+       dev_dbg(musb->controller, "<== static silicon ep config\n");
+
+       /* FIXME pick up ep0 maxpacket size */
+
+       for (epnum = 1; epnum < musb->config->num_eps; epnum++) {
+               musb_ep_select(mbase, epnum);
+               hw_ep = musb->endpoints + epnum;
+
+               ret = musb_read_fifosize(musb, hw_ep, epnum);
+               if (ret < 0)
+                       break;
+
+               /* FIXME set up hw_ep->{rx,tx}_double_buffered */
+
+               /* pick an RX/TX endpoint for bulk */
+               if (hw_ep->max_packet_sz_tx < 512
+                               || hw_ep->max_packet_sz_rx < 512)
+                       continue;
+
+               /* REVISIT:  this algorithm is lazy, we should at least
+                * try to pick a double buffered endpoint.
+                */
+               if (musb->bulk_ep)
+                       continue;
+               musb->bulk_ep = hw_ep;
+       }
+
+       if (!musb->bulk_ep) {
+               pr_debug("%s: missing bulk\n", musb_driver_name);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, };
+
+/* Initialize MUSB (M)HDRC part of the USB hardware subsystem;
+ * configure endpoints, or take their config from silicon
+ */
+static int __devinit musb_core_init(u16 musb_type, struct musb *musb)
+{
+       u8 reg;
+       char *type;
+       char aInfo[90], aRevision[32], aDate[12];
+       void __iomem    *mbase = musb->mregs;
+       int             status = 0;
+       int             i;
+
+       /* log core options (read using indexed model) */
+       reg = musb_read_configdata(mbase);
+
+       strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8");
+       if (reg & MUSB_CONFIGDATA_DYNFIFO) {
+               strcat(aInfo, ", dyn FIFOs");
+               musb->dyn_fifo = true;
+       }
+       if (reg & MUSB_CONFIGDATA_MPRXE) {
+               strcat(aInfo, ", bulk combine");
+               musb->bulk_combine = true;
+       }
+       if (reg & MUSB_CONFIGDATA_MPTXE) {
+               strcat(aInfo, ", bulk split");
+               musb->bulk_split = true;
+       }
+       if (reg & MUSB_CONFIGDATA_HBRXE) {
+               strcat(aInfo, ", HB-ISO Rx");
+               musb->hb_iso_rx = true;
+       }
+       if (reg & MUSB_CONFIGDATA_HBTXE) {
+               strcat(aInfo, ", HB-ISO Tx");
+               musb->hb_iso_tx = true;
+       }
+       if (reg & MUSB_CONFIGDATA_SOFTCONE)
+               strcat(aInfo, ", SoftConn");
+
+       printk(KERN_DEBUG "%s: ConfigData=0x%02x (%s)\n",
+                       musb_driver_name, reg, aInfo);
+
+       aDate[0] = 0;
+       if (MUSB_CONTROLLER_MHDRC == musb_type) {
+               musb->is_multipoint = 1;
+               type = "M";
+       } else {
+               musb->is_multipoint = 0;
+               type = "";
+#ifndef        CONFIG_USB_OTG_BLACKLIST_HUB
+               printk(KERN_ERR
+                       "%s: kernel must blacklist external hubs\n",
+                       musb_driver_name);
+#endif
+       }
+
+       /* log release info */
+       musb->hwvers = musb_read_hwvers(mbase);
+       snprintf(aRevision, 32, "%d.%d%s", MUSB_HWVERS_MAJOR(musb->hwvers),
+               MUSB_HWVERS_MINOR(musb->hwvers),
+               (musb->hwvers & MUSB_HWVERS_RC) ? "RC" : "");
+       printk(KERN_DEBUG "%s: %sHDRC RTL version %s %s\n",
+                       musb_driver_name, type, aRevision, aDate);
+
+       /* configure ep0 */
+       musb_configure_ep0(musb);
+
+       /* discover endpoint configuration */
+       musb->nr_endpoints = 1;
+       musb->epmask = 1;
+
+       if (musb->dyn_fifo)
+               status = ep_config_from_table(musb);
+       else
+               status = ep_config_from_hw(musb);
+
+       if (status < 0)
+               return status;
+
+       /* finish init, and print endpoint config */
+       for (i = 0; i < musb->nr_endpoints; i++) {
+               struct musb_hw_ep       *hw_ep = musb->endpoints + i;
+
+               hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase;
+#if defined(CONFIG_USB_MUSB_TUSB6010) || defined (CONFIG_USB_MUSB_TUSB6010_MODULE)
+               hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i);
+               hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i);
+               hw_ep->fifo_sync_va =
+                       musb->sync_va + 0x400 + MUSB_FIFO_OFFSET(i);
+
+               if (i == 0)
+                       hw_ep->conf = mbase - 0x400 + TUSB_EP0_CONF;
+               else
+                       hw_ep->conf = mbase + 0x400 + (((i - 1) & 0xf) << 2);
+#endif
+
+               hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase;
+               hw_ep->target_regs = musb_read_target_reg_base(i, mbase);
+               hw_ep->rx_reinit = 1;
+               hw_ep->tx_reinit = 1;
+
+               if (hw_ep->max_packet_sz_tx) {
+                       dev_dbg(musb->controller,
+                               "%s: hw_ep %d%s, %smax %d\n",
+                               musb_driver_name, i,
+                               hw_ep->is_shared_fifo ? "shared" : "tx",
+                               hw_ep->tx_double_buffered
+                                       ? "doublebuffer, " : "",
+                               hw_ep->max_packet_sz_tx);
+               }
+               if (hw_ep->max_packet_sz_rx && !hw_ep->is_shared_fifo) {
+                       dev_dbg(musb->controller,
+                               "%s: hw_ep %d%s, %smax %d\n",
+                               musb_driver_name, i,
+                               "rx",
+                               hw_ep->rx_double_buffered
+                                       ? "doublebuffer, " : "",
+                               hw_ep->max_packet_sz_rx);
+               }
+               if (!(hw_ep->max_packet_sz_tx || hw_ep->max_packet_sz_rx))
+                       dev_dbg(musb->controller, "hw_ep %d not configured\n", i);
+       }
+
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \
+       defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500)
+
+static irqreturn_t generic_interrupt(int irq, void *__hci)
+{
+       unsigned long   flags;
+       irqreturn_t     retval = IRQ_NONE;
+       struct musb     *musb = __hci;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
+       musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
+       musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
+
+       if (musb->int_usb || musb->int_tx || musb->int_rx)
+               retval = musb_interrupt(musb);
+
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return retval;
+}
+
+#else
+#define generic_interrupt      NULL
+#endif
+
+/*
+ * handle all the irqs defined by the HDRC core. for now we expect:  other
+ * irq sources (phy, dma, etc) will be handled first, musb->int_* values
+ * will be assigned, and the irq will already have been acked.
+ *
+ * called in irq context with spinlock held, irqs blocked
+ */
+irqreturn_t musb_interrupt(struct musb *musb)
+{
+       irqreturn_t     retval = IRQ_NONE;
+       u8              devctl, power;
+       int             ep_num;
+       u32             reg;
+
+       devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+       power = musb_readb(musb->mregs, MUSB_POWER);
+
+       dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n",
+               (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral",
+               musb->int_usb, musb->int_tx, musb->int_rx);
+
+       /* the core can interrupt us for multiple reasons; docs have
+        * a generic interrupt flowchart to follow
+        */
+       if (musb->int_usb)
+               retval |= musb_stage0_irq(musb, musb->int_usb,
+                               devctl, power);
+
+       /* "stage 1" is handling endpoint irqs */
+
+       /* handle endpoint 0 first */
+       if (musb->int_tx & 1) {
+               if (devctl & MUSB_DEVCTL_HM) {
+                       if (is_host_capable())
+                               retval |= musb_h_ep0_irq(musb);
+               } else {
+                       if (is_peripheral_capable())
+                               retval |= musb_g_ep0_irq(musb);
+               }
+       }
+
+       /* RX on endpoints 1-15 */
+       reg = musb->int_rx >> 1;
+       ep_num = 1;
+       while (reg) {
+               if (reg & 1) {
+                       /* musb_ep_select(musb->mregs, ep_num); */
+                       /* REVISIT just retval = ep->rx_irq(...) */
+                       retval = IRQ_HANDLED;
+                       if (devctl & MUSB_DEVCTL_HM) {
+                               if (is_host_capable())
+                                       musb_host_rx(musb, ep_num);
+                       } else {
+                               if (is_peripheral_capable())
+                                       musb_g_rx(musb, ep_num);
+                       }
+               }
+
+               reg >>= 1;
+               ep_num++;
+       }
+
+       /* TX on endpoints 1-15 */
+       reg = musb->int_tx >> 1;
+       ep_num = 1;
+       while (reg) {
+               if (reg & 1) {
+                       /* musb_ep_select(musb->mregs, ep_num); */
+                       /* REVISIT just retval |= ep->tx_irq(...) */
+                       retval = IRQ_HANDLED;
+                       if (devctl & MUSB_DEVCTL_HM) {
+                               if (is_host_capable())
+                                       musb_host_tx(musb, ep_num);
+                       } else {
+                               if (is_peripheral_capable())
+                                       musb_g_tx(musb, ep_num);
+                       }
+               }
+               reg >>= 1;
+               ep_num++;
+       }
+
+       return retval;
+}
+EXPORT_SYMBOL_GPL(musb_interrupt);
+
+#ifndef CONFIG_MUSB_PIO_ONLY
+static bool __devinitdata use_dma = 1;
+
+/* "modprobe ... use_dma=0" etc */
+module_param(use_dma, bool, 0);
+MODULE_PARM_DESC(use_dma, "enable/disable use of DMA");
+
+void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)
+{
+       u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+
+       /* called with controller lock already held */
+
+       if (!epnum) {
+#ifndef CONFIG_USB_TUSB_OMAP_DMA
+               if (!is_cppi_enabled()) {
+                       /* endpoint 0 */
+                       if (devctl & MUSB_DEVCTL_HM)
+                               musb_h_ep0_irq(musb);
+                       else
+                               musb_g_ep0_irq(musb);
+               }
+#endif
+       } else {
+               /* endpoints 1..15 */
+               if (transmit) {
+                       if (devctl & MUSB_DEVCTL_HM) {
+                               if (is_host_capable())
+                                       musb_host_tx(musb, epnum);
+                       } else {
+                               if (is_peripheral_capable())
+                                       musb_g_tx(musb, epnum);
+                       }
+               } else {
+                       /* receive */
+                       if (devctl & MUSB_DEVCTL_HM) {
+                               if (is_host_capable())
+                                       musb_host_rx(musb, epnum);
+                       } else {
+                               if (is_peripheral_capable())
+                                       musb_g_rx(musb, epnum);
+                       }
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(musb_dma_completion);
+
+#else
+#define use_dma                        0
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_SYSFS
+
+static ssize_t
+musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct musb *musb = dev_to_musb(dev);
+       unsigned long flags;
+       int ret = -EINVAL;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       ret = sprintf(buf, "%s\n", otg_state_string(musb->xceiv->state));
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return ret;
+}
+
+static ssize_t
+musb_mode_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t n)
+{
+       struct musb     *musb = dev_to_musb(dev);
+       unsigned long   flags;
+       int             status;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       if (sysfs_streq(buf, "host"))
+               status = musb_platform_set_mode(musb, MUSB_HOST);
+       else if (sysfs_streq(buf, "peripheral"))
+               status = musb_platform_set_mode(musb, MUSB_PERIPHERAL);
+       else if (sysfs_streq(buf, "otg"))
+               status = musb_platform_set_mode(musb, MUSB_OTG);
+       else
+               status = -EINVAL;
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return (status == 0) ? n : status;
+}
+static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store);
+
+static ssize_t
+musb_vbus_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t n)
+{
+       struct musb     *musb = dev_to_musb(dev);
+       unsigned long   flags;
+       unsigned long   val;
+
+       if (sscanf(buf, "%lu", &val) < 1) {
+               dev_err(dev, "Invalid VBUS timeout ms value\n");
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&musb->lock, flags);
+       /* force T(a_wait_bcon) to be zero/unlimited *OR* valid */
+       musb->a_wait_bcon = val ? max_t(int, val, OTG_TIME_A_WAIT_BCON) : 0 ;
+       if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON)
+               musb->is_active = 0;
+       musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val));
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return n;
+}
+
+static ssize_t
+musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct musb     *musb = dev_to_musb(dev);
+       unsigned long   flags;
+       unsigned long   val;
+       int             vbus;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       val = musb->a_wait_bcon;
+       /* FIXME get_vbus_status() is normally #defined as false...
+        * and is effectively TUSB-specific.
+        */
+       vbus = musb_platform_get_vbus_status(musb);
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return sprintf(buf, "Vbus %s, timeout %lu msec\n",
+                       vbus ? "on" : "off", val);
+}
+static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store);
+
+/* Gadget drivers can't know that a host is connected so they might want
+ * to start SRP, but users can.  This allows userspace to trigger SRP.
+ */
+static ssize_t
+musb_srp_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t n)
+{
+       struct musb     *musb = dev_to_musb(dev);
+       unsigned short  srp;
+
+       if (sscanf(buf, "%hu", &srp) != 1
+                       || (srp != 1)) {
+               dev_err(dev, "SRP: Value must be 1\n");
+               return -EINVAL;
+       }
+
+       if (srp == 1)
+               musb_g_wakeup(musb);
+
+       return n;
+}
+static DEVICE_ATTR(srp, 0644, NULL, musb_srp_store);
+
+static struct attribute *musb_attributes[] = {
+       &dev_attr_mode.attr,
+       &dev_attr_vbus.attr,
+       &dev_attr_srp.attr,
+       NULL
+};
+
+static const struct attribute_group musb_attr_group = {
+       .attrs = musb_attributes,
+};
+
+#endif /* sysfs */
+
+#ifndef __UBOOT__
+/* Only used to provide driver mode change events */
+static void musb_irq_work(struct work_struct *data)
+{
+       struct musb *musb = container_of(data, struct musb, irq_work);
+       static int old_state;
+
+       if (musb->xceiv->state != old_state) {
+               old_state = musb->xceiv->state;
+               sysfs_notify(&musb->controller->kobj, NULL, "mode");
+       }
+}
+#endif
+
+/* --------------------------------------------------------------------------
+ * Init support
+ */
+
+static struct musb *__devinit
+allocate_instance(struct device *dev,
+               struct musb_hdrc_config *config, void __iomem *mbase)
+{
+       struct musb             *musb;
+       struct musb_hw_ep       *ep;
+       int                     epnum;
+#ifndef __UBOOT__
+       struct usb_hcd  *hcd;
+
+       hcd = usb_create_hcd(&musb_hc_driver, dev, dev_name(dev));
+       if (!hcd)
+               return NULL;
+       /* usbcore sets dev->driver_data to hcd, and sometimes uses that... */
+
+       musb = hcd_to_musb(hcd);
+#else
+       musb = calloc(1, sizeof(*musb));
+       if (!musb)
+               return NULL;
+#endif
+       INIT_LIST_HEAD(&musb->control);
+       INIT_LIST_HEAD(&musb->in_bulk);
+       INIT_LIST_HEAD(&musb->out_bulk);
+
+#ifndef __UBOOT__
+       hcd->uses_new_polling = 1;
+       hcd->has_tt = 1;
+#endif
+
+       musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
+       musb->a_wait_bcon = OTG_TIME_A_WAIT_BCON;
+       dev_set_drvdata(dev, musb);
+       musb->mregs = mbase;
+       musb->ctrl_base = mbase;
+       musb->nIrq = -ENODEV;
+       musb->config = config;
+       BUG_ON(musb->config->num_eps > MUSB_C_NUM_EPS);
+       for (epnum = 0, ep = musb->endpoints;
+                       epnum < musb->config->num_eps;
+                       epnum++, ep++) {
+               ep->musb = musb;
+               ep->epnum = epnum;
+       }
+
+       musb->controller = dev;
+
+       return musb;
+}
+
+static void musb_free(struct musb *musb)
+{
+       /* this has multiple entry modes. it handles fault cleanup after
+        * probe(), where things may be partially set up, as well as rmmod
+        * cleanup after everything's been de-activated.
+        */
+
+#ifdef CONFIG_SYSFS
+       sysfs_remove_group(&musb->controller->kobj, &musb_attr_group);
+#endif
+
+       if (musb->nIrq >= 0) {
+               if (musb->irq_wake)
+                       disable_irq_wake(musb->nIrq);
+               free_irq(musb->nIrq, musb);
+       }
+       if (is_dma_capable() && musb->dma_controller) {
+               struct dma_controller   *c = musb->dma_controller;
+
+               (void) c->stop(c);
+               dma_controller_destroy(c);
+       }
+
+       kfree(musb);
+}
+
+/*
+ * Perform generic per-controller initialization.
+ *
+ * @pDevice: the controller (already clocked, etc)
+ * @nIrq: irq
+ * @mregs: virtual address of controller registers,
+ *     not yet corrected for platform-specific offsets
+ */
+#ifndef __UBOOT__
+static int __devinit
+musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
+#else
+struct musb *
+musb_init_controller(struct musb_hdrc_platform_data *plat, struct device *dev,
+                            void *ctrl)
+#endif
+{
+       int                     status;
+       struct musb             *musb;
+#ifndef __UBOOT__
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+#else
+       int nIrq = 0;
+#endif
+
+       /* The driver might handle more features than the board; OK.
+        * Fail when the board needs a feature that's not enabled.
+        */
+       if (!plat) {
+               dev_dbg(dev, "no platform_data?\n");
+               status = -ENODEV;
+               goto fail0;
+       }
+
+       /* allocate */
+       musb = allocate_instance(dev, plat->config, ctrl);
+       if (!musb) {
+               status = -ENOMEM;
+               goto fail0;
+       }
+
+       pm_runtime_use_autosuspend(musb->controller);
+       pm_runtime_set_autosuspend_delay(musb->controller, 200);
+       pm_runtime_enable(musb->controller);
+
+       spin_lock_init(&musb->lock);
+       musb->board_mode = plat->mode;
+       musb->board_set_power = plat->set_power;
+       musb->min_power = plat->min_power;
+       musb->ops = plat->platform_ops;
+
+       /* The musb_platform_init() call:
+        *   - adjusts musb->mregs and musb->isr if needed,
+        *   - may initialize an integrated tranceiver
+        *   - initializes musb->xceiv, usually by otg_get_phy()
+        *   - stops powering VBUS
+        *
+        * There are various transceiver configurations.  Blackfin,
+        * DaVinci, TUSB60x0, and others integrate them.  OMAP3 uses
+        * external/discrete ones in various flavors (twl4030 family,
+        * isp1504, non-OTG, etc) mostly hooking up through ULPI.
+        */
+       musb->isr = generic_interrupt;
+       status = musb_platform_init(musb);
+       if (status < 0)
+               goto fail1;
+
+       if (!musb->isr) {
+               status = -ENODEV;
+               goto fail2;
+       }
+
+#ifndef __UBOOT__
+       if (!musb->xceiv->io_ops) {
+               musb->xceiv->io_dev = musb->controller;
+               musb->xceiv->io_priv = musb->mregs;
+               musb->xceiv->io_ops = &musb_ulpi_access;
+       }
+#endif
+
+       pm_runtime_get_sync(musb->controller);
+
+#ifndef CONFIG_MUSB_PIO_ONLY
+       if (use_dma && dev->dma_mask) {
+               struct dma_controller   *c;
+
+               c = dma_controller_create(musb, musb->mregs);
+               musb->dma_controller = c;
+               if (c)
+                       (void) c->start(c);
+       }
+#endif
+#ifndef __UBOOT__
+       /* ideally this would be abstracted in platform setup */
+       if (!is_dma_capable() || !musb->dma_controller)
+               dev->dma_mask = NULL;
+#endif
+
+       /* be sure interrupts are disabled before connecting ISR */
+       musb_platform_disable(musb);
+       musb_generic_disable(musb);
+
+       /* setup musb parts of the core (especially endpoints) */
+       status = musb_core_init(plat->config->multipoint
+                       ? MUSB_CONTROLLER_MHDRC
+                       : MUSB_CONTROLLER_HDRC, musb);
+       if (status < 0)
+               goto fail3;
+
+       setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
+
+       /* Init IRQ workqueue before request_irq */
+       INIT_WORK(&musb->irq_work, musb_irq_work);
+
+       /* attach to the IRQ */
+       if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) {
+               dev_err(dev, "request_irq %d failed!\n", nIrq);
+               status = -ENODEV;
+               goto fail3;
+       }
+       musb->nIrq = nIrq;
+/* FIXME this handles wakeup irqs wrong */
+       if (enable_irq_wake(nIrq) == 0) {
+               musb->irq_wake = 1;
+               device_init_wakeup(dev, 1);
+       } else {
+               musb->irq_wake = 0;
+       }
+
+#ifndef __UBOOT__
+       /* host side needs more setup */
+       if (is_host_enabled(musb)) {
+               struct usb_hcd  *hcd = musb_to_hcd(musb);
+
+               otg_set_host(musb->xceiv->otg, &hcd->self);
+
+               if (is_otg_enabled(musb))
+                       hcd->self.otg_port = 1;
+               musb->xceiv->otg->host = &hcd->self;
+               hcd->power_budget = 2 * (plat->power ? : 250);
+
+               /* program PHY to use external vBus if required */
+               if (plat->extvbus) {
+                       u8 busctl = musb_read_ulpi_buscontrol(musb->mregs);
+                       busctl |= MUSB_ULPI_USE_EXTVBUS;
+                       musb_write_ulpi_buscontrol(musb->mregs, busctl);
+               }
+       }
+#endif
+
+       /* For the host-only role, we can activate right away.
+        * (We expect the ID pin to be forcibly grounded!!)
+        * Otherwise, wait till the gadget driver hooks up.
+        */
+       if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
+               struct usb_hcd  *hcd = musb_to_hcd(musb);
+
+               MUSB_HST_MODE(musb);
+#ifndef __UBOOT__
+               musb->xceiv->otg->default_a = 1;
+               musb->xceiv->state = OTG_STATE_A_IDLE;
+
+               status = usb_add_hcd(musb_to_hcd(musb), 0, 0);
+
+               hcd->self.uses_pio_for_control = 1;
+               dev_dbg(musb->controller, "%s mode, status %d, devctl %02x %c\n",
+                       "HOST", status,
+                       musb_readb(musb->mregs, MUSB_DEVCTL),
+                       (musb_readb(musb->mregs, MUSB_DEVCTL)
+                                       & MUSB_DEVCTL_BDEVICE
+                               ? 'B' : 'A'));
+#endif
+
+       } else /* peripheral is enabled */ {
+               MUSB_DEV_MODE(musb);
+#ifndef __UBOOT__
+               musb->xceiv->otg->default_a = 0;
+               musb->xceiv->state = OTG_STATE_B_IDLE;
+#endif
+
+               if (is_peripheral_capable())
+                       status = musb_gadget_setup(musb);
+
+#ifndef __UBOOT__
+               dev_dbg(musb->controller, "%s mode, status %d, dev%02x\n",
+                       is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
+                       status,
+                       musb_readb(musb->mregs, MUSB_DEVCTL));
+#endif
+
+       }
+       if (status < 0)
+               goto fail3;
+
+       status = musb_init_debugfs(musb);
+       if (status < 0)
+               goto fail4;
+
+#ifdef CONFIG_SYSFS
+       status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
+       if (status)
+               goto fail5;
+#endif
+
+       pm_runtime_put(musb->controller);
+
+       dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
+                       ({char *s;
+                        switch (musb->board_mode) {
+                        case MUSB_HOST:                s = "Host"; break;
+                        case MUSB_PERIPHERAL:  s = "Peripheral"; break;
+                        default:               s = "OTG"; break;
+                        }; s; }),
+                       ctrl,
+                       (is_dma_capable() && musb->dma_controller)
+                       ? "DMA" : "PIO",
+                       musb->nIrq);
+
+#ifndef __UBOOT__
+       return 0;
+#else
+       return status == 0 ? musb : NULL;
+#endif
+
+fail5:
+       musb_exit_debugfs(musb);
+
+fail4:
+#ifndef __UBOOT__
+       if (!is_otg_enabled(musb) && is_host_enabled(musb))
+               usb_remove_hcd(musb_to_hcd(musb));
+       else
+#endif
+               musb_gadget_cleanup(musb);
+
+fail3:
+       pm_runtime_put_sync(musb->controller);
+
+fail2:
+       if (musb->irq_wake)
+               device_init_wakeup(dev, 0);
+       musb_platform_exit(musb);
+
+fail1:
+       dev_err(musb->controller,
+               "musb_init_controller failed with status %d\n", status);
+
+       musb_free(musb);
+
+fail0:
+
+#ifndef __UBOOT__
+       return status;
+#else
+       return status == 0 ? musb : NULL;
+#endif
+
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* all implementations (PCI bridge to FPGA, VLYNQ, etc) should just
+ * bridge to a platform device; this driver then suffices.
+ */
+
+#ifndef CONFIG_MUSB_PIO_ONLY
+static u64     *orig_dma_mask;
+#endif
+
+#ifndef __UBOOT__
+static int __devinit musb_probe(struct platform_device *pdev)
+{
+       struct device   *dev = &pdev->dev;
+       int             irq = platform_get_irq_byname(pdev, "mc");
+       int             status;
+       struct resource *iomem;
+       void __iomem    *base;
+
+       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!iomem || irq <= 0)
+               return -ENODEV;
+
+       base = ioremap(iomem->start, resource_size(iomem));
+       if (!base) {
+               dev_err(dev, "ioremap failed\n");
+               return -ENOMEM;
+       }
+
+#ifndef CONFIG_MUSB_PIO_ONLY
+       /* clobbered by use_dma=n */
+       orig_dma_mask = dev->dma_mask;
+#endif
+       status = musb_init_controller(dev, irq, base);
+       if (status < 0)
+               iounmap(base);
+
+       return status;
+}
+
+static int __devexit musb_remove(struct platform_device *pdev)
+{
+       struct musb     *musb = dev_to_musb(&pdev->dev);
+       void __iomem    *ctrl_base = musb->ctrl_base;
+
+       /* this gets called on rmmod.
+        *  - Host mode: host may still be active
+        *  - Peripheral mode: peripheral is deactivated (or never-activated)
+        *  - OTG mode: both roles are deactivated (or never-activated)
+        */
+       musb_exit_debugfs(musb);
+       musb_shutdown(pdev);
+
+       musb_free(musb);
+       iounmap(ctrl_base);
+       device_init_wakeup(&pdev->dev, 0);
+#ifndef CONFIG_MUSB_PIO_ONLY
+       pdev->dev.dma_mask = orig_dma_mask;
+#endif
+       return 0;
+}
+
+#ifdef CONFIG_PM
+
+static void musb_save_context(struct musb *musb)
+{
+       int i;
+       void __iomem *musb_base = musb->mregs;
+       void __iomem *epio;
+
+       if (is_host_enabled(musb)) {
+               musb->context.frame = musb_readw(musb_base, MUSB_FRAME);
+               musb->context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
+               musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
+       }
+       musb->context.power = musb_readb(musb_base, MUSB_POWER);
+       musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
+       musb->context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE);
+       musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE);
+       musb->context.index = musb_readb(musb_base, MUSB_INDEX);
+       musb->context.devctl = musb_readb(musb_base, MUSB_DEVCTL);
+
+       for (i = 0; i < musb->config->num_eps; ++i) {
+               struct musb_hw_ep       *hw_ep;
+
+               hw_ep = &musb->endpoints[i];
+               if (!hw_ep)
+                       continue;
+
+               epio = hw_ep->regs;
+               if (!epio)
+                       continue;
+
+               musb_writeb(musb_base, MUSB_INDEX, i);
+               musb->context.index_regs[i].txmaxp =
+                       musb_readw(epio, MUSB_TXMAXP);
+               musb->context.index_regs[i].txcsr =
+                       musb_readw(epio, MUSB_TXCSR);
+               musb->context.index_regs[i].rxmaxp =
+                       musb_readw(epio, MUSB_RXMAXP);
+               musb->context.index_regs[i].rxcsr =
+                       musb_readw(epio, MUSB_RXCSR);
+
+               if (musb->dyn_fifo) {
+                       musb->context.index_regs[i].txfifoadd =
+                                       musb_read_txfifoadd(musb_base);
+                       musb->context.index_regs[i].rxfifoadd =
+                                       musb_read_rxfifoadd(musb_base);
+                       musb->context.index_regs[i].txfifosz =
+                                       musb_read_txfifosz(musb_base);
+                       musb->context.index_regs[i].rxfifosz =
+                                       musb_read_rxfifosz(musb_base);
+               }
+               if (is_host_enabled(musb)) {
+                       musb->context.index_regs[i].txtype =
+                               musb_readb(epio, MUSB_TXTYPE);
+                       musb->context.index_regs[i].txinterval =
+                               musb_readb(epio, MUSB_TXINTERVAL);
+                       musb->context.index_regs[i].rxtype =
+                               musb_readb(epio, MUSB_RXTYPE);
+                       musb->context.index_regs[i].rxinterval =
+                               musb_readb(epio, MUSB_RXINTERVAL);
+
+                       musb->context.index_regs[i].txfunaddr =
+                               musb_read_txfunaddr(musb_base, i);
+                       musb->context.index_regs[i].txhubaddr =
+                               musb_read_txhubaddr(musb_base, i);
+                       musb->context.index_regs[i].txhubport =
+                               musb_read_txhubport(musb_base, i);
+
+                       musb->context.index_regs[i].rxfunaddr =
+                               musb_read_rxfunaddr(musb_base, i);
+                       musb->context.index_regs[i].rxhubaddr =
+                               musb_read_rxhubaddr(musb_base, i);
+                       musb->context.index_regs[i].rxhubport =
+                               musb_read_rxhubport(musb_base, i);
+               }
+       }
+}
+
+static void musb_restore_context(struct musb *musb)
+{
+       int i;
+       void __iomem *musb_base = musb->mregs;
+       void __iomem *ep_target_regs;
+       void __iomem *epio;
+
+       if (is_host_enabled(musb)) {
+               musb_writew(musb_base, MUSB_FRAME, musb->context.frame);
+               musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode);
+               musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl);
+       }
+       musb_writeb(musb_base, MUSB_POWER, musb->context.power);
+       musb_writew(musb_base, MUSB_INTRTXE, musb->context.intrtxe);
+       musb_writew(musb_base, MUSB_INTRRXE, musb->context.intrrxe);
+       musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe);
+       musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl);
+
+       for (i = 0; i < musb->config->num_eps; ++i) {
+               struct musb_hw_ep       *hw_ep;
+
+               hw_ep = &musb->endpoints[i];
+               if (!hw_ep)
+                       continue;
+
+               epio = hw_ep->regs;
+               if (!epio)
+                       continue;
+
+               musb_writeb(musb_base, MUSB_INDEX, i);
+               musb_writew(epio, MUSB_TXMAXP,
+                       musb->context.index_regs[i].txmaxp);
+               musb_writew(epio, MUSB_TXCSR,
+                       musb->context.index_regs[i].txcsr);
+               musb_writew(epio, MUSB_RXMAXP,
+                       musb->context.index_regs[i].rxmaxp);
+               musb_writew(epio, MUSB_RXCSR,
+                       musb->context.index_regs[i].rxcsr);
+
+               if (musb->dyn_fifo) {
+                       musb_write_txfifosz(musb_base,
+                               musb->context.index_regs[i].txfifosz);
+                       musb_write_rxfifosz(musb_base,
+                               musb->context.index_regs[i].rxfifosz);
+                       musb_write_txfifoadd(musb_base,
+                               musb->context.index_regs[i].txfifoadd);
+                       musb_write_rxfifoadd(musb_base,
+                               musb->context.index_regs[i].rxfifoadd);
+               }
+
+               if (is_host_enabled(musb)) {
+                       musb_writeb(epio, MUSB_TXTYPE,
+                               musb->context.index_regs[i].txtype);
+                       musb_writeb(epio, MUSB_TXINTERVAL,
+                               musb->context.index_regs[i].txinterval);
+                       musb_writeb(epio, MUSB_RXTYPE,
+                               musb->context.index_regs[i].rxtype);
+                       musb_writeb(epio, MUSB_RXINTERVAL,
+
+                       musb->context.index_regs[i].rxinterval);
+                       musb_write_txfunaddr(musb_base, i,
+                               musb->context.index_regs[i].txfunaddr);
+                       musb_write_txhubaddr(musb_base, i,
+                               musb->context.index_regs[i].txhubaddr);
+                       musb_write_txhubport(musb_base, i,
+                               musb->context.index_regs[i].txhubport);
+
+                       ep_target_regs =
+                               musb_read_target_reg_base(i, musb_base);
+
+                       musb_write_rxfunaddr(ep_target_regs,
+                               musb->context.index_regs[i].rxfunaddr);
+                       musb_write_rxhubaddr(ep_target_regs,
+                               musb->context.index_regs[i].rxhubaddr);
+                       musb_write_rxhubport(ep_target_regs,
+                               musb->context.index_regs[i].rxhubport);
+               }
+       }
+       musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
+}
+
+static int musb_suspend(struct device *dev)
+{
+       struct musb     *musb = dev_to_musb(dev);
+       unsigned long   flags;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       if (is_peripheral_active(musb)) {
+               /* FIXME force disconnect unless we know USB will wake
+                * the system up quickly enough to respond ...
+                */
+       } else if (is_host_active(musb)) {
+               /* we know all the children are suspended; sometimes
+                * they will even be wakeup-enabled.
+                */
+       }
+
+       spin_unlock_irqrestore(&musb->lock, flags);
+       return 0;
+}
+
+static int musb_resume_noirq(struct device *dev)
+{
+       /* for static cmos like DaVinci, register values were preserved
+        * unless for some reason the whole soc powered down or the USB
+        * module got reset through the PSC (vs just being disabled).
+        */
+       return 0;
+}
+
+static int musb_runtime_suspend(struct device *dev)
+{
+       struct musb     *musb = dev_to_musb(dev);
+
+       musb_save_context(musb);
+
+       return 0;
+}
+
+static int musb_runtime_resume(struct device *dev)
+{
+       struct musb     *musb = dev_to_musb(dev);
+       static int      first = 1;
+
+       /*
+        * When pm_runtime_get_sync called for the first time in driver
+        * init,  some of the structure is still not initialized which is
+        * used in restore function. But clock needs to be
+        * enabled before any register access, so
+        * pm_runtime_get_sync has to be called.
+        * Also context restore without save does not make
+        * any sense
+        */
+       if (!first)
+               musb_restore_context(musb);
+       first = 0;
+
+       return 0;
+}
+
+static const struct dev_pm_ops musb_dev_pm_ops = {
+       .suspend        = musb_suspend,
+       .resume_noirq   = musb_resume_noirq,
+       .runtime_suspend = musb_runtime_suspend,
+       .runtime_resume = musb_runtime_resume,
+};
+
+#define MUSB_DEV_PM_OPS (&musb_dev_pm_ops)
+#else
+#define        MUSB_DEV_PM_OPS NULL
+#endif
+
+static struct platform_driver musb_driver = {
+       .driver = {
+               .name           = (char *)musb_driver_name,
+               .bus            = &platform_bus_type,
+               .owner          = THIS_MODULE,
+               .pm             = MUSB_DEV_PM_OPS,
+       },
+       .probe          = musb_probe,
+       .remove         = __devexit_p(musb_remove),
+       .shutdown       = musb_shutdown,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init musb_init(void)
+{
+       if (usb_disabled())
+               return 0;
+
+       pr_info("%s: version " MUSB_VERSION ", "
+               "?dma?"
+               ", "
+               "otg (peripheral+host)",
+               musb_driver_name);
+       return platform_driver_register(&musb_driver);
+}
+module_init(musb_init);
+
+static void __exit musb_cleanup(void)
+{
+       platform_driver_unregister(&musb_driver);
+}
+module_exit(musb_cleanup);
+#endif
diff --git a/drivers/usb/musb-new/musb_core.h b/drivers/usb/musb-new/musb_core.h
new file mode 100644 (file)
index 0000000..2695742
--- /dev/null
@@ -0,0 +1,623 @@
+/*
+ * MUSB OTG driver defines
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#ifndef __MUSB_CORE_H__
+#define __MUSB_CORE_H__
+
+#ifndef __UBOOT__
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+#include <linux/device.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
+#else
+#include <asm/errno.h>
+#endif
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
+
+struct musb;
+struct musb_hw_ep;
+struct musb_ep;
+
+/* Helper defines for struct musb->hwvers */
+#define MUSB_HWVERS_MAJOR(x)   ((x >> 10) & 0x1f)
+#define MUSB_HWVERS_MINOR(x)   (x & 0x3ff)
+#define MUSB_HWVERS_RC         0x8000
+#define MUSB_HWVERS_1300       0x52C
+#define MUSB_HWVERS_1400       0x590
+#define MUSB_HWVERS_1800       0x720
+#define MUSB_HWVERS_1900       0x784
+#define MUSB_HWVERS_2000       0x800
+
+#include "musb_debug.h"
+#include "musb_dma.h"
+
+#include "musb_io.h"
+#include "musb_regs.h"
+
+#include "musb_gadget.h"
+#ifndef __UBOOT__
+#include <linux/usb/hcd.h>
+#endif
+#include "musb_host.h"
+
+#define        is_peripheral_enabled(musb)     ((musb)->board_mode != MUSB_HOST)
+#define        is_host_enabled(musb)           ((musb)->board_mode != MUSB_PERIPHERAL)
+#define        is_otg_enabled(musb)            ((musb)->board_mode == MUSB_OTG)
+
+/* NOTE:  otg and peripheral-only state machines start at B_IDLE.
+ * OTG or host-only go to A_IDLE when ID is sensed.
+ */
+#define is_peripheral_active(m)                (!(m)->is_host)
+#define is_host_active(m)              ((m)->is_host)
+
+#ifdef CONFIG_PROC_FS
+#include <linux/fs.h>
+#define MUSB_CONFIG_PROC_FS
+#endif
+
+/****************************** PERIPHERAL ROLE *****************************/
+
+#ifndef __UBOOT__
+#define        is_peripheral_capable() (1)
+#else
+#ifdef CONFIG_MUSB_GADGET
+#define        is_peripheral_capable() (1)
+#else
+#define        is_peripheral_capable() (0)
+#endif
+#endif
+
+extern irqreturn_t musb_g_ep0_irq(struct musb *);
+extern void musb_g_tx(struct musb *, u8);
+extern void musb_g_rx(struct musb *, u8);
+extern void musb_g_reset(struct musb *);
+extern void musb_g_suspend(struct musb *);
+extern void musb_g_resume(struct musb *);
+extern void musb_g_wakeup(struct musb *);
+extern void musb_g_disconnect(struct musb *);
+
+/****************************** HOST ROLE ***********************************/
+
+#ifndef __UBOOT__
+#define        is_host_capable()       (1)
+#else
+#ifdef CONFIG_MUSB_HOST
+#define        is_host_capable()       (1)
+#else
+#define        is_host_capable()       (0)
+#endif
+#endif
+
+extern irqreturn_t musb_h_ep0_irq(struct musb *);
+extern void musb_host_tx(struct musb *, u8);
+extern void musb_host_rx(struct musb *, u8);
+
+/****************************** CONSTANTS ********************************/
+
+#ifndef MUSB_C_NUM_EPS
+#define MUSB_C_NUM_EPS ((u8)16)
+#endif
+
+#ifndef MUSB_MAX_END0_PACKET
+#define MUSB_MAX_END0_PACKET ((u16)MUSB_EP0_FIFOSIZE)
+#endif
+
+/* host side ep0 states */
+enum musb_h_ep0_state {
+       MUSB_EP0_IDLE,
+       MUSB_EP0_START,                 /* expect ack of setup */
+       MUSB_EP0_IN,                    /* expect IN DATA */
+       MUSB_EP0_OUT,                   /* expect ack of OUT DATA */
+       MUSB_EP0_STATUS,                /* expect ack of STATUS */
+} __attribute__ ((packed));
+
+/* peripheral side ep0 states */
+enum musb_g_ep0_state {
+       MUSB_EP0_STAGE_IDLE,            /* idle, waiting for SETUP */
+       MUSB_EP0_STAGE_SETUP,           /* received SETUP */
+       MUSB_EP0_STAGE_TX,              /* IN data */
+       MUSB_EP0_STAGE_RX,              /* OUT data */
+       MUSB_EP0_STAGE_STATUSIN,        /* (after OUT data) */
+       MUSB_EP0_STAGE_STATUSOUT,       /* (after IN data) */
+       MUSB_EP0_STAGE_ACKWAIT,         /* after zlp, before statusin */
+} __attribute__ ((packed));
+
+/*
+ * OTG protocol constants.  See USB OTG 1.3 spec,
+ * sections 5.5 "Device Timings" and 6.6.5 "Timers".
+ */
+#define OTG_TIME_A_WAIT_VRISE  100             /* msec (max) */
+#define OTG_TIME_A_WAIT_BCON   1100            /* min 1 second */
+#define OTG_TIME_A_AIDL_BDIS   200             /* min 200 msec */
+#define OTG_TIME_B_ASE0_BRST   100             /* min 3.125 ms */
+
+
+/*************************** REGISTER ACCESS ********************************/
+
+/* Endpoint registers (other than dynfifo setup) can be accessed either
+ * directly with the "flat" model, or after setting up an index register.
+ */
+
+#if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_SOC_OMAP2430) \
+               || defined(CONFIG_SOC_OMAP3430) || defined(CONFIG_BLACKFIN) \
+               || defined(CONFIG_ARCH_OMAP4)
+/* REVISIT indexed access seemed to
+ * misbehave (on DaVinci) for at least peripheral IN ...
+ */
+#define        MUSB_FLAT_REG
+#endif
+
+/* TUSB mapping: "flat" plus ep0 special cases */
+#if defined(CONFIG_USB_MUSB_TUSB6010) || \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
+#define musb_ep_select(_mbase, _epnum) \
+       musb_writeb((_mbase), MUSB_INDEX, (_epnum))
+#define        MUSB_EP_OFFSET                  MUSB_TUSB_OFFSET
+
+/* "flat" mapping: each endpoint has its own i/o address */
+#elif  defined(MUSB_FLAT_REG)
+#define musb_ep_select(_mbase, _epnum) (((void)(_mbase)), ((void)(_epnum)))
+#define        MUSB_EP_OFFSET                  MUSB_FLAT_OFFSET
+
+/* "indexed" mapping: INDEX register controls register bank select */
+#else
+#define musb_ep_select(_mbase, _epnum) \
+       musb_writeb((_mbase), MUSB_INDEX, (_epnum))
+#define        MUSB_EP_OFFSET                  MUSB_INDEXED_OFFSET
+#endif
+
+/****************************** FUNCTIONS ********************************/
+
+#define MUSB_HST_MODE(_musb)\
+       { (_musb)->is_host = true; }
+#define MUSB_DEV_MODE(_musb) \
+       { (_musb)->is_host = false; }
+
+#define test_devctl_hst_mode(_x) \
+       (musb_readb((_x)->mregs, MUSB_DEVCTL)&MUSB_DEVCTL_HM)
+
+#define MUSB_MODE(musb) ((musb)->is_host ? "Host" : "Peripheral")
+
+/******************************** TYPES *************************************/
+
+/**
+ * struct musb_platform_ops - Operations passed to musb_core by HW glue layer
+ * @init:      turns on clocks, sets up platform-specific registers, etc
+ * @exit:      undoes @init
+ * @set_mode:  forcefully changes operating mode
+ * @try_ilde:  tries to idle the IP
+ * @vbus_status: returns vbus status if possible
+ * @set_vbus:  forces vbus status
+ * @adjust_channel_params: pre check for standard dma channel_program func
+ */
+struct musb_platform_ops {
+       int     (*init)(struct musb *musb);
+       int     (*exit)(struct musb *musb);
+
+       void    (*enable)(struct musb *musb);
+       void    (*disable)(struct musb *musb);
+
+       int     (*set_mode)(struct musb *musb, u8 mode);
+       void    (*try_idle)(struct musb *musb, unsigned long timeout);
+
+       int     (*vbus_status)(struct musb *musb);
+       void    (*set_vbus)(struct musb *musb, int on);
+
+       int     (*adjust_channel_params)(struct dma_channel *channel,
+                               u16 packet_sz, u8 *mode,
+                               dma_addr_t *dma_addr, u32 *len);
+};
+
+/*
+ * struct musb_hw_ep - endpoint hardware (bidirectional)
+ *
+ * Ordered slightly for better cacheline locality.
+ */
+struct musb_hw_ep {
+       struct musb             *musb;
+       void __iomem            *fifo;
+       void __iomem            *regs;
+
+#if defined(CONFIG_USB_MUSB_TUSB6010) || \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
+       void __iomem            *conf;
+#endif
+
+       /* index in musb->endpoints[]  */
+       u8                      epnum;
+
+       /* hardware configuration, possibly dynamic */
+       bool                    is_shared_fifo;
+       bool                    tx_double_buffered;
+       bool                    rx_double_buffered;
+       u16                     max_packet_sz_tx;
+       u16                     max_packet_sz_rx;
+
+       struct dma_channel      *tx_channel;
+       struct dma_channel      *rx_channel;
+
+#if defined(CONFIG_USB_MUSB_TUSB6010) || \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
+       /* TUSB has "asynchronous" and "synchronous" dma modes */
+       dma_addr_t              fifo_async;
+       dma_addr_t              fifo_sync;
+       void __iomem            *fifo_sync_va;
+#endif
+
+       void __iomem            *target_regs;
+
+       /* currently scheduled peripheral endpoint */
+       struct musb_qh          *in_qh;
+       struct musb_qh          *out_qh;
+
+       u8                      rx_reinit;
+       u8                      tx_reinit;
+
+       /* peripheral side */
+       struct musb_ep          ep_in;                  /* TX */
+       struct musb_ep          ep_out;                 /* RX */
+};
+
+static inline struct musb_request *next_in_request(struct musb_hw_ep *hw_ep)
+{
+       return next_request(&hw_ep->ep_in);
+}
+
+static inline struct musb_request *next_out_request(struct musb_hw_ep *hw_ep)
+{
+       return next_request(&hw_ep->ep_out);
+}
+
+struct musb_csr_regs {
+       /* FIFO registers */
+       u16 txmaxp, txcsr, rxmaxp, rxcsr;
+       u16 rxfifoadd, txfifoadd;
+       u8 txtype, txinterval, rxtype, rxinterval;
+       u8 rxfifosz, txfifosz;
+       u8 txfunaddr, txhubaddr, txhubport;
+       u8 rxfunaddr, rxhubaddr, rxhubport;
+};
+
+struct musb_context_registers {
+
+       u8 power;
+       u16 intrtxe, intrrxe;
+       u8 intrusbe;
+       u16 frame;
+       u8 index, testmode;
+
+       u8 devctl, busctl, misc;
+       u32 otg_interfsel;
+
+       struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
+};
+
+/*
+ * struct musb - Driver instance data.
+ */
+struct musb {
+       /* device lock */
+       spinlock_t              lock;
+
+       const struct musb_platform_ops *ops;
+       struct musb_context_registers context;
+
+       irqreturn_t             (*isr)(int, void *);
+       struct work_struct      irq_work;
+       u16                     hwvers;
+
+/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
+#define MUSB_PORT_STAT_RESUME  (1 << 31)
+
+       u32                     port1_status;
+
+       unsigned long           rh_timer;
+
+       enum musb_h_ep0_state   ep0_stage;
+
+       /* bulk traffic normally dedicates endpoint hardware, and each
+        * direction has its own ring of host side endpoints.
+        * we try to progress the transfer at the head of each endpoint's
+        * queue until it completes or NAKs too much; then we try the next
+        * endpoint.
+        */
+       struct musb_hw_ep       *bulk_ep;
+
+       struct list_head        control;        /* of musb_qh */
+       struct list_head        in_bulk;        /* of musb_qh */
+       struct list_head        out_bulk;       /* of musb_qh */
+
+       struct timer_list       otg_timer;
+       struct notifier_block   nb;
+
+       struct dma_controller   *dma_controller;
+
+       struct device           *controller;
+       void __iomem            *ctrl_base;
+       void __iomem            *mregs;
+
+#if defined(CONFIG_USB_MUSB_TUSB6010) || \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
+       dma_addr_t              async;
+       dma_addr_t              sync;
+       void __iomem            *sync_va;
+#endif
+
+       /* passed down from chip/board specific irq handlers */
+       u8                      int_usb;
+       u16                     int_rx;
+       u16                     int_tx;
+
+       struct usb_phy          *xceiv;
+
+       int nIrq;
+       unsigned                irq_wake:1;
+
+       struct musb_hw_ep        endpoints[MUSB_C_NUM_EPS];
+#define control_ep             endpoints
+
+#define VBUSERR_RETRY_COUNT    3
+       u16                     vbuserr_retry;
+       u16 epmask;
+       u8 nr_endpoints;
+
+       u8 board_mode;          /* enum musb_mode */
+       int                     (*board_set_power)(int state);
+
+       u8                      min_power;      /* vbus for periph, in mA/2 */
+
+       bool                    is_host;
+
+       int                     a_wait_bcon;    /* VBUS timeout in msecs */
+       unsigned long           idle_timeout;   /* Next timeout in jiffies */
+
+       /* active means connected and not suspended */
+       unsigned                is_active:1;
+
+       unsigned is_multipoint:1;
+       unsigned ignore_disconnect:1;   /* during bus resets */
+
+       unsigned                hb_iso_rx:1;    /* high bandwidth iso rx? */
+       unsigned                hb_iso_tx:1;    /* high bandwidth iso tx? */
+       unsigned                dyn_fifo:1;     /* dynamic FIFO supported? */
+
+       unsigned                bulk_split:1;
+#define        can_bulk_split(musb,type) \
+       (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split)
+
+       unsigned                bulk_combine:1;
+#define        can_bulk_combine(musb,type) \
+       (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine)
+
+       /* is_suspended means USB B_PERIPHERAL suspend */
+       unsigned                is_suspended:1;
+
+       /* may_wakeup means remote wakeup is enabled */
+       unsigned                may_wakeup:1;
+
+       /* is_self_powered is reported in device status and the
+        * config descriptor.  is_bus_powered means B_PERIPHERAL
+        * draws some VBUS current; both can be true.
+        */
+       unsigned                is_self_powered:1;
+       unsigned                is_bus_powered:1;
+
+       unsigned                set_address:1;
+       unsigned                test_mode:1;
+       unsigned                softconnect:1;
+
+       u8                      address;
+       u8                      test_mode_nr;
+       u16                     ackpend;                /* ep0 */
+       enum musb_g_ep0_state   ep0_state;
+       struct usb_gadget       g;                      /* the gadget */
+       struct usb_gadget_driver *gadget_driver;        /* its driver */
+
+       /*
+        * FIXME: Remove this flag.
+        *
+        * This is only added to allow Blackfin to work
+        * with current driver. For some unknown reason
+        * Blackfin doesn't work with double buffering
+        * and that's enabled by default.
+        *
+        * We added this flag to forcefully disable double
+        * buffering until we get it working.
+        */
+       unsigned                double_buffer_not_ok:1;
+
+       struct musb_hdrc_config *config;
+
+#ifdef MUSB_CONFIG_PROC_FS
+       struct proc_dir_entry *proc_entry;
+#endif
+};
+
+static inline struct musb *gadget_to_musb(struct usb_gadget *g)
+{
+       return container_of(g, struct musb, g);
+}
+
+#ifdef CONFIG_BLACKFIN
+static inline int musb_read_fifosize(struct musb *musb,
+               struct musb_hw_ep *hw_ep, u8 epnum)
+{
+       musb->nr_endpoints++;
+       musb->epmask |= (1 << epnum);
+
+       if (epnum < 5) {
+               hw_ep->max_packet_sz_tx = 128;
+               hw_ep->max_packet_sz_rx = 128;
+       } else {
+               hw_ep->max_packet_sz_tx = 1024;
+               hw_ep->max_packet_sz_rx = 1024;
+       }
+       hw_ep->is_shared_fifo = false;
+
+       return 0;
+}
+
+static inline void musb_configure_ep0(struct musb *musb)
+{
+       musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
+       musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+       musb->endpoints[0].is_shared_fifo = true;
+}
+
+#else
+
+static inline int musb_read_fifosize(struct musb *musb,
+               struct musb_hw_ep *hw_ep, u8 epnum)
+{
+       void *mbase = musb->mregs;
+       u8 reg = 0;
+
+       /* read from core using indexed model */
+       reg = musb_readb(mbase, MUSB_EP_OFFSET(epnum, MUSB_FIFOSIZE));
+       /* 0's returned when no more endpoints */
+       if (!reg)
+               return -ENODEV;
+
+       musb->nr_endpoints++;
+       musb->epmask |= (1 << epnum);
+
+       hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f);
+
+       /* shared TX/RX FIFO? */
+       if ((reg & 0xf0) == 0xf0) {
+               hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx;
+               hw_ep->is_shared_fifo = true;
+               return 0;
+       } else {
+               hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4);
+               hw_ep->is_shared_fifo = false;
+       }
+
+       return 0;
+}
+
+static inline void musb_configure_ep0(struct musb *musb)
+{
+       musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
+       musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+       musb->endpoints[0].is_shared_fifo = true;
+}
+#endif /* CONFIG_BLACKFIN */
+
+
+/***************************** Glue it together *****************************/
+
+extern const char musb_driver_name[];
+
+extern void musb_start(struct musb *musb);
+extern void musb_stop(struct musb *musb);
+
+extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
+extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst);
+
+extern void musb_load_testpacket(struct musb *);
+
+extern irqreturn_t musb_interrupt(struct musb *);
+
+extern void musb_hnp_stop(struct musb *musb);
+
+static inline void musb_platform_set_vbus(struct musb *musb, int is_on)
+{
+       if (musb->ops->set_vbus)
+               musb->ops->set_vbus(musb, is_on);
+}
+
+static inline void musb_platform_enable(struct musb *musb)
+{
+       if (musb->ops->enable)
+               musb->ops->enable(musb);
+}
+
+static inline void musb_platform_disable(struct musb *musb)
+{
+       if (musb->ops->disable)
+               musb->ops->disable(musb);
+}
+
+static inline int musb_platform_set_mode(struct musb *musb, u8 mode)
+{
+       if (!musb->ops->set_mode)
+               return 0;
+
+       return musb->ops->set_mode(musb, mode);
+}
+
+static inline void musb_platform_try_idle(struct musb *musb,
+               unsigned long timeout)
+{
+       if (musb->ops->try_idle)
+               musb->ops->try_idle(musb, timeout);
+}
+
+static inline int musb_platform_get_vbus_status(struct musb *musb)
+{
+       if (!musb->ops->vbus_status)
+               return 0;
+
+       return musb->ops->vbus_status(musb);
+}
+
+static inline int musb_platform_init(struct musb *musb)
+{
+       if (!musb->ops->init)
+               return -EINVAL;
+
+       return musb->ops->init(musb);
+}
+
+static inline int musb_platform_exit(struct musb *musb)
+{
+       if (!musb->ops->exit)
+               return -EINVAL;
+
+       return musb->ops->exit(musb);
+}
+
+#ifdef __UBOOT__
+struct musb *
+musb_init_controller(struct musb_hdrc_platform_data *plat, struct device *dev,
+                            void *ctrl);
+#endif
+#endif /* __MUSB_CORE_H__ */
diff --git a/drivers/usb/musb-new/musb_debug.h b/drivers/usb/musb-new/musb_debug.h
new file mode 100644 (file)
index 0000000..27ba8f7
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * MUSB OTG driver debug defines
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#ifndef __MUSB_LINUX_DEBUG_H__
+#define __MUSB_LINUX_DEBUG_H__
+
+#define yprintk(facility, format, args...) \
+       do { printk(facility "%s %d: " format , \
+       __func__, __LINE__ , ## args); } while (0)
+#define WARNING(fmt, args...) yprintk(KERN_WARNING, fmt, ## args)
+#define INFO(fmt, args...) yprintk(KERN_INFO, fmt, ## args)
+#define ERR(fmt, args...) yprintk(KERN_ERR, fmt, ## args)
+
+#ifdef CONFIG_DEBUG_FS
+int musb_init_debugfs(struct musb *musb);
+void musb_exit_debugfs(struct musb *musb);
+#else
+static inline int musb_init_debugfs(struct musb *musb)
+{
+       return 0;
+}
+static inline void musb_exit_debugfs(struct musb *musb)
+{
+}
+#endif
+
+#endif                         /*  __MUSB_LINUX_DEBUG_H__ */
diff --git a/drivers/usb/musb-new/musb_dma.h b/drivers/usb/musb-new/musb_dma.h
new file mode 100644 (file)
index 0000000..3a97c4e
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * MUSB OTG driver DMA controller abstraction
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#ifndef __MUSB_DMA_H__
+#define __MUSB_DMA_H__
+
+struct musb_hw_ep;
+
+/*
+ * DMA Controller Abstraction
+ *
+ * DMA Controllers are abstracted to allow use of a variety of different
+ * implementations of DMA, as allowed by the Inventra USB cores.  On the
+ * host side, usbcore sets up the DMA mappings and flushes caches; on the
+ * peripheral side, the gadget controller driver does.  Responsibilities
+ * of a DMA controller driver include:
+ *
+ *  - Handling the details of moving multiple USB packets
+ *    in cooperation with the Inventra USB core, including especially
+ *    the correct RX side treatment of short packets and buffer-full
+ *    states (both of which terminate transfers).
+ *
+ *  - Knowing the correlation between dma channels and the
+ *    Inventra core's local endpoint resources and data direction.
+ *
+ *  - Maintaining a list of allocated/available channels.
+ *
+ *  - Updating channel status on interrupts,
+ *    whether shared with the Inventra core or separate.
+ */
+
+#define        DMA_ADDR_INVALID        (~(dma_addr_t)0)
+
+#ifndef CONFIG_MUSB_PIO_ONLY
+#define        is_dma_capable()        (1)
+#else
+#define        is_dma_capable()        (0)
+#endif
+
+#ifdef CONFIG_USB_TI_CPPI_DMA
+#define        is_cppi_enabled()       1
+#else
+#define        is_cppi_enabled()       0
+#endif
+
+#ifdef CONFIG_USB_TUSB_OMAP_DMA
+#define tusb_dma_omap()                        1
+#else
+#define tusb_dma_omap()                        0
+#endif
+
+/* Anomaly 05000456 - USB Receive Interrupt Is Not Generated in DMA Mode 1
+ *     Only allow DMA mode 1 to be used when the USB will actually generate the
+ *     interrupts we expect.
+ */
+#ifdef CONFIG_BLACKFIN
+# undef USE_MODE1
+# if !ANOMALY_05000456
+#  define USE_MODE1
+# endif
+#endif
+
+/*
+ * DMA channel status ... updated by the dma controller driver whenever that
+ * status changes, and protected by the overall controller spinlock.
+ */
+enum dma_channel_status {
+       /* unallocated */
+       MUSB_DMA_STATUS_UNKNOWN,
+       /* allocated ... but not busy, no errors */
+       MUSB_DMA_STATUS_FREE,
+       /* busy ... transactions are active */
+       MUSB_DMA_STATUS_BUSY,
+       /* transaction(s) aborted due to ... dma or memory bus error */
+       MUSB_DMA_STATUS_BUS_ABORT,
+       /* transaction(s) aborted due to ... core error or USB fault */
+       MUSB_DMA_STATUS_CORE_ABORT
+};
+
+struct dma_controller;
+
+/**
+ * struct dma_channel - A DMA channel.
+ * @private_data: channel-private data
+ * @max_len: the maximum number of bytes the channel can move in one
+ *     transaction (typically representing many USB maximum-sized packets)
+ * @actual_len: how many bytes have been transferred
+ * @status: current channel status (updated e.g. on interrupt)
+ * @desired_mode: true if mode 1 is desired; false if mode 0 is desired
+ *
+ * channels are associated with an endpoint for the duration of at least
+ * one usb transfer.
+ */
+struct dma_channel {
+       void                    *private_data;
+       /* FIXME not void* private_data, but a dma_controller * */
+       size_t                  max_len;
+       size_t                  actual_len;
+       enum dma_channel_status status;
+       bool                    desired_mode;
+};
+
+/*
+ * dma_channel_status - return status of dma channel
+ * @c: the channel
+ *
+ * Returns the software's view of the channel status.  If that status is BUSY
+ * then it's possible that the hardware has completed (or aborted) a transfer,
+ * so the driver needs to update that status.
+ */
+static inline enum dma_channel_status
+dma_channel_status(struct dma_channel *c)
+{
+       return (is_dma_capable() && c) ? c->status : MUSB_DMA_STATUS_UNKNOWN;
+}
+
+/**
+ * struct dma_controller - A DMA Controller.
+ * @start: call this to start a DMA controller;
+ *     return 0 on success, else negative errno
+ * @stop: call this to stop a DMA controller
+ *     return 0 on success, else negative errno
+ * @channel_alloc: call this to allocate a DMA channel
+ * @channel_release: call this to release a DMA channel
+ * @channel_abort: call this to abort a pending DMA transaction,
+ *     returning it to FREE (but allocated) state
+ *
+ * Controllers manage dma channels.
+ */
+struct dma_controller {
+       int                     (*start)(struct dma_controller *);
+       int                     (*stop)(struct dma_controller *);
+       struct dma_channel      *(*channel_alloc)(struct dma_controller *,
+                                       struct musb_hw_ep *, u8 is_tx);
+       void                    (*channel_release)(struct dma_channel *);
+       int                     (*channel_program)(struct dma_channel *channel,
+                                                       u16 maxpacket, u8 mode,
+                                                       dma_addr_t dma_addr,
+                                                       u32 length);
+       int                     (*channel_abort)(struct dma_channel *);
+       int                     (*is_compatible)(struct dma_channel *channel,
+                                                       u16 maxpacket,
+                                                       void *buf, u32 length);
+};
+
+/* called after channel_program(), may indicate a fault */
+extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit);
+
+
+extern struct dma_controller *__init
+dma_controller_create(struct musb *, void __iomem *);
+
+extern void dma_controller_destroy(struct dma_controller *);
+
+#endif /* __MUSB_DMA_H__ */
diff --git a/drivers/usb/musb-new/musb_dsps.c b/drivers/usb/musb-new/musb_dsps.c
new file mode 100644 (file)
index 0000000..9a03917
--- /dev/null
@@ -0,0 +1,771 @@
+/*
+ * Texas Instruments DSPS platforms "glue layer"
+ *
+ * Copyright (C) 2012, by Texas Instruments
+ *
+ * Based on the am35x "glue layer" code.
+ *
+ * This file is part of the Inventra Controller Driver for Linux.
+ *
+ * The Inventra Controller Driver for Linux 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.
+ *
+ * The Inventra Controller Driver for Linux 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 The Inventra Controller Driver for Linux ; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA  02111-1307  USA
+ *
+ * musb_dsps.c will be a common file for all the TI DSPS platforms
+ * such as dm64x, dm36x, dm35x, da8x, am35x and ti81x.
+ * For now only ti81x is using this and in future davinci.c, am35x.c
+ * da8xx.c would be merged to this file after testing.
+ */
+
+#define __UBOOT__
+#ifndef __UBOOT__
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
+#include <linux/module.h>
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+
+#include <plat/usb.h>
+#else
+#include <common.h>
+#include <asm/omap_musb.h>
+#include "linux-compat.h"
+#endif
+
+#include "musb_core.h"
+
+/**
+ * avoid using musb_readx()/musb_writex() as glue layer should not be
+ * dependent on musb core layer symbols.
+ */
+static inline u8 dsps_readb(const void __iomem *addr, unsigned offset)
+       { return __raw_readb(addr + offset); }
+
+static inline u32 dsps_readl(const void __iomem *addr, unsigned offset)
+       { return __raw_readl(addr + offset); }
+
+static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data)
+       { __raw_writeb(data, addr + offset); }
+
+static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data)
+       { __raw_writel(data, addr + offset); }
+
+/**
+ * DSPS musb wrapper register offset.
+ * FIXME: This should be expanded to have all the wrapper registers from TI DSPS
+ * musb ips.
+ */
+struct dsps_musb_wrapper {
+       u16     revision;
+       u16     control;
+       u16     status;
+       u16     eoi;
+       u16     epintr_set;
+       u16     epintr_clear;
+       u16     epintr_status;
+       u16     coreintr_set;
+       u16     coreintr_clear;
+       u16     coreintr_status;
+       u16     phy_utmi;
+       u16     mode;
+
+       /* bit positions for control */
+       unsigned        reset:5;
+
+       /* bit positions for interrupt */
+       unsigned        usb_shift:5;
+       u32             usb_mask;
+       u32             usb_bitmap;
+       unsigned        drvvbus:5;
+
+       unsigned        txep_shift:5;
+       u32             txep_mask;
+       u32             txep_bitmap;
+
+       unsigned        rxep_shift:5;
+       u32             rxep_mask;
+       u32             rxep_bitmap;
+
+       /* bit positions for phy_utmi */
+       unsigned        otg_disable:5;
+
+       /* bit positions for mode */
+       unsigned        iddig:5;
+       /* miscellaneous stuff */
+       u32             musb_core_offset;
+       u8              poll_seconds;
+};
+
+static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = {
+       .revision               = 0x00,
+       .control                = 0x14,
+       .status                 = 0x18,
+       .eoi                    = 0x24,
+       .epintr_set             = 0x38,
+       .epintr_clear           = 0x40,
+       .epintr_status          = 0x30,
+       .coreintr_set           = 0x3c,
+       .coreintr_clear         = 0x44,
+       .coreintr_status        = 0x34,
+       .phy_utmi               = 0xe0,
+       .mode                   = 0xe8,
+       .reset                  = 0,
+       .otg_disable            = 21,
+       .iddig                  = 8,
+       .usb_shift              = 0,
+       .usb_mask               = 0x1ff,
+       .usb_bitmap             = (0x1ff << 0),
+       .drvvbus                = 8,
+       .txep_shift             = 0,
+       .txep_mask              = 0xffff,
+       .txep_bitmap            = (0xffff << 0),
+       .rxep_shift             = 16,
+       .rxep_mask              = 0xfffe,
+       .rxep_bitmap            = (0xfffe << 16),
+       .musb_core_offset       = 0x400,
+       .poll_seconds           = 2,
+};
+
+/**
+ * DSPS glue structure.
+ */
+struct dsps_glue {
+       struct device *dev;
+       struct platform_device *musb;   /* child musb pdev */
+       const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
+       struct timer_list timer;        /* otg_workaround timer */
+};
+
+/**
+ * dsps_musb_enable - enable interrupts
+ */
+static void dsps_musb_enable(struct musb *musb)
+{
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct platform_device *pdev = to_platform_device(dev->parent);
+       struct dsps_glue *glue = platform_get_drvdata(pdev);
+       const struct dsps_musb_wrapper *wrp = glue->wrp;
+#else
+       const struct dsps_musb_wrapper *wrp = &ti81xx_driver_data;
+#endif
+       void __iomem *reg_base = musb->ctrl_base;
+       u32 epmask, coremask;
+
+       /* Workaround: setup IRQs through both register sets. */
+       epmask = ((musb->epmask & wrp->txep_mask) << wrp->txep_shift) |
+              ((musb->epmask & wrp->rxep_mask) << wrp->rxep_shift);
+       coremask = (wrp->usb_bitmap & ~MUSB_INTR_SOF);
+
+       dsps_writel(reg_base, wrp->epintr_set, epmask);
+       dsps_writel(reg_base, wrp->coreintr_set, coremask);
+       /* Force the DRVVBUS IRQ so we can start polling for ID change. */
+#ifndef __UBOOT__
+       if (is_otg_enabled(musb))
+               dsps_writel(reg_base, wrp->coreintr_set,
+                           (1 << wrp->drvvbus) << wrp->usb_shift);
+#endif
+}
+
+/**
+ * dsps_musb_disable - disable HDRC and flush interrupts
+ */
+static void dsps_musb_disable(struct musb *musb)
+{
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct platform_device *pdev = to_platform_device(dev->parent);
+       struct dsps_glue *glue = platform_get_drvdata(pdev);
+       const struct dsps_musb_wrapper *wrp = glue->wrp;
+       void __iomem *reg_base = musb->ctrl_base;
+
+       dsps_writel(reg_base, wrp->coreintr_clear, wrp->usb_bitmap);
+       dsps_writel(reg_base, wrp->epintr_clear,
+                        wrp->txep_bitmap | wrp->rxep_bitmap);
+       dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
+       dsps_writel(reg_base, wrp->eoi, 0);
+#endif
+}
+
+#ifndef __UBOOT__
+static void otg_timer(unsigned long _musb)
+{
+       struct musb *musb = (void *)_musb;
+       void __iomem *mregs = musb->mregs;
+       struct device *dev = musb->controller;
+       struct platform_device *pdev = to_platform_device(dev->parent);
+       struct dsps_glue *glue = platform_get_drvdata(pdev);
+       const struct dsps_musb_wrapper *wrp = glue->wrp;
+       u8 devctl;
+       unsigned long flags;
+
+       /*
+        * We poll because DSPS IP's won't expose several OTG-critical
+        * status change events (from the transceiver) otherwise.
+        */
+       devctl = dsps_readb(mregs, MUSB_DEVCTL);
+       dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
+                               otg_state_string(musb->xceiv->state));
+
+       spin_lock_irqsave(&musb->lock, flags);
+       switch (musb->xceiv->state) {
+       case OTG_STATE_A_WAIT_BCON:
+               devctl &= ~MUSB_DEVCTL_SESSION;
+               dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+               devctl = dsps_readb(musb->mregs, MUSB_DEVCTL);
+               if (devctl & MUSB_DEVCTL_BDEVICE) {
+                       musb->xceiv->state = OTG_STATE_B_IDLE;
+                       MUSB_DEV_MODE(musb);
+               } else {
+                       musb->xceiv->state = OTG_STATE_A_IDLE;
+                       MUSB_HST_MODE(musb);
+               }
+               break;
+       case OTG_STATE_A_WAIT_VFALL:
+               musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+               dsps_writel(musb->ctrl_base, wrp->coreintr_set,
+                           MUSB_INTR_VBUSERROR << wrp->usb_shift);
+               break;
+       case OTG_STATE_B_IDLE:
+               if (!is_peripheral_enabled(musb))
+                       break;
+
+               devctl = dsps_readb(mregs, MUSB_DEVCTL);
+               if (devctl & MUSB_DEVCTL_BDEVICE)
+                       mod_timer(&glue->timer,
+                                       jiffies + wrp->poll_seconds * HZ);
+               else
+                       musb->xceiv->state = OTG_STATE_A_IDLE;
+               break;
+       default:
+               break;
+       }
+       spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
+{
+       struct device *dev = musb->controller;
+       struct platform_device *pdev = to_platform_device(dev->parent);
+       struct dsps_glue *glue = platform_get_drvdata(pdev);
+       static unsigned long last_timer;
+
+       if (!is_otg_enabled(musb))
+               return;
+
+       if (timeout == 0)
+               timeout = jiffies + msecs_to_jiffies(3);
+
+       /* Never idle if active, or when VBUS timeout is not set as host */
+       if (musb->is_active || (musb->a_wait_bcon == 0 &&
+                               musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
+               dev_dbg(musb->controller, "%s active, deleting timer\n",
+                               otg_state_string(musb->xceiv->state));
+               del_timer(&glue->timer);
+               last_timer = jiffies;
+               return;
+       }
+
+       if (time_after(last_timer, timeout) && timer_pending(&glue->timer)) {
+               dev_dbg(musb->controller,
+                       "Longer idle timer already pending, ignoring...\n");
+               return;
+       }
+       last_timer = timeout;
+
+       dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
+               otg_state_string(musb->xceiv->state),
+                       jiffies_to_msecs(timeout - jiffies));
+       mod_timer(&glue->timer, timeout);
+}
+#endif
+
+static irqreturn_t dsps_interrupt(int irq, void *hci)
+{
+       struct musb  *musb = hci;
+       void __iomem *reg_base = musb->ctrl_base;
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct platform_device *pdev = to_platform_device(dev->parent);
+       struct dsps_glue *glue = platform_get_drvdata(pdev);
+       const struct dsps_musb_wrapper *wrp = glue->wrp;
+#else
+       const struct dsps_musb_wrapper *wrp = &ti81xx_driver_data;
+#endif
+       unsigned long flags;
+       irqreturn_t ret = IRQ_NONE;
+       u32 epintr, usbintr;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       /* Get endpoint interrupts */
+       epintr = dsps_readl(reg_base, wrp->epintr_status);
+       musb->int_rx = (epintr & wrp->rxep_bitmap) >> wrp->rxep_shift;
+       musb->int_tx = (epintr & wrp->txep_bitmap) >> wrp->txep_shift;
+
+       if (epintr)
+               dsps_writel(reg_base, wrp->epintr_status, epintr);
+
+       /* Get usb core interrupts */
+       usbintr = dsps_readl(reg_base, wrp->coreintr_status);
+       if (!usbintr && !epintr)
+               goto eoi;
+
+       musb->int_usb = (usbintr & wrp->usb_bitmap) >> wrp->usb_shift;
+       if (usbintr)
+               dsps_writel(reg_base, wrp->coreintr_status, usbintr);
+
+       dev_dbg(musb->controller, "usbintr (%x) epintr(%x)\n",
+                       usbintr, epintr);
+#ifndef __UBOOT__
+       /*
+        * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
+        * DSPS IP's missing ID change IRQ.  We need an ID change IRQ to
+        * switch appropriately between halves of the OTG state machine.
+        * Managing DEVCTL.SESSION per Mentor docs requires that we know its
+        * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
+        * Also, DRVVBUS pulses for SRP (but not at 5V) ...
+        */
+       if ((usbintr & MUSB_INTR_BABBLE) && is_host_enabled(musb))
+               pr_info("CAUTION: musb: Babble Interrupt Occured\n");
+
+       if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) {
+               int drvvbus = dsps_readl(reg_base, wrp->status);
+               void __iomem *mregs = musb->mregs;
+               u8 devctl = dsps_readb(mregs, MUSB_DEVCTL);
+               int err;
+
+               err = is_host_enabled(musb) && (musb->int_usb &
+                                               MUSB_INTR_VBUSERROR);
+               if (err) {
+                       /*
+                        * The Mentor core doesn't debounce VBUS as needed
+                        * to cope with device connect current spikes. This
+                        * means it's not uncommon for bus-powered devices
+                        * to get VBUS errors during enumeration.
+                        *
+                        * This is a workaround, but newer RTL from Mentor
+                        * seems to allow a better one: "re"-starting sessions
+                        * without waiting for VBUS to stop registering in
+                        * devctl.
+                        */
+                       musb->int_usb &= ~MUSB_INTR_VBUSERROR;
+                       musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
+                       mod_timer(&glue->timer,
+                                       jiffies + wrp->poll_seconds * HZ);
+                       WARNING("VBUS error workaround (delay coming)\n");
+               } else if (is_host_enabled(musb) && drvvbus) {
+                       musb->is_active = 1;
+                       MUSB_HST_MODE(musb);
+                       musb->xceiv->otg->default_a = 1;
+                       musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+                       del_timer(&glue->timer);
+               } else {
+                       musb->is_active = 0;
+                       MUSB_DEV_MODE(musb);
+                       musb->xceiv->otg->default_a = 0;
+                       musb->xceiv->state = OTG_STATE_B_IDLE;
+               }
+
+               /* NOTE: this must complete power-on within 100 ms. */
+               dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
+                               drvvbus ? "on" : "off",
+                               otg_state_string(musb->xceiv->state),
+                               err ? " ERROR" : "",
+                               devctl);
+               ret = IRQ_HANDLED;
+       }
+#endif
+
+       if (musb->int_tx || musb->int_rx || musb->int_usb)
+               ret |= musb_interrupt(musb);
+
+ eoi:
+       /* EOI needs to be written for the IRQ to be re-asserted. */
+       if (ret == IRQ_HANDLED || epintr || usbintr)
+               dsps_writel(reg_base, wrp->eoi, 1);
+
+#ifndef __UBOOT__
+       /* Poll for ID change */
+       if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE)
+               mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
+#endif
+
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return ret;
+}
+
+static int dsps_musb_init(struct musb *musb)
+{
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct platform_device *pdev = to_platform_device(dev->parent);
+       struct dsps_glue *glue = platform_get_drvdata(pdev);
+       const struct dsps_musb_wrapper *wrp = glue->wrp;
+       struct omap_musb_board_data *data = plat->board_data;
+#else
+       struct omap_musb_board_data *data =
+                       (struct omap_musb_board_data *)musb->controller;
+       const struct dsps_musb_wrapper *wrp = &ti81xx_driver_data;
+#endif
+       void __iomem *reg_base = musb->ctrl_base;
+       u32 rev, val;
+       int status;
+
+       /* mentor core register starts at offset of 0x400 from musb base */
+       musb->mregs += wrp->musb_core_offset;
+
+#ifndef __UBOOT__
+       /* NOP driver needs change if supporting dual instance */
+       usb_nop_xceiv_register();
+       musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv))
+               return -ENODEV;
+#endif
+
+       /* Returns zero if e.g. not clocked */
+       rev = dsps_readl(reg_base, wrp->revision);
+       if (!rev) {
+               status = -ENODEV;
+               goto err0;
+       }
+
+#ifndef __UBOOT__
+       if (is_host_enabled(musb))
+               setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
+#endif
+
+       /* Reset the musb */
+       dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
+
+       /* Start the on-chip PHY and its PLL. */
+       if (data->set_phy_power)
+               data->set_phy_power(1);
+
+       musb->isr = dsps_interrupt;
+
+       /* reset the otgdisable bit, needed for host mode to work */
+       val = dsps_readl(reg_base, wrp->phy_utmi);
+       val &= ~(1 << wrp->otg_disable);
+       dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
+
+       /* clear level interrupt */
+       dsps_writel(reg_base, wrp->eoi, 0);
+
+       return 0;
+err0:
+#ifndef __UBOOT__
+       usb_put_phy(musb->xceiv);
+       usb_nop_xceiv_unregister();
+#endif
+       return status;
+}
+
+static int dsps_musb_exit(struct musb *musb)
+{
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+       struct platform_device *pdev = to_platform_device(dev->parent);
+       struct dsps_glue *glue = platform_get_drvdata(pdev);
+#else
+       struct omap_musb_board_data *data =
+                       (struct omap_musb_board_data *)musb->controller;
+#endif
+
+#ifndef __UBOOT__
+       if (is_host_enabled(musb))
+               del_timer_sync(&glue->timer);
+#endif
+
+       /* Shutdown the on-chip PHY and its PLL. */
+       if (data->set_phy_power)
+               data->set_phy_power(0);
+
+#ifndef __UBOOT__
+       /* NOP driver needs change if supporting dual instance */
+       usb_put_phy(musb->xceiv);
+       usb_nop_xceiv_unregister();
+#endif
+
+       return 0;
+}
+
+#ifndef __UBOOT__
+static struct musb_platform_ops dsps_ops = {
+#else
+struct musb_platform_ops musb_dsps_ops = {
+#endif
+       .init           = dsps_musb_init,
+       .exit           = dsps_musb_exit,
+
+       .enable         = dsps_musb_enable,
+       .disable        = dsps_musb_disable,
+
+#ifndef __UBOOT__
+       .try_idle       = dsps_musb_try_idle,
+#endif
+};
+
+#ifndef __UBOOT__
+static u64 musb_dmamask = DMA_BIT_MASK(32);
+#endif
+
+#ifndef __UBOOT__
+static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
+{
+       struct device *dev = glue->dev;
+       struct platform_device *pdev = to_platform_device(dev);
+       struct musb_hdrc_platform_data  *pdata = dev->platform_data;
+       struct platform_device  *musb;
+       struct resource *res;
+       struct resource resources[2];
+       char res_name[10];
+       int ret;
+
+       /* get memory resource */
+       sprintf(res_name, "musb%d", id);
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
+       if (!res) {
+               dev_err(dev, "%s get mem resource failed\n", res_name);
+               ret = -ENODEV;
+               goto err0;
+       }
+       res->parent = NULL;
+       resources[0] = *res;
+
+       /* get irq resource */
+       sprintf(res_name, "musb%d-irq", id);
+       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
+       if (!res) {
+               dev_err(dev, "%s get irq resource failed\n", res_name);
+               ret = -ENODEV;
+               goto err0;
+       }
+       res->parent = NULL;
+       resources[1] = *res;
+       resources[1].name = "mc";
+
+       /* allocate the child platform device */
+       musb = platform_device_alloc("musb-hdrc", -1);
+       if (!musb) {
+               dev_err(dev, "failed to allocate musb device\n");
+               ret = -ENOMEM;
+               goto err0;
+       }
+
+       musb->dev.parent                = dev;
+       musb->dev.dma_mask              = &musb_dmamask;
+       musb->dev.coherent_dma_mask     = musb_dmamask;
+
+       glue->musb                      = musb;
+
+       pdata->platform_ops             = &dsps_ops;
+
+       ret = platform_device_add_resources(musb, resources, 2);
+       if (ret) {
+               dev_err(dev, "failed to add resources\n");
+               goto err1;
+       }
+
+       ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+       if (ret) {
+               dev_err(dev, "failed to add platform_data\n");
+               goto err1;
+       }
+
+       ret = platform_device_add(musb);
+       if (ret) {
+               dev_err(dev, "failed to register musb device\n");
+               goto err1;
+       }
+
+       return 0;
+
+err1:
+       platform_device_put(musb);
+err0:
+       return ret;
+}
+
+static void __devexit dsps_delete_musb_pdev(struct dsps_glue *glue)
+{
+       platform_device_del(glue->musb);
+       platform_device_put(glue->musb);
+}
+
+static int __devinit dsps_probe(struct platform_device *pdev)
+{
+       const struct platform_device_id *id = platform_get_device_id(pdev);
+       const struct dsps_musb_wrapper *wrp =
+                               (struct dsps_musb_wrapper *)id->driver_data;
+       struct dsps_glue *glue;
+       struct resource *iomem;
+       int ret;
+
+       /* allocate glue */
+       glue = kzalloc(sizeof(*glue), GFP_KERNEL);
+       if (!glue) {
+               dev_err(&pdev->dev, "unable to allocate glue memory\n");
+               ret = -ENOMEM;
+               goto err0;
+       }
+
+       /* get memory resource */
+       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!iomem) {
+               dev_err(&pdev->dev, "failed to get usbss mem resourse\n");
+               ret = -ENODEV;
+               goto err1;
+       }
+
+       glue->dev = &pdev->dev;
+
+       glue->wrp = kmemdup(wrp, sizeof(*wrp), GFP_KERNEL);
+       if (!glue->wrp) {
+               dev_err(&pdev->dev, "failed to duplicate wrapper struct memory\n");
+               ret = -ENOMEM;
+               goto err1;
+       }
+       platform_set_drvdata(pdev, glue);
+
+       /* enable the usbss clocks */
+       pm_runtime_enable(&pdev->dev);
+
+       ret = pm_runtime_get_sync(&pdev->dev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "pm_runtime_get_sync FAILED");
+               goto err2;
+       }
+
+       /* create the child platform device for first instances of musb */
+       ret = dsps_create_musb_pdev(glue, 0);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "failed to create child pdev\n");
+               goto err3;
+       }
+
+       return 0;
+
+err3:
+       pm_runtime_put(&pdev->dev);
+err2:
+       pm_runtime_disable(&pdev->dev);
+       kfree(glue->wrp);
+err1:
+       kfree(glue);
+err0:
+       return ret;
+}
+static int __devexit dsps_remove(struct platform_device *pdev)
+{
+       struct dsps_glue *glue = platform_get_drvdata(pdev);
+
+       /* delete the child platform device */
+       dsps_delete_musb_pdev(glue);
+
+       /* disable usbss clocks */
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       kfree(glue->wrp);
+       kfree(glue);
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dsps_suspend(struct device *dev)
+{
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+
+       /* Shutdown the on-chip PHY and its PLL. */
+       if (data->set_phy_power)
+               data->set_phy_power(0);
+
+       return 0;
+}
+
+static int dsps_resume(struct device *dev)
+{
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+
+       /* Start the on-chip PHY and its PLL. */
+       if (data->set_phy_power)
+               data->set_phy_power(1);
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume);
+#endif
+
+#ifndef __UBOOT__
+static const struct platform_device_id musb_dsps_id_table[] __devinitconst = {
+       {
+               .name   = "musb-ti81xx",
+               .driver_data    = (kernel_ulong_t) &ti81xx_driver_data,
+       },
+       {  },   /* Terminating Entry */
+};
+MODULE_DEVICE_TABLE(platform, musb_dsps_id_table);
+
+static const struct of_device_id musb_dsps_of_match[] __devinitconst = {
+       { .compatible = "musb-ti81xx", },
+       { .compatible = "ti,ti81xx-musb", },
+       { .compatible = "ti,am335x-musb", },
+       {  },
+};
+MODULE_DEVICE_TABLE(of, musb_dsps_of_match);
+
+static struct platform_driver dsps_usbss_driver = {
+       .probe          = dsps_probe,
+       .remove         = __devexit_p(dsps_remove),
+       .driver         = {
+               .name   = "musb-dsps",
+               .pm     = &dsps_pm_ops,
+               .of_match_table = musb_dsps_of_match,
+       },
+       .id_table       = musb_dsps_id_table,
+};
+
+MODULE_DESCRIPTION("TI DSPS MUSB Glue Layer");
+MODULE_AUTHOR("Ravi B <ravibabu@ti.com>");
+MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
+MODULE_LICENSE("GPL v2");
+
+static int __init dsps_init(void)
+{
+       return platform_driver_register(&dsps_usbss_driver);
+}
+subsys_initcall(dsps_init);
+
+static void __exit dsps_exit(void)
+{
+       platform_driver_unregister(&dsps_usbss_driver);
+}
+module_exit(dsps_exit);
+#endif
diff --git a/drivers/usb/musb-new/musb_gadget.c b/drivers/usb/musb-new/musb_gadget.c
new file mode 100644 (file)
index 0000000..d2cb91a
--- /dev/null
@@ -0,0 +1,2333 @@
+/*
+ * MUSB OTG driver peripheral support
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.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.
+ *
+ * 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#define __UBOOT__
+#ifndef __UBOOT__
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#else
+#include <common.h>
+#include <linux/usb/ch9.h>
+#include "linux-compat.h"
+#endif
+
+#include "musb_core.h"
+
+
+/* MUSB PERIPHERAL status 3-mar-2006:
+ *
+ * - EP0 seems solid.  It passes both USBCV and usbtest control cases.
+ *   Minor glitches:
+ *
+ *     + remote wakeup to Linux hosts work, but saw USBCV failures;
+ *       in one test run (operator error?)
+ *     + endpoint halt tests -- in both usbtest and usbcv -- seem
+ *       to break when dma is enabled ... is something wrongly
+ *       clearing SENDSTALL?
+ *
+ * - Mass storage behaved ok when last tested.  Network traffic patterns
+ *   (with lots of short transfers etc) need retesting; they turn up the
+ *   worst cases of the DMA, since short packets are typical but are not
+ *   required.
+ *
+ * - TX/IN
+ *     + both pio and dma behave in with network and g_zero tests
+ *     + no cppi throughput issues other than no-hw-queueing
+ *     + failed with FLAT_REG (DaVinci)
+ *     + seems to behave with double buffering, PIO -and- CPPI
+ *     + with gadgetfs + AIO, requests got lost?
+ *
+ * - RX/OUT
+ *     + both pio and dma behave in with network and g_zero tests
+ *     + dma is slow in typical case (short_not_ok is clear)
+ *     + double buffering ok with PIO
+ *     + double buffering *FAILS* with CPPI, wrong data bytes sometimes
+ *     + request lossage observed with gadgetfs
+ *
+ * - ISO not tested ... might work, but only weakly isochronous
+ *
+ * - Gadget driver disabling of softconnect during bind() is ignored; so
+ *   drivers can't hold off host requests until userspace is ready.
+ *   (Workaround:  they can turn it off later.)
+ *
+ * - PORTABILITY (assumes PIO works):
+ *     + DaVinci, basically works with cppi dma
+ *     + OMAP 2430, ditto with mentor dma
+ *     + TUSB 6010, platform-specific dma in the works
+ */
+
+/* ----------------------------------------------------------------------- */
+
+#define is_buffer_mapped(req) (is_dma_capable() && \
+                                       (req->map_state != UN_MAPPED))
+
+#ifndef CONFIG_MUSB_PIO_ONLY
+/* Maps the buffer to dma  */
+
+static inline void map_dma_buffer(struct musb_request *request,
+                       struct musb *musb, struct musb_ep *musb_ep)
+{
+       int compatible = true;
+       struct dma_controller *dma = musb->dma_controller;
+
+       request->map_state = UN_MAPPED;
+
+       if (!is_dma_capable() || !musb_ep->dma)
+               return;
+
+       /* Check if DMA engine can handle this request.
+        * DMA code must reject the USB request explicitly.
+        * Default behaviour is to map the request.
+        */
+       if (dma->is_compatible)
+               compatible = dma->is_compatible(musb_ep->dma,
+                               musb_ep->packet_sz, request->request.buf,
+                               request->request.length);
+       if (!compatible)
+               return;
+
+       if (request->request.dma == DMA_ADDR_INVALID) {
+               request->request.dma = dma_map_single(
+                               musb->controller,
+                               request->request.buf,
+                               request->request.length,
+                               request->tx
+                                       ? DMA_TO_DEVICE
+                                       : DMA_FROM_DEVICE);
+               request->map_state = MUSB_MAPPED;
+       } else {
+               dma_sync_single_for_device(musb->controller,
+                       request->request.dma,
+                       request->request.length,
+                       request->tx
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+               request->map_state = PRE_MAPPED;
+       }
+}
+
+/* Unmap the buffer from dma and maps it back to cpu */
+static inline void unmap_dma_buffer(struct musb_request *request,
+                               struct musb *musb)
+{
+       if (!is_buffer_mapped(request))
+               return;
+
+       if (request->request.dma == DMA_ADDR_INVALID) {
+               dev_vdbg(musb->controller,
+                               "not unmapping a never mapped buffer\n");
+               return;
+       }
+       if (request->map_state == MUSB_MAPPED) {
+               dma_unmap_single(musb->controller,
+                       request->request.dma,
+                       request->request.length,
+                       request->tx
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+               request->request.dma = DMA_ADDR_INVALID;
+       } else { /* PRE_MAPPED */
+               dma_sync_single_for_cpu(musb->controller,
+                       request->request.dma,
+                       request->request.length,
+                       request->tx
+                               ? DMA_TO_DEVICE
+                               : DMA_FROM_DEVICE);
+       }
+       request->map_state = UN_MAPPED;
+}
+#else
+static inline void map_dma_buffer(struct musb_request *request,
+                       struct musb *musb, struct musb_ep *musb_ep)
+{
+}
+
+static inline void unmap_dma_buffer(struct musb_request *request,
+                               struct musb *musb)
+{
+}
+#endif
+
+/*
+ * Immediately complete a request.
+ *
+ * @param request the request to complete
+ * @param status the status to complete the request with
+ * Context: controller locked, IRQs blocked.
+ */
+void musb_g_giveback(
+       struct musb_ep          *ep,
+       struct usb_request      *request,
+       int                     status)
+__releases(ep->musb->lock)
+__acquires(ep->musb->lock)
+{
+       struct musb_request     *req;
+       struct musb             *musb;
+       int                     busy = ep->busy;
+
+       req = to_musb_request(request);
+
+       list_del(&req->list);
+       if (req->request.status == -EINPROGRESS)
+               req->request.status = status;
+       musb = req->musb;
+
+       ep->busy = 1;
+       spin_unlock(&musb->lock);
+       unmap_dma_buffer(req, musb);
+       if (request->status == 0)
+               dev_dbg(musb->controller, "%s done request %p,  %d/%d\n",
+                               ep->end_point.name, request,
+                               req->request.actual, req->request.length);
+       else
+               dev_dbg(musb->controller, "%s request %p, %d/%d fault %d\n",
+                               ep->end_point.name, request,
+                               req->request.actual, req->request.length,
+                               request->status);
+       req->request.complete(&req->ep->end_point, &req->request);
+       spin_lock(&musb->lock);
+       ep->busy = busy;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/*
+ * Abort requests queued to an endpoint using the status. Synchronous.
+ * caller locked controller and blocked irqs, and selected this ep.
+ */
+static void nuke(struct musb_ep *ep, const int status)
+{
+       struct musb             *musb = ep->musb;
+       struct musb_request     *req = NULL;
+       void __iomem *epio = ep->musb->endpoints[ep->current_epnum].regs;
+
+       ep->busy = 1;
+
+       if (is_dma_capable() && ep->dma) {
+               struct dma_controller   *c = ep->musb->dma_controller;
+               int value;
+
+               if (ep->is_in) {
+                       /*
+                        * The programming guide says that we must not clear
+                        * the DMAMODE bit before DMAENAB, so we only
+                        * clear it in the second write...
+                        */
+                       musb_writew(epio, MUSB_TXCSR,
+                                   MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO);
+                       musb_writew(epio, MUSB_TXCSR,
+                                       0 | MUSB_TXCSR_FLUSHFIFO);
+               } else {
+                       musb_writew(epio, MUSB_RXCSR,
+                                       0 | MUSB_RXCSR_FLUSHFIFO);
+                       musb_writew(epio, MUSB_RXCSR,
+                                       0 | MUSB_RXCSR_FLUSHFIFO);
+               }
+
+               value = c->channel_abort(ep->dma);
+               dev_dbg(musb->controller, "%s: abort DMA --> %d\n",
+                               ep->name, value);
+               c->channel_release(ep->dma);
+               ep->dma = NULL;
+       }
+
+       while (!list_empty(&ep->req_list)) {
+               req = list_first_entry(&ep->req_list, struct musb_request, list);
+               musb_g_giveback(ep, &req->request, status);
+       }
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* Data transfers - pure PIO, pure DMA, or mixed mode */
+
+/*
+ * This assumes the separate CPPI engine is responding to DMA requests
+ * from the usb core ... sequenced a bit differently from mentor dma.
+ */
+
+static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep)
+{
+       if (can_bulk_split(musb, ep->type))
+               return ep->hw_ep->max_packet_sz_tx;
+       else
+               return ep->packet_sz;
+}
+
+
+#ifdef CONFIG_USB_INVENTRA_DMA
+
+/* Peripheral tx (IN) using Mentor DMA works as follows:
+       Only mode 0 is used for transfers <= wPktSize,
+       mode 1 is used for larger transfers,
+
+       One of the following happens:
+       - Host sends IN token which causes an endpoint interrupt
+               -> TxAvail
+                       -> if DMA is currently busy, exit.
+                       -> if queue is non-empty, txstate().
+
+       - Request is queued by the gadget driver.
+               -> if queue was previously empty, txstate()
+
+       txstate()
+               -> start
+                 /\    -> setup DMA
+                 |     (data is transferred to the FIFO, then sent out when
+                 |     IN token(s) are recd from Host.
+                 |             -> DMA interrupt on completion
+                 |                calls TxAvail.
+                 |                   -> stop DMA, ~DMAENAB,
+                 |                   -> set TxPktRdy for last short pkt or zlp
+                 |                   -> Complete Request
+                 |                   -> Continue next request (call txstate)
+                 |___________________________________|
+
+ * Non-Mentor DMA engines can of course work differently, such as by
+ * upleveling from irq-per-packet to irq-per-buffer.
+ */
+
+#endif
+
+/*
+ * An endpoint is transmitting data. This can be called either from
+ * the IRQ routine or from ep.queue() to kickstart a request on an
+ * endpoint.
+ *
+ * Context: controller locked, IRQs blocked, endpoint selected
+ */
+static void txstate(struct musb *musb, struct musb_request *req)
+{
+       u8                      epnum = req->epnum;
+       struct musb_ep          *musb_ep;
+       void __iomem            *epio = musb->endpoints[epnum].regs;
+       struct usb_request      *request;
+       u16                     fifo_count = 0, csr;
+       int                     use_dma = 0;
+
+       musb_ep = req->ep;
+
+       /* Check if EP is disabled */
+       if (!musb_ep->desc) {
+               dev_dbg(musb->controller, "ep:%s disabled - ignore request\n",
+                                               musb_ep->end_point.name);
+               return;
+       }
+
+       /* we shouldn't get here while DMA is active ... but we do ... */
+       if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
+               dev_dbg(musb->controller, "dma pending...\n");
+               return;
+       }
+
+       /* read TXCSR before */
+       csr = musb_readw(epio, MUSB_TXCSR);
+
+       request = &req->request;
+       fifo_count = min(max_ep_writesize(musb, musb_ep),
+                       (int)(request->length - request->actual));
+
+       if (csr & MUSB_TXCSR_TXPKTRDY) {
+               dev_dbg(musb->controller, "%s old packet still ready , txcsr %03x\n",
+                               musb_ep->end_point.name, csr);
+               return;
+       }
+
+       if (csr & MUSB_TXCSR_P_SENDSTALL) {
+               dev_dbg(musb->controller, "%s stalling, txcsr %03x\n",
+                               musb_ep->end_point.name, csr);
+               return;
+       }
+
+       dev_dbg(musb->controller, "hw_ep%d, maxpacket %d, fifo count %d, txcsr %03x\n",
+                       epnum, musb_ep->packet_sz, fifo_count,
+                       csr);
+
+#ifndef        CONFIG_MUSB_PIO_ONLY
+       if (is_buffer_mapped(req)) {
+               struct dma_controller   *c = musb->dma_controller;
+               size_t request_size;
+
+               /* setup DMA, then program endpoint CSR */
+               request_size = min_t(size_t, request->length - request->actual,
+                                       musb_ep->dma->max_len);
+
+               use_dma = (request->dma != DMA_ADDR_INVALID);
+
+               /* MUSB_TXCSR_P_ISO is still set correctly */
+
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA)
+               {
+                       if (request_size < musb_ep->packet_sz)
+                               musb_ep->dma->desired_mode = 0;
+                       else
+                               musb_ep->dma->desired_mode = 1;
+
+                       use_dma = use_dma && c->channel_program(
+                                       musb_ep->dma, musb_ep->packet_sz,
+                                       musb_ep->dma->desired_mode,
+                                       request->dma + request->actual, request_size);
+                       if (use_dma) {
+                               if (musb_ep->dma->desired_mode == 0) {
+                                       /*
+                                        * We must not clear the DMAMODE bit
+                                        * before the DMAENAB bit -- and the
+                                        * latter doesn't always get cleared
+                                        * before we get here...
+                                        */
+                                       csr &= ~(MUSB_TXCSR_AUTOSET
+                                               | MUSB_TXCSR_DMAENAB);
+                                       musb_writew(epio, MUSB_TXCSR, csr
+                                               | MUSB_TXCSR_P_WZC_BITS);
+                                       csr &= ~MUSB_TXCSR_DMAMODE;
+                                       csr |= (MUSB_TXCSR_DMAENAB |
+                                                       MUSB_TXCSR_MODE);
+                                       /* against programming guide */
+                               } else {
+                                       csr |= (MUSB_TXCSR_DMAENAB
+                                                       | MUSB_TXCSR_DMAMODE
+                                                       | MUSB_TXCSR_MODE);
+                                       if (!musb_ep->hb_mult)
+                                               csr |= MUSB_TXCSR_AUTOSET;
+                               }
+                               csr &= ~MUSB_TXCSR_P_UNDERRUN;
+
+                               musb_writew(epio, MUSB_TXCSR, csr);
+                       }
+               }
+
+#elif defined(CONFIG_USB_TI_CPPI_DMA)
+               /* program endpoint CSR first, then setup DMA */
+               csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
+               csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE |
+                      MUSB_TXCSR_MODE;
+               musb_writew(epio, MUSB_TXCSR,
+                       (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
+                               | csr);
+
+               /* ensure writebuffer is empty */
+               csr = musb_readw(epio, MUSB_TXCSR);
+
+               /* NOTE host side sets DMAENAB later than this; both are
+                * OK since the transfer dma glue (between CPPI and Mentor
+                * fifos) just tells CPPI it could start.  Data only moves
+                * to the USB TX fifo when both fifos are ready.
+                */
+
+               /* "mode" is irrelevant here; handle terminating ZLPs like
+                * PIO does, since the hardware RNDIS mode seems unreliable
+                * except for the last-packet-is-already-short case.
+                */
+               use_dma = use_dma && c->channel_program(
+                               musb_ep->dma, musb_ep->packet_sz,
+                               0,
+                               request->dma + request->actual,
+                               request_size);
+               if (!use_dma) {
+                       c->channel_release(musb_ep->dma);
+                       musb_ep->dma = NULL;
+                       csr &= ~MUSB_TXCSR_DMAENAB;
+                       musb_writew(epio, MUSB_TXCSR, csr);
+                       /* invariant: prequest->buf is non-null */
+               }
+#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
+               use_dma = use_dma && c->channel_program(
+                               musb_ep->dma, musb_ep->packet_sz,
+                               request->zero,
+                               request->dma + request->actual,
+                               request_size);
+#endif
+       }
+#endif
+
+       if (!use_dma) {
+               /*
+                * Unmap the dma buffer back to cpu if dma channel
+                * programming fails
+                */
+               unmap_dma_buffer(req, musb);
+
+               musb_write_fifo(musb_ep->hw_ep, fifo_count,
+                               (u8 *) (request->buf + request->actual));
+               request->actual += fifo_count;
+               csr |= MUSB_TXCSR_TXPKTRDY;
+               csr &= ~MUSB_TXCSR_P_UNDERRUN;
+               musb_writew(epio, MUSB_TXCSR, csr);
+       }
+
+       /* host may already have the data when this message shows... */
+       dev_dbg(musb->controller, "%s TX/IN %s len %d/%d, txcsr %04x, fifo %d/%d\n",
+                       musb_ep->end_point.name, use_dma ? "dma" : "pio",
+                       request->actual, request->length,
+                       musb_readw(epio, MUSB_TXCSR),
+                       fifo_count,
+                       musb_readw(epio, MUSB_TXMAXP));
+}
+
+/*
+ * FIFO state update (e.g. data ready).
+ * Called from IRQ,  with controller locked.
+ */
+void musb_g_tx(struct musb *musb, u8 epnum)
+{
+       u16                     csr;
+       struct musb_request     *req;
+       struct usb_request      *request;
+       u8 __iomem              *mbase = musb->mregs;
+       struct musb_ep          *musb_ep = &musb->endpoints[epnum].ep_in;
+       void __iomem            *epio = musb->endpoints[epnum].regs;
+       struct dma_channel      *dma;
+
+       musb_ep_select(mbase, epnum);
+       req = next_request(musb_ep);
+       request = &req->request;
+
+       csr = musb_readw(epio, MUSB_TXCSR);
+       dev_dbg(musb->controller, "<== %s, txcsr %04x\n", musb_ep->end_point.name, csr);
+
+       dma = is_dma_capable() ? musb_ep->dma : NULL;
+
+       /*
+        * REVISIT: for high bandwidth, MUSB_TXCSR_P_INCOMPTX
+        * probably rates reporting as a host error.
+        */
+       if (csr & MUSB_TXCSR_P_SENTSTALL) {
+               csr |=  MUSB_TXCSR_P_WZC_BITS;
+               csr &= ~MUSB_TXCSR_P_SENTSTALL;
+               musb_writew(epio, MUSB_TXCSR, csr);
+               return;
+       }
+
+       if (csr & MUSB_TXCSR_P_UNDERRUN) {
+               /* We NAKed, no big deal... little reason to care. */
+               csr |=   MUSB_TXCSR_P_WZC_BITS;
+               csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
+               musb_writew(epio, MUSB_TXCSR, csr);
+               dev_vdbg(musb->controller, "underrun on ep%d, req %p\n",
+                               epnum, request);
+       }
+
+       if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+               /*
+                * SHOULD NOT HAPPEN... has with CPPI though, after
+                * changing SENDSTALL (and other cases); harmless?
+                */
+               dev_dbg(musb->controller, "%s dma still busy?\n", musb_ep->end_point.name);
+               return;
+       }
+
+       if (request) {
+               u8      is_dma = 0;
+
+               if (dma && (csr & MUSB_TXCSR_DMAENAB)) {
+                       is_dma = 1;
+                       csr |= MUSB_TXCSR_P_WZC_BITS;
+                       csr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_P_UNDERRUN |
+                                MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_AUTOSET);
+                       musb_writew(epio, MUSB_TXCSR, csr);
+                       /* Ensure writebuffer is empty. */
+                       csr = musb_readw(epio, MUSB_TXCSR);
+                       request->actual += musb_ep->dma->actual_len;
+                       dev_dbg(musb->controller, "TXCSR%d %04x, DMA off, len %zu, req %p\n",
+                               epnum, csr, musb_ep->dma->actual_len, request);
+               }
+
+               /*
+                * First, maybe a terminating short packet. Some DMA
+                * engines might handle this by themselves.
+                */
+               if ((request->zero && request->length
+                       && (request->length % musb_ep->packet_sz == 0)
+                       && (request->actual == request->length))
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA)
+                       || (is_dma && (!dma->desired_mode ||
+                               (request->actual &
+                                       (musb_ep->packet_sz - 1))))
+#endif
+               ) {
+                       /*
+                        * On DMA completion, FIFO may not be
+                        * available yet...
+                        */
+                       if (csr & MUSB_TXCSR_TXPKTRDY)
+                               return;
+
+                       dev_dbg(musb->controller, "sending zero pkt\n");
+                       musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE
+                                       | MUSB_TXCSR_TXPKTRDY);
+                       request->zero = 0;
+               }
+
+               if (request->actual == request->length) {
+                       musb_g_giveback(musb_ep, request, 0);
+                       /*
+                        * In the giveback function the MUSB lock is
+                        * released and acquired after sometime. During
+                        * this time period the INDEX register could get
+                        * changed by the gadget_queue function especially
+                        * on SMP systems. Reselect the INDEX to be sure
+                        * we are reading/modifying the right registers
+                        */
+                       musb_ep_select(mbase, epnum);
+                       req = musb_ep->desc ? next_request(musb_ep) : NULL;
+                       if (!req) {
+                               dev_dbg(musb->controller, "%s idle now\n",
+                                       musb_ep->end_point.name);
+                               return;
+                       }
+               }
+
+               txstate(musb, req);
+       }
+}
+
+/* ------------------------------------------------------------ */
+
+#ifdef CONFIG_USB_INVENTRA_DMA
+
+/* Peripheral rx (OUT) using Mentor DMA works as follows:
+       - Only mode 0 is used.
+
+       - Request is queued by the gadget class driver.
+               -> if queue was previously empty, rxstate()
+
+       - Host sends OUT token which causes an endpoint interrupt
+         /\      -> RxReady
+         |           -> if request queued, call rxstate
+         |             /\      -> setup DMA
+         |             |            -> DMA interrupt on completion
+         |             |               -> RxReady
+         |             |                     -> stop DMA
+         |             |                     -> ack the read
+         |             |                     -> if data recd = max expected
+         |             |                               by the request, or host
+         |             |                               sent a short packet,
+         |             |                               complete the request,
+         |             |                               and start the next one.
+         |             |_____________________________________|
+         |                                      else just wait for the host
+         |                                         to send the next OUT token.
+         |__________________________________________________|
+
+ * Non-Mentor DMA engines can of course work differently.
+ */
+
+#endif
+
+/*
+ * Context: controller locked, IRQs blocked, endpoint selected
+ */
+static void rxstate(struct musb *musb, struct musb_request *req)
+{
+       const u8                epnum = req->epnum;
+       struct usb_request      *request = &req->request;
+       struct musb_ep          *musb_ep;
+       void __iomem            *epio = musb->endpoints[epnum].regs;
+       unsigned                fifo_count = 0;
+       u16                     len;
+       u16                     csr = musb_readw(epio, MUSB_RXCSR);
+       struct musb_hw_ep       *hw_ep = &musb->endpoints[epnum];
+       u8                      use_mode_1;
+
+       if (hw_ep->is_shared_fifo)
+               musb_ep = &hw_ep->ep_in;
+       else
+               musb_ep = &hw_ep->ep_out;
+
+       len = musb_ep->packet_sz;
+
+       /* Check if EP is disabled */
+       if (!musb_ep->desc) {
+               dev_dbg(musb->controller, "ep:%s disabled - ignore request\n",
+                                               musb_ep->end_point.name);
+               return;
+       }
+
+       /* We shouldn't get here while DMA is active, but we do... */
+       if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
+               dev_dbg(musb->controller, "DMA pending...\n");
+               return;
+       }
+
+       if (csr & MUSB_RXCSR_P_SENDSTALL) {
+               dev_dbg(musb->controller, "%s stalling, RXCSR %04x\n",
+                   musb_ep->end_point.name, csr);
+               return;
+       }
+
+       if (is_cppi_enabled() && is_buffer_mapped(req)) {
+               struct dma_controller   *c = musb->dma_controller;
+               struct dma_channel      *channel = musb_ep->dma;
+
+               /* NOTE:  CPPI won't actually stop advancing the DMA
+                * queue after short packet transfers, so this is almost
+                * always going to run as IRQ-per-packet DMA so that
+                * faults will be handled correctly.
+                */
+               if (c->channel_program(channel,
+                               musb_ep->packet_sz,
+                               !request->short_not_ok,
+                               request->dma + request->actual,
+                               request->length - request->actual)) {
+
+                       /* make sure that if an rxpkt arrived after the irq,
+                        * the cppi engine will be ready to take it as soon
+                        * as DMA is enabled
+                        */
+                       csr &= ~(MUSB_RXCSR_AUTOCLEAR
+                                       | MUSB_RXCSR_DMAMODE);
+                       csr |= MUSB_RXCSR_DMAENAB | MUSB_RXCSR_P_WZC_BITS;
+                       musb_writew(epio, MUSB_RXCSR, csr);
+                       return;
+               }
+       }
+
+       if (csr & MUSB_RXCSR_RXPKTRDY) {
+               len = musb_readw(epio, MUSB_RXCOUNT);
+
+               /*
+                * Enable Mode 1 on RX transfers only when short_not_ok flag
+                * is set. Currently short_not_ok flag is set only from
+                * file_storage and f_mass_storage drivers
+                */
+
+               if (request->short_not_ok && len == musb_ep->packet_sz)
+                       use_mode_1 = 1;
+               else
+                       use_mode_1 = 0;
+
+               if (request->actual < request->length) {
+#ifdef CONFIG_USB_INVENTRA_DMA
+                       if (is_buffer_mapped(req)) {
+                               struct dma_controller   *c;
+                               struct dma_channel      *channel;
+                               int                     use_dma = 0;
+
+                               c = musb->dma_controller;
+                               channel = musb_ep->dma;
+
+       /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
+        * mode 0 only. So we do not get endpoint interrupts due to DMA
+        * completion. We only get interrupts from DMA controller.
+        *
+        * We could operate in DMA mode 1 if we knew the size of the tranfer
+        * in advance. For mass storage class, request->length = what the host
+        * sends, so that'd work.  But for pretty much everything else,
+        * request->length is routinely more than what the host sends. For
+        * most these gadgets, end of is signified either by a short packet,
+        * or filling the last byte of the buffer.  (Sending extra data in
+        * that last pckate should trigger an overflow fault.)  But in mode 1,
+        * we don't get DMA completion interrupt for short packets.
+        *
+        * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),
+        * to get endpoint interrupt on every DMA req, but that didn't seem
+        * to work reliably.
+        *
+        * REVISIT an updated g_file_storage can set req->short_not_ok, which
+        * then becomes usable as a runtime "use mode 1" hint...
+        */
+
+                               /* Experimental: Mode1 works with mass storage use cases */
+                               if (use_mode_1) {
+                                       csr |= MUSB_RXCSR_AUTOCLEAR;
+                                       musb_writew(epio, MUSB_RXCSR, csr);
+                                       csr |= MUSB_RXCSR_DMAENAB;
+                                       musb_writew(epio, MUSB_RXCSR, csr);
+
+                                       /*
+                                        * this special sequence (enabling and then
+                                        * disabling MUSB_RXCSR_DMAMODE) is required
+                                        * to get DMAReq to activate
+                                        */
+                                       musb_writew(epio, MUSB_RXCSR,
+                                               csr | MUSB_RXCSR_DMAMODE);
+                                       musb_writew(epio, MUSB_RXCSR, csr);
+
+                               } else {
+                                       if (!musb_ep->hb_mult &&
+                                               musb_ep->hw_ep->rx_double_buffered)
+                                               csr |= MUSB_RXCSR_AUTOCLEAR;
+                                       csr |= MUSB_RXCSR_DMAENAB;
+                                       musb_writew(epio, MUSB_RXCSR, csr);
+                               }
+
+                               if (request->actual < request->length) {
+                                       int transfer_size = 0;
+                                       if (use_mode_1) {
+                                               transfer_size = min(request->length - request->actual,
+                                                               channel->max_len);
+                                               musb_ep->dma->desired_mode = 1;
+                                       } else {
+                                               transfer_size = min(request->length - request->actual,
+                                                               (unsigned)len);
+                                               musb_ep->dma->desired_mode = 0;
+                                       }
+
+                                       use_dma = c->channel_program(
+                                                       channel,
+                                                       musb_ep->packet_sz,
+                                                       channel->desired_mode,
+                                                       request->dma
+                                                       + request->actual,
+                                                       transfer_size);
+                               }
+
+                               if (use_dma)
+                                       return;
+                       }
+#elif defined(CONFIG_USB_UX500_DMA)
+                       if ((is_buffer_mapped(req)) &&
+                               (request->actual < request->length)) {
+
+                               struct dma_controller *c;
+                               struct dma_channel *channel;
+                               int transfer_size = 0;
+
+                               c = musb->dma_controller;
+                               channel = musb_ep->dma;
+
+                               /* In case first packet is short */
+                               if (len < musb_ep->packet_sz)
+                                       transfer_size = len;
+                               else if (request->short_not_ok)
+                                       transfer_size = min(request->length -
+                                                       request->actual,
+                                                       channel->max_len);
+                               else
+                                       transfer_size = min(request->length -
+                                                       request->actual,
+                                                       (unsigned)len);
+
+                               csr &= ~MUSB_RXCSR_DMAMODE;
+                               csr |= (MUSB_RXCSR_DMAENAB |
+                                       MUSB_RXCSR_AUTOCLEAR);
+
+                               musb_writew(epio, MUSB_RXCSR, csr);
+
+                               if (transfer_size <= musb_ep->packet_sz) {
+                                       musb_ep->dma->desired_mode = 0;
+                               } else {
+                                       musb_ep->dma->desired_mode = 1;
+                                       /* Mode must be set after DMAENAB */
+                                       csr |= MUSB_RXCSR_DMAMODE;
+                                       musb_writew(epio, MUSB_RXCSR, csr);
+                               }
+
+                               if (c->channel_program(channel,
+                                                       musb_ep->packet_sz,
+                                                       channel->desired_mode,
+                                                       request->dma
+                                                       + request->actual,
+                                                       transfer_size))
+
+                                       return;
+                       }
+#endif /* Mentor's DMA */
+
+                       fifo_count = request->length - request->actual;
+                       dev_dbg(musb->controller, "%s OUT/RX pio fifo %d/%d, maxpacket %d\n",
+                                       musb_ep->end_point.name,
+                                       len, fifo_count,
+                                       musb_ep->packet_sz);
+
+                       fifo_count = min_t(unsigned, len, fifo_count);
+
+#ifdef CONFIG_USB_TUSB_OMAP_DMA
+                       if (tusb_dma_omap() && is_buffer_mapped(req)) {
+                               struct dma_controller *c = musb->dma_controller;
+                               struct dma_channel *channel = musb_ep->dma;
+                               u32 dma_addr = request->dma + request->actual;
+                               int ret;
+
+                               ret = c->channel_program(channel,
+                                               musb_ep->packet_sz,
+                                               channel->desired_mode,
+                                               dma_addr,
+                                               fifo_count);
+                               if (ret)
+                                       return;
+                       }
+#endif
+                       /*
+                        * Unmap the dma buffer back to cpu if dma channel
+                        * programming fails. This buffer is mapped if the
+                        * channel allocation is successful
+                        */
+                        if (is_buffer_mapped(req)) {
+                               unmap_dma_buffer(req, musb);
+
+                               /*
+                                * Clear DMAENAB and AUTOCLEAR for the
+                                * PIO mode transfer
+                                */
+                               csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR);
+                               musb_writew(epio, MUSB_RXCSR, csr);
+                       }
+
+                       musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
+                                       (request->buf + request->actual));
+                       request->actual += fifo_count;
+
+                       /* REVISIT if we left anything in the fifo, flush
+                        * it and report -EOVERFLOW
+                        */
+
+                       /* ack the read! */
+                       csr |= MUSB_RXCSR_P_WZC_BITS;
+                       csr &= ~MUSB_RXCSR_RXPKTRDY;
+                       musb_writew(epio, MUSB_RXCSR, csr);
+               }
+       }
+
+       /* reach the end or short packet detected */
+       if (request->actual == request->length || len < musb_ep->packet_sz)
+               musb_g_giveback(musb_ep, request, 0);
+}
+
+/*
+ * Data ready for a request; called from IRQ
+ */
+void musb_g_rx(struct musb *musb, u8 epnum)
+{
+       u16                     csr;
+       struct musb_request     *req;
+       struct usb_request      *request;
+       void __iomem            *mbase = musb->mregs;
+       struct musb_ep          *musb_ep;
+       void __iomem            *epio = musb->endpoints[epnum].regs;
+       struct dma_channel      *dma;
+       struct musb_hw_ep       *hw_ep = &musb->endpoints[epnum];
+
+       if (hw_ep->is_shared_fifo)
+               musb_ep = &hw_ep->ep_in;
+       else
+               musb_ep = &hw_ep->ep_out;
+
+       musb_ep_select(mbase, epnum);
+
+       req = next_request(musb_ep);
+       if (!req)
+               return;
+
+       request = &req->request;
+
+       csr = musb_readw(epio, MUSB_RXCSR);
+       dma = is_dma_capable() ? musb_ep->dma : NULL;
+
+       dev_dbg(musb->controller, "<== %s, rxcsr %04x%s %p\n", musb_ep->end_point.name,
+                       csr, dma ? " (dma)" : "", request);
+
+       if (csr & MUSB_RXCSR_P_SENTSTALL) {
+               csr |= MUSB_RXCSR_P_WZC_BITS;
+               csr &= ~MUSB_RXCSR_P_SENTSTALL;
+               musb_writew(epio, MUSB_RXCSR, csr);
+               return;
+       }
+
+       if (csr & MUSB_RXCSR_P_OVERRUN) {
+               /* csr |= MUSB_RXCSR_P_WZC_BITS; */
+               csr &= ~MUSB_RXCSR_P_OVERRUN;
+               musb_writew(epio, MUSB_RXCSR, csr);
+
+               dev_dbg(musb->controller, "%s iso overrun on %p\n", musb_ep->name, request);
+               if (request->status == -EINPROGRESS)
+                       request->status = -EOVERFLOW;
+       }
+       if (csr & MUSB_RXCSR_INCOMPRX) {
+               /* REVISIT not necessarily an error */
+               dev_dbg(musb->controller, "%s, incomprx\n", musb_ep->end_point.name);
+       }
+
+       if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+               /* "should not happen"; likely RXPKTRDY pending for DMA */
+               dev_dbg(musb->controller, "%s busy, csr %04x\n",
+                       musb_ep->end_point.name, csr);
+               return;
+       }
+
+       if (dma && (csr & MUSB_RXCSR_DMAENAB)) {
+               csr &= ~(MUSB_RXCSR_AUTOCLEAR
+                               | MUSB_RXCSR_DMAENAB
+                               | MUSB_RXCSR_DMAMODE);
+               musb_writew(epio, MUSB_RXCSR,
+                       MUSB_RXCSR_P_WZC_BITS | csr);
+
+               request->actual += musb_ep->dma->actual_len;
+
+               dev_dbg(musb->controller, "RXCSR%d %04x, dma off, %04x, len %zu, req %p\n",
+                       epnum, csr,
+                       musb_readw(epio, MUSB_RXCSR),
+                       musb_ep->dma->actual_len, request);
+
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) || \
+       defined(CONFIG_USB_UX500_DMA)
+               /* Autoclear doesn't clear RxPktRdy for short packets */
+               if ((dma->desired_mode == 0 && !hw_ep->rx_double_buffered)
+                               || (dma->actual_len
+                                       & (musb_ep->packet_sz - 1))) {
+                       /* ack the read! */
+                       csr &= ~MUSB_RXCSR_RXPKTRDY;
+                       musb_writew(epio, MUSB_RXCSR, csr);
+               }
+
+               /* incomplete, and not short? wait for next IN packet */
+               if ((request->actual < request->length)
+                               && (musb_ep->dma->actual_len
+                                       == musb_ep->packet_sz)) {
+                       /* In double buffer case, continue to unload fifo if
+                        * there is Rx packet in FIFO.
+                        **/
+                       csr = musb_readw(epio, MUSB_RXCSR);
+                       if ((csr & MUSB_RXCSR_RXPKTRDY) &&
+                               hw_ep->rx_double_buffered)
+                               goto exit;
+                       return;
+               }
+#endif
+               musb_g_giveback(musb_ep, request, 0);
+               /*
+                * In the giveback function the MUSB lock is
+                * released and acquired after sometime. During
+                * this time period the INDEX register could get
+                * changed by the gadget_queue function especially
+                * on SMP systems. Reselect the INDEX to be sure
+                * we are reading/modifying the right registers
+                */
+               musb_ep_select(mbase, epnum);
+
+               req = next_request(musb_ep);
+               if (!req)
+                       return;
+       }
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) || \
+       defined(CONFIG_USB_UX500_DMA)
+exit:
+#endif
+       /* Analyze request */
+       rxstate(musb, req);
+}
+
+/* ------------------------------------------------------------ */
+
+static int musb_gadget_enable(struct usb_ep *ep,
+                       const struct usb_endpoint_descriptor *desc)
+{
+       unsigned long           flags;
+       struct musb_ep          *musb_ep;
+       struct musb_hw_ep       *hw_ep;
+       void __iomem            *regs;
+       struct musb             *musb;
+       void __iomem    *mbase;
+       u8              epnum;
+       u16             csr;
+       unsigned        tmp;
+       int             status = -EINVAL;
+
+       if (!ep || !desc)
+               return -EINVAL;
+
+       musb_ep = to_musb_ep(ep);
+       hw_ep = musb_ep->hw_ep;
+       regs = hw_ep->regs;
+       musb = musb_ep->musb;
+       mbase = musb->mregs;
+       epnum = musb_ep->current_epnum;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       if (musb_ep->desc) {
+               status = -EBUSY;
+               goto fail;
+       }
+       musb_ep->type = usb_endpoint_type(desc);
+
+       /* check direction and (later) maxpacket size against endpoint */
+       if (usb_endpoint_num(desc) != epnum)
+               goto fail;
+
+       /* REVISIT this rules out high bandwidth periodic transfers */
+       tmp = usb_endpoint_maxp(desc);
+       if (tmp & ~0x07ff) {
+               int ok;
+
+               if (usb_endpoint_dir_in(desc))
+                       ok = musb->hb_iso_tx;
+               else
+                       ok = musb->hb_iso_rx;
+
+               if (!ok) {
+                       dev_dbg(musb->controller, "no support for high bandwidth ISO\n");
+                       goto fail;
+               }
+               musb_ep->hb_mult = (tmp >> 11) & 3;
+       } else {
+               musb_ep->hb_mult = 0;
+       }
+
+       musb_ep->packet_sz = tmp & 0x7ff;
+       tmp = musb_ep->packet_sz * (musb_ep->hb_mult + 1);
+
+       /* enable the interrupts for the endpoint, set the endpoint
+        * packet size (or fail), set the mode, clear the fifo
+        */
+       musb_ep_select(mbase, epnum);
+       if (usb_endpoint_dir_in(desc)) {
+               u16 int_txe = musb_readw(mbase, MUSB_INTRTXE);
+
+               if (hw_ep->is_shared_fifo)
+                       musb_ep->is_in = 1;
+               if (!musb_ep->is_in)
+                       goto fail;
+
+               if (tmp > hw_ep->max_packet_sz_tx) {
+                       dev_dbg(musb->controller, "packet size beyond hardware FIFO size\n");
+                       goto fail;
+               }
+
+               int_txe |= (1 << epnum);
+               musb_writew(mbase, MUSB_INTRTXE, int_txe);
+
+               /* REVISIT if can_bulk_split(), use by updating "tmp";
+                * likewise high bandwidth periodic tx
+                */
+               /* Set TXMAXP with the FIFO size of the endpoint
+                * to disable double buffering mode.
+                */
+               if (musb->double_buffer_not_ok)
+                       musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx);
+               else
+                       musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz
+                                       | (musb_ep->hb_mult << 11));
+
+               csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
+               if (musb_readw(regs, MUSB_TXCSR)
+                               & MUSB_TXCSR_FIFONOTEMPTY)
+                       csr |= MUSB_TXCSR_FLUSHFIFO;
+               if (musb_ep->type == USB_ENDPOINT_XFER_ISOC)
+                       csr |= MUSB_TXCSR_P_ISO;
+
+               /* set twice in case of double buffering */
+               musb_writew(regs, MUSB_TXCSR, csr);
+               /* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
+               musb_writew(regs, MUSB_TXCSR, csr);
+
+       } else {
+               u16 int_rxe = musb_readw(mbase, MUSB_INTRRXE);
+
+               if (hw_ep->is_shared_fifo)
+                       musb_ep->is_in = 0;
+               if (musb_ep->is_in)
+                       goto fail;
+
+               if (tmp > hw_ep->max_packet_sz_rx) {
+                       dev_dbg(musb->controller, "packet size beyond hardware FIFO size\n");
+                       goto fail;
+               }
+
+               int_rxe |= (1 << epnum);
+               musb_writew(mbase, MUSB_INTRRXE, int_rxe);
+
+               /* REVISIT if can_bulk_combine() use by updating "tmp"
+                * likewise high bandwidth periodic rx
+                */
+               /* Set RXMAXP with the FIFO size of the endpoint
+                * to disable double buffering mode.
+                */
+               if (musb->double_buffer_not_ok)
+                       musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_tx);
+               else
+                       musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz
+                                       | (musb_ep->hb_mult << 11));
+
+               /* force shared fifo to OUT-only mode */
+               if (hw_ep->is_shared_fifo) {
+                       csr = musb_readw(regs, MUSB_TXCSR);
+                       csr &= ~(MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY);
+                       musb_writew(regs, MUSB_TXCSR, csr);
+               }
+
+               csr = MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_CLRDATATOG;
+               if (musb_ep->type == USB_ENDPOINT_XFER_ISOC)
+                       csr |= MUSB_RXCSR_P_ISO;
+               else if (musb_ep->type == USB_ENDPOINT_XFER_INT)
+                       csr |= MUSB_RXCSR_DISNYET;
+
+               /* set twice in case of double buffering */
+               musb_writew(regs, MUSB_RXCSR, csr);
+               musb_writew(regs, MUSB_RXCSR, csr);
+       }
+
+       /* NOTE:  all the I/O code _should_ work fine without DMA, in case
+        * for some reason you run out of channels here.
+        */
+       if (is_dma_capable() && musb->dma_controller) {
+               struct dma_controller   *c = musb->dma_controller;
+
+               musb_ep->dma = c->channel_alloc(c, hw_ep,
+                               (desc->bEndpointAddress & USB_DIR_IN));
+       } else
+               musb_ep->dma = NULL;
+
+       musb_ep->desc = desc;
+       musb_ep->busy = 0;
+       musb_ep->wedged = 0;
+       status = 0;
+
+       pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n",
+                       musb_driver_name, musb_ep->end_point.name,
+                       ({ char *s; switch (musb_ep->type) {
+                       case USB_ENDPOINT_XFER_BULK:    s = "bulk"; break;
+                       case USB_ENDPOINT_XFER_INT:     s = "int"; break;
+                       default:                        s = "iso"; break;
+                       }; s; }),
+                       musb_ep->is_in ? "IN" : "OUT",
+                       musb_ep->dma ? "dma, " : "",
+                       musb_ep->packet_sz);
+
+       schedule_work(&musb->irq_work);
+
+fail:
+       spin_unlock_irqrestore(&musb->lock, flags);
+       return status;
+}
+
+/*
+ * Disable an endpoint flushing all requests queued.
+ */
+static int musb_gadget_disable(struct usb_ep *ep)
+{
+       unsigned long   flags;
+       struct musb     *musb;
+       u8              epnum;
+       struct musb_ep  *musb_ep;
+       void __iomem    *epio;
+       int             status = 0;
+
+       musb_ep = to_musb_ep(ep);
+       musb = musb_ep->musb;
+       epnum = musb_ep->current_epnum;
+       epio = musb->endpoints[epnum].regs;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       musb_ep_select(musb->mregs, epnum);
+
+       /* zero the endpoint sizes */
+       if (musb_ep->is_in) {
+               u16 int_txe = musb_readw(musb->mregs, MUSB_INTRTXE);
+               int_txe &= ~(1 << epnum);
+               musb_writew(musb->mregs, MUSB_INTRTXE, int_txe);
+               musb_writew(epio, MUSB_TXMAXP, 0);
+       } else {
+               u16 int_rxe = musb_readw(musb->mregs, MUSB_INTRRXE);
+               int_rxe &= ~(1 << epnum);
+               musb_writew(musb->mregs, MUSB_INTRRXE, int_rxe);
+               musb_writew(epio, MUSB_RXMAXP, 0);
+       }
+
+       musb_ep->desc = NULL;
+#ifndef __UBOOT__
+       musb_ep->end_point.desc = NULL;
+#endif
+
+       /* abort all pending DMA and requests */
+       nuke(musb_ep, -ESHUTDOWN);
+
+       schedule_work(&musb->irq_work);
+
+       spin_unlock_irqrestore(&(musb->lock), flags);
+
+       dev_dbg(musb->controller, "%s\n", musb_ep->end_point.name);
+
+       return status;
+}
+
+/*
+ * Allocate a request for an endpoint.
+ * Reused by ep0 code.
+ */
+struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
+{
+       struct musb_ep          *musb_ep = to_musb_ep(ep);
+       struct musb             *musb = musb_ep->musb;
+       struct musb_request     *request = NULL;
+
+       request = kzalloc(sizeof *request, gfp_flags);
+       if (!request) {
+               dev_dbg(musb->controller, "not enough memory\n");
+               return NULL;
+       }
+
+       request->request.dma = DMA_ADDR_INVALID;
+       request->epnum = musb_ep->current_epnum;
+       request->ep = musb_ep;
+
+       return &request->request;
+}
+
+/*
+ * Free a request
+ * Reused by ep0 code.
+ */
+void musb_free_request(struct usb_ep *ep, struct usb_request *req)
+{
+       kfree(to_musb_request(req));
+}
+
+static LIST_HEAD(buffers);
+
+struct free_record {
+       struct list_head        list;
+       struct device           *dev;
+       unsigned                bytes;
+       dma_addr_t              dma;
+};
+
+/*
+ * Context: controller locked, IRQs blocked.
+ */
+void musb_ep_restart(struct musb *musb, struct musb_request *req)
+{
+       dev_dbg(musb->controller, "<== %s request %p len %u on hw_ep%d\n",
+               req->tx ? "TX/IN" : "RX/OUT",
+               &req->request, req->request.length, req->epnum);
+
+       musb_ep_select(musb->mregs, req->epnum);
+       if (req->tx)
+               txstate(musb, req);
+       else
+               rxstate(musb, req);
+}
+
+static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
+                       gfp_t gfp_flags)
+{
+       struct musb_ep          *musb_ep;
+       struct musb_request     *request;
+       struct musb             *musb;
+       int                     status = 0;
+       unsigned long           lockflags;
+
+       if (!ep || !req)
+               return -EINVAL;
+       if (!req->buf)
+               return -ENODATA;
+
+       musb_ep = to_musb_ep(ep);
+       musb = musb_ep->musb;
+
+       request = to_musb_request(req);
+       request->musb = musb;
+
+       if (request->ep != musb_ep)
+               return -EINVAL;
+
+       dev_dbg(musb->controller, "<== to %s request=%p\n", ep->name, req);
+
+       /* request is mine now... */
+       request->request.actual = 0;
+       request->request.status = -EINPROGRESS;
+       request->epnum = musb_ep->current_epnum;
+       request->tx = musb_ep->is_in;
+
+       map_dma_buffer(request, musb, musb_ep);
+
+       spin_lock_irqsave(&musb->lock, lockflags);
+
+       /* don't queue if the ep is down */
+       if (!musb_ep->desc) {
+               dev_dbg(musb->controller, "req %p queued to %s while ep %s\n",
+                               req, ep->name, "disabled");
+               status = -ESHUTDOWN;
+               goto cleanup;
+       }
+
+       /* add request to the list */
+       list_add_tail(&request->list, &musb_ep->req_list);
+
+       /* it this is the head of the queue, start i/o ... */
+       if (!musb_ep->busy && &request->list == musb_ep->req_list.next)
+               musb_ep_restart(musb, request);
+
+cleanup:
+       spin_unlock_irqrestore(&musb->lock, lockflags);
+       return status;
+}
+
+static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request)
+{
+       struct musb_ep          *musb_ep = to_musb_ep(ep);
+       struct musb_request     *req = to_musb_request(request);
+       struct musb_request     *r;
+       unsigned long           flags;
+       int                     status = 0;
+       struct musb             *musb = musb_ep->musb;
+
+       if (!ep || !request || to_musb_request(request)->ep != musb_ep)
+               return -EINVAL;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       list_for_each_entry(r, &musb_ep->req_list, list) {
+               if (r == req)
+                       break;
+       }
+       if (r != req) {
+               dev_dbg(musb->controller, "request %p not queued to %s\n", request, ep->name);
+               status = -EINVAL;
+               goto done;
+       }
+
+       /* if the hardware doesn't have the request, easy ... */
+       if (musb_ep->req_list.next != &req->list || musb_ep->busy)
+               musb_g_giveback(musb_ep, request, -ECONNRESET);
+
+       /* ... else abort the dma transfer ... */
+       else if (is_dma_capable() && musb_ep->dma) {
+               struct dma_controller   *c = musb->dma_controller;
+
+               musb_ep_select(musb->mregs, musb_ep->current_epnum);
+               if (c->channel_abort)
+                       status = c->channel_abort(musb_ep->dma);
+               else
+                       status = -EBUSY;
+               if (status == 0)
+                       musb_g_giveback(musb_ep, request, -ECONNRESET);
+       } else {
+               /* NOTE: by sticking to easily tested hardware/driver states,
+                * we leave counting of in-flight packets imprecise.
+                */
+               musb_g_giveback(musb_ep, request, -ECONNRESET);
+       }
+
+done:
+       spin_unlock_irqrestore(&musb->lock, flags);
+       return status;
+}
+
+/*
+ * Set or clear the halt bit of an endpoint. A halted enpoint won't tx/rx any
+ * data but will queue requests.
+ *
+ * exported to ep0 code
+ */
+static int musb_gadget_set_halt(struct usb_ep *ep, int value)
+{
+       struct musb_ep          *musb_ep = to_musb_ep(ep);
+       u8                      epnum = musb_ep->current_epnum;
+       struct musb             *musb = musb_ep->musb;
+       void __iomem            *epio = musb->endpoints[epnum].regs;
+       void __iomem            *mbase;
+       unsigned long           flags;
+       u16                     csr;
+       struct musb_request     *request;
+       int                     status = 0;
+
+       if (!ep)
+               return -EINVAL;
+       mbase = musb->mregs;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       if ((USB_ENDPOINT_XFER_ISOC == musb_ep->type)) {
+               status = -EINVAL;
+               goto done;
+       }
+
+       musb_ep_select(mbase, epnum);
+
+       request = next_request(musb_ep);
+       if (value) {
+               if (request) {
+                       dev_dbg(musb->controller, "request in progress, cannot halt %s\n",
+                           ep->name);
+                       status = -EAGAIN;
+                       goto done;
+               }
+               /* Cannot portably stall with non-empty FIFO */
+               if (musb_ep->is_in) {
+                       csr = musb_readw(epio, MUSB_TXCSR);
+                       if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
+                               dev_dbg(musb->controller, "FIFO busy, cannot halt %s\n", ep->name);
+                               status = -EAGAIN;
+                               goto done;
+                       }
+               }
+       } else
+               musb_ep->wedged = 0;
+
+       /* set/clear the stall and toggle bits */
+       dev_dbg(musb->controller, "%s: %s stall\n", ep->name, value ? "set" : "clear");
+       if (musb_ep->is_in) {
+               csr = musb_readw(epio, MUSB_TXCSR);
+               csr |= MUSB_TXCSR_P_WZC_BITS
+                       | MUSB_TXCSR_CLRDATATOG;
+               if (value)
+                       csr |= MUSB_TXCSR_P_SENDSTALL;
+               else
+                       csr &= ~(MUSB_TXCSR_P_SENDSTALL
+                               | MUSB_TXCSR_P_SENTSTALL);
+               csr &= ~MUSB_TXCSR_TXPKTRDY;
+               musb_writew(epio, MUSB_TXCSR, csr);
+       } else {
+               csr = musb_readw(epio, MUSB_RXCSR);
+               csr |= MUSB_RXCSR_P_WZC_BITS
+                       | MUSB_RXCSR_FLUSHFIFO
+                       | MUSB_RXCSR_CLRDATATOG;
+               if (value)
+                       csr |= MUSB_RXCSR_P_SENDSTALL;
+               else
+                       csr &= ~(MUSB_RXCSR_P_SENDSTALL
+                               | MUSB_RXCSR_P_SENTSTALL);
+               musb_writew(epio, MUSB_RXCSR, csr);
+       }
+
+       /* maybe start the first request in the queue */
+       if (!musb_ep->busy && !value && request) {
+               dev_dbg(musb->controller, "restarting the request\n");
+               musb_ep_restart(musb, request);
+       }
+
+done:
+       spin_unlock_irqrestore(&musb->lock, flags);
+       return status;
+}
+
+#ifndef __UBOOT__
+/*
+ * Sets the halt feature with the clear requests ignored
+ */
+static int musb_gadget_set_wedge(struct usb_ep *ep)
+{
+       struct musb_ep          *musb_ep = to_musb_ep(ep);
+
+       if (!ep)
+               return -EINVAL;
+
+       musb_ep->wedged = 1;
+
+       return usb_ep_set_halt(ep);
+}
+#endif
+
+static int musb_gadget_fifo_status(struct usb_ep *ep)
+{
+       struct musb_ep          *musb_ep = to_musb_ep(ep);
+       void __iomem            *epio = musb_ep->hw_ep->regs;
+       int                     retval = -EINVAL;
+
+       if (musb_ep->desc && !musb_ep->is_in) {
+               struct musb             *musb = musb_ep->musb;
+               int                     epnum = musb_ep->current_epnum;
+               void __iomem            *mbase = musb->mregs;
+               unsigned long           flags;
+
+               spin_lock_irqsave(&musb->lock, flags);
+
+               musb_ep_select(mbase, epnum);
+               /* FIXME return zero unless RXPKTRDY is set */
+               retval = musb_readw(epio, MUSB_RXCOUNT);
+
+               spin_unlock_irqrestore(&musb->lock, flags);
+       }
+       return retval;
+}
+
+static void musb_gadget_fifo_flush(struct usb_ep *ep)
+{
+       struct musb_ep  *musb_ep = to_musb_ep(ep);
+       struct musb     *musb = musb_ep->musb;
+       u8              epnum = musb_ep->current_epnum;
+       void __iomem    *epio = musb->endpoints[epnum].regs;
+       void __iomem    *mbase;
+       unsigned long   flags;
+       u16             csr, int_txe;
+
+       mbase = musb->mregs;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       musb_ep_select(mbase, (u8) epnum);
+
+       /* disable interrupts */
+       int_txe = musb_readw(mbase, MUSB_INTRTXE);
+       musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum));
+
+       if (musb_ep->is_in) {
+               csr = musb_readw(epio, MUSB_TXCSR);
+               if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
+                       csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_P_WZC_BITS;
+                       /*
+                        * Setting both TXPKTRDY and FLUSHFIFO makes controller
+                        * to interrupt current FIFO loading, but not flushing
+                        * the already loaded ones.
+                        */
+                       csr &= ~MUSB_TXCSR_TXPKTRDY;
+                       musb_writew(epio, MUSB_TXCSR, csr);
+                       /* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
+                       musb_writew(epio, MUSB_TXCSR, csr);
+               }
+       } else {
+               csr = musb_readw(epio, MUSB_RXCSR);
+               csr |= MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_P_WZC_BITS;
+               musb_writew(epio, MUSB_RXCSR, csr);
+               musb_writew(epio, MUSB_RXCSR, csr);
+       }
+
+       /* re-enable interrupt */
+       musb_writew(mbase, MUSB_INTRTXE, int_txe);
+       spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+static const struct usb_ep_ops musb_ep_ops = {
+       .enable         = musb_gadget_enable,
+       .disable        = musb_gadget_disable,
+       .alloc_request  = musb_alloc_request,
+       .free_request   = musb_free_request,
+       .queue          = musb_gadget_queue,
+       .dequeue        = musb_gadget_dequeue,
+       .set_halt       = musb_gadget_set_halt,
+#ifndef __UBOOT__
+       .set_wedge      = musb_gadget_set_wedge,
+#endif
+       .fifo_status    = musb_gadget_fifo_status,
+       .fifo_flush     = musb_gadget_fifo_flush
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int musb_gadget_get_frame(struct usb_gadget *gadget)
+{
+       struct musb     *musb = gadget_to_musb(gadget);
+
+       return (int)musb_readw(musb->mregs, MUSB_FRAME);
+}
+
+static int musb_gadget_wakeup(struct usb_gadget *gadget)
+{
+#ifndef __UBOOT__
+       struct musb     *musb = gadget_to_musb(gadget);
+       void __iomem    *mregs = musb->mregs;
+       unsigned long   flags;
+       int             status = -EINVAL;
+       u8              power, devctl;
+       int             retries;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       switch (musb->xceiv->state) {
+       case OTG_STATE_B_PERIPHERAL:
+               /* NOTE:  OTG state machine doesn't include B_SUSPENDED;
+                * that's part of the standard usb 1.1 state machine, and
+                * doesn't affect OTG transitions.
+                */
+               if (musb->may_wakeup && musb->is_suspended)
+                       break;
+               goto done;
+       case OTG_STATE_B_IDLE:
+               /* Start SRP ... OTG not required. */
+               devctl = musb_readb(mregs, MUSB_DEVCTL);
+               dev_dbg(musb->controller, "Sending SRP: devctl: %02x\n", devctl);
+               devctl |= MUSB_DEVCTL_SESSION;
+               musb_writeb(mregs, MUSB_DEVCTL, devctl);
+               devctl = musb_readb(mregs, MUSB_DEVCTL);
+               retries = 100;
+               while (!(devctl & MUSB_DEVCTL_SESSION)) {
+                       devctl = musb_readb(mregs, MUSB_DEVCTL);
+                       if (retries-- < 1)
+                               break;
+               }
+               retries = 10000;
+               while (devctl & MUSB_DEVCTL_SESSION) {
+                       devctl = musb_readb(mregs, MUSB_DEVCTL);
+                       if (retries-- < 1)
+                               break;
+               }
+
+               spin_unlock_irqrestore(&musb->lock, flags);
+               otg_start_srp(musb->xceiv->otg);
+               spin_lock_irqsave(&musb->lock, flags);
+
+               /* Block idling for at least 1s */
+               musb_platform_try_idle(musb,
+                       jiffies + msecs_to_jiffies(1 * HZ));
+
+               status = 0;
+               goto done;
+       default:
+               dev_dbg(musb->controller, "Unhandled wake: %s\n",
+                       otg_state_string(musb->xceiv->state));
+               goto done;
+       }
+
+       status = 0;
+
+       power = musb_readb(mregs, MUSB_POWER);
+       power |= MUSB_POWER_RESUME;
+       musb_writeb(mregs, MUSB_POWER, power);
+       dev_dbg(musb->controller, "issue wakeup\n");
+
+       /* FIXME do this next chunk in a timer callback, no udelay */
+       mdelay(2);
+
+       power = musb_readb(mregs, MUSB_POWER);
+       power &= ~MUSB_POWER_RESUME;
+       musb_writeb(mregs, MUSB_POWER, power);
+done:
+       spin_unlock_irqrestore(&musb->lock, flags);
+       return status;
+#else
+       return 0;
+#endif
+}
+
+static int
+musb_gadget_set_self_powered(struct usb_gadget *gadget, int is_selfpowered)
+{
+       struct musb     *musb = gadget_to_musb(gadget);
+
+       musb->is_self_powered = !!is_selfpowered;
+       return 0;
+}
+
+static void musb_pullup(struct musb *musb, int is_on)
+{
+       u8 power;
+
+       power = musb_readb(musb->mregs, MUSB_POWER);
+       if (is_on)
+               power |= MUSB_POWER_SOFTCONN;
+       else
+               power &= ~MUSB_POWER_SOFTCONN;
+
+       /* FIXME if on, HdrcStart; if off, HdrcStop */
+
+       dev_dbg(musb->controller, "gadget D+ pullup %s\n",
+               is_on ? "on" : "off");
+       musb_writeb(musb->mregs, MUSB_POWER, power);
+}
+
+#if 0
+static int musb_gadget_vbus_session(struct usb_gadget *gadget, int is_active)
+{
+       dev_dbg(musb->controller, "<= %s =>\n", __func__);
+
+       /*
+        * FIXME iff driver's softconnect flag is set (as it is during probe,
+        * though that can clear it), just musb_pullup().
+        */
+
+       return -EINVAL;
+}
+#endif
+
+static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+{
+#ifndef __UBOOT__
+       struct musb     *musb = gadget_to_musb(gadget);
+
+       if (!musb->xceiv->set_power)
+               return -EOPNOTSUPP;
+       return usb_phy_set_power(musb->xceiv, mA);
+#else
+       return 0;
+#endif
+}
+
+static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on)
+{
+       struct musb     *musb = gadget_to_musb(gadget);
+       unsigned long   flags;
+
+       is_on = !!is_on;
+
+       pm_runtime_get_sync(musb->controller);
+
+       /* NOTE: this assumes we are sensing vbus; we'd rather
+        * not pullup unless the B-session is active.
+        */
+       spin_lock_irqsave(&musb->lock, flags);
+       if (is_on != musb->softconnect) {
+               musb->softconnect = is_on;
+               musb_pullup(musb, is_on);
+       }
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       pm_runtime_put(musb->controller);
+
+       return 0;
+}
+
+#ifndef __UBOOT__
+static int musb_gadget_start(struct usb_gadget *g,
+               struct usb_gadget_driver *driver);
+static int musb_gadget_stop(struct usb_gadget *g,
+               struct usb_gadget_driver *driver);
+#endif
+
+static const struct usb_gadget_ops musb_gadget_operations = {
+       .get_frame              = musb_gadget_get_frame,
+       .wakeup                 = musb_gadget_wakeup,
+       .set_selfpowered        = musb_gadget_set_self_powered,
+       /* .vbus_session                = musb_gadget_vbus_session, */
+       .vbus_draw              = musb_gadget_vbus_draw,
+       .pullup                 = musb_gadget_pullup,
+#ifndef __UBOOT__
+       .udc_start              = musb_gadget_start,
+       .udc_stop               = musb_gadget_stop,
+#endif
+};
+
+/* ----------------------------------------------------------------------- */
+
+/* Registration */
+
+/* Only this registration code "knows" the rule (from USB standards)
+ * about there being only one external upstream port.  It assumes
+ * all peripheral ports are external...
+ */
+
+#ifndef __UBOOT__
+static void musb_gadget_release(struct device *dev)
+{
+       /* kref_put(WHAT) */
+       dev_dbg(dev, "%s\n", __func__);
+}
+#endif
+
+
+static void __devinit
+init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in)
+{
+       struct musb_hw_ep       *hw_ep = musb->endpoints + epnum;
+
+       memset(ep, 0, sizeof *ep);
+
+       ep->current_epnum = epnum;
+       ep->musb = musb;
+       ep->hw_ep = hw_ep;
+       ep->is_in = is_in;
+
+       INIT_LIST_HEAD(&ep->req_list);
+
+       sprintf(ep->name, "ep%d%s", epnum,
+                       (!epnum || hw_ep->is_shared_fifo) ? "" : (
+                               is_in ? "in" : "out"));
+       ep->end_point.name = ep->name;
+       INIT_LIST_HEAD(&ep->end_point.ep_list);
+       if (!epnum) {
+               ep->end_point.maxpacket = 64;
+               ep->end_point.ops = &musb_g_ep0_ops;
+               musb->g.ep0 = &ep->end_point;
+       } else {
+               if (is_in)
+                       ep->end_point.maxpacket = hw_ep->max_packet_sz_tx;
+               else
+                       ep->end_point.maxpacket = hw_ep->max_packet_sz_rx;
+               ep->end_point.ops = &musb_ep_ops;
+               list_add_tail(&ep->end_point.ep_list, &musb->g.ep_list);
+       }
+}
+
+/*
+ * Initialize the endpoints exposed to peripheral drivers, with backlinks
+ * to the rest of the driver state.
+ */
+static inline void __devinit musb_g_init_endpoints(struct musb *musb)
+{
+       u8                      epnum;
+       struct musb_hw_ep       *hw_ep;
+       unsigned                count = 0;
+
+       /* initialize endpoint list just once */
+       INIT_LIST_HEAD(&(musb->g.ep_list));
+
+       for (epnum = 0, hw_ep = musb->endpoints;
+                       epnum < musb->nr_endpoints;
+                       epnum++, hw_ep++) {
+               if (hw_ep->is_shared_fifo /* || !epnum */) {
+                       init_peripheral_ep(musb, &hw_ep->ep_in, epnum, 0);
+                       count++;
+               } else {
+                       if (hw_ep->max_packet_sz_tx) {
+                               init_peripheral_ep(musb, &hw_ep->ep_in,
+                                                       epnum, 1);
+                               count++;
+                       }
+                       if (hw_ep->max_packet_sz_rx) {
+                               init_peripheral_ep(musb, &hw_ep->ep_out,
+                                                       epnum, 0);
+                               count++;
+                       }
+               }
+       }
+}
+
+/* called once during driver setup to initialize and link into
+ * the driver model; memory is zeroed.
+ */
+int __devinit musb_gadget_setup(struct musb *musb)
+{
+       int status;
+
+       /* REVISIT minor race:  if (erroneously) setting up two
+        * musb peripherals at the same time, only the bus lock
+        * is probably held.
+        */
+
+       musb->g.ops = &musb_gadget_operations;
+#ifndef __UBOOT__
+       musb->g.max_speed = USB_SPEED_HIGH;
+#endif
+       musb->g.speed = USB_SPEED_UNKNOWN;
+
+#ifndef __UBOOT__
+       /* this "gadget" abstracts/virtualizes the controller */
+       dev_set_name(&musb->g.dev, "gadget");
+       musb->g.dev.parent = musb->controller;
+       musb->g.dev.dma_mask = musb->controller->dma_mask;
+       musb->g.dev.release = musb_gadget_release;
+#endif
+       musb->g.name = musb_driver_name;
+
+#ifndef __UBOOT__
+       if (is_otg_enabled(musb))
+               musb->g.is_otg = 1;
+#endif
+
+       musb_g_init_endpoints(musb);
+
+       musb->is_active = 0;
+       musb_platform_try_idle(musb, 0);
+
+#ifndef __UBOOT__
+       status = device_register(&musb->g.dev);
+       if (status != 0) {
+               put_device(&musb->g.dev);
+               return status;
+       }
+       status = usb_add_gadget_udc(musb->controller, &musb->g);
+       if (status)
+               goto err;
+#endif
+
+       return 0;
+#ifndef __UBOOT__
+err:
+       musb->g.dev.parent = NULL;
+       device_unregister(&musb->g.dev);
+       return status;
+#endif
+}
+
+void musb_gadget_cleanup(struct musb *musb)
+{
+#ifndef __UBOOT__
+       usb_del_gadget_udc(&musb->g);
+       if (musb->g.dev.parent)
+               device_unregister(&musb->g.dev);
+#endif
+}
+
+/*
+ * Register the gadget driver. Used by gadget drivers when
+ * registering themselves with the controller.
+ *
+ * -EINVAL something went wrong (not driver)
+ * -EBUSY another gadget is already using the controller
+ * -ENOMEM no memory to perform the operation
+ *
+ * @param driver the gadget driver
+ * @return <0 if error, 0 if everything is fine
+ */
+#ifndef __UBOOT__
+static int musb_gadget_start(struct usb_gadget *g,
+               struct usb_gadget_driver *driver)
+#else
+int musb_gadget_start(struct usb_gadget *g,
+               struct usb_gadget_driver *driver)
+#endif
+{
+       struct musb             *musb = gadget_to_musb(g);
+#ifndef __UBOOT__
+       struct usb_otg          *otg = musb->xceiv->otg;
+#endif
+       unsigned long           flags;
+       int                     retval = -EINVAL;
+
+#ifndef __UBOOT__
+       if (driver->max_speed < USB_SPEED_HIGH)
+               goto err0;
+#endif
+
+       pm_runtime_get_sync(musb->controller);
+
+#ifndef __UBOOT__
+       dev_dbg(musb->controller, "registering driver %s\n", driver->function);
+#endif
+
+       musb->softconnect = 0;
+       musb->gadget_driver = driver;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       musb->is_active = 1;
+
+#ifndef __UBOOT__
+       otg_set_peripheral(otg, &musb->g);
+       musb->xceiv->state = OTG_STATE_B_IDLE;
+
+       /*
+        * FIXME this ignores the softconnect flag.  Drivers are
+        * allowed hold the peripheral inactive until for example
+        * userspace hooks up printer hardware or DSP codecs, so
+        * hosts only see fully functional devices.
+        */
+
+       if (!is_otg_enabled(musb))
+#endif
+               musb_start(musb);
+
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+#ifndef __UBOOT__
+       if (is_otg_enabled(musb)) {
+               struct usb_hcd  *hcd = musb_to_hcd(musb);
+
+               dev_dbg(musb->controller, "OTG startup...\n");
+
+               /* REVISIT:  funcall to other code, which also
+                * handles power budgeting ... this way also
+                * ensures HdrcStart is indirectly called.
+                */
+               retval = usb_add_hcd(musb_to_hcd(musb), 0, 0);
+               if (retval < 0) {
+                       dev_dbg(musb->controller, "add_hcd failed, %d\n", retval);
+                       goto err2;
+               }
+
+               if ((musb->xceiv->last_event == USB_EVENT_ID)
+                                       && otg->set_vbus)
+                       otg_set_vbus(otg, 1);
+
+               hcd->self.uses_pio_for_control = 1;
+       }
+       if (musb->xceiv->last_event == USB_EVENT_NONE)
+               pm_runtime_put(musb->controller);
+#endif
+
+       return 0;
+
+#ifndef __UBOOT__
+err2:
+       if (!is_otg_enabled(musb))
+               musb_stop(musb);
+err0:
+       return retval;
+#endif
+}
+
+#ifndef __UBOOT__
+static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)
+{
+       int                     i;
+       struct musb_hw_ep       *hw_ep;
+
+       /* don't disconnect if it's not connected */
+       if (musb->g.speed == USB_SPEED_UNKNOWN)
+               driver = NULL;
+       else
+               musb->g.speed = USB_SPEED_UNKNOWN;
+
+       /* deactivate the hardware */
+       if (musb->softconnect) {
+               musb->softconnect = 0;
+               musb_pullup(musb, 0);
+       }
+       musb_stop(musb);
+
+       /* killing any outstanding requests will quiesce the driver;
+        * then report disconnect
+        */
+       if (driver) {
+               for (i = 0, hw_ep = musb->endpoints;
+                               i < musb->nr_endpoints;
+                               i++, hw_ep++) {
+                       musb_ep_select(musb->mregs, i);
+                       if (hw_ep->is_shared_fifo /* || !epnum */) {
+                               nuke(&hw_ep->ep_in, -ESHUTDOWN);
+                       } else {
+                               if (hw_ep->max_packet_sz_tx)
+                                       nuke(&hw_ep->ep_in, -ESHUTDOWN);
+                               if (hw_ep->max_packet_sz_rx)
+                                       nuke(&hw_ep->ep_out, -ESHUTDOWN);
+                       }
+               }
+       }
+}
+
+/*
+ * Unregister the gadget driver. Used by gadget drivers when
+ * unregistering themselves from the controller.
+ *
+ * @param driver the gadget driver to unregister
+ */
+static int musb_gadget_stop(struct usb_gadget *g,
+               struct usb_gadget_driver *driver)
+{
+       struct musb     *musb = gadget_to_musb(g);
+       unsigned long   flags;
+
+       if (musb->xceiv->last_event == USB_EVENT_NONE)
+               pm_runtime_get_sync(musb->controller);
+
+       /*
+        * REVISIT always use otg_set_peripheral() here too;
+        * this needs to shut down the OTG engine.
+        */
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       musb_hnp_stop(musb);
+
+       (void) musb_gadget_vbus_draw(&musb->g, 0);
+
+       musb->xceiv->state = OTG_STATE_UNDEFINED;
+       stop_activity(musb, driver);
+       otg_set_peripheral(musb->xceiv->otg, NULL);
+
+       dev_dbg(musb->controller, "unregistering driver %s\n", driver->function);
+
+       musb->is_active = 0;
+       musb_platform_try_idle(musb, 0);
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       if (is_otg_enabled(musb)) {
+               usb_remove_hcd(musb_to_hcd(musb));
+               /* FIXME we need to be able to register another
+                * gadget driver here and have everything work;
+                * that currently misbehaves.
+                */
+       }
+
+       if (!is_otg_enabled(musb))
+               musb_stop(musb);
+
+       pm_runtime_put(musb->controller);
+
+       return 0;
+}
+#endif
+
+/* ----------------------------------------------------------------------- */
+
+/* lifecycle operations called through plat_uds.c */
+
+void musb_g_resume(struct musb *musb)
+{
+#ifndef __UBOOT__
+       musb->is_suspended = 0;
+       switch (musb->xceiv->state) {
+       case OTG_STATE_B_IDLE:
+               break;
+       case OTG_STATE_B_WAIT_ACON:
+       case OTG_STATE_B_PERIPHERAL:
+               musb->is_active = 1;
+               if (musb->gadget_driver && musb->gadget_driver->resume) {
+                       spin_unlock(&musb->lock);
+                       musb->gadget_driver->resume(&musb->g);
+                       spin_lock(&musb->lock);
+               }
+               break;
+       default:
+               WARNING("unhandled RESUME transition (%s)\n",
+                               otg_state_string(musb->xceiv->state));
+       }
+#endif
+}
+
+/* called when SOF packets stop for 3+ msec */
+void musb_g_suspend(struct musb *musb)
+{
+#ifndef __UBOOT__
+       u8      devctl;
+
+       devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+       dev_dbg(musb->controller, "devctl %02x\n", devctl);
+
+       switch (musb->xceiv->state) {
+       case OTG_STATE_B_IDLE:
+               if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
+                       musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+               break;
+       case OTG_STATE_B_PERIPHERAL:
+               musb->is_suspended = 1;
+               if (musb->gadget_driver && musb->gadget_driver->suspend) {
+                       spin_unlock(&musb->lock);
+                       musb->gadget_driver->suspend(&musb->g);
+                       spin_lock(&musb->lock);
+               }
+               break;
+       default:
+               /* REVISIT if B_HOST, clear DEVCTL.HOSTREQ;
+                * A_PERIPHERAL may need care too
+                */
+               WARNING("unhandled SUSPEND transition (%s)\n",
+                               otg_state_string(musb->xceiv->state));
+       }
+#endif
+}
+
+/* Called during SRP */
+void musb_g_wakeup(struct musb *musb)
+{
+       musb_gadget_wakeup(&musb->g);
+}
+
+/* called when VBUS drops below session threshold, and in other cases */
+void musb_g_disconnect(struct musb *musb)
+{
+       void __iomem    *mregs = musb->mregs;
+       u8      devctl = musb_readb(mregs, MUSB_DEVCTL);
+
+       dev_dbg(musb->controller, "devctl %02x\n", devctl);
+
+       /* clear HR */
+       musb_writeb(mregs, MUSB_DEVCTL, devctl & MUSB_DEVCTL_SESSION);
+
+       /* don't draw vbus until new b-default session */
+       (void) musb_gadget_vbus_draw(&musb->g, 0);
+
+       musb->g.speed = USB_SPEED_UNKNOWN;
+       if (musb->gadget_driver && musb->gadget_driver->disconnect) {
+               spin_unlock(&musb->lock);
+               musb->gadget_driver->disconnect(&musb->g);
+               spin_lock(&musb->lock);
+       }
+
+#ifndef __UBOOT__
+       switch (musb->xceiv->state) {
+       default:
+               dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n",
+                       otg_state_string(musb->xceiv->state));
+               musb->xceiv->state = OTG_STATE_A_IDLE;
+               MUSB_HST_MODE(musb);
+               break;
+       case OTG_STATE_A_PERIPHERAL:
+               musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
+               MUSB_HST_MODE(musb);
+               break;
+       case OTG_STATE_B_WAIT_ACON:
+       case OTG_STATE_B_HOST:
+       case OTG_STATE_B_PERIPHERAL:
+       case OTG_STATE_B_IDLE:
+               musb->xceiv->state = OTG_STATE_B_IDLE;
+               break;
+       case OTG_STATE_B_SRP_INIT:
+               break;
+       }
+#endif
+
+       musb->is_active = 0;
+}
+
+void musb_g_reset(struct musb *musb)
+__releases(musb->lock)
+__acquires(musb->lock)
+{
+       void __iomem    *mbase = musb->mregs;
+       u8              devctl = musb_readb(mbase, MUSB_DEVCTL);
+       u8              power;
+
+#ifndef __UBOOT__
+       dev_dbg(musb->controller, "<== %s addr=%x driver '%s'\n",
+                       (devctl & MUSB_DEVCTL_BDEVICE)
+                               ? "B-Device" : "A-Device",
+                       musb_readb(mbase, MUSB_FADDR),
+                       musb->gadget_driver
+                               ? musb->gadget_driver->driver.name
+                               : NULL
+                       );
+#endif
+
+       /* report disconnect, if we didn't already (flushing EP state) */
+       if (musb->g.speed != USB_SPEED_UNKNOWN)
+               musb_g_disconnect(musb);
+
+       /* clear HR */
+       else if (devctl & MUSB_DEVCTL_HR)
+               musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
+
+
+       /* what speed did we negotiate? */
+       power = musb_readb(mbase, MUSB_POWER);
+       musb->g.speed = (power & MUSB_POWER_HSMODE)
+                       ? USB_SPEED_HIGH : USB_SPEED_FULL;
+
+       /* start in USB_STATE_DEFAULT */
+       musb->is_active = 1;
+       musb->is_suspended = 0;
+       MUSB_DEV_MODE(musb);
+       musb->address = 0;
+       musb->ep0_state = MUSB_EP0_STAGE_SETUP;
+
+       musb->may_wakeup = 0;
+       musb->g.b_hnp_enable = 0;
+       musb->g.a_alt_hnp_support = 0;
+       musb->g.a_hnp_support = 0;
+
+#ifndef __UBOOT__
+       /* Normal reset, as B-Device;
+        * or else after HNP, as A-Device
+        */
+       if (devctl & MUSB_DEVCTL_BDEVICE) {
+               musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+               musb->g.is_a_peripheral = 0;
+       } else if (is_otg_enabled(musb)) {
+               musb->xceiv->state = OTG_STATE_A_PERIPHERAL;
+               musb->g.is_a_peripheral = 1;
+       } else
+               WARN_ON(1);
+
+       /* start with default limits on VBUS power draw */
+       (void) musb_gadget_vbus_draw(&musb->g,
+                       is_otg_enabled(musb) ? 8 : 100);
+#endif
+}
diff --git a/drivers/usb/musb-new/musb_gadget.h b/drivers/usb/musb-new/musb_gadget.h
new file mode 100644 (file)
index 0000000..392f701
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * MUSB OTG driver peripheral defines
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#ifndef __MUSB_GADGET_H
+#define __MUSB_GADGET_H
+
+#include <linux/list.h>
+#ifdef __UBOOT__
+#include <asm/byteorder.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#endif
+
+enum buffer_map_state {
+       UN_MAPPED = 0,
+       PRE_MAPPED,
+       MUSB_MAPPED
+};
+
+struct musb_request {
+       struct usb_request      request;
+       struct list_head        list;
+       struct musb_ep          *ep;
+       struct musb             *musb;
+       u8 tx;                  /* endpoint direction */
+       u8 epnum;
+       enum buffer_map_state map_state;
+};
+
+static inline struct musb_request *to_musb_request(struct usb_request *req)
+{
+       return req ? container_of(req, struct musb_request, request) : NULL;
+}
+
+extern struct usb_request *
+musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags);
+extern void musb_free_request(struct usb_ep *ep, struct usb_request *req);
+
+
+/*
+ * struct musb_ep - peripheral side view of endpoint rx or tx side
+ */
+struct musb_ep {
+       /* stuff towards the head is basically write-once. */
+       struct usb_ep                   end_point;
+       char                            name[12];
+       struct musb_hw_ep               *hw_ep;
+       struct musb                     *musb;
+       u8                              current_epnum;
+
+       /* ... when enabled/disabled ... */
+       u8                              type;
+       u8                              is_in;
+       u16                             packet_sz;
+       const struct usb_endpoint_descriptor    *desc;
+       struct dma_channel              *dma;
+
+       /* later things are modified based on usage */
+       struct list_head                req_list;
+
+       u8                              wedged;
+
+       /* true if lock must be dropped but req_list may not be advanced */
+       u8                              busy;
+
+       u8                              hb_mult;
+};
+
+static inline struct musb_ep *to_musb_ep(struct usb_ep *ep)
+{
+       return ep ? container_of(ep, struct musb_ep, end_point) : NULL;
+}
+
+static inline struct musb_request *next_request(struct musb_ep *ep)
+{
+       struct list_head        *queue = &ep->req_list;
+
+       if (list_empty(queue))
+               return NULL;
+       return container_of(queue->next, struct musb_request, list);
+}
+
+extern void musb_g_tx(struct musb *musb, u8 epnum);
+extern void musb_g_rx(struct musb *musb, u8 epnum);
+
+extern const struct usb_ep_ops musb_g_ep0_ops;
+
+extern int musb_gadget_setup(struct musb *);
+extern void musb_gadget_cleanup(struct musb *);
+
+extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
+
+extern void musb_ep_restart(struct musb *, struct musb_request *);
+
+#ifdef __UBOOT__
+int musb_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver);
+#endif
+#endif         /* __MUSB_GADGET_H */
diff --git a/drivers/usb/musb-new/musb_gadget_ep0.c b/drivers/usb/musb-new/musb_gadget_ep0.c
new file mode 100644 (file)
index 0000000..6599d38
--- /dev/null
@@ -0,0 +1,1089 @@
+/*
+ * MUSB OTG peripheral driver ep0 handling
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.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.
+ *
+ * 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#define __UBOOT__
+#ifndef __UBOOT__
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#else
+#include <common.h>
+#include "linux-compat.h"
+#endif
+
+#include "musb_core.h"
+
+/* ep0 is always musb->endpoints[0].ep_in */
+#define        next_ep0_request(musb)  next_in_request(&(musb)->endpoints[0])
+
+/*
+ * locking note:  we use only the controller lock, for simpler correctness.
+ * It's always held with IRQs blocked.
+ *
+ * It protects the ep0 request queue as well as ep0_state, not just the
+ * controller and indexed registers.  And that lock stays held unless it
+ * needs to be dropped to allow reentering this driver ... like upcalls to
+ * the gadget driver, or adjusting endpoint halt status.
+ */
+
+static char *decode_ep0stage(u8 stage)
+{
+       switch (stage) {
+       case MUSB_EP0_STAGE_IDLE:       return "idle";
+       case MUSB_EP0_STAGE_SETUP:      return "setup";
+       case MUSB_EP0_STAGE_TX:         return "in";
+       case MUSB_EP0_STAGE_RX:         return "out";
+       case MUSB_EP0_STAGE_ACKWAIT:    return "wait";
+       case MUSB_EP0_STAGE_STATUSIN:   return "in/status";
+       case MUSB_EP0_STAGE_STATUSOUT:  return "out/status";
+       default:                        return "?";
+       }
+}
+
+/* handle a standard GET_STATUS request
+ * Context:  caller holds controller lock
+ */
+static int service_tx_status_request(
+       struct musb *musb,
+       const struct usb_ctrlrequest *ctrlrequest)
+{
+       void __iomem    *mbase = musb->mregs;
+       int handled = 1;
+       u8 result[2], epnum = 0;
+       const u8 recip = ctrlrequest->bRequestType & USB_RECIP_MASK;
+
+       result[1] = 0;
+
+       switch (recip) {
+       case USB_RECIP_DEVICE:
+               result[0] = musb->is_self_powered << USB_DEVICE_SELF_POWERED;
+               result[0] |= musb->may_wakeup << USB_DEVICE_REMOTE_WAKEUP;
+               if (musb->g.is_otg) {
+                       result[0] |= musb->g.b_hnp_enable
+                               << USB_DEVICE_B_HNP_ENABLE;
+                       result[0] |= musb->g.a_alt_hnp_support
+                               << USB_DEVICE_A_ALT_HNP_SUPPORT;
+                       result[0] |= musb->g.a_hnp_support
+                               << USB_DEVICE_A_HNP_SUPPORT;
+               }
+               break;
+
+       case USB_RECIP_INTERFACE:
+               result[0] = 0;
+               break;
+
+       case USB_RECIP_ENDPOINT: {
+               int             is_in;
+               struct musb_ep  *ep;
+               u16             tmp;
+               void __iomem    *regs;
+
+               epnum = (u8) ctrlrequest->wIndex;
+               if (!epnum) {
+                       result[0] = 0;
+                       break;
+               }
+
+               is_in = epnum & USB_DIR_IN;
+               if (is_in) {
+                       epnum &= 0x0f;
+                       ep = &musb->endpoints[epnum].ep_in;
+               } else {
+                       ep = &musb->endpoints[epnum].ep_out;
+               }
+               regs = musb->endpoints[epnum].regs;
+
+               if (epnum >= MUSB_C_NUM_EPS || !ep->desc) {
+                       handled = -EINVAL;
+                       break;
+               }
+
+               musb_ep_select(mbase, epnum);
+               if (is_in)
+                       tmp = musb_readw(regs, MUSB_TXCSR)
+                                               & MUSB_TXCSR_P_SENDSTALL;
+               else
+                       tmp = musb_readw(regs, MUSB_RXCSR)
+                                               & MUSB_RXCSR_P_SENDSTALL;
+               musb_ep_select(mbase, 0);
+
+               result[0] = tmp ? 1 : 0;
+               } break;
+
+       default:
+               /* class, vendor, etc ... delegate */
+               handled = 0;
+               break;
+       }
+
+       /* fill up the fifo; caller updates csr0 */
+       if (handled > 0) {
+               u16     len = le16_to_cpu(ctrlrequest->wLength);
+
+               if (len > 2)
+                       len = 2;
+               musb_write_fifo(&musb->endpoints[0], len, result);
+       }
+
+       return handled;
+}
+
+/*
+ * handle a control-IN request, the end0 buffer contains the current request
+ * that is supposed to be a standard control request. Assumes the fifo to
+ * be at least 2 bytes long.
+ *
+ * @return 0 if the request was NOT HANDLED,
+ * < 0 when error
+ * > 0 when the request is processed
+ *
+ * Context:  caller holds controller lock
+ */
+static int
+service_in_request(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest)
+{
+       int handled = 0;        /* not handled */
+
+       if ((ctrlrequest->bRequestType & USB_TYPE_MASK)
+                       == USB_TYPE_STANDARD) {
+               switch (ctrlrequest->bRequest) {
+               case USB_REQ_GET_STATUS:
+                       handled = service_tx_status_request(musb,
+                                       ctrlrequest);
+                       break;
+
+               /* case USB_REQ_SYNC_FRAME: */
+
+               default:
+                       break;
+               }
+       }
+       return handled;
+}
+
+/*
+ * Context:  caller holds controller lock
+ */
+static void musb_g_ep0_giveback(struct musb *musb, struct usb_request *req)
+{
+       musb_g_giveback(&musb->endpoints[0].ep_in, req, 0);
+}
+
+/*
+ * Tries to start B-device HNP negotiation if enabled via sysfs
+ */
+static inline void musb_try_b_hnp_enable(struct musb *musb)
+{
+       void __iomem    *mbase = musb->mregs;
+       u8              devctl;
+
+       dev_dbg(musb->controller, "HNP: Setting HR\n");
+       devctl = musb_readb(mbase, MUSB_DEVCTL);
+       musb_writeb(mbase, MUSB_DEVCTL, devctl | MUSB_DEVCTL_HR);
+}
+
+/*
+ * Handle all control requests with no DATA stage, including standard
+ * requests such as:
+ * USB_REQ_SET_CONFIGURATION, USB_REQ_SET_INTERFACE, unrecognized
+ *     always delegated to the gadget driver
+ * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE
+ *     always handled here, except for class/vendor/... features
+ *
+ * Context:  caller holds controller lock
+ */
+static int
+service_zero_data_request(struct musb *musb,
+               struct usb_ctrlrequest *ctrlrequest)
+__releases(musb->lock)
+__acquires(musb->lock)
+{
+       int handled = -EINVAL;
+       void __iomem *mbase = musb->mregs;
+       const u8 recip = ctrlrequest->bRequestType & USB_RECIP_MASK;
+
+       /* the gadget driver handles everything except what we MUST handle */
+       if ((ctrlrequest->bRequestType & USB_TYPE_MASK)
+                       == USB_TYPE_STANDARD) {
+               switch (ctrlrequest->bRequest) {
+               case USB_REQ_SET_ADDRESS:
+                       /* change it after the status stage */
+                       musb->set_address = true;
+                       musb->address = (u8) (ctrlrequest->wValue & 0x7f);
+                       handled = 1;
+                       break;
+
+               case USB_REQ_CLEAR_FEATURE:
+                       switch (recip) {
+                       case USB_RECIP_DEVICE:
+                               if (ctrlrequest->wValue
+                                               != USB_DEVICE_REMOTE_WAKEUP)
+                                       break;
+                               musb->may_wakeup = 0;
+                               handled = 1;
+                               break;
+                       case USB_RECIP_INTERFACE:
+                               break;
+                       case USB_RECIP_ENDPOINT:{
+                               const u8                epnum =
+                                       ctrlrequest->wIndex & 0x0f;
+                               struct musb_ep          *musb_ep;
+                               struct musb_hw_ep       *ep;
+                               struct musb_request     *request;
+                               void __iomem            *regs;
+                               int                     is_in;
+                               u16                     csr;
+
+                               if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
+                                   ctrlrequest->wValue != USB_ENDPOINT_HALT)
+                                       break;
+
+                               ep = musb->endpoints + epnum;
+                               regs = ep->regs;
+                               is_in = ctrlrequest->wIndex & USB_DIR_IN;
+                               if (is_in)
+                                       musb_ep = &ep->ep_in;
+                               else
+                                       musb_ep = &ep->ep_out;
+                               if (!musb_ep->desc)
+                                       break;
+
+                               handled = 1;
+                               /* Ignore request if endpoint is wedged */
+                               if (musb_ep->wedged)
+                                       break;
+
+                               musb_ep_select(mbase, epnum);
+                               if (is_in) {
+                                       csr  = musb_readw(regs, MUSB_TXCSR);
+                                       csr |= MUSB_TXCSR_CLRDATATOG |
+                                              MUSB_TXCSR_P_WZC_BITS;
+                                       csr &= ~(MUSB_TXCSR_P_SENDSTALL |
+                                                MUSB_TXCSR_P_SENTSTALL |
+                                                MUSB_TXCSR_TXPKTRDY);
+                                       musb_writew(regs, MUSB_TXCSR, csr);
+                               } else {
+                                       csr  = musb_readw(regs, MUSB_RXCSR);
+                                       csr |= MUSB_RXCSR_CLRDATATOG |
+                                              MUSB_RXCSR_P_WZC_BITS;
+                                       csr &= ~(MUSB_RXCSR_P_SENDSTALL |
+                                                MUSB_RXCSR_P_SENTSTALL);
+                                       musb_writew(regs, MUSB_RXCSR, csr);
+                               }
+
+                               /* Maybe start the first request in the queue */
+                               request = next_request(musb_ep);
+                               if (!musb_ep->busy && request) {
+                                       dev_dbg(musb->controller, "restarting the request\n");
+                                       musb_ep_restart(musb, request);
+                               }
+
+                               /* select ep0 again */
+                               musb_ep_select(mbase, 0);
+                               } break;
+                       default:
+                               /* class, vendor, etc ... delegate */
+                               handled = 0;
+                               break;
+                       }
+                       break;
+
+               case USB_REQ_SET_FEATURE:
+                       switch (recip) {
+                       case USB_RECIP_DEVICE:
+                               handled = 1;
+                               switch (ctrlrequest->wValue) {
+                               case USB_DEVICE_REMOTE_WAKEUP:
+                                       musb->may_wakeup = 1;
+                                       break;
+                               case USB_DEVICE_TEST_MODE:
+                                       if (musb->g.speed != USB_SPEED_HIGH)
+                                               goto stall;
+                                       if (ctrlrequest->wIndex & 0xff)
+                                               goto stall;
+
+                                       switch (ctrlrequest->wIndex >> 8) {
+                                       case 1:
+                                               pr_debug("TEST_J\n");
+                                               /* TEST_J */
+                                               musb->test_mode_nr =
+                                                       MUSB_TEST_J;
+                                               break;
+                                       case 2:
+                                               /* TEST_K */
+                                               pr_debug("TEST_K\n");
+                                               musb->test_mode_nr =
+                                                       MUSB_TEST_K;
+                                               break;
+                                       case 3:
+                                               /* TEST_SE0_NAK */
+                                               pr_debug("TEST_SE0_NAK\n");
+                                               musb->test_mode_nr =
+                                                       MUSB_TEST_SE0_NAK;
+                                               break;
+                                       case 4:
+                                               /* TEST_PACKET */
+                                               pr_debug("TEST_PACKET\n");
+                                               musb->test_mode_nr =
+                                                       MUSB_TEST_PACKET;
+                                               break;
+
+                                       case 0xc0:
+                                               /* TEST_FORCE_HS */
+                                               pr_debug("TEST_FORCE_HS\n");
+                                               musb->test_mode_nr =
+                                                       MUSB_TEST_FORCE_HS;
+                                               break;
+                                       case 0xc1:
+                                               /* TEST_FORCE_FS */
+                                               pr_debug("TEST_FORCE_FS\n");
+                                               musb->test_mode_nr =
+                                                       MUSB_TEST_FORCE_FS;
+                                               break;
+                                       case 0xc2:
+                                               /* TEST_FIFO_ACCESS */
+                                               pr_debug("TEST_FIFO_ACCESS\n");
+                                               musb->test_mode_nr =
+                                                       MUSB_TEST_FIFO_ACCESS;
+                                               break;
+                                       case 0xc3:
+                                               /* TEST_FORCE_HOST */
+                                               pr_debug("TEST_FORCE_HOST\n");
+                                               musb->test_mode_nr =
+                                                       MUSB_TEST_FORCE_HOST;
+                                               break;
+                                       default:
+                                               goto stall;
+                                       }
+
+                                       /* enter test mode after irq */
+                                       if (handled > 0)
+                                               musb->test_mode = true;
+                                       break;
+                               case USB_DEVICE_B_HNP_ENABLE:
+                                       if (!musb->g.is_otg)
+                                               goto stall;
+                                       musb->g.b_hnp_enable = 1;
+                                       musb_try_b_hnp_enable(musb);
+                                       break;
+                               case USB_DEVICE_A_HNP_SUPPORT:
+                                       if (!musb->g.is_otg)
+                                               goto stall;
+                                       musb->g.a_hnp_support = 1;
+                                       break;
+                               case USB_DEVICE_A_ALT_HNP_SUPPORT:
+                                       if (!musb->g.is_otg)
+                                               goto stall;
+                                       musb->g.a_alt_hnp_support = 1;
+                                       break;
+                               case USB_DEVICE_DEBUG_MODE:
+                                       handled = 0;
+                                       break;
+stall:
+                               default:
+                                       handled = -EINVAL;
+                                       break;
+                               }
+                               break;
+
+                       case USB_RECIP_INTERFACE:
+                               break;
+
+                       case USB_RECIP_ENDPOINT:{
+                               const u8                epnum =
+                                       ctrlrequest->wIndex & 0x0f;
+                               struct musb_ep          *musb_ep;
+                               struct musb_hw_ep       *ep;
+                               void __iomem            *regs;
+                               int                     is_in;
+                               u16                     csr;
+
+                               if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
+                                   ctrlrequest->wValue != USB_ENDPOINT_HALT)
+                                       break;
+
+                               ep = musb->endpoints + epnum;
+                               regs = ep->regs;
+                               is_in = ctrlrequest->wIndex & USB_DIR_IN;
+                               if (is_in)
+                                       musb_ep = &ep->ep_in;
+                               else
+                                       musb_ep = &ep->ep_out;
+                               if (!musb_ep->desc)
+                                       break;
+
+                               musb_ep_select(mbase, epnum);
+                               if (is_in) {
+                                       csr = musb_readw(regs, MUSB_TXCSR);
+                                       if (csr & MUSB_TXCSR_FIFONOTEMPTY)
+                                               csr |= MUSB_TXCSR_FLUSHFIFO;
+                                       csr |= MUSB_TXCSR_P_SENDSTALL
+                                               | MUSB_TXCSR_CLRDATATOG
+                                               | MUSB_TXCSR_P_WZC_BITS;
+                                       musb_writew(regs, MUSB_TXCSR, csr);
+                               } else {
+                                       csr = musb_readw(regs, MUSB_RXCSR);
+                                       csr |= MUSB_RXCSR_P_SENDSTALL
+                                               | MUSB_RXCSR_FLUSHFIFO
+                                               | MUSB_RXCSR_CLRDATATOG
+                                               | MUSB_RXCSR_P_WZC_BITS;
+                                       musb_writew(regs, MUSB_RXCSR, csr);
+                               }
+
+                               /* select ep0 again */
+                               musb_ep_select(mbase, 0);
+                               handled = 1;
+                               } break;
+
+                       default:
+                               /* class, vendor, etc ... delegate */
+                               handled = 0;
+                               break;
+                       }
+                       break;
+               default:
+                       /* delegate SET_CONFIGURATION, etc */
+                       handled = 0;
+               }
+       } else
+               handled = 0;
+       return handled;
+}
+
+/* we have an ep0out data packet
+ * Context:  caller holds controller lock
+ */
+static void ep0_rxstate(struct musb *musb)
+{
+       void __iomem            *regs = musb->control_ep->regs;
+       struct musb_request     *request;
+       struct usb_request      *req;
+       u16                     count, csr;
+
+       request = next_ep0_request(musb);
+       req = &request->request;
+
+       /* read packet and ack; or stall because of gadget driver bug:
+        * should have provided the rx buffer before setup() returned.
+        */
+       if (req) {
+               void            *buf = req->buf + req->actual;
+               unsigned        len = req->length - req->actual;
+
+               /* read the buffer */
+               count = musb_readb(regs, MUSB_COUNT0);
+               if (count > len) {
+                       req->status = -EOVERFLOW;
+                       count = len;
+               }
+               musb_read_fifo(&musb->endpoints[0], count, buf);
+               req->actual += count;
+               csr = MUSB_CSR0_P_SVDRXPKTRDY;
+               if (count < 64 || req->actual == req->length) {
+                       musb->ep0_state = MUSB_EP0_STAGE_STATUSIN;
+                       csr |= MUSB_CSR0_P_DATAEND;
+               } else
+                       req = NULL;
+       } else
+               csr = MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_SENDSTALL;
+
+
+       /* Completion handler may choose to stall, e.g. because the
+        * message just received holds invalid data.
+        */
+       if (req) {
+               musb->ackpend = csr;
+               musb_g_ep0_giveback(musb, req);
+               if (!musb->ackpend)
+                       return;
+               musb->ackpend = 0;
+       }
+       musb_ep_select(musb->mregs, 0);
+       musb_writew(regs, MUSB_CSR0, csr);
+}
+
+/*
+ * transmitting to the host (IN), this code might be called from IRQ
+ * and from kernel thread.
+ *
+ * Context:  caller holds controller lock
+ */
+static void ep0_txstate(struct musb *musb)
+{
+       void __iomem            *regs = musb->control_ep->regs;
+       struct musb_request     *req = next_ep0_request(musb);
+       struct usb_request      *request;
+       u16                     csr = MUSB_CSR0_TXPKTRDY;
+       u8                      *fifo_src;
+       u8                      fifo_count;
+
+       if (!req) {
+               /* WARN_ON(1); */
+               dev_dbg(musb->controller, "odd; csr0 %04x\n", musb_readw(regs, MUSB_CSR0));
+               return;
+       }
+
+       request = &req->request;
+
+       /* load the data */
+       fifo_src = (u8 *) request->buf + request->actual;
+       fifo_count = min((unsigned) MUSB_EP0_FIFOSIZE,
+               request->length - request->actual);
+       musb_write_fifo(&musb->endpoints[0], fifo_count, fifo_src);
+       request->actual += fifo_count;
+
+       /* update the flags */
+       if (fifo_count < MUSB_MAX_END0_PACKET
+                       || (request->actual == request->length
+                               && !request->zero)) {
+               musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT;
+               csr |= MUSB_CSR0_P_DATAEND;
+       } else
+               request = NULL;
+
+       /* report completions as soon as the fifo's loaded; there's no
+        * win in waiting till this last packet gets acked.  (other than
+        * very precise fault reporting, needed by USB TMC; possible with
+        * this hardware, but not usable from portable gadget drivers.)
+        */
+       if (request) {
+               musb->ackpend = csr;
+               musb_g_ep0_giveback(musb, request);
+               if (!musb->ackpend)
+                       return;
+               musb->ackpend = 0;
+       }
+
+       /* send it out, triggering a "txpktrdy cleared" irq */
+       musb_ep_select(musb->mregs, 0);
+       musb_writew(regs, MUSB_CSR0, csr);
+}
+
+/*
+ * Read a SETUP packet (struct usb_ctrlrequest) from the hardware.
+ * Fields are left in USB byte-order.
+ *
+ * Context:  caller holds controller lock.
+ */
+static void
+musb_read_setup(struct musb *musb, struct usb_ctrlrequest *req)
+{
+       struct musb_request     *r;
+       void __iomem            *regs = musb->control_ep->regs;
+
+       musb_read_fifo(&musb->endpoints[0], sizeof *req, (u8 *)req);
+
+       /* NOTE:  earlier 2.6 versions changed setup packets to host
+        * order, but now USB packets always stay in USB byte order.
+        */
+       dev_dbg(musb->controller, "SETUP req%02x.%02x v%04x i%04x l%d\n",
+               req->bRequestType,
+               req->bRequest,
+               le16_to_cpu(req->wValue),
+               le16_to_cpu(req->wIndex),
+               le16_to_cpu(req->wLength));
+
+       /* clean up any leftover transfers */
+       r = next_ep0_request(musb);
+       if (r)
+               musb_g_ep0_giveback(musb, &r->request);
+
+       /* For zero-data requests we want to delay the STATUS stage to
+        * avoid SETUPEND errors.  If we read data (OUT), delay accepting
+        * packets until there's a buffer to store them in.
+        *
+        * If we write data, the controller acts happier if we enable
+        * the TX FIFO right away, and give the controller a moment
+        * to switch modes...
+        */
+       musb->set_address = false;
+       musb->ackpend = MUSB_CSR0_P_SVDRXPKTRDY;
+       if (req->wLength == 0) {
+               if (req->bRequestType & USB_DIR_IN)
+                       musb->ackpend |= MUSB_CSR0_TXPKTRDY;
+               musb->ep0_state = MUSB_EP0_STAGE_ACKWAIT;
+       } else if (req->bRequestType & USB_DIR_IN) {
+               musb->ep0_state = MUSB_EP0_STAGE_TX;
+               musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDRXPKTRDY);
+               while ((musb_readw(regs, MUSB_CSR0)
+                               & MUSB_CSR0_RXPKTRDY) != 0)
+                       cpu_relax();
+               musb->ackpend = 0;
+       } else
+               musb->ep0_state = MUSB_EP0_STAGE_RX;
+}
+
+static int
+forward_to_driver(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest)
+__releases(musb->lock)
+__acquires(musb->lock)
+{
+       int retval;
+       if (!musb->gadget_driver)
+               return -EOPNOTSUPP;
+       spin_unlock(&musb->lock);
+       retval = musb->gadget_driver->setup(&musb->g, ctrlrequest);
+       spin_lock(&musb->lock);
+       return retval;
+}
+
+/*
+ * Handle peripheral ep0 interrupt
+ *
+ * Context: irq handler; we won't re-enter the driver that way.
+ */
+irqreturn_t musb_g_ep0_irq(struct musb *musb)
+{
+       u16             csr;
+       u16             len;
+       void __iomem    *mbase = musb->mregs;
+       void __iomem    *regs = musb->endpoints[0].regs;
+       irqreturn_t     retval = IRQ_NONE;
+
+       musb_ep_select(mbase, 0);       /* select ep0 */
+       csr = musb_readw(regs, MUSB_CSR0);
+       len = musb_readb(regs, MUSB_COUNT0);
+
+       dev_dbg(musb->controller, "csr %04x, count %d, myaddr %d, ep0stage %s\n",
+                       csr, len,
+                       musb_readb(mbase, MUSB_FADDR),
+                       decode_ep0stage(musb->ep0_state));
+
+       if (csr & MUSB_CSR0_P_DATAEND) {
+               /*
+                * If DATAEND is set we should not call the callback,
+                * hence the status stage is not complete.
+                */
+               return IRQ_HANDLED;
+       }
+
+       /* I sent a stall.. need to acknowledge it now.. */
+       if (csr & MUSB_CSR0_P_SENTSTALL) {
+               musb_writew(regs, MUSB_CSR0,
+                               csr & ~MUSB_CSR0_P_SENTSTALL);
+               retval = IRQ_HANDLED;
+               musb->ep0_state = MUSB_EP0_STAGE_IDLE;
+               csr = musb_readw(regs, MUSB_CSR0);
+       }
+
+       /* request ended "early" */
+       if (csr & MUSB_CSR0_P_SETUPEND) {
+               musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDSETUPEND);
+               retval = IRQ_HANDLED;
+               /* Transition into the early status phase */
+               switch (musb->ep0_state) {
+               case MUSB_EP0_STAGE_TX:
+                       musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT;
+                       break;
+               case MUSB_EP0_STAGE_RX:
+                       musb->ep0_state = MUSB_EP0_STAGE_STATUSIN;
+                       break;
+               default:
+                       ERR("SetupEnd came in a wrong ep0stage %s\n",
+                           decode_ep0stage(musb->ep0_state));
+               }
+               csr = musb_readw(regs, MUSB_CSR0);
+               /* NOTE:  request may need completion */
+       }
+
+       /* docs from Mentor only describe tx, rx, and idle/setup states.
+        * we need to handle nuances around status stages, and also the
+        * case where status and setup stages come back-to-back ...
+        */
+       switch (musb->ep0_state) {
+
+       case MUSB_EP0_STAGE_TX:
+               /* irq on clearing txpktrdy */
+               if ((csr & MUSB_CSR0_TXPKTRDY) == 0) {
+                       ep0_txstate(musb);
+                       retval = IRQ_HANDLED;
+               }
+               break;
+
+       case MUSB_EP0_STAGE_RX:
+               /* irq on set rxpktrdy */
+               if (csr & MUSB_CSR0_RXPKTRDY) {
+                       ep0_rxstate(musb);
+                       retval = IRQ_HANDLED;
+               }
+               break;
+
+       case MUSB_EP0_STAGE_STATUSIN:
+               /* end of sequence #2 (OUT/RX state) or #3 (no data) */
+
+               /* update address (if needed) only @ the end of the
+                * status phase per usb spec, which also guarantees
+                * we get 10 msec to receive this irq... until this
+                * is done we won't see the next packet.
+                */
+               if (musb->set_address) {
+                       musb->set_address = false;
+                       musb_writeb(mbase, MUSB_FADDR, musb->address);
+               }
+
+               /* enter test mode if needed (exit by reset) */
+               else if (musb->test_mode) {
+                       dev_dbg(musb->controller, "entering TESTMODE\n");
+
+                       if (MUSB_TEST_PACKET == musb->test_mode_nr)
+                               musb_load_testpacket(musb);
+
+                       musb_writeb(mbase, MUSB_TESTMODE,
+                                       musb->test_mode_nr);
+               }
+               /* FALLTHROUGH */
+
+       case MUSB_EP0_STAGE_STATUSOUT:
+               /* end of sequence #1: write to host (TX state) */
+               {
+                       struct musb_request     *req;
+
+                       req = next_ep0_request(musb);
+                       if (req)
+                               musb_g_ep0_giveback(musb, &req->request);
+               }
+
+               /*
+                * In case when several interrupts can get coalesced,
+                * check to see if we've already received a SETUP packet...
+                */
+               if (csr & MUSB_CSR0_RXPKTRDY)
+                       goto setup;
+
+               retval = IRQ_HANDLED;
+               musb->ep0_state = MUSB_EP0_STAGE_IDLE;
+               break;
+
+       case MUSB_EP0_STAGE_IDLE:
+               /*
+                * This state is typically (but not always) indiscernible
+                * from the status states since the corresponding interrupts
+                * tend to happen within too little period of time (with only
+                * a zero-length packet in between) and so get coalesced...
+                */
+               retval = IRQ_HANDLED;
+               musb->ep0_state = MUSB_EP0_STAGE_SETUP;
+               /* FALLTHROUGH */
+
+       case MUSB_EP0_STAGE_SETUP:
+setup:
+               if (csr & MUSB_CSR0_RXPKTRDY) {
+                       struct usb_ctrlrequest  setup;
+                       int                     handled = 0;
+
+                       if (len != 8) {
+                               ERR("SETUP packet len %d != 8 ?\n", len);
+                               break;
+                       }
+                       musb_read_setup(musb, &setup);
+                       retval = IRQ_HANDLED;
+
+                       /* sometimes the RESET won't be reported */
+                       if (unlikely(musb->g.speed == USB_SPEED_UNKNOWN)) {
+                               u8      power;
+
+                               printk(KERN_NOTICE "%s: peripheral reset "
+                                               "irq lost!\n",
+                                               musb_driver_name);
+                               power = musb_readb(mbase, MUSB_POWER);
+                               musb->g.speed = (power & MUSB_POWER_HSMODE)
+                                       ? USB_SPEED_HIGH : USB_SPEED_FULL;
+
+                       }
+
+                       switch (musb->ep0_state) {
+
+                       /* sequence #3 (no data stage), includes requests
+                        * we can't forward (notably SET_ADDRESS and the
+                        * device/endpoint feature set/clear operations)
+                        * plus SET_CONFIGURATION and others we must
+                        */
+                       case MUSB_EP0_STAGE_ACKWAIT:
+                               handled = service_zero_data_request(
+                                               musb, &setup);
+
+                               /*
+                                * We're expecting no data in any case, so
+                                * always set the DATAEND bit -- doing this
+                                * here helps avoid SetupEnd interrupt coming
+                                * in the idle stage when we're stalling...
+                                */
+                               musb->ackpend |= MUSB_CSR0_P_DATAEND;
+
+                               /* status stage might be immediate */
+                               if (handled > 0)
+                                       musb->ep0_state =
+                                               MUSB_EP0_STAGE_STATUSIN;
+                               break;
+
+                       /* sequence #1 (IN to host), includes GET_STATUS
+                        * requests that we can't forward, GET_DESCRIPTOR
+                        * and others that we must
+                        */
+                       case MUSB_EP0_STAGE_TX:
+                               handled = service_in_request(musb, &setup);
+                               if (handled > 0) {
+                                       musb->ackpend = MUSB_CSR0_TXPKTRDY
+                                               | MUSB_CSR0_P_DATAEND;
+                                       musb->ep0_state =
+                                               MUSB_EP0_STAGE_STATUSOUT;
+                               }
+                               break;
+
+                       /* sequence #2 (OUT from host), always forward */
+                       default:                /* MUSB_EP0_STAGE_RX */
+                               break;
+                       }
+
+                       dev_dbg(musb->controller, "handled %d, csr %04x, ep0stage %s\n",
+                               handled, csr,
+                               decode_ep0stage(musb->ep0_state));
+
+                       /* unless we need to delegate this to the gadget
+                        * driver, we know how to wrap this up:  csr0 has
+                        * not yet been written.
+                        */
+                       if (handled < 0)
+                               goto stall;
+                       else if (handled > 0)
+                               goto finish;
+
+                       handled = forward_to_driver(musb, &setup);
+                       if (handled < 0) {
+                               musb_ep_select(mbase, 0);
+stall:
+                               dev_dbg(musb->controller, "stall (%d)\n", handled);
+                               musb->ackpend |= MUSB_CSR0_P_SENDSTALL;
+                               musb->ep0_state = MUSB_EP0_STAGE_IDLE;
+finish:
+                               musb_writew(regs, MUSB_CSR0,
+                                               musb->ackpend);
+                               musb->ackpend = 0;
+                       }
+               }
+               break;
+
+       case MUSB_EP0_STAGE_ACKWAIT:
+               /* This should not happen. But happens with tusb6010 with
+                * g_file_storage and high speed. Do nothing.
+                */
+               retval = IRQ_HANDLED;
+               break;
+
+       default:
+               /* "can't happen" */
+               WARN_ON(1);
+               musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SENDSTALL);
+               musb->ep0_state = MUSB_EP0_STAGE_IDLE;
+               break;
+       }
+
+       return retval;
+}
+
+
+static int
+musb_g_ep0_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc)
+{
+       /* always enabled */
+       return -EINVAL;
+}
+
+static int musb_g_ep0_disable(struct usb_ep *e)
+{
+       /* always enabled */
+       return -EINVAL;
+}
+
+static int
+musb_g_ep0_queue(struct usb_ep *e, struct usb_request *r, gfp_t gfp_flags)
+{
+       struct musb_ep          *ep;
+       struct musb_request     *req;
+       struct musb             *musb;
+       int                     status;
+       unsigned long           lockflags;
+       void __iomem            *regs;
+
+       if (!e || !r)
+               return -EINVAL;
+
+       ep = to_musb_ep(e);
+       musb = ep->musb;
+       regs = musb->control_ep->regs;
+
+       req = to_musb_request(r);
+       req->musb = musb;
+       req->request.actual = 0;
+       req->request.status = -EINPROGRESS;
+       req->tx = ep->is_in;
+
+       spin_lock_irqsave(&musb->lock, lockflags);
+
+       if (!list_empty(&ep->req_list)) {
+               status = -EBUSY;
+               goto cleanup;
+       }
+
+       switch (musb->ep0_state) {
+       case MUSB_EP0_STAGE_RX:         /* control-OUT data */
+       case MUSB_EP0_STAGE_TX:         /* control-IN data */
+       case MUSB_EP0_STAGE_ACKWAIT:    /* zero-length data */
+               status = 0;
+               break;
+       default:
+               dev_dbg(musb->controller, "ep0 request queued in state %d\n",
+                               musb->ep0_state);
+               status = -EINVAL;
+               goto cleanup;
+       }
+
+       /* add request to the list */
+       list_add_tail(&req->list, &ep->req_list);
+
+       dev_dbg(musb->controller, "queue to %s (%s), length=%d\n",
+                       ep->name, ep->is_in ? "IN/TX" : "OUT/RX",
+                       req->request.length);
+
+       musb_ep_select(musb->mregs, 0);
+
+       /* sequence #1, IN ... start writing the data */
+       if (musb->ep0_state == MUSB_EP0_STAGE_TX)
+               ep0_txstate(musb);
+
+       /* sequence #3, no-data ... issue IN status */
+       else if (musb->ep0_state == MUSB_EP0_STAGE_ACKWAIT) {
+               if (req->request.length)
+                       status = -EINVAL;
+               else {
+                       musb->ep0_state = MUSB_EP0_STAGE_STATUSIN;
+                       musb_writew(regs, MUSB_CSR0,
+                                       musb->ackpend | MUSB_CSR0_P_DATAEND);
+                       musb->ackpend = 0;
+                       musb_g_ep0_giveback(ep->musb, r);
+               }
+
+       /* else for sequence #2 (OUT), caller provides a buffer
+        * before the next packet arrives.  deferred responses
+        * (after SETUP is acked) are racey.
+        */
+       } else if (musb->ackpend) {
+               musb_writew(regs, MUSB_CSR0, musb->ackpend);
+               musb->ackpend = 0;
+       }
+
+cleanup:
+       spin_unlock_irqrestore(&musb->lock, lockflags);
+       return status;
+}
+
+static int musb_g_ep0_dequeue(struct usb_ep *ep, struct usb_request *req)
+{
+       /* we just won't support this */
+       return -EINVAL;
+}
+
+static int musb_g_ep0_halt(struct usb_ep *e, int value)
+{
+       struct musb_ep          *ep;
+       struct musb             *musb;
+       void __iomem            *base, *regs;
+       unsigned long           flags;
+       int                     status;
+       u16                     csr;
+
+       if (!e || !value)
+               return -EINVAL;
+
+       ep = to_musb_ep(e);
+       musb = ep->musb;
+       base = musb->mregs;
+       regs = musb->control_ep->regs;
+       status = 0;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       if (!list_empty(&ep->req_list)) {
+               status = -EBUSY;
+               goto cleanup;
+       }
+
+       musb_ep_select(base, 0);
+       csr = musb->ackpend;
+
+       switch (musb->ep0_state) {
+
+       /* Stalls are usually issued after parsing SETUP packet, either
+        * directly in irq context from setup() or else later.
+        */
+       case MUSB_EP0_STAGE_TX:         /* control-IN data */
+       case MUSB_EP0_STAGE_ACKWAIT:    /* STALL for zero-length data */
+       case MUSB_EP0_STAGE_RX:         /* control-OUT data */
+               csr = musb_readw(regs, MUSB_CSR0);
+               /* FALLTHROUGH */
+
+       /* It's also OK to issue stalls during callbacks when a non-empty
+        * DATA stage buffer has been read (or even written).
+        */
+       case MUSB_EP0_STAGE_STATUSIN:   /* control-OUT status */
+       case MUSB_EP0_STAGE_STATUSOUT:  /* control-IN status */
+
+               csr |= MUSB_CSR0_P_SENDSTALL;
+               musb_writew(regs, MUSB_CSR0, csr);
+               musb->ep0_state = MUSB_EP0_STAGE_IDLE;
+               musb->ackpend = 0;
+               break;
+       default:
+               dev_dbg(musb->controller, "ep0 can't halt in state %d\n", musb->ep0_state);
+               status = -EINVAL;
+       }
+
+cleanup:
+       spin_unlock_irqrestore(&musb->lock, flags);
+       return status;
+}
+
+const struct usb_ep_ops musb_g_ep0_ops = {
+       .enable         = musb_g_ep0_enable,
+       .disable        = musb_g_ep0_disable,
+       .alloc_request  = musb_alloc_request,
+       .free_request   = musb_free_request,
+       .queue          = musb_g_ep0_queue,
+       .dequeue        = musb_g_ep0_dequeue,
+       .set_halt       = musb_g_ep0_halt,
+};
diff --git a/drivers/usb/musb-new/musb_host.c b/drivers/usb/musb-new/musb_host.c
new file mode 100644 (file)
index 0000000..9a2cf59
--- /dev/null
@@ -0,0 +1,2400 @@
+/*
+ * MUSB OTG driver host support
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.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.
+ *
+ * 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 St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#define __UBOOT__
+#ifndef __UBOOT__
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/dma-mapping.h>
+#else
+#include <common.h>
+#include <usb.h>
+#include "linux-compat.h"
+#include "usb-compat.h"
+#endif
+
+#include "musb_core.h"
+#include "musb_host.h"
+
+
+/* MUSB HOST status 22-mar-2006
+ *
+ * - There's still lots of partial code duplication for fault paths, so
+ *   they aren't handled as consistently as they need to be.
+ *
+ * - PIO mostly behaved when last tested.
+ *     + including ep0, with all usbtest cases 9, 10
+ *     + usbtest 14 (ep0out) doesn't seem to run at all
+ *     + double buffered OUT/TX endpoints saw stalls(!) with certain usbtest
+ *       configurations, but otherwise double buffering passes basic tests.
+ *     + for 2.6.N, for N > ~10, needs API changes for hcd framework.
+ *
+ * - DMA (CPPI) ... partially behaves, not currently recommended
+ *     + about 1/15 the speed of typical EHCI implementations (PCI)
+ *     + RX, all too often reqpkt seems to misbehave after tx
+ *     + TX, no known issues (other than evident silicon issue)
+ *
+ * - DMA (Mentor/OMAP) ...has at least toggle update problems
+ *
+ * - [23-feb-2009] minimal traffic scheduling to avoid bulk RX packet
+ *   starvation ... nothing yet for TX, interrupt, or bulk.
+ *
+ * - Not tested with HNP, but some SRP paths seem to behave.
+ *
+ * NOTE 24-August-2006:
+ *
+ * - Bulk traffic finally uses both sides of hardware ep1, freeing up an
+ *   extra endpoint for periodic use enabling hub + keybd + mouse.  That
+ *   mostly works, except that with "usbnet" it's easy to trigger cases
+ *   with "ping" where RX loses.  (a) ping to davinci, even "ping -f",
+ *   fine; but (b) ping _from_ davinci, even "ping -c 1", ICMP RX loses
+ *   although ARP RX wins.  (That test was done with a full speed link.)
+ */
+
+
+/*
+ * NOTE on endpoint usage:
+ *
+ * CONTROL transfers all go through ep0.  BULK ones go through dedicated IN
+ * and OUT endpoints ... hardware is dedicated for those "async" queue(s).
+ * (Yes, bulk _could_ use more of the endpoints than that, and would even
+ * benefit from it.)
+ *
+ * INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints.
+ * So far that scheduling is both dumb and optimistic:  the endpoint will be
+ * "claimed" until its software queue is no longer refilled.  No multiplexing
+ * of transfers between endpoints, or anything clever.
+ */
+
+
+static void musb_ep_program(struct musb *musb, u8 epnum,
+                       struct urb *urb, int is_out,
+                       u8 *buf, u32 offset, u32 len);
+
+/*
+ * Clear TX fifo. Needed to avoid BABBLE errors.
+ */
+static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
+{
+       struct musb     *musb = ep->musb;
+       void __iomem    *epio = ep->regs;
+       u16             csr;
+       u16             lastcsr = 0;
+       int             retries = 1000;
+
+       csr = musb_readw(epio, MUSB_TXCSR);
+       while (csr & MUSB_TXCSR_FIFONOTEMPTY) {
+               if (csr != lastcsr)
+                       dev_dbg(musb->controller, "Host TX FIFONOTEMPTY csr: %02x\n", csr);
+               lastcsr = csr;
+               csr |= MUSB_TXCSR_FLUSHFIFO;
+               musb_writew(epio, MUSB_TXCSR, csr);
+               csr = musb_readw(epio, MUSB_TXCSR);
+               if (WARN(retries-- < 1,
+                               "Could not flush host TX%d fifo: csr: %04x\n",
+                               ep->epnum, csr))
+                       return;
+               mdelay(1);
+       }
+}
+
+static void musb_h_ep0_flush_fifo(struct musb_hw_ep *ep)
+{
+       void __iomem    *epio = ep->regs;
+       u16             csr;
+       int             retries = 5;
+
+       /* scrub any data left in the fifo */
+       do {
+               csr = musb_readw(epio, MUSB_TXCSR);
+               if (!(csr & (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_RXPKTRDY)))
+                       break;
+               musb_writew(epio, MUSB_TXCSR, MUSB_CSR0_FLUSHFIFO);
+               csr = musb_readw(epio, MUSB_TXCSR);
+               udelay(10);
+       } while (--retries);
+
+       WARN(!retries, "Could not flush host TX%d fifo: csr: %04x\n",
+                       ep->epnum, csr);
+
+       /* and reset for the next transfer */
+       musb_writew(epio, MUSB_TXCSR, 0);
+}
+
+/*
+ * Start transmit. Caller is responsible for locking shared resources.
+ * musb must be locked.
+ */
+static inline void musb_h_tx_start(struct musb_hw_ep *ep)
+{
+       u16     txcsr;
+
+       /* NOTE: no locks here; caller should lock and select EP */
+       if (ep->epnum) {
+               txcsr = musb_readw(ep->regs, MUSB_TXCSR);
+               txcsr |= MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_H_WZC_BITS;
+               musb_writew(ep->regs, MUSB_TXCSR, txcsr);
+       } else {
+               txcsr = MUSB_CSR0_H_SETUPPKT | MUSB_CSR0_TXPKTRDY;
+               musb_writew(ep->regs, MUSB_CSR0, txcsr);
+       }
+
+}
+
+static inline void musb_h_tx_dma_start(struct musb_hw_ep *ep)
+{
+       u16     txcsr;
+
+       /* NOTE: no locks here; caller should lock and select EP */
+       txcsr = musb_readw(ep->regs, MUSB_TXCSR);
+       txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS;
+       if (is_cppi_enabled())
+               txcsr |= MUSB_TXCSR_DMAMODE;
+       musb_writew(ep->regs, MUSB_TXCSR, txcsr);
+}
+
+static void musb_ep_set_qh(struct musb_hw_ep *ep, int is_in, struct musb_qh *qh)
+{
+       if (is_in != 0 || ep->is_shared_fifo)
+               ep->in_qh  = qh;
+       if (is_in == 0 || ep->is_shared_fifo)
+               ep->out_qh = qh;
+}
+
+static struct musb_qh *musb_ep_get_qh(struct musb_hw_ep *ep, int is_in)
+{
+       return is_in ? ep->in_qh : ep->out_qh;
+}
+
+/*
+ * Start the URB at the front of an endpoint's queue
+ * end must be claimed from the caller.
+ *
+ * Context: controller locked, irqs blocked
+ */
+static void
+musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
+{
+       u16                     frame;
+       u32                     len;
+       void __iomem            *mbase =  musb->mregs;
+       struct urb              *urb = next_urb(qh);
+       void                    *buf = urb->transfer_buffer;
+       u32                     offset = 0;
+       struct musb_hw_ep       *hw_ep = qh->hw_ep;
+       unsigned                pipe = urb->pipe;
+       u8                      address = usb_pipedevice(pipe);
+       int                     epnum = hw_ep->epnum;
+
+       /* initialize software qh state */
+       qh->offset = 0;
+       qh->segsize = 0;
+
+       /* gather right source of data */
+       switch (qh->type) {
+       case USB_ENDPOINT_XFER_CONTROL:
+               /* control transfers always start with SETUP */
+               is_in = 0;
+               musb->ep0_stage = MUSB_EP0_START;
+               buf = urb->setup_packet;
+               len = 8;
+               break;
+#ifndef __UBOOT__
+       case USB_ENDPOINT_XFER_ISOC:
+               qh->iso_idx = 0;
+               qh->frame = 0;
+               offset = urb->iso_frame_desc[0].offset;
+               len = urb->iso_frame_desc[0].length;
+               break;
+#endif
+       default:                /* bulk, interrupt */
+               /* actual_length may be nonzero on retry paths */
+               buf = urb->transfer_buffer + urb->actual_length;
+               len = urb->transfer_buffer_length - urb->actual_length;
+       }
+
+       dev_dbg(musb->controller, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n",
+                       qh, urb, address, qh->epnum,
+                       is_in ? "in" : "out",
+                       ({char *s; switch (qh->type) {
+                       case USB_ENDPOINT_XFER_CONTROL: s = ""; break;
+                       case USB_ENDPOINT_XFER_BULK:    s = "-bulk"; break;
+#ifndef __UBOOT__
+                       case USB_ENDPOINT_XFER_ISOC:    s = "-iso"; break;
+#endif
+                       default:                        s = "-intr"; break;
+                       }; s; }),
+                       epnum, buf + offset, len);
+
+       /* Configure endpoint */
+       musb_ep_set_qh(hw_ep, is_in, qh);
+       musb_ep_program(musb, epnum, urb, !is_in, buf, offset, len);
+
+       /* transmit may have more work: start it when it is time */
+       if (is_in)
+               return;
+
+       /* determine if the time is right for a periodic transfer */
+       switch (qh->type) {
+#ifndef __UBOOT__
+       case USB_ENDPOINT_XFER_ISOC:
+#endif
+       case USB_ENDPOINT_XFER_INT:
+               dev_dbg(musb->controller, "check whether there's still time for periodic Tx\n");
+               frame = musb_readw(mbase, MUSB_FRAME);
+               /* FIXME this doesn't implement that scheduling policy ...
+                * or handle framecounter wrapping
+                */
+#ifndef __UBOOT__
+               if ((urb->transfer_flags & URB_ISO_ASAP)
+                               || (frame >= urb->start_frame)) {
+                       /* REVISIT the SOF irq handler shouldn't duplicate
+                        * this code; and we don't init urb->start_frame...
+                        */
+                       qh->frame = 0;
+                       goto start;
+               } else {
+#endif
+                       qh->frame = urb->start_frame;
+                       /* enable SOF interrupt so we can count down */
+                       dev_dbg(musb->controller, "SOF for %d\n", epnum);
+#if 1 /* ifndef        CONFIG_ARCH_DAVINCI */
+                       musb_writeb(mbase, MUSB_INTRUSBE, 0xff);
+#endif
+#ifndef __UBOOT__
+               }
+#endif
+               break;
+       default:
+start:
+               dev_dbg(musb->controller, "Start TX%d %s\n", epnum,
+                       hw_ep->tx_channel ? "dma" : "pio");
+
+               if (!hw_ep->tx_channel)
+                       musb_h_tx_start(hw_ep);
+               else if (is_cppi_enabled() || tusb_dma_omap())
+                       musb_h_tx_dma_start(hw_ep);
+       }
+}
+
+/* Context: caller owns controller lock, IRQs are blocked */
+static void musb_giveback(struct musb *musb, struct urb *urb, int status)
+__releases(musb->lock)
+__acquires(musb->lock)
+{
+       dev_dbg(musb->controller,
+                       "complete %p %pF (%d), dev%d ep%d%s, %d/%d\n",
+                       urb, urb->complete, status,
+                       usb_pipedevice(urb->pipe),
+                       usb_pipeendpoint(urb->pipe),
+                       usb_pipein(urb->pipe) ? "in" : "out",
+                       urb->actual_length, urb->transfer_buffer_length
+                       );
+
+       usb_hcd_unlink_urb_from_ep(musb_to_hcd(musb), urb);
+       spin_unlock(&musb->lock);
+       usb_hcd_giveback_urb(musb_to_hcd(musb), urb, status);
+       spin_lock(&musb->lock);
+}
+
+/* For bulk/interrupt endpoints only */
+static inline void musb_save_toggle(struct musb_qh *qh, int is_in,
+                                   struct urb *urb)
+{
+       void __iomem            *epio = qh->hw_ep->regs;
+       u16                     csr;
+
+       /*
+        * FIXME: the current Mentor DMA code seems to have
+        * problems getting toggle correct.
+        */
+
+       if (is_in)
+               csr = musb_readw(epio, MUSB_RXCSR) & MUSB_RXCSR_H_DATATOGGLE;
+       else
+               csr = musb_readw(epio, MUSB_TXCSR) & MUSB_TXCSR_H_DATATOGGLE;
+
+       usb_settoggle(urb->dev, qh->epnum, !is_in, csr ? 1 : 0);
+}
+
+/*
+ * Advance this hardware endpoint's queue, completing the specified URB and
+ * advancing to either the next URB queued to that qh, or else invalidating
+ * that qh and advancing to the next qh scheduled after the current one.
+ *
+ * Context: caller owns controller lock, IRQs are blocked
+ */
+static void musb_advance_schedule(struct musb *musb, struct urb *urb,
+                                 struct musb_hw_ep *hw_ep, int is_in)
+{
+       struct musb_qh          *qh = musb_ep_get_qh(hw_ep, is_in);
+       struct musb_hw_ep       *ep = qh->hw_ep;
+       int                     ready = qh->is_ready;
+       int                     status;
+
+       status = (urb->status == -EINPROGRESS) ? 0 : urb->status;
+
+       /* save toggle eagerly, for paranoia */
+       switch (qh->type) {
+       case USB_ENDPOINT_XFER_BULK:
+       case USB_ENDPOINT_XFER_INT:
+               musb_save_toggle(qh, is_in, urb);
+               break;
+#ifndef __UBOOT__
+       case USB_ENDPOINT_XFER_ISOC:
+               if (status == 0 && urb->error_count)
+                       status = -EXDEV;
+               break;
+#endif
+       }
+
+       qh->is_ready = 0;
+       musb_giveback(musb, urb, status);
+       qh->is_ready = ready;
+
+       /* reclaim resources (and bandwidth) ASAP; deschedule it, and
+        * invalidate qh as soon as list_empty(&hep->urb_list)
+        */
+       if (list_empty(&qh->hep->urb_list)) {
+               struct list_head        *head;
+               struct dma_controller   *dma = musb->dma_controller;
+
+               if (is_in) {
+                       ep->rx_reinit = 1;
+                       if (ep->rx_channel) {
+                               dma->channel_release(ep->rx_channel);
+                               ep->rx_channel = NULL;
+                       }
+               } else {
+                       ep->tx_reinit = 1;
+                       if (ep->tx_channel) {
+                               dma->channel_release(ep->tx_channel);
+                               ep->tx_channel = NULL;
+                       }
+               }
+
+               /* Clobber old pointers to this qh */
+               musb_ep_set_qh(ep, is_in, NULL);
+               qh->hep->hcpriv = NULL;
+
+               switch (qh->type) {
+
+               case USB_ENDPOINT_XFER_CONTROL:
+               case USB_ENDPOINT_XFER_BULK:
+                       /* fifo policy for these lists, except that NAKing
+                        * should rotate a qh to the end (for fairness).
+                        */
+                       if (qh->mux == 1) {
+                               head = qh->ring.prev;
+                               list_del(&qh->ring);
+                               kfree(qh);
+                               qh = first_qh(head);
+                               break;
+                       }
+
+               case USB_ENDPOINT_XFER_ISOC:
+               case USB_ENDPOINT_XFER_INT:
+                       /* this is where periodic bandwidth should be
+                        * de-allocated if it's tracked and allocated;
+                        * and where we'd update the schedule tree...
+                        */
+                       kfree(qh);
+                       qh = NULL;
+                       break;
+               }
+       }
+
+       if (qh != NULL && qh->is_ready) {
+               dev_dbg(musb->controller, "... next ep%d %cX urb %p\n",
+                   hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh));
+               musb_start_urb(musb, is_in, qh);
+       }
+}
+
+static u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr)
+{
+       /* we don't want fifo to fill itself again;
+        * ignore dma (various models),
+        * leave toggle alone (may not have been saved yet)
+        */
+       csr |= MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_RXPKTRDY;
+       csr &= ~(MUSB_RXCSR_H_REQPKT
+               | MUSB_RXCSR_H_AUTOREQ
+               | MUSB_RXCSR_AUTOCLEAR);
+
+       /* write 2x to allow double buffering */
+       musb_writew(hw_ep->regs, MUSB_RXCSR, csr);
+       musb_writew(hw_ep->regs, MUSB_RXCSR, csr);
+
+       /* flush writebuffer */
+       return musb_readw(hw_ep->regs, MUSB_RXCSR);
+}
+
+/*
+ * PIO RX for a packet (or part of it).
+ */
+static bool
+musb_host_packet_rx(struct musb *musb, struct urb *urb, u8 epnum, u8 iso_err)
+{
+       u16                     rx_count;
+       u8                      *buf;
+       u16                     csr;
+       bool                    done = false;
+       u32                     length;
+       int                     do_flush = 0;
+       struct musb_hw_ep       *hw_ep = musb->endpoints + epnum;
+       void __iomem            *epio = hw_ep->regs;
+       struct musb_qh          *qh = hw_ep->in_qh;
+       int                     pipe = urb->pipe;
+       void                    *buffer = urb->transfer_buffer;
+
+       /* musb_ep_select(mbase, epnum); */
+       rx_count = musb_readw(epio, MUSB_RXCOUNT);
+       dev_dbg(musb->controller, "RX%d count %d, buffer %p len %d/%d\n", epnum, rx_count,
+                       urb->transfer_buffer, qh->offset,
+                       urb->transfer_buffer_length);
+
+       /* unload FIFO */
+#ifndef __UBOOT__
+       if (usb_pipeisoc(pipe)) {
+               int                                     status = 0;
+               struct usb_iso_packet_descriptor        *d;
+
+               if (iso_err) {
+                       status = -EILSEQ;
+                       urb->error_count++;
+               }
+
+               d = urb->iso_frame_desc + qh->iso_idx;
+               buf = buffer + d->offset;
+               length = d->length;
+               if (rx_count > length) {
+                       if (status == 0) {
+                               status = -EOVERFLOW;
+                               urb->error_count++;
+                       }
+                       dev_dbg(musb->controller, "** OVERFLOW %d into %d\n", rx_count, length);
+                       do_flush = 1;
+               } else
+                       length = rx_count;
+               urb->actual_length += length;
+               d->actual_length = length;
+
+               d->status = status;
+
+               /* see if we are done */
+               done = (++qh->iso_idx >= urb->number_of_packets);
+       } else {
+#endif
+               /* non-isoch */
+               buf = buffer + qh->offset;
+               length = urb->transfer_buffer_length - qh->offset;
+               if (rx_count > length) {
+                       if (urb->status == -EINPROGRESS)
+                               urb->status = -EOVERFLOW;
+                       dev_dbg(musb->controller, "** OVERFLOW %d into %d\n", rx_count, length);
+                       do_flush = 1;
+               } else
+                       length = rx_count;
+               urb->actual_length += length;
+               qh->offset += length;
+
+               /* see if we are done */
+               done = (urb->actual_length == urb->transfer_buffer_length)
+                       || (rx_count < qh->maxpacket)
+                       || (urb->status != -EINPROGRESS);
+               if (done
+                               && (urb->status == -EINPROGRESS)
+                               && (urb->transfer_flags & URB_SHORT_NOT_OK)
+                               && (urb->actual_length
+                                       < urb->transfer_buffer_length))
+                       urb->status = -EREMOTEIO;
+#ifndef __UBOOT__
+       }
+#endif
+
+       musb_read_fifo(hw_ep, length, buf);
+
+       csr = musb_readw(epio, MUSB_RXCSR);
+       csr |= MUSB_RXCSR_H_WZC_BITS;
+       if (unlikely(do_flush))
+               musb_h_flush_rxfifo(hw_ep, csr);
+       else {
+               /* REVISIT this assumes AUTOCLEAR is never set */
+               csr &= ~(MUSB_RXCSR_RXPKTRDY | MUSB_RXCSR_H_REQPKT);
+               if (!done)
+                       csr |= MUSB_RXCSR_H_REQPKT;
+               musb_writew(epio, MUSB_RXCSR, csr);
+       }
+
+       return done;
+}
+
+/* we don't always need to reinit a given side of an endpoint...
+ * when we do, use tx/rx reinit routine and then construct a new CSR
+ * to address data toggle, NYET, and DMA or PIO.
+ *
+ * it's possible that driver bugs (especially for DMA) or aborting a
+ * transfer might have left the endpoint busier than it should be.
+ * the busy/not-empty tests are basically paranoia.
+ */
+static void
+musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
+{
+       u16     csr;
+
+       /* NOTE:  we know the "rx" fifo reinit never triggers for ep0.
+        * That always uses tx_reinit since ep0 repurposes TX register
+        * offsets; the initial SETUP packet is also a kind of OUT.
+        */
+
+       /* if programmed for Tx, put it in RX mode */
+       if (ep->is_shared_fifo) {
+               csr = musb_readw(ep->regs, MUSB_TXCSR);
+               if (csr & MUSB_TXCSR_MODE) {
+                       musb_h_tx_flush_fifo(ep);
+                       csr = musb_readw(ep->regs, MUSB_TXCSR);
+                       musb_writew(ep->regs, MUSB_TXCSR,
+                                   csr | MUSB_TXCSR_FRCDATATOG);
+               }
+
+               /*
+                * Clear the MODE bit (and everything else) to enable Rx.
+                * NOTE: we mustn't clear the DMAMODE bit before DMAENAB.
+                */
+               if (csr & MUSB_TXCSR_DMAMODE)
+                       musb_writew(ep->regs, MUSB_TXCSR, MUSB_TXCSR_DMAMODE);
+               musb_writew(ep->regs, MUSB_TXCSR, 0);
+
+       /* scrub all previous state, clearing toggle */
+       } else {
+               csr = musb_readw(ep->regs, MUSB_RXCSR);
+               if (csr & MUSB_RXCSR_RXPKTRDY)
+                       WARNING("rx%d, packet/%d ready?\n", ep->epnum,
+                               musb_readw(ep->regs, MUSB_RXCOUNT));
+
+               musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
+       }
+
+       /* target addr and (for multipoint) hub addr/port */
+       if (musb->is_multipoint) {
+               musb_write_rxfunaddr(ep->target_regs, qh->addr_reg);
+               musb_write_rxhubaddr(ep->target_regs, qh->h_addr_reg);
+               musb_write_rxhubport(ep->target_regs, qh->h_port_reg);
+
+       } else
+               musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg);
+
+       /* protocol/endpoint, interval/NAKlimit, i/o size */
+       musb_writeb(ep->regs, MUSB_RXTYPE, qh->type_reg);
+       musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg);
+       /* NOTE: bulk combining rewrites high bits of maxpacket */
+       /* Set RXMAXP with the FIFO size of the endpoint
+        * to disable double buffer mode.
+        */
+       if (musb->double_buffer_not_ok)
+               musb_writew(ep->regs, MUSB_RXMAXP, ep->max_packet_sz_rx);
+       else
+               musb_writew(ep->regs, MUSB_RXMAXP,
+                               qh->maxpacket | ((qh->hb_mult - 1) << 11));
+
+       ep->rx_reinit = 0;
+}
+
+static bool musb_tx_dma_program(struct dma_controller *dma,
+               struct musb_hw_ep *hw_ep, struct musb_qh *qh,
+               struct urb *urb, u32 offset, u32 length)
+{
+       struct dma_channel      *channel = hw_ep->tx_channel;
+       void __iomem            *epio = hw_ep->regs;
+       u16                     pkt_size = qh->maxpacket;
+       u16                     csr;
+       u8                      mode;
+
+#ifdef CONFIG_USB_INVENTRA_DMA
+       if (length > channel->max_len)
+               length = channel->max_len;
+
+       csr = musb_readw(epio, MUSB_TXCSR);
+       if (length > pkt_size) {
+               mode = 1;
+               csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB;
+               /* autoset shouldn't be set in high bandwidth */
+               if (qh->hb_mult == 1)
+                       csr |= MUSB_TXCSR_AUTOSET;
+       } else {
+               mode = 0;
+               csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE);
+               csr |= MUSB_TXCSR_DMAENAB; /* against programmer's guide */
+       }
+       channel->desired_mode = mode;
+       musb_writew(epio, MUSB_TXCSR, csr);
+#else
+       if (!is_cppi_enabled() && !tusb_dma_omap())
+               return false;
+
+       channel->actual_len = 0;
+
+       /*
+        * TX uses "RNDIS" mode automatically but needs help
+        * to identify the zero-length-final-packet case.
+        */
+       mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0;
+#endif
+
+       qh->segsize = length;
+
+       /*
+        * Ensure the data reaches to main memory before starting
+        * DMA transfer
+        */
+       wmb();
+
+       if (!dma->channel_program(channel, pkt_size, mode,
+                       urb->transfer_dma + offset, length)) {
+               dma->channel_release(channel);
+               hw_ep->tx_channel = NULL;
+
+               csr = musb_readw(epio, MUSB_TXCSR);
+               csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
+               musb_writew(epio, MUSB_TXCSR, csr | MUSB_TXCSR_H_WZC_BITS);
+               return false;
+       }
+       return true;
+}
+
+/*
+ * Program an HDRC endpoint as per the given URB
+ * Context: irqs blocked, controller lock held
+ */
+static void musb_ep_program(struct musb *musb, u8 epnum,
+                       struct urb *urb, int is_out,
+                       u8 *buf, u32 offset, u32 len)
+{
+       struct dma_controller   *dma_controller;
+       struct dma_channel      *dma_channel;
+       u8                      dma_ok;
+       void __iomem            *mbase = musb->mregs;
+       struct musb_hw_ep       *hw_ep = musb->endpoints + epnum;
+       void __iomem            *epio = hw_ep->regs;
+       struct musb_qh          *qh = musb_ep_get_qh(hw_ep, !is_out);
+       u16                     packet_sz = qh->maxpacket;
+
+       dev_dbg(musb->controller, "%s hw%d urb %p spd%d dev%d ep%d%s "
+                               "h_addr%02x h_port%02x bytes %d\n",
+                       is_out ? "-->" : "<--",
+                       epnum, urb, urb->dev->speed,
+                       qh->addr_reg, qh->epnum, is_out ? "out" : "in",
+                       qh->h_addr_reg, qh->h_port_reg,
+                       len);
+
+       musb_ep_select(mbase, epnum);
+
+       /* candidate for DMA? */
+       dma_controller = musb->dma_controller;
+       if (is_dma_capable() && epnum && dma_controller) {
+               dma_channel = is_out ? hw_ep->tx_channel : hw_ep->rx_channel;
+               if (!dma_channel) {
+                       dma_channel = dma_controller->channel_alloc(
+                                       dma_controller, hw_ep, is_out);
+                       if (is_out)
+                               hw_ep->tx_channel = dma_channel;
+                       else
+                               hw_ep->rx_channel = dma_channel;
+               }
+       } else
+               dma_channel = NULL;
+
+       /* make sure we clear DMAEnab, autoSet bits from previous run */
+
+       /* OUT/transmit/EP0 or IN/receive? */
+       if (is_out) {
+               u16     csr;
+               u16     int_txe;
+               u16     load_count;
+
+               csr = musb_readw(epio, MUSB_TXCSR);
+
+               /* disable interrupt in case we flush */
+               int_txe = musb_readw(mbase, MUSB_INTRTXE);
+               musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum));
+
+               /* general endpoint setup */
+               if (epnum) {
+                       /* flush all old state, set default */
+                       musb_h_tx_flush_fifo(hw_ep);
+
+                       /*
+                        * We must not clear the DMAMODE bit before or in
+                        * the same cycle with the DMAENAB bit, so we clear
+                        * the latter first...
+                        */
+                       csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT
+                                       | MUSB_TXCSR_AUTOSET
+                                       | MUSB_TXCSR_DMAENAB
+                                       | MUSB_TXCSR_FRCDATATOG
+                                       | MUSB_TXCSR_H_RXSTALL
+                                       | MUSB_TXCSR_H_ERROR
+                                       | MUSB_TXCSR_TXPKTRDY
+                                       );
+                       csr |= MUSB_TXCSR_MODE;
+
+                       if (usb_gettoggle(urb->dev, qh->epnum, 1))
+                               csr |= MUSB_TXCSR_H_WR_DATATOGGLE
+                                       | MUSB_TXCSR_H_DATATOGGLE;
+                       else
+                               csr |= MUSB_TXCSR_CLRDATATOG;
+
+                       musb_writew(epio, MUSB_TXCSR, csr);
+                       /* REVISIT may need to clear FLUSHFIFO ... */
+                       csr &= ~MUSB_TXCSR_DMAMODE;
+                       musb_writew(epio, MUSB_TXCSR, csr);
+                       csr = musb_readw(epio, MUSB_TXCSR);
+               } else {
+                       /* endpoint 0: just flush */
+                       musb_h_ep0_flush_fifo(hw_ep);
+               }
+
+               /* target addr and (for multipoint) hub addr/port */
+               if (musb->is_multipoint) {
+                       musb_write_txfunaddr(mbase, epnum, qh->addr_reg);
+                       musb_write_txhubaddr(mbase, epnum, qh->h_addr_reg);
+                       musb_write_txhubport(mbase, epnum, qh->h_port_reg);
+/* FIXME if !epnum, do the same for RX ... */
+               } else
+                       musb_writeb(mbase, MUSB_FADDR, qh->addr_reg);
+
+               /* protocol/endpoint/interval/NAKlimit */
+               if (epnum) {
+                       musb_writeb(epio, MUSB_TXTYPE, qh->type_reg);
+                       if (musb->double_buffer_not_ok)
+                               musb_writew(epio, MUSB_TXMAXP,
+                                               hw_ep->max_packet_sz_tx);
+                       else if (can_bulk_split(musb, qh->type))
+                               musb_writew(epio, MUSB_TXMAXP, packet_sz
+                                       | ((hw_ep->max_packet_sz_tx /
+                                               packet_sz) - 1) << 11);
+                       else
+                               musb_writew(epio, MUSB_TXMAXP,
+                                               qh->maxpacket |
+                                               ((qh->hb_mult - 1) << 11));
+                       musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg);
+               } else {
+                       musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg);
+                       if (musb->is_multipoint)
+                               musb_writeb(epio, MUSB_TYPE0,
+                                               qh->type_reg);
+               }
+
+               if (can_bulk_split(musb, qh->type))
+                       load_count = min((u32) hw_ep->max_packet_sz_tx,
+                                               len);
+               else
+                       load_count = min((u32) packet_sz, len);
+
+               if (dma_channel && musb_tx_dma_program(dma_controller,
+                                       hw_ep, qh, urb, offset, len))
+                       load_count = 0;
+
+               if (load_count) {
+                       /* PIO to load FIFO */
+                       qh->segsize = load_count;
+                       musb_write_fifo(hw_ep, load_count, buf);
+               }
+
+               /* re-enable interrupt */
+               musb_writew(mbase, MUSB_INTRTXE, int_txe);
+
+       /* IN/receive */
+       } else {
+               u16     csr;
+
+               if (hw_ep->rx_reinit) {
+                       musb_rx_reinit(musb, qh, hw_ep);
+
+                       /* init new state: toggle and NYET, maybe DMA later */
+                       if (usb_gettoggle(urb->dev, qh->epnum, 0))
+                               csr = MUSB_RXCSR_H_WR_DATATOGGLE
+                                       | MUSB_RXCSR_H_DATATOGGLE;
+                       else
+                               csr = 0;
+                       if (qh->type == USB_ENDPOINT_XFER_INT)
+                               csr |= MUSB_RXCSR_DISNYET;
+
+               } else {
+                       csr = musb_readw(hw_ep->regs, MUSB_RXCSR);
+
+                       if (csr & (MUSB_RXCSR_RXPKTRDY
+                                       | MUSB_RXCSR_DMAENAB
+                                       | MUSB_RXCSR_H_REQPKT))
+                               ERR("broken !rx_reinit, ep%d csr %04x\n",
+                                               hw_ep->epnum, csr);
+
+                       /* scrub any stale state, leaving toggle alone */
+                       csr &= MUSB_RXCSR_DISNYET;
+               }
+
+               /* kick things off */
+
+               if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) {
+                       /* Candidate for DMA */
+                       dma_channel->actual_len = 0L;
+                       qh->segsize = len;
+
+                       /* AUTOREQ is in a DMA register */
+                       musb_writew(hw_ep->regs, MUSB_RXCSR, csr);
+                       csr = musb_readw(hw_ep->regs, MUSB_RXCSR);
+
+                       /*
+                        * Unless caller treats short RX transfers as
+                        * errors, we dare not queue multiple transfers.
+                        */
+                       dma_ok = dma_controller->channel_program(dma_channel,
+                                       packet_sz, !(urb->transfer_flags &
+                                                    URB_SHORT_NOT_OK),
+                                       urb->transfer_dma + offset,
+                                       qh->segsize);
+                       if (!dma_ok) {
+                               dma_controller->channel_release(dma_channel);
+                               hw_ep->rx_channel = dma_channel = NULL;
+                       } else
+                               csr |= MUSB_RXCSR_DMAENAB;
+               }
+
+               csr |= MUSB_RXCSR_H_REQPKT;
+               dev_dbg(musb->controller, "RXCSR%d := %04x\n", epnum, csr);
+               musb_writew(hw_ep->regs, MUSB_RXCSR, csr);
+               csr = musb_readw(hw_ep->regs, MUSB_RXCSR);
+       }
+}
+
+
+/*
+ * Service the default endpoint (ep0) as host.
+ * Return true until it's time to start the status stage.
+ */
+static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
+{
+       bool                     more = false;
+       u8                      *fifo_dest = NULL;
+       u16                     fifo_count = 0;
+       struct musb_hw_ep       *hw_ep = musb->control_ep;
+       struct musb_qh          *qh = hw_ep->in_qh;
+       struct usb_ctrlrequest  *request;
+
+       switch (musb->ep0_stage) {
+       case MUSB_EP0_IN:
+               fifo_dest = urb->transfer_buffer + urb->actual_length;
+               fifo_count = min_t(size_t, len, urb->transfer_buffer_length -
+                                  urb->actual_length);
+               if (fifo_count < len)
+                       urb->status = -EOVERFLOW;
+
+               musb_read_fifo(hw_ep, fifo_count, fifo_dest);
+
+               urb->actual_length += fifo_count;
+               if (len < qh->maxpacket) {
+                       /* always terminate on short read; it's
+                        * rarely reported as an error.
+                        */
+               } else if (urb->actual_length <
+                               urb->transfer_buffer_length)
+                       more = true;
+               break;
+       case MUSB_EP0_START:
+               request = (struct usb_ctrlrequest *) urb->setup_packet;
+
+               if (!request->wLength) {
+                       dev_dbg(musb->controller, "start no-DATA\n");
+                       break;
+               } else if (request->bRequestType & USB_DIR_IN) {
+                       dev_dbg(musb->controller, "start IN-DATA\n");
+                       musb->ep0_stage = MUSB_EP0_IN;
+                       more = true;
+                       break;
+               } else {
+                       dev_dbg(musb->controller, "start OUT-DATA\n");
+                       musb->ep0_stage = MUSB_EP0_OUT;
+                       more = true;
+               }
+               /* FALLTHROUGH */
+       case MUSB_EP0_OUT:
+               fifo_count = min_t(size_t, qh->maxpacket,
+                                  urb->transfer_buffer_length -
+                                  urb->actual_length);
+               if (fifo_count) {
+                       fifo_dest = (u8 *) (urb->transfer_buffer
+                                       + urb->actual_length);
+                       dev_dbg(musb->controller, "Sending %d byte%s to ep0 fifo %p\n",
+                                       fifo_count,
+                                       (fifo_count == 1) ? "" : "s",
+                                       fifo_dest);
+                       musb_write_fifo(hw_ep, fifo_count, fifo_dest);
+
+                       urb->actual_length += fifo_count;
+                       more = true;
+               }
+               break;
+       default:
+               ERR("bogus ep0 stage %d\n", musb->ep0_stage);
+               break;
+       }
+
+       return more;
+}
+
+/*
+ * Handle default endpoint interrupt as host. Only called in IRQ time
+ * from musb_interrupt().
+ *
+ * called with controller irqlocked
+ */
+irqreturn_t musb_h_ep0_irq(struct musb *musb)
+{
+       struct urb              *urb;
+       u16                     csr, len;
+       int                     status = 0;
+       void __iomem            *mbase = musb->mregs;
+       struct musb_hw_ep       *hw_ep = musb->control_ep;
+       void __iomem            *epio = hw_ep->regs;
+       struct musb_qh          *qh = hw_ep->in_qh;
+       bool                    complete = false;
+       irqreturn_t             retval = IRQ_NONE;
+
+       /* ep0 only has one queue, "in" */
+       urb = next_urb(qh);
+
+       musb_ep_select(mbase, 0);
+       csr = musb_readw(epio, MUSB_CSR0);
+       len = (csr & MUSB_CSR0_RXPKTRDY)
+                       ? musb_readb(epio, MUSB_COUNT0)
+                       : 0;
+
+       dev_dbg(musb->controller, "<== csr0 %04x, qh %p, count %d, urb %p, stage %d\n",
+               csr, qh, len, urb, musb->ep0_stage);
+
+       /* if we just did status stage, we are done */
+       if (MUSB_EP0_STATUS == musb->ep0_stage) {
+               retval = IRQ_HANDLED;
+               complete = true;
+       }
+
+       /* prepare status */
+       if (csr & MUSB_CSR0_H_RXSTALL) {
+               dev_dbg(musb->controller, "STALLING ENDPOINT\n");
+               status = -EPIPE;
+
+       } else if (csr & MUSB_CSR0_H_ERROR) {
+               dev_dbg(musb->controller, "no response, csr0 %04x\n", csr);
+               status = -EPROTO;
+
+       } else if (csr & MUSB_CSR0_H_NAKTIMEOUT) {
+               dev_dbg(musb->controller, "control NAK timeout\n");
+
+               /* NOTE:  this code path would be a good place to PAUSE a
+                * control transfer, if another one is queued, so that
+                * ep0 is more likely to stay busy.  That's already done
+                * for bulk RX transfers.
+                *
+                * if (qh->ring.next != &musb->control), then
+                * we have a candidate... NAKing is *NOT* an error
+                */
+               musb_writew(epio, MUSB_CSR0, 0);
+               retval = IRQ_HANDLED;
+       }
+
+       if (status) {
+               dev_dbg(musb->controller, "aborting\n");
+               retval = IRQ_HANDLED;
+               if (urb)
+                       urb->status = status;
+               complete = true;
+
+               /* use the proper sequence to abort the transfer */
+               if (csr & MUSB_CSR0_H_REQPKT) {
+                       csr &= ~MUSB_CSR0_H_REQPKT;
+                       musb_writew(epio, MUSB_CSR0, csr);
+                       csr &= ~MUSB_CSR0_H_NAKTIMEOUT;
+                       musb_writew(epio, MUSB_CSR0, csr);
+               } else {
+                       musb_h_ep0_flush_fifo(hw_ep);
+               }
+
+               musb_writeb(epio, MUSB_NAKLIMIT0, 0);
+
+               /* clear it */
+               musb_writew(epio, MUSB_CSR0, 0);
+       }
+
+       if (unlikely(!urb)) {
+               /* stop endpoint since we have no place for its data, this
+                * SHOULD NEVER HAPPEN! */
+               ERR("no URB for end 0\n");
+
+               musb_h_ep0_flush_fifo(hw_ep);
+               goto done;
+       }
+
+       if (!complete) {
+               /* call common logic and prepare response */
+               if (musb_h_ep0_continue(musb, len, urb)) {
+                       /* more packets required */
+                       csr = (MUSB_EP0_IN == musb->ep0_stage)
+                               ?  MUSB_CSR0_H_REQPKT : MUSB_CSR0_TXPKTRDY;
+               } else {
+                       /* data transfer complete; perform status phase */
+                       if (usb_pipeout(urb->pipe)
+                                       || !urb->transfer_buffer_length)
+                               csr = MUSB_CSR0_H_STATUSPKT
+                                       | MUSB_CSR0_H_REQPKT;
+                       else
+                               csr = MUSB_CSR0_H_STATUSPKT
+                                       | MUSB_CSR0_TXPKTRDY;
+
+                       /* flag status stage */
+                       musb->ep0_stage = MUSB_EP0_STATUS;
+
+                       dev_dbg(musb->controller, "ep0 STATUS, csr %04x\n", csr);
+
+               }
+               musb_writew(epio, MUSB_CSR0, csr);
+               retval = IRQ_HANDLED;
+       } else
+               musb->ep0_stage = MUSB_EP0_IDLE;
+
+       /* call completion handler if done */
+       if (complete)
+               musb_advance_schedule(musb, urb, hw_ep, 1);
+done:
+       return retval;
+}
+
+
+#ifdef CONFIG_USB_INVENTRA_DMA
+
+/* Host side TX (OUT) using Mentor DMA works as follows:
+       submit_urb ->
+               - if queue was empty, Program Endpoint
+               - ... which starts DMA to fifo in mode 1 or 0
+
+       DMA Isr (transfer complete) -> TxAvail()
+               - Stop DMA (~DmaEnab)   (<--- Alert ... currently happens
+                                       only in musb_cleanup_urb)
+               - TxPktRdy has to be set in mode 0 or for
+                       short packets in mode 1.
+*/
+
+#endif
+
+/* Service a Tx-Available or dma completion irq for the endpoint */
+void musb_host_tx(struct musb *musb, u8 epnum)
+{
+       int                     pipe;
+       bool                    done = false;
+       u16                     tx_csr;
+       size_t                  length = 0;
+       size_t                  offset = 0;
+       struct musb_hw_ep       *hw_ep = musb->endpoints + epnum;
+       void __iomem            *epio = hw_ep->regs;
+       struct musb_qh          *qh = hw_ep->out_qh;
+       struct urb              *urb = next_urb(qh);
+       u32                     status = 0;
+       void __iomem            *mbase = musb->mregs;
+       struct dma_channel      *dma;
+       bool                    transfer_pending = false;
+
+       musb_ep_select(mbase, epnum);
+       tx_csr = musb_readw(epio, MUSB_TXCSR);
+
+       /* with CPPI, DMA sometimes triggers "extra" irqs */
+       if (!urb) {
+               dev_dbg(musb->controller, "extra TX%d ready, csr %04x\n", epnum, tx_csr);
+               return;
+       }
+
+       pipe = urb->pipe;
+       dma = is_dma_capable() ? hw_ep->tx_channel : NULL;
+       dev_dbg(musb->controller, "OUT/TX%d end, csr %04x%s\n", epnum, tx_csr,
+                       dma ? ", dma" : "");
+
+       /* check for errors */
+       if (tx_csr & MUSB_TXCSR_H_RXSTALL) {
+               /* dma was disabled, fifo flushed */
+               dev_dbg(musb->controller, "TX end %d stall\n", epnum);
+
+               /* stall; record URB status */
+               status = -EPIPE;
+
+       } else if (tx_csr & MUSB_TXCSR_H_ERROR) {
+               /* (NON-ISO) dma was disabled, fifo flushed */
+               dev_dbg(musb->controller, "TX 3strikes on ep=%d\n", epnum);
+
+               status = -ETIMEDOUT;
+
+       } else if (tx_csr & MUSB_TXCSR_H_NAKTIMEOUT) {
+               dev_dbg(musb->controller, "TX end=%d device not responding\n", epnum);
+
+               /* NOTE:  this code path would be a good place to PAUSE a
+                * transfer, if there's some other (nonperiodic) tx urb
+                * that could use this fifo.  (dma complicates it...)
+                * That's already done for bulk RX transfers.
+                *
+                * if (bulk && qh->ring.next != &musb->out_bulk), then
+                * we have a candidate... NAKing is *NOT* an error
+                */
+               musb_ep_select(mbase, epnum);
+               musb_writew(epio, MUSB_TXCSR,
+                               MUSB_TXCSR_H_WZC_BITS
+                               | MUSB_TXCSR_TXPKTRDY);
+               return;
+       }
+
+       if (status) {
+               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
+                       (void) musb->dma_controller->channel_abort(dma);
+               }
+
+               /* do the proper sequence to abort the transfer in the
+                * usb core; the dma engine should already be stopped.
+                */
+               musb_h_tx_flush_fifo(hw_ep);
+               tx_csr &= ~(MUSB_TXCSR_AUTOSET
+                               | MUSB_TXCSR_DMAENAB
+                               | MUSB_TXCSR_H_ERROR
+                               | MUSB_TXCSR_H_RXSTALL
+                               | MUSB_TXCSR_H_NAKTIMEOUT
+                               );
+
+               musb_ep_select(mbase, epnum);
+               musb_writew(epio, MUSB_TXCSR, tx_csr);
+               /* REVISIT may need to clear FLUSHFIFO ... */
+               musb_writew(epio, MUSB_TXCSR, tx_csr);
+               musb_writeb(epio, MUSB_TXINTERVAL, 0);
+
+               done = true;
+       }
+
+       /* second cppi case */
+       if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+               dev_dbg(musb->controller, "extra TX%d ready, csr %04x\n", epnum, tx_csr);
+               return;
+       }
+
+       if (is_dma_capable() && dma && !status) {
+               /*
+                * DMA has completed.  But if we're using DMA mode 1 (multi
+                * packet DMA), we need a terminal TXPKTRDY interrupt before
+                * we can consider this transfer completed, lest we trash
+                * its last packet when writing the next URB's data.  So we
+                * switch back to mode 0 to get that interrupt; we'll come
+                * back here once it happens.
+                */
+               if (tx_csr & MUSB_TXCSR_DMAMODE) {
+                       /*
+                        * We shouldn't clear DMAMODE with DMAENAB set; so
+                        * clear them in a safe order.  That should be OK
+                        * once TXPKTRDY has been set (and I've never seen
+                        * it being 0 at this moment -- DMA interrupt latency
+                        * is significant) but if it hasn't been then we have
+                        * no choice but to stop being polite and ignore the
+                        * programmer's guide... :-)
+                        *
+                        * Note that we must write TXCSR with TXPKTRDY cleared
+                        * in order not to re-trigger the packet send (this bit
+                        * can't be cleared by CPU), and there's another caveat:
+                        * TXPKTRDY may be set shortly and then cleared in the
+                        * double-buffered FIFO mode, so we do an extra TXCSR
+                        * read for debouncing...
+                        */
+                       tx_csr &= musb_readw(epio, MUSB_TXCSR);
+                       if (tx_csr & MUSB_TXCSR_TXPKTRDY) {
+                               tx_csr &= ~(MUSB_TXCSR_DMAENAB |
+                                           MUSB_TXCSR_TXPKTRDY);
+                               musb_writew(epio, MUSB_TXCSR,
+                                           tx_csr | MUSB_TXCSR_H_WZC_BITS);
+                       }
+                       tx_csr &= ~(MUSB_TXCSR_DMAMODE |
+                                   MUSB_TXCSR_TXPKTRDY);
+                       musb_writew(epio, MUSB_TXCSR,
+                                   tx_csr | MUSB_TXCSR_H_WZC_BITS);
+
+                       /*
+                        * There is no guarantee that we'll get an interrupt
+                        * after clearing DMAMODE as we might have done this
+                        * too late (after TXPKTRDY was cleared by controller).
+                        * Re-read TXCSR as we have spoiled its previous value.
+                        */
+                       tx_csr = musb_readw(epio, MUSB_TXCSR);
+               }
+
+               /*
+                * We may get here from a DMA completion or TXPKTRDY interrupt.
+                * In any case, we must check the FIFO status here and bail out
+                * only if the FIFO still has data -- that should prevent the
+                * "missed" TXPKTRDY interrupts and deal with double-buffered
+                * FIFO mode too...
+                */
+               if (tx_csr & (MUSB_TXCSR_FIFONOTEMPTY | MUSB_TXCSR_TXPKTRDY)) {
+                       dev_dbg(musb->controller, "DMA complete but packet still in FIFO, "
+                           "CSR %04x\n", tx_csr);
+                       return;
+               }
+       }
+
+       if (!status || dma || usb_pipeisoc(pipe)) {
+               if (dma)
+                       length = dma->actual_len;
+               else
+                       length = qh->segsize;
+               qh->offset += length;
+
+               if (usb_pipeisoc(pipe)) {
+#ifndef __UBOOT__
+                       struct usb_iso_packet_descriptor        *d;
+
+                       d = urb->iso_frame_desc + qh->iso_idx;
+                       d->actual_length = length;
+                       d->status = status;
+                       if (++qh->iso_idx >= urb->number_of_packets) {
+                               done = true;
+                       } else {
+                               d++;
+                               offset = d->offset;
+                               length = d->length;
+                       }
+#endif
+               } else if (dma && urb->transfer_buffer_length == qh->offset) {
+                       done = true;
+               } else {
+                       /* see if we need to send more data, or ZLP */
+                       if (qh->segsize < qh->maxpacket)
+                               done = true;
+                       else if (qh->offset == urb->transfer_buffer_length
+                                       && !(urb->transfer_flags
+                                               & URB_ZERO_PACKET))
+                               done = true;
+                       if (!done) {
+                               offset = qh->offset;
+                               length = urb->transfer_buffer_length - offset;
+                               transfer_pending = true;
+                       }
+               }
+       }
+
+       /* urb->status != -EINPROGRESS means request has been faulted,
+        * so we must abort this transfer after cleanup
+        */
+       if (urb->status != -EINPROGRESS) {
+               done = true;
+               if (status == 0)
+                       status = urb->status;
+       }
+
+       if (done) {
+               /* set status */
+               urb->status = status;
+               urb->actual_length = qh->offset;
+               musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT);
+               return;
+       } else if ((usb_pipeisoc(pipe) || transfer_pending) && dma) {
+               if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb,
+                               offset, length)) {
+                       if (is_cppi_enabled() || tusb_dma_omap())
+                               musb_h_tx_dma_start(hw_ep);
+                       return;
+               }
+       } else  if (tx_csr & MUSB_TXCSR_DMAENAB) {
+               dev_dbg(musb->controller, "not complete, but DMA enabled?\n");
+               return;
+       }
+
+       /*
+        * PIO: start next packet in this URB.
+        *
+        * REVISIT: some docs say that when hw_ep->tx_double_buffered,
+        * (and presumably, FIFO is not half-full) we should write *two*
+        * packets before updating TXCSR; other docs disagree...
+        */
+       if (length > qh->maxpacket)
+               length = qh->maxpacket;
+       /* Unmap the buffer so that CPU can use it */
+       usb_hcd_unmap_urb_for_dma(musb_to_hcd(musb), urb);
+       musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset);
+       qh->segsize = length;
+
+       musb_ep_select(mbase, epnum);
+       musb_writew(epio, MUSB_TXCSR,
+                       MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
+}
+
+
+#ifdef CONFIG_USB_INVENTRA_DMA
+
+/* Host side RX (IN) using Mentor DMA works as follows:
+       submit_urb ->
+               - if queue was empty, ProgramEndpoint
+               - first IN token is sent out (by setting ReqPkt)
+       LinuxIsr -> RxReady()
+       /\      => first packet is received
+       |       - Set in mode 0 (DmaEnab, ~ReqPkt)
+       |               -> DMA Isr (transfer complete) -> RxReady()
+       |                   - Ack receive (~RxPktRdy), turn off DMA (~DmaEnab)
+       |                   - if urb not complete, send next IN token (ReqPkt)
+       |                          |            else complete urb.
+       |                          |
+       ---------------------------
+ *
+ * Nuances of mode 1:
+ *     For short packets, no ack (+RxPktRdy) is sent automatically
+ *     (even if AutoClear is ON)
+ *     For full packets, ack (~RxPktRdy) and next IN token (+ReqPkt) is sent
+ *     automatically => major problem, as collecting the next packet becomes
+ *     difficult. Hence mode 1 is not used.
+ *
+ * REVISIT
+ *     All we care about at this driver level is that
+ *       (a) all URBs terminate with REQPKT cleared and fifo(s) empty;
+ *       (b) termination conditions are: short RX, or buffer full;
+ *       (c) fault modes include
+ *           - iff URB_SHORT_NOT_OK, short RX status is -EREMOTEIO.
+ *             (and that endpoint's dma queue stops immediately)
+ *           - overflow (full, PLUS more bytes in the terminal packet)
+ *
+ *     So for example, usb-storage sets URB_SHORT_NOT_OK, and would
+ *     thus be a great candidate for using mode 1 ... for all but the
+ *     last packet of one URB's transfer.
+ */
+
+#endif
+
+/* Schedule next QH from musb->in_bulk and move the current qh to
+ * the end; avoids starvation for other endpoints.
+ */
+static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
+{
+       struct dma_channel      *dma;
+       struct urb              *urb;
+       void __iomem            *mbase = musb->mregs;
+       void __iomem            *epio = ep->regs;
+       struct musb_qh          *cur_qh, *next_qh;
+       u16                     rx_csr;
+
+       musb_ep_select(mbase, ep->epnum);
+       dma = is_dma_capable() ? ep->rx_channel : NULL;
+
+       /* clear nak timeout bit */
+       rx_csr = musb_readw(epio, MUSB_RXCSR);
+       rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+       rx_csr &= ~MUSB_RXCSR_DATAERROR;
+       musb_writew(epio, MUSB_RXCSR, rx_csr);
+
+       cur_qh = first_qh(&musb->in_bulk);
+       if (cur_qh) {
+               urb = next_urb(cur_qh);
+               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
+                       musb->dma_controller->channel_abort(dma);
+                       urb->actual_length += dma->actual_len;
+                       dma->actual_len = 0L;
+               }
+               musb_save_toggle(cur_qh, 1, urb);
+
+               /* move cur_qh to end of queue */
+               list_move_tail(&cur_qh->ring, &musb->in_bulk);
+
+               /* get the next qh from musb->in_bulk */
+               next_qh = first_qh(&musb->in_bulk);
+
+               /* set rx_reinit and schedule the next qh */
+               ep->rx_reinit = 1;
+               musb_start_urb(musb, 1, next_qh);
+       }
+}
+
+/*
+ * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso,
+ * and high-bandwidth IN transfer cases.
+ */
+void musb_host_rx(struct musb *musb, u8 epnum)
+{
+       struct urb              *urb;
+       struct musb_hw_ep       *hw_ep = musb->endpoints + epnum;
+       void __iomem            *epio = hw_ep->regs;
+       struct musb_qh          *qh = hw_ep->in_qh;
+       size_t                  xfer_len;
+       void __iomem            *mbase = musb->mregs;
+       int                     pipe;
+       u16                     rx_csr, val;
+       bool                    iso_err = false;
+       bool                    done = false;
+       u32                     status;
+       struct dma_channel      *dma;
+
+       musb_ep_select(mbase, epnum);
+
+       urb = next_urb(qh);
+       dma = is_dma_capable() ? hw_ep->rx_channel : NULL;
+       status = 0;
+       xfer_len = 0;
+
+       rx_csr = musb_readw(epio, MUSB_RXCSR);
+       val = rx_csr;
+
+       if (unlikely(!urb)) {
+               /* REVISIT -- THIS SHOULD NEVER HAPPEN ... but, at least
+                * usbtest #11 (unlinks) triggers it regularly, sometimes
+                * with fifo full.  (Only with DMA??)
+                */
+               dev_dbg(musb->controller, "BOGUS RX%d ready, csr %04x, count %d\n", epnum, val,
+                       musb_readw(epio, MUSB_RXCOUNT));
+               musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG);
+               return;
+       }
+
+       pipe = urb->pipe;
+
+       dev_dbg(musb->controller, "<== hw %d rxcsr %04x, urb actual %d (+dma %zu)\n",
+               epnum, rx_csr, urb->actual_length,
+               dma ? dma->actual_len : 0);
+
+       /* check for errors, concurrent stall & unlink is not really
+        * handled yet! */
+       if (rx_csr & MUSB_RXCSR_H_RXSTALL) {
+               dev_dbg(musb->controller, "RX end %d STALL\n", epnum);
+
+               /* stall; record URB status */
+               status = -EPIPE;
+
+       } else if (rx_csr & MUSB_RXCSR_H_ERROR) {
+               dev_dbg(musb->controller, "end %d RX proto error\n", epnum);
+
+               status = -EPROTO;
+               musb_writeb(epio, MUSB_RXINTERVAL, 0);
+
+       } else if (rx_csr & MUSB_RXCSR_DATAERROR) {
+
+               if (USB_ENDPOINT_XFER_ISOC != qh->type) {
+                       dev_dbg(musb->controller, "RX end %d NAK timeout\n", epnum);
+
+                       /* NOTE: NAKing is *NOT* an error, so we want to
+                        * continue.  Except ... if there's a request for
+                        * another QH, use that instead of starving it.
+                        *
+                        * Devices like Ethernet and serial adapters keep
+                        * reads posted at all times, which will starve
+                        * other devices without this logic.
+                        */
+                       if (usb_pipebulk(urb->pipe)
+                                       && qh->mux == 1
+                                       && !list_is_singular(&musb->in_bulk)) {
+                               musb_bulk_rx_nak_timeout(musb, hw_ep);
+                               return;
+                       }
+                       musb_ep_select(mbase, epnum);
+                       rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+                       rx_csr &= ~MUSB_RXCSR_DATAERROR;
+                       musb_writew(epio, MUSB_RXCSR, rx_csr);
+
+                       goto finish;
+               } else {
+                       dev_dbg(musb->controller, "RX end %d ISO data error\n", epnum);
+                       /* packet error reported later */
+                       iso_err = true;
+               }
+       } else if (rx_csr & MUSB_RXCSR_INCOMPRX) {
+               dev_dbg(musb->controller, "end %d high bandwidth incomplete ISO packet RX\n",
+                               epnum);
+               status = -EPROTO;
+       }
+
+       /* faults abort the transfer */
+       if (status) {
+               /* clean up dma and collect transfer count */
+               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
+                       (void) musb->dma_controller->channel_abort(dma);
+                       xfer_len = dma->actual_len;
+               }
+               musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG);
+               musb_writeb(epio, MUSB_RXINTERVAL, 0);
+               done = true;
+               goto finish;
+       }
+
+       if (unlikely(dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY)) {
+               /* SHOULD NEVER HAPPEN ... but at least DaVinci has done it */
+               ERR("RX%d dma busy, csr %04x\n", epnum, rx_csr);
+               goto finish;
+       }
+
+       /* thorough shutdown for now ... given more precise fault handling
+        * and better queueing support, we might keep a DMA pipeline going
+        * while processing this irq for earlier completions.
+        */
+
+       /* FIXME this is _way_ too much in-line logic for Mentor DMA */
+
+#ifndef CONFIG_USB_INVENTRA_DMA
+       if (rx_csr & MUSB_RXCSR_H_REQPKT)  {
+               /* REVISIT this happened for a while on some short reads...
+                * the cleanup still needs investigation... looks bad...
+                * and also duplicates dma cleanup code above ... plus,
+                * shouldn't this be the "half full" double buffer case?
+                */
+               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
+                       (void) musb->dma_controller->channel_abort(dma);
+                       xfer_len = dma->actual_len;
+                       done = true;
+               }
+
+               dev_dbg(musb->controller, "RXCSR%d %04x, reqpkt, len %zu%s\n", epnum, rx_csr,
+                               xfer_len, dma ? ", dma" : "");
+               rx_csr &= ~MUSB_RXCSR_H_REQPKT;
+
+               musb_ep_select(mbase, epnum);
+               musb_writew(epio, MUSB_RXCSR,
+                               MUSB_RXCSR_H_WZC_BITS | rx_csr);
+       }
+#endif
+       if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) {
+               xfer_len = dma->actual_len;
+
+               val &= ~(MUSB_RXCSR_DMAENAB
+                       | MUSB_RXCSR_H_AUTOREQ
+                       | MUSB_RXCSR_AUTOCLEAR
+                       | MUSB_RXCSR_RXPKTRDY);
+               musb_writew(hw_ep->regs, MUSB_RXCSR, val);
+
+#ifdef CONFIG_USB_INVENTRA_DMA
+               if (usb_pipeisoc(pipe)) {
+                       struct usb_iso_packet_descriptor *d;
+
+                       d = urb->iso_frame_desc + qh->iso_idx;
+                       d->actual_length = xfer_len;
+
+                       /* even if there was an error, we did the dma
+                        * for iso_frame_desc->length
+                        */
+                       if (d->status != -EILSEQ && d->status != -EOVERFLOW)
+                               d->status = 0;
+
+                       if (++qh->iso_idx >= urb->number_of_packets)
+                               done = true;
+                       else
+                               done = false;
+
+               } else  {
+               /* done if urb buffer is full or short packet is recd */
+               done = (urb->actual_length + xfer_len >=
+                               urb->transfer_buffer_length
+                       || dma->actual_len < qh->maxpacket);
+               }
+
+               /* send IN token for next packet, without AUTOREQ */
+               if (!done) {
+                       val |= MUSB_RXCSR_H_REQPKT;
+                       musb_writew(epio, MUSB_RXCSR,
+                               MUSB_RXCSR_H_WZC_BITS | val);
+               }
+
+               dev_dbg(musb->controller, "ep %d dma %s, rxcsr %04x, rxcount %d\n", epnum,
+                       done ? "off" : "reset",
+                       musb_readw(epio, MUSB_RXCSR),
+                       musb_readw(epio, MUSB_RXCOUNT));
+#else
+               done = true;
+#endif
+       } else if (urb->status == -EINPROGRESS) {
+               /* if no errors, be sure a packet is ready for unloading */
+               if (unlikely(!(rx_csr & MUSB_RXCSR_RXPKTRDY))) {
+                       status = -EPROTO;
+                       ERR("Rx interrupt with no errors or packet!\n");
+
+                       /* FIXME this is another "SHOULD NEVER HAPPEN" */
+
+/* SCRUB (RX) */
+                       /* do the proper sequence to abort the transfer */
+                       musb_ep_select(mbase, epnum);
+                       val &= ~MUSB_RXCSR_H_REQPKT;
+                       musb_writew(epio, MUSB_RXCSR, val);
+                       goto finish;
+               }
+
+               /* we are expecting IN packets */
+#ifdef CONFIG_USB_INVENTRA_DMA
+               if (dma) {
+                       struct dma_controller   *c;
+                       u16                     rx_count;
+                       int                     ret, length;
+                       dma_addr_t              buf;
+
+                       rx_count = musb_readw(epio, MUSB_RXCOUNT);
+
+                       dev_dbg(musb->controller, "RX%d count %d, buffer 0x%x len %d/%d\n",
+                                       epnum, rx_count,
+                                       urb->transfer_dma
+                                               + urb->actual_length,
+                                       qh->offset,
+                                       urb->transfer_buffer_length);
+
+                       c = musb->dma_controller;
+
+                       if (usb_pipeisoc(pipe)) {
+                               int d_status = 0;
+                               struct usb_iso_packet_descriptor *d;
+
+                               d = urb->iso_frame_desc + qh->iso_idx;
+
+                               if (iso_err) {
+                                       d_status = -EILSEQ;
+                                       urb->error_count++;
+                               }
+                               if (rx_count > d->length) {
+                                       if (d_status == 0) {
+                                               d_status = -EOVERFLOW;
+                                               urb->error_count++;
+                                       }
+                                       dev_dbg(musb->controller, "** OVERFLOW %d into %d\n",\
+                                           rx_count, d->length);
+
+                                       length = d->length;
+                               } else
+                                       length = rx_count;
+                               d->status = d_status;
+                               buf = urb->transfer_dma + d->offset;
+                       } else {
+                               length = rx_count;
+                               buf = urb->transfer_dma +
+                                               urb->actual_length;
+                       }
+
+                       dma->desired_mode = 0;
+#ifdef USE_MODE1
+                       /* because of the issue below, mode 1 will
+                        * only rarely behave with correct semantics.
+                        */
+                       if ((urb->transfer_flags &
+                                               URB_SHORT_NOT_OK)
+                               && (urb->transfer_buffer_length -
+                                               urb->actual_length)
+                                       > qh->maxpacket)
+                               dma->desired_mode = 1;
+                       if (rx_count < hw_ep->max_packet_sz_rx) {
+                               length = rx_count;
+                               dma->desired_mode = 0;
+                       } else {
+                               length = urb->transfer_buffer_length;
+                       }
+#endif
+
+/* Disadvantage of using mode 1:
+ *     It's basically usable only for mass storage class; essentially all
+ *     other protocols also terminate transfers on short packets.
+ *
+ * Details:
+ *     An extra IN token is sent at the end of the transfer (due to AUTOREQ)
+ *     If you try to use mode 1 for (transfer_buffer_length - 512), and try
+ *     to use the extra IN token to grab the last packet using mode 0, then
+ *     the problem is that you cannot be sure when the device will send the
+ *     last packet and RxPktRdy set. Sometimes the packet is recd too soon
+ *     such that it gets lost when RxCSR is re-set at the end of the mode 1
+ *     transfer, while sometimes it is recd just a little late so that if you
+ *     try to configure for mode 0 soon after the mode 1 transfer is
+ *     completed, you will find rxcount 0. Okay, so you might think why not
+ *     wait for an interrupt when the pkt is recd. Well, you won't get any!
+ */
+
+                       val = musb_readw(epio, MUSB_RXCSR);
+                       val &= ~MUSB_RXCSR_H_REQPKT;
+
+                       if (dma->desired_mode == 0)
+                               val &= ~MUSB_RXCSR_H_AUTOREQ;
+                       else
+                               val |= MUSB_RXCSR_H_AUTOREQ;
+                       val |= MUSB_RXCSR_DMAENAB;
+
+                       /* autoclear shouldn't be set in high bandwidth */
+                       if (qh->hb_mult == 1)
+                               val |= MUSB_RXCSR_AUTOCLEAR;
+
+                       musb_writew(epio, MUSB_RXCSR,
+                               MUSB_RXCSR_H_WZC_BITS | val);
+
+                       /* REVISIT if when actual_length != 0,
+                        * transfer_buffer_length needs to be
+                        * adjusted first...
+                        */
+                       ret = c->channel_program(
+                               dma, qh->maxpacket,
+                               dma->desired_mode, buf, length);
+
+                       if (!ret) {
+                               c->channel_release(dma);
+                               hw_ep->rx_channel = NULL;
+                               dma = NULL;
+                               val = musb_readw(epio, MUSB_RXCSR);
+                               val &= ~(MUSB_RXCSR_DMAENAB
+                                       | MUSB_RXCSR_H_AUTOREQ
+                                       | MUSB_RXCSR_AUTOCLEAR);
+                               musb_writew(epio, MUSB_RXCSR, val);
+                       }
+               }
+#endif /* Mentor DMA */
+
+               if (!dma) {
+                       /* Unmap the buffer so that CPU can use it */
+                       usb_hcd_unmap_urb_for_dma(musb_to_hcd(musb), urb);
+                       done = musb_host_packet_rx(musb, urb,
+                                       epnum, iso_err);
+                       dev_dbg(musb->controller, "read %spacket\n", done ? "last " : "");
+               }
+       }
+
+finish:
+       urb->actual_length += xfer_len;
+       qh->offset += xfer_len;
+       if (done) {
+               if (urb->status == -EINPROGRESS)
+                       urb->status = status;
+               musb_advance_schedule(musb, urb, hw_ep, USB_DIR_IN);
+       }
+}
+
+/* schedule nodes correspond to peripheral endpoints, like an OHCI QH.
+ * the software schedule associates multiple such nodes with a given
+ * host side hardware endpoint + direction; scheduling may activate
+ * that hardware endpoint.
+ */
+static int musb_schedule(
+       struct musb             *musb,
+       struct musb_qh          *qh,
+       int                     is_in)
+{
+       int                     idle;
+       int                     best_diff;
+       int                     best_end, epnum;
+       struct musb_hw_ep       *hw_ep = NULL;
+       struct list_head        *head = NULL;
+       u8                      toggle;
+       u8                      txtype;
+       struct urb              *urb = next_urb(qh);
+
+       /* use fixed hardware for control and bulk */
+       if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
+               head = &musb->control;
+               hw_ep = musb->control_ep;
+               goto success;
+       }
+
+       /* else, periodic transfers get muxed to other endpoints */
+
+       /*
+        * We know this qh hasn't been scheduled, so all we need to do
+        * is choose which hardware endpoint to put it on ...
+        *
+        * REVISIT what we really want here is a regular schedule tree
+        * like e.g. OHCI uses.
+        */
+       best_diff = 4096;
+       best_end = -1;
+
+       for (epnum = 1, hw_ep = musb->endpoints + 1;
+                       epnum < musb->nr_endpoints;
+                       epnum++, hw_ep++) {
+               int     diff;
+
+               if (musb_ep_get_qh(hw_ep, is_in) != NULL)
+                       continue;
+
+               if (hw_ep == musb->bulk_ep)
+                       continue;
+
+               if (is_in)
+                       diff = hw_ep->max_packet_sz_rx;
+               else
+                       diff = hw_ep->max_packet_sz_tx;
+               diff -= (qh->maxpacket * qh->hb_mult);
+
+               if (diff >= 0 && best_diff > diff) {
+
+                       /*
+                        * Mentor controller has a bug in that if we schedule
+                        * a BULK Tx transfer on an endpoint that had earlier
+                        * handled ISOC then the BULK transfer has to start on
+                        * a zero toggle.  If the BULK transfer starts on a 1
+                        * toggle then this transfer will fail as the mentor
+                        * controller starts the Bulk transfer on a 0 toggle
+                        * irrespective of the programming of the toggle bits
+                        * in the TXCSR register.  Check for this condition
+                        * while allocating the EP for a Tx Bulk transfer.  If
+                        * so skip this EP.
+                        */
+                       hw_ep = musb->endpoints + epnum;
+                       toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
+                       txtype = (musb_readb(hw_ep->regs, MUSB_TXTYPE)
+                                       >> 4) & 0x3;
+                       if (!is_in && (qh->type == USB_ENDPOINT_XFER_BULK) &&
+                               toggle && (txtype == USB_ENDPOINT_XFER_ISOC))
+                               continue;
+
+                       best_diff = diff;
+                       best_end = epnum;
+               }
+       }
+       /* use bulk reserved ep1 if no other ep is free */
+       if (best_end < 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
+               hw_ep = musb->bulk_ep;
+               if (is_in)
+                       head = &musb->in_bulk;
+               else
+                       head = &musb->out_bulk;
+
+               /* Enable bulk RX NAK timeout scheme when bulk requests are
+                * multiplexed.  This scheme doen't work in high speed to full
+                * speed scenario as NAK interrupts are not coming from a
+                * full speed device connected to a high speed device.
+                * NAK timeout interval is 8 (128 uframe or 16ms) for HS and
+                * 4 (8 frame or 8ms) for FS device.
+                */
+               if (is_in && qh->dev)
+                       qh->intv_reg =
+                               (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4;
+               goto success;
+       } else if (best_end < 0) {
+               return -ENOSPC;
+       }
+
+       idle = 1;
+       qh->mux = 0;
+       hw_ep = musb->endpoints + best_end;
+       dev_dbg(musb->controller, "qh %p periodic slot %d\n", qh, best_end);
+success:
+       if (head) {
+               idle = list_empty(head);
+               list_add_tail(&qh->ring, head);
+               qh->mux = 1;
+       }
+       qh->hw_ep = hw_ep;
+       qh->hep->hcpriv = qh;
+       if (idle)
+               musb_start_urb(musb, is_in, qh);
+       return 0;
+}
+
+#ifdef __UBOOT__
+/* check if transaction translator is needed for device */
+static int tt_needed(struct musb *musb, struct usb_device *dev)
+{
+       if ((musb_readb(musb->mregs, MUSB_POWER) & MUSB_POWER_HSMODE) &&
+                       (dev->speed < USB_SPEED_HIGH))
+               return 1;
+       return 0;
+}
+#endif
+
+#ifndef __UBOOT__
+static int musb_urb_enqueue(
+#else
+int musb_urb_enqueue(
+#endif
+       struct usb_hcd                  *hcd,
+       struct urb                      *urb,
+       gfp_t                           mem_flags)
+{
+       unsigned long                   flags;
+       struct musb                     *musb = hcd_to_musb(hcd);
+       struct usb_host_endpoint        *hep = urb->ep;
+       struct musb_qh                  *qh;
+       struct usb_endpoint_descriptor  *epd = &hep->desc;
+       int                             ret;
+       unsigned                        type_reg;
+       unsigned                        interval;
+
+       /* host role must be active */
+       if (!is_host_active(musb) || !musb->is_active)
+               return -ENODEV;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       ret = usb_hcd_link_urb_to_ep(hcd, urb);
+       qh = ret ? NULL : hep->hcpriv;
+       if (qh)
+               urb->hcpriv = qh;
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       /* DMA mapping was already done, if needed, and this urb is on
+        * hep->urb_list now ... so we're done, unless hep wasn't yet
+        * scheduled onto a live qh.
+        *
+        * REVISIT best to keep hep->hcpriv valid until the endpoint gets
+        * disabled, testing for empty qh->ring and avoiding qh setup costs
+        * except for the first urb queued after a config change.
+        */
+       if (qh || ret)
+               return ret;
+
+       /* Allocate and initialize qh, minimizing the work done each time
+        * hw_ep gets reprogrammed, or with irqs blocked.  Then schedule it.
+        *
+        * REVISIT consider a dedicated qh kmem_cache, so it's harder
+        * for bugs in other kernel code to break this driver...
+        */
+       qh = kzalloc(sizeof *qh, mem_flags);
+       if (!qh) {
+               spin_lock_irqsave(&musb->lock, flags);
+               usb_hcd_unlink_urb_from_ep(hcd, urb);
+               spin_unlock_irqrestore(&musb->lock, flags);
+               return -ENOMEM;
+       }
+
+       qh->hep = hep;
+       qh->dev = urb->dev;
+       INIT_LIST_HEAD(&qh->ring);
+       qh->is_ready = 1;
+
+       qh->maxpacket = usb_endpoint_maxp(epd);
+       qh->type = usb_endpoint_type(epd);
+
+       /* Bits 11 & 12 of wMaxPacketSize encode high bandwidth multiplier.
+        * Some musb cores don't support high bandwidth ISO transfers; and
+        * we don't (yet!) support high bandwidth interrupt transfers.
+        */
+       qh->hb_mult = 1 + ((qh->maxpacket >> 11) & 0x03);
+       if (qh->hb_mult > 1) {
+               int ok = (qh->type == USB_ENDPOINT_XFER_ISOC);
+
+               if (ok)
+                       ok = (usb_pipein(urb->pipe) && musb->hb_iso_rx)
+                               || (usb_pipeout(urb->pipe) && musb->hb_iso_tx);
+               if (!ok) {
+                       ret = -EMSGSIZE;
+                       goto done;
+               }
+               qh->maxpacket &= 0x7ff;
+       }
+
+       qh->epnum = usb_endpoint_num(epd);
+
+       /* NOTE: urb->dev->devnum is wrong during SET_ADDRESS */
+       qh->addr_reg = (u8) usb_pipedevice(urb->pipe);
+
+       /* precompute rxtype/txtype/type0 register */
+       type_reg = (qh->type << 4) | qh->epnum;
+       switch (urb->dev->speed) {
+       case USB_SPEED_LOW:
+               type_reg |= 0xc0;
+               break;
+       case USB_SPEED_FULL:
+               type_reg |= 0x80;
+               break;
+       default:
+               type_reg |= 0x40;
+       }
+       qh->type_reg = type_reg;
+
+       /* Precompute RXINTERVAL/TXINTERVAL register */
+       switch (qh->type) {
+       case USB_ENDPOINT_XFER_INT:
+               /*
+                * Full/low speeds use the  linear encoding,
+                * high speed uses the logarithmic encoding.
+                */
+               if (urb->dev->speed <= USB_SPEED_FULL) {
+                       interval = max_t(u8, epd->bInterval, 1);
+                       break;
+               }
+               /* FALLTHROUGH */
+       case USB_ENDPOINT_XFER_ISOC:
+               /* ISO always uses logarithmic encoding */
+               interval = min_t(u8, epd->bInterval, 16);
+               break;
+       default:
+               /* REVISIT we actually want to use NAK limits, hinting to the
+                * transfer scheduling logic to try some other qh, e.g. try
+                * for 2 msec first:
+                *
+                * interval = (USB_SPEED_HIGH == urb->dev->speed) ? 16 : 2;
+                *
+                * The downside of disabling this is that transfer scheduling
+                * gets VERY unfair for nonperiodic transfers; a misbehaving
+                * peripheral could make that hurt.  That's perfectly normal
+                * for reads from network or serial adapters ... so we have
+                * partial NAKlimit support for bulk RX.
+                *
+                * The upside of disabling it is simpler transfer scheduling.
+                */
+               interval = 0;
+       }
+       qh->intv_reg = interval;
+
+       /* precompute addressing for external hub/tt ports */
+       if (musb->is_multipoint) {
+               struct usb_device       *parent = urb->dev->parent;
+
+#ifndef __UBOOT__
+               if (parent != hcd->self.root_hub) {
+#else
+               if (parent) {
+#endif
+                       qh->h_addr_reg = (u8) parent->devnum;
+
+#ifndef __UBOOT__
+                       /* set up tt info if needed */
+                       if (urb->dev->tt) {
+                               qh->h_port_reg = (u8) urb->dev->ttport;
+                               if (urb->dev->tt->hub)
+                                       qh->h_addr_reg =
+                                               (u8) urb->dev->tt->hub->devnum;
+                               if (urb->dev->tt->multi)
+                                       qh->h_addr_reg |= 0x80;
+                       }
+#else
+                       if (tt_needed(musb, urb->dev)) {
+                               u16 hub_port = find_tt(urb->dev);
+                               qh->h_addr_reg = (u8) (hub_port >> 8);
+                               qh->h_port_reg = (u8) (hub_port & 0xff);
+                       }
+#endif
+               }
+       }
+
+       /* invariant: hep->hcpriv is null OR the qh that's already scheduled.
+        * until we get real dma queues (with an entry for each urb/buffer),
+        * we only have work to do in the former case.
+        */
+       spin_lock_irqsave(&musb->lock, flags);
+       if (hep->hcpriv) {
+               /* some concurrent activity submitted another urb to hep...
+                * odd, rare, error prone, but legal.
+                */
+               kfree(qh);
+               qh = NULL;
+               ret = 0;
+       } else
+               ret = musb_schedule(musb, qh,
+                               epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK);
+
+       if (ret == 0) {
+               urb->hcpriv = qh;
+               /* FIXME set urb->start_frame for iso/intr, it's tested in
+                * musb_start_urb(), but otherwise only konicawc cares ...
+                */
+       }
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+done:
+       if (ret != 0) {
+               spin_lock_irqsave(&musb->lock, flags);
+               usb_hcd_unlink_urb_from_ep(hcd, urb);
+               spin_unlock_irqrestore(&musb->lock, flags);
+               kfree(qh);
+       }
+       return ret;
+}
+
+
+#ifndef __UBOOT__
+/*
+ * abort a transfer that's at the head of a hardware queue.
+ * called with controller locked, irqs blocked
+ * that hardware queue advances to the next transfer, unless prevented
+ */
+static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
+{
+       struct musb_hw_ep       *ep = qh->hw_ep;
+       struct musb             *musb = ep->musb;
+       void __iomem            *epio = ep->regs;
+       unsigned                hw_end = ep->epnum;
+       void __iomem            *regs = ep->musb->mregs;
+       int                     is_in = usb_pipein(urb->pipe);
+       int                     status = 0;
+       u16                     csr;
+
+       musb_ep_select(regs, hw_end);
+
+       if (is_dma_capable()) {
+               struct dma_channel      *dma;
+
+               dma = is_in ? ep->rx_channel : ep->tx_channel;
+               if (dma) {
+                       status = ep->musb->dma_controller->channel_abort(dma);
+                       dev_dbg(musb->controller,
+                               "abort %cX%d DMA for urb %p --> %d\n",
+                               is_in ? 'R' : 'T', ep->epnum,
+                               urb, status);
+                       urb->actual_length += dma->actual_len;
+               }
+       }
+
+       /* turn off DMA requests, discard state, stop polling ... */
+       if (ep->epnum && is_in) {
+               /* giveback saves bulk toggle */
+               csr = musb_h_flush_rxfifo(ep, 0);
+
+               /* REVISIT we still get an irq; should likely clear the
+                * endpoint's irq status here to avoid bogus irqs.
+                * clearing that status is platform-specific...
+                */
+       } else if (ep->epnum) {
+               musb_h_tx_flush_fifo(ep);
+               csr = musb_readw(epio, MUSB_TXCSR);
+               csr &= ~(MUSB_TXCSR_AUTOSET
+                       | MUSB_TXCSR_DMAENAB
+                       | MUSB_TXCSR_H_RXSTALL
+                       | MUSB_TXCSR_H_NAKTIMEOUT
+                       | MUSB_TXCSR_H_ERROR
+                       | MUSB_TXCSR_TXPKTRDY);
+               musb_writew(epio, MUSB_TXCSR, csr);
+               /* REVISIT may need to clear FLUSHFIFO ... */
+               musb_writew(epio, MUSB_TXCSR, csr);
+               /* flush cpu writebuffer */
+               csr = musb_readw(epio, MUSB_TXCSR);
+       } else  {
+               musb_h_ep0_flush_fifo(ep);
+       }
+       if (status == 0)
+               musb_advance_schedule(ep->musb, urb, ep, is_in);
+       return status;
+}
+
+static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+       struct musb             *musb = hcd_to_musb(hcd);
+       struct musb_qh          *qh;
+       unsigned long           flags;
+       int                     is_in  = usb_pipein(urb->pipe);
+       int                     ret;
+
+       dev_dbg(musb->controller, "urb=%p, dev%d ep%d%s\n", urb,
+                       usb_pipedevice(urb->pipe),
+                       usb_pipeendpoint(urb->pipe),
+                       is_in ? "in" : "out");
+
+       spin_lock_irqsave(&musb->lock, flags);
+       ret = usb_hcd_check_unlink_urb(hcd, urb, status);
+       if (ret)
+               goto done;
+
+       qh = urb->hcpriv;
+       if (!qh)
+               goto done;
+
+       /*
+        * Any URB not actively programmed into endpoint hardware can be
+        * immediately given back; that's any URB not at the head of an
+        * endpoint queue, unless someday we get real DMA queues.  And even
+        * if it's at the head, it might not be known to the hardware...
+        *
+        * Otherwise abort current transfer, pending DMA, etc.; urb->status
+        * has already been updated.  This is a synchronous abort; it'd be
+        * OK to hold off until after some IRQ, though.
+        *
+        * NOTE: qh is invalid unless !list_empty(&hep->urb_list)
+        */
+       if (!qh->is_ready
+                       || urb->urb_list.prev != &qh->hep->urb_list
+                       || musb_ep_get_qh(qh->hw_ep, is_in) != qh) {
+               int     ready = qh->is_ready;
+
+               qh->is_ready = 0;
+               musb_giveback(musb, urb, 0);
+               qh->is_ready = ready;
+
+               /* If nothing else (usually musb_giveback) is using it
+                * and its URB list has emptied, recycle this qh.
+                */
+               if (ready && list_empty(&qh->hep->urb_list)) {
+                       qh->hep->hcpriv = NULL;
+                       list_del(&qh->ring);
+                       kfree(qh);
+               }
+       } else
+               ret = musb_cleanup_urb(urb, qh);
+done:
+       spin_unlock_irqrestore(&musb->lock, flags);
+       return ret;
+}
+
+/* disable an endpoint */
+static void
+musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
+{
+       u8                      is_in = hep->desc.bEndpointAddress & USB_DIR_IN;
+       unsigned long           flags;
+       struct musb             *musb = hcd_to_musb(hcd);
+       struct musb_qh          *qh;
+       struct urb              *urb;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       qh = hep->hcpriv;
+       if (qh == NULL)
+               goto exit;
+
+       /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */
+
+       /* Kick the first URB off the hardware, if needed */
+       qh->is_ready = 0;
+       if (musb_ep_get_qh(qh->hw_ep, is_in) == qh) {
+               urb = next_urb(qh);
+
+               /* make software (then hardware) stop ASAP */
+               if (!urb->unlinked)
+                       urb->status = -ESHUTDOWN;
+
+               /* cleanup */
+               musb_cleanup_urb(urb, qh);
+
+               /* Then nuke all the others ... and advance the
+                * queue on hw_ep (e.g. bulk ring) when we're done.
+                */
+               while (!list_empty(&hep->urb_list)) {
+                       urb = next_urb(qh);
+                       urb->status = -ESHUTDOWN;
+                       musb_advance_schedule(musb, urb, qh->hw_ep, is_in);
+               }
+       } else {
+               /* Just empty the queue; the hardware is busy with
+                * other transfers, and since !qh->is_ready nothing
+                * will activate any of these as it advances.
+                */
+               while (!list_empty(&hep->urb_list))
+                       musb_giveback(musb, next_urb(qh), -ESHUTDOWN);
+
+               hep->hcpriv = NULL;
+               list_del(&qh->ring);
+               kfree(qh);
+       }
+exit:
+       spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+static int musb_h_get_frame_number(struct usb_hcd *hcd)
+{
+       struct musb     *musb = hcd_to_musb(hcd);
+
+       return musb_readw(musb->mregs, MUSB_FRAME);
+}
+
+static int musb_h_start(struct usb_hcd *hcd)
+{
+       struct musb     *musb = hcd_to_musb(hcd);
+
+       /* NOTE: musb_start() is called when the hub driver turns
+        * on port power, or when (OTG) peripheral starts.
+        */
+       hcd->state = HC_STATE_RUNNING;
+       musb->port1_status = 0;
+       return 0;
+}
+
+static void musb_h_stop(struct usb_hcd *hcd)
+{
+       musb_stop(hcd_to_musb(hcd));
+       hcd->state = HC_STATE_HALT;
+}
+
+static int musb_bus_suspend(struct usb_hcd *hcd)
+{
+       struct musb     *musb = hcd_to_musb(hcd);
+       u8              devctl;
+
+       if (!is_host_active(musb))
+               return 0;
+
+       switch (musb->xceiv->state) {
+       case OTG_STATE_A_SUSPEND:
+               return 0;
+       case OTG_STATE_A_WAIT_VRISE:
+               /* ID could be grounded even if there's no device
+                * on the other end of the cable.  NOTE that the
+                * A_WAIT_VRISE timers are messy with MUSB...
+                */
+               devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+               if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
+                       musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
+               break;
+       default:
+               break;
+       }
+
+       if (musb->is_active) {
+               WARNING("trying to suspend as %s while active\n",
+                               otg_state_string(musb->xceiv->state));
+               return -EBUSY;
+       } else
+               return 0;
+}
+
+static int musb_bus_resume(struct usb_hcd *hcd)
+{
+       /* resuming child port does the work */
+       return 0;
+}
+
+const struct hc_driver musb_hc_driver = {
+       .description            = "musb-hcd",
+       .product_desc           = "MUSB HDRC host driver",
+       .hcd_priv_size          = sizeof(struct musb),
+       .flags                  = HCD_USB2 | HCD_MEMORY,
+
+       /* not using irq handler or reset hooks from usbcore, since
+        * those must be shared with peripheral code for OTG configs
+        */
+
+       .start                  = musb_h_start,
+       .stop                   = musb_h_stop,
+
+       .get_frame_number       = musb_h_get_frame_number,
+
+       .urb_enqueue            = musb_urb_enqueue,
+       .urb_dequeue            = musb_urb_dequeue,
+       .endpoint_disable       = musb_h_disable,
+
+       .hub_status_data        = musb_hub_status_data,
+       .hub_control            = musb_hub_control,
+       .bus_suspend            = musb_bus_suspend,
+       .bus_resume             = musb_bus_resume,
+       /* .start_port_reset    = NULL, */
+       /* .hub_irq_enable      = NULL, */
+};
+#endif
diff --git a/drivers/usb/musb-new/musb_host.h b/drivers/usb/musb-new/musb_host.h
new file mode 100644 (file)
index 0000000..ebebe0c
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * MUSB OTG driver host defines
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#ifndef _MUSB_HOST_H
+#define _MUSB_HOST_H
+#ifdef __UBOOT__
+#include "usb-compat.h"
+#endif
+
+static inline struct usb_hcd *musb_to_hcd(struct musb *musb)
+{
+       return container_of((void *) musb, struct usb_hcd, hcd_priv);
+}
+
+static inline struct musb *hcd_to_musb(struct usb_hcd *hcd)
+{
+       return (struct musb *) (hcd->hcd_priv);
+}
+
+/* stored in "usb_host_endpoint.hcpriv" for scheduled endpoints */
+struct musb_qh {
+       struct usb_host_endpoint *hep;          /* usbcore info */
+       struct usb_device       *dev;
+       struct musb_hw_ep       *hw_ep;         /* current binding */
+
+       struct list_head        ring;           /* of musb_qh */
+       /* struct musb_qh               *next; */       /* for periodic tree */
+       u8                      mux;            /* qh multiplexed to hw_ep */
+
+       unsigned                offset;         /* in urb->transfer_buffer */
+       unsigned                segsize;        /* current xfer fragment */
+
+       u8                      type_reg;       /* {rx,tx} type register */
+       u8                      intv_reg;       /* {rx,tx} interval register */
+       u8                      addr_reg;       /* device address register */
+       u8                      h_addr_reg;     /* hub address register */
+       u8                      h_port_reg;     /* hub port register */
+
+       u8                      is_ready;       /* safe to modify hw_ep */
+       u8                      type;           /* XFERTYPE_* */
+       u8                      epnum;
+       u8                      hb_mult;        /* high bandwidth pkts per uf */
+       u16                     maxpacket;
+       u16                     frame;          /* for periodic schedule */
+       unsigned                iso_idx;        /* in urb->iso_frame_desc[] */
+};
+
+/* map from control or bulk queue head to the first qh on that ring */
+static inline struct musb_qh *first_qh(struct list_head *q)
+{
+       if (list_empty(q))
+               return NULL;
+       return list_entry(q->next, struct musb_qh, ring);
+}
+
+
+extern void musb_root_disconnect(struct musb *musb);
+
+struct usb_hcd;
+
+extern int musb_hub_status_data(struct usb_hcd *hcd, char *buf);
+extern int musb_hub_control(struct usb_hcd *hcd,
+                       u16 typeReq, u16 wValue, u16 wIndex,
+                       char *buf, u16 wLength);
+
+extern const struct hc_driver musb_hc_driver;
+
+static inline struct urb *next_urb(struct musb_qh *qh)
+{
+       struct list_head        *queue;
+
+       if (!qh)
+               return NULL;
+       queue = &qh->hep->urb_list;
+       if (list_empty(queue))
+               return NULL;
+       return list_entry(queue->next, struct urb, urb_list);
+}
+
+#ifdef __UBOOT__
+int musb_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
+#endif
+#endif                         /* _MUSB_HOST_H */
diff --git a/drivers/usb/musb-new/musb_io.h b/drivers/usb/musb-new/musb_io.h
new file mode 100644 (file)
index 0000000..51730ae
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * MUSB OTG driver register I/O
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#ifndef __MUSB_LINUX_PLATFORM_ARCH_H__
+#define __MUSB_LINUX_PLATFORM_ARCH_H__
+
+#ifndef __UBOOT__
+#include <linux/io.h>
+#else
+#include <asm/io.h>
+#endif
+
+#if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \
+       && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \
+       && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) \
+       && !defined(CONFIG_MIPS) && !defined(CONFIG_M68K)
+static inline void readsl(const void __iomem *addr, void *buf, int len)
+       { insl((unsigned long)addr, buf, len); }
+static inline void readsw(const void __iomem *addr, void *buf, int len)
+       { insw((unsigned long)addr, buf, len); }
+static inline void readsb(const void __iomem *addr, void *buf, int len)
+       { insb((unsigned long)addr, buf, len); }
+
+static inline void writesl(const void __iomem *addr, const void *buf, int len)
+       { outsl((unsigned long)addr, buf, len); }
+static inline void writesw(const void __iomem *addr, const void *buf, int len)
+       { outsw((unsigned long)addr, buf, len); }
+static inline void writesb(const void __iomem *addr, const void *buf, int len)
+       { outsb((unsigned long)addr, buf, len); }
+
+#endif
+
+#ifndef CONFIG_BLACKFIN
+
+/* NOTE:  these offsets are all in bytes */
+
+static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
+       { return __raw_readw(addr + offset); }
+
+static inline u32 musb_readl(const void __iomem *addr, unsigned offset)
+       { return __raw_readl(addr + offset); }
+
+
+static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data)
+       { __raw_writew(data, addr + offset); }
+
+static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
+       { __raw_writel(data, addr + offset); }
+
+
+#if defined(CONFIG_USB_MUSB_TUSB6010) || defined (CONFIG_USB_MUSB_TUSB6010_MODULE)
+
+/*
+ * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum.
+ */
+static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
+{
+       u16 tmp;
+       u8 val;
+
+       tmp = __raw_readw(addr + (offset & ~1));
+       if (offset & 1)
+               val = (tmp >> 8);
+       else
+               val = tmp & 0xff;
+
+       return val;
+}
+
+static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
+{
+       u16 tmp;
+
+       tmp = __raw_readw(addr + (offset & ~1));
+       if (offset & 1)
+               tmp = (data << 8) | (tmp & 0xff);
+       else
+               tmp = (tmp & 0xff00) | data;
+
+       __raw_writew(tmp, addr + (offset & ~1));
+}
+
+#else
+
+static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
+       { return __raw_readb(addr + offset); }
+
+static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
+       { __raw_writeb(data, addr + offset); }
+
+#endif /* CONFIG_USB_MUSB_TUSB6010 */
+
+#else
+
+static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
+       { return (u8) (bfin_read16(addr + offset)); }
+
+static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
+       { return bfin_read16(addr + offset); }
+
+static inline u32 musb_readl(const void __iomem *addr, unsigned offset)
+       { return (u32) (bfin_read16(addr + offset)); }
+
+static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
+       { bfin_write16(addr + offset, (u16) data); }
+
+static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data)
+       { bfin_write16(addr + offset, data); }
+
+static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
+       { bfin_write16(addr + offset, (u16) data); }
+
+#endif /* CONFIG_BLACKFIN */
+
+#endif
diff --git a/drivers/usb/musb-new/musb_regs.h b/drivers/usb/musb-new/musb_regs.h
new file mode 100644 (file)
index 0000000..03f2655
--- /dev/null
@@ -0,0 +1,645 @@
+/*
+ * MUSB OTG driver register defines
+ *
+ * Copyright 2005 Mentor Graphics Corporation
+ * Copyright (C) 2005-2006 by Texas Instruments
+ * Copyright (C) 2006-2007 Nokia Corporation
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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.
+ *
+ */
+
+#ifndef __MUSB_REGS_H__
+#define __MUSB_REGS_H__
+
+#define MUSB_EP0_FIFOSIZE      64      /* This is non-configurable */
+
+/*
+ * MUSB Register bits
+ */
+
+/* POWER */
+#define MUSB_POWER_ISOUPDATE   0x80
+#define MUSB_POWER_SOFTCONN    0x40
+#define MUSB_POWER_HSENAB      0x20
+#define MUSB_POWER_HSMODE      0x10
+#define MUSB_POWER_RESET       0x08
+#define MUSB_POWER_RESUME      0x04
+#define MUSB_POWER_SUSPENDM    0x02
+#define MUSB_POWER_ENSUSPEND   0x01
+
+/* INTRUSB */
+#define MUSB_INTR_SUSPEND      0x01
+#define MUSB_INTR_RESUME       0x02
+#define MUSB_INTR_RESET                0x04
+#define MUSB_INTR_BABBLE       0x04
+#define MUSB_INTR_SOF          0x08
+#define MUSB_INTR_CONNECT      0x10
+#define MUSB_INTR_DISCONNECT   0x20
+#define MUSB_INTR_SESSREQ      0x40
+#define MUSB_INTR_VBUSERROR    0x80    /* For SESSION end */
+
+/* DEVCTL */
+#define MUSB_DEVCTL_BDEVICE    0x80
+#define MUSB_DEVCTL_FSDEV      0x40
+#define MUSB_DEVCTL_LSDEV      0x20
+#define MUSB_DEVCTL_VBUS       0x18
+#define MUSB_DEVCTL_VBUS_SHIFT 3
+#define MUSB_DEVCTL_HM         0x04
+#define MUSB_DEVCTL_HR         0x02
+#define MUSB_DEVCTL_SESSION    0x01
+
+/* MUSB ULPI VBUSCONTROL */
+#define MUSB_ULPI_USE_EXTVBUS  0x01
+#define MUSB_ULPI_USE_EXTVBUSIND 0x02
+/* ULPI_REG_CONTROL */
+#define MUSB_ULPI_REG_REQ      (1 << 0)
+#define MUSB_ULPI_REG_CMPLT    (1 << 1)
+#define MUSB_ULPI_RDN_WR       (1 << 2)
+
+/* TESTMODE */
+#define MUSB_TEST_FORCE_HOST   0x80
+#define MUSB_TEST_FIFO_ACCESS  0x40
+#define MUSB_TEST_FORCE_FS     0x20
+#define MUSB_TEST_FORCE_HS     0x10
+#define MUSB_TEST_PACKET       0x08
+#define MUSB_TEST_K            0x04
+#define MUSB_TEST_J            0x02
+#define MUSB_TEST_SE0_NAK      0x01
+
+/* Allocate for double-packet buffering (effectively doubles assigned _SIZE) */
+#define MUSB_FIFOSZ_DPB        0x10
+/* Allocation size (8, 16, 32, ... 4096) */
+#define MUSB_FIFOSZ_SIZE       0x0f
+
+/* CSR0 */
+#define MUSB_CSR0_FLUSHFIFO    0x0100
+#define MUSB_CSR0_TXPKTRDY     0x0002
+#define MUSB_CSR0_RXPKTRDY     0x0001
+
+/* CSR0 in Peripheral mode */
+#define MUSB_CSR0_P_SVDSETUPEND        0x0080
+#define MUSB_CSR0_P_SVDRXPKTRDY        0x0040
+#define MUSB_CSR0_P_SENDSTALL  0x0020
+#define MUSB_CSR0_P_SETUPEND   0x0010
+#define MUSB_CSR0_P_DATAEND    0x0008
+#define MUSB_CSR0_P_SENTSTALL  0x0004
+
+/* CSR0 in Host mode */
+#define MUSB_CSR0_H_DIS_PING           0x0800
+#define MUSB_CSR0_H_WR_DATATOGGLE      0x0400  /* Set to allow setting: */
+#define MUSB_CSR0_H_DATATOGGLE         0x0200  /* Data toggle control */
+#define MUSB_CSR0_H_NAKTIMEOUT         0x0080
+#define MUSB_CSR0_H_STATUSPKT          0x0040
+#define MUSB_CSR0_H_REQPKT             0x0020
+#define MUSB_CSR0_H_ERROR              0x0010
+#define MUSB_CSR0_H_SETUPPKT           0x0008
+#define MUSB_CSR0_H_RXSTALL            0x0004
+
+/* CSR0 bits to avoid zeroing (write zero clears, write 1 ignored) */
+#define MUSB_CSR0_P_WZC_BITS   \
+       (MUSB_CSR0_P_SENTSTALL)
+#define MUSB_CSR0_H_WZC_BITS   \
+       (MUSB_CSR0_H_NAKTIMEOUT | MUSB_CSR0_H_RXSTALL \
+       | MUSB_CSR0_RXPKTRDY)
+
+/* TxType/RxType */
+#define MUSB_TYPE_SPEED                0xc0
+#define MUSB_TYPE_SPEED_SHIFT  6
+#define MUSB_TYPE_PROTO                0x30    /* Implicitly zero for ep0 */
+#define MUSB_TYPE_PROTO_SHIFT  4
+#define MUSB_TYPE_REMOTE_END   0xf     /* Implicitly zero for ep0 */
+
+/* CONFIGDATA */
+#define MUSB_CONFIGDATA_MPRXE          0x80    /* Auto bulk pkt combining */
+#define MUSB_CONFIGDATA_MPTXE          0x40    /* Auto bulk pkt splitting */
+#define MUSB_CONFIGDATA_BIGENDIAN      0x20
+#define MUSB_CONFIGDATA_HBRXE          0x10    /* HB-ISO for RX */
+#define MUSB_CONFIGDATA_HBTXE          0x08    /* HB-ISO for TX */
+#define MUSB_CONFIGDATA_DYNFIFO                0x04    /* Dynamic FIFO sizing */
+#define MUSB_CONFIGDATA_SOFTCONE       0x02    /* SoftConnect */
+#define MUSB_CONFIGDATA_UTMIDW         0x01    /* Data width 0/1 => 8/16bits */
+
+/* TXCSR in Peripheral and Host mode */
+#define MUSB_TXCSR_AUTOSET             0x8000
+#define MUSB_TXCSR_DMAENAB             0x1000
+#define MUSB_TXCSR_FRCDATATOG          0x0800
+#define MUSB_TXCSR_DMAMODE             0x0400
+#define MUSB_TXCSR_CLRDATATOG          0x0040
+#define MUSB_TXCSR_FLUSHFIFO           0x0008
+#define MUSB_TXCSR_FIFONOTEMPTY                0x0002
+#define MUSB_TXCSR_TXPKTRDY            0x0001
+
+/* TXCSR in Peripheral mode */
+#define MUSB_TXCSR_P_ISO               0x4000
+#define MUSB_TXCSR_P_INCOMPTX          0x0080
+#define MUSB_TXCSR_P_SENTSTALL         0x0020
+#define MUSB_TXCSR_P_SENDSTALL         0x0010
+#define MUSB_TXCSR_P_UNDERRUN          0x0004
+
+/* TXCSR in Host mode */
+#define MUSB_TXCSR_H_WR_DATATOGGLE     0x0200
+#define MUSB_TXCSR_H_DATATOGGLE                0x0100
+#define MUSB_TXCSR_H_NAKTIMEOUT                0x0080
+#define MUSB_TXCSR_H_RXSTALL           0x0020
+#define MUSB_TXCSR_H_ERROR             0x0004
+
+/* TXCSR bits to avoid zeroing (write zero clears, write 1 ignored) */
+#define MUSB_TXCSR_P_WZC_BITS  \
+       (MUSB_TXCSR_P_INCOMPTX | MUSB_TXCSR_P_SENTSTALL \
+       | MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_FIFONOTEMPTY)
+#define MUSB_TXCSR_H_WZC_BITS  \
+       (MUSB_TXCSR_H_NAKTIMEOUT | MUSB_TXCSR_H_RXSTALL \
+       | MUSB_TXCSR_H_ERROR | MUSB_TXCSR_FIFONOTEMPTY)
+
+/* RXCSR in Peripheral and Host mode */
+#define MUSB_RXCSR_AUTOCLEAR           0x8000
+#define MUSB_RXCSR_DMAENAB             0x2000
+#define MUSB_RXCSR_DISNYET             0x1000
+#define MUSB_RXCSR_PID_ERR             0x1000
+#define MUSB_RXCSR_DMAMODE             0x0800
+#define MUSB_RXCSR_INCOMPRX            0x0100
+#define MUSB_RXCSR_CLRDATATOG          0x0080
+#define MUSB_RXCSR_FLUSHFIFO           0x0010
+#define MUSB_RXCSR_DATAERROR           0x0008
+#define MUSB_RXCSR_FIFOFULL            0x0002
+#define MUSB_RXCSR_RXPKTRDY            0x0001
+
+/* RXCSR in Peripheral mode */
+#define MUSB_RXCSR_P_ISO               0x4000
+#define MUSB_RXCSR_P_SENTSTALL         0x0040
+#define MUSB_RXCSR_P_SENDSTALL         0x0020
+#define MUSB_RXCSR_P_OVERRUN           0x0004
+
+/* RXCSR in Host mode */
+#define MUSB_RXCSR_H_AUTOREQ           0x4000
+#define MUSB_RXCSR_H_WR_DATATOGGLE     0x0400
+#define MUSB_RXCSR_H_DATATOGGLE                0x0200
+#define MUSB_RXCSR_H_RXSTALL           0x0040
+#define MUSB_RXCSR_H_REQPKT            0x0020
+#define MUSB_RXCSR_H_ERROR             0x0004
+
+/* RXCSR bits to avoid zeroing (write zero clears, write 1 ignored) */
+#define MUSB_RXCSR_P_WZC_BITS  \
+       (MUSB_RXCSR_P_SENTSTALL | MUSB_RXCSR_P_OVERRUN \
+       | MUSB_RXCSR_RXPKTRDY)
+#define MUSB_RXCSR_H_WZC_BITS  \
+       (MUSB_RXCSR_H_RXSTALL | MUSB_RXCSR_H_ERROR \
+       | MUSB_RXCSR_DATAERROR | MUSB_RXCSR_RXPKTRDY)
+
+/* HUBADDR */
+#define MUSB_HUBADDR_MULTI_TT          0x80
+
+
+#ifndef CONFIG_BLACKFIN
+
+/*
+ * Common USB registers
+ */
+
+#define MUSB_FADDR             0x00    /* 8-bit */
+#define MUSB_POWER             0x01    /* 8-bit */
+
+#define MUSB_INTRTX            0x02    /* 16-bit */
+#define MUSB_INTRRX            0x04
+#define MUSB_INTRTXE           0x06
+#define MUSB_INTRRXE           0x08
+#define MUSB_INTRUSB           0x0A    /* 8 bit */
+#define MUSB_INTRUSBE          0x0B    /* 8 bit */
+#define MUSB_FRAME             0x0C
+#define MUSB_INDEX             0x0E    /* 8 bit */
+#define MUSB_TESTMODE          0x0F    /* 8 bit */
+
+/* Get offset for a given FIFO from musb->mregs */
+#if defined(CONFIG_USB_MUSB_TUSB6010) ||       \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
+#define MUSB_FIFO_OFFSET(epnum)        (0x200 + ((epnum) * 0x20))
+#else
+#define MUSB_FIFO_OFFSET(epnum)        (0x20 + ((epnum) * 4))
+#endif
+
+/*
+ * Additional Control Registers
+ */
+
+#define MUSB_DEVCTL            0x60    /* 8 bit */
+
+/* These are always controlled through the INDEX register */
+#define MUSB_TXFIFOSZ          0x62    /* 8-bit (see masks) */
+#define MUSB_RXFIFOSZ          0x63    /* 8-bit (see masks) */
+#define MUSB_TXFIFOADD         0x64    /* 16-bit offset shifted right 3 */
+#define MUSB_RXFIFOADD         0x66    /* 16-bit offset shifted right 3 */
+
+/* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */
+#define MUSB_HWVERS            0x6C    /* 8 bit */
+#define MUSB_ULPI_BUSCONTROL   0x70    /* 8 bit */
+#define MUSB_ULPI_INT_MASK     0x72    /* 8 bit */
+#define MUSB_ULPI_INT_SRC      0x73    /* 8 bit */
+#define MUSB_ULPI_REG_DATA     0x74    /* 8 bit */
+#define MUSB_ULPI_REG_ADDR     0x75    /* 8 bit */
+#define MUSB_ULPI_REG_CONTROL  0x76    /* 8 bit */
+#define MUSB_ULPI_RAW_DATA     0x77    /* 8 bit */
+
+#define MUSB_EPINFO            0x78    /* 8 bit */
+#define MUSB_RAMINFO           0x79    /* 8 bit */
+#define MUSB_LINKINFO          0x7a    /* 8 bit */
+#define MUSB_VPLEN             0x7b    /* 8 bit */
+#define MUSB_HS_EOF1           0x7c    /* 8 bit */
+#define MUSB_FS_EOF1           0x7d    /* 8 bit */
+#define MUSB_LS_EOF1           0x7e    /* 8 bit */
+
+/* Offsets to endpoint registers */
+#define MUSB_TXMAXP            0x00
+#define MUSB_TXCSR             0x02
+#define MUSB_CSR0              MUSB_TXCSR      /* Re-used for EP0 */
+#define MUSB_RXMAXP            0x04
+#define MUSB_RXCSR             0x06
+#define MUSB_RXCOUNT           0x08
+#define MUSB_COUNT0            MUSB_RXCOUNT    /* Re-used for EP0 */
+#define MUSB_TXTYPE            0x0A
+#define MUSB_TYPE0             MUSB_TXTYPE     /* Re-used for EP0 */
+#define MUSB_TXINTERVAL                0x0B
+#define MUSB_NAKLIMIT0         MUSB_TXINTERVAL /* Re-used for EP0 */
+#define MUSB_RXTYPE            0x0C
+#define MUSB_RXINTERVAL                0x0D
+#define MUSB_FIFOSIZE          0x0F
+#define MUSB_CONFIGDATA                MUSB_FIFOSIZE   /* Re-used for EP0 */
+
+/* Offsets to endpoint registers in indexed model (using INDEX register) */
+#define MUSB_INDEXED_OFFSET(_epnum, _offset)   \
+       (0x10 + (_offset))
+
+/* Offsets to endpoint registers in flat models */
+#define MUSB_FLAT_OFFSET(_epnum, _offset)      \
+       (0x100 + (0x10*(_epnum)) + (_offset))
+
+#if defined(CONFIG_USB_MUSB_TUSB6010) ||       \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
+/* TUSB6010 EP0 configuration register is special */
+#define MUSB_TUSB_OFFSET(_epnum, _offset)      \
+       (0x10 + _offset)
+#include "tusb6010.h"          /* Needed "only" for TUSB_EP0_CONF */
+#endif
+
+#define MUSB_TXCSR_MODE                        0x2000
+
+/* "bus control"/target registers, for host side multipoint (external hubs) */
+#define MUSB_TXFUNCADDR                0x00
+#define MUSB_TXHUBADDR         0x02
+#define MUSB_TXHUBPORT         0x03
+
+#define MUSB_RXFUNCADDR                0x04
+#define MUSB_RXHUBADDR         0x06
+#define MUSB_RXHUBPORT         0x07
+
+#define MUSB_BUSCTL_OFFSET(_epnum, _offset) \
+       (0x80 + (8*(_epnum)) + (_offset))
+
+static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
+{
+       musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
+}
+
+static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off)
+{
+       musb_writew(mbase, MUSB_TXFIFOADD, c_off);
+}
+
+static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size)
+{
+       musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
+}
+
+static inline void  musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
+{
+       musb_writew(mbase, MUSB_RXFIFOADD, c_off);
+}
+
+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
+{
+       musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val);
+}
+
+static inline u8 musb_read_txfifosz(void __iomem *mbase)
+{
+       return musb_readb(mbase, MUSB_TXFIFOSZ);
+}
+
+static inline u16 musb_read_txfifoadd(void __iomem *mbase)
+{
+       return musb_readw(mbase, MUSB_TXFIFOADD);
+}
+
+static inline u8 musb_read_rxfifosz(void __iomem *mbase)
+{
+       return musb_readb(mbase, MUSB_RXFIFOSZ);
+}
+
+static inline u16  musb_read_rxfifoadd(void __iomem *mbase)
+{
+       return musb_readw(mbase, MUSB_RXFIFOADD);
+}
+
+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
+{
+       return musb_readb(mbase, MUSB_ULPI_BUSCONTROL);
+}
+
+static inline u8 musb_read_configdata(void __iomem *mbase)
+{
+       musb_writeb(mbase, MUSB_INDEX, 0);
+       return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA);
+}
+
+static inline u16 musb_read_hwvers(void __iomem *mbase)
+{
+       return musb_readw(mbase, MUSB_HWVERS);
+}
+
+static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
+{
+       return (MUSB_BUSCTL_OFFSET(i, 0) + mbase);
+}
+
+static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+               u8 qh_addr_reg)
+{
+       musb_writeb(ep_target_regs, MUSB_RXFUNCADDR, qh_addr_reg);
+}
+
+static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+               u8 qh_h_addr_reg)
+{
+       musb_writeb(ep_target_regs, MUSB_RXHUBADDR, qh_h_addr_reg);
+}
+
+static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+               u8 qh_h_port_reg)
+{
+       musb_writeb(ep_target_regs, MUSB_RXHUBPORT, qh_h_port_reg);
+}
+
+static inline void  musb_write_txfunaddr(void __iomem *mbase, u8 epnum,
+               u8 qh_addr_reg)
+{
+       musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR),
+                       qh_addr_reg);
+}
+
+static inline void  musb_write_txhubaddr(void __iomem *mbase, u8 epnum,
+               u8 qh_addr_reg)
+{
+       musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR),
+                       qh_addr_reg);
+}
+
+static inline void  musb_write_txhubport(void __iomem *mbase, u8 epnum,
+               u8 qh_h_port_reg)
+{
+       musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT),
+                       qh_h_port_reg);
+}
+
+static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum)
+{
+       return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR));
+}
+
+static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum)
+{
+       return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR));
+}
+
+static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum)
+{
+       return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT));
+}
+
+static inline u8  musb_read_txfunaddr(void __iomem *mbase, u8 epnum)
+{
+       return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR));
+}
+
+static inline u8  musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
+{
+       return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR));
+}
+
+static inline u8  musb_read_txhubport(void __iomem *mbase, u8 epnum)
+{
+       return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT));
+}
+
+#else /* CONFIG_BLACKFIN */
+
+#define USB_BASE               USB_FADDR
+#define USB_OFFSET(reg)                (reg - USB_BASE)
+
+/*
+ * Common USB registers
+ */
+#define MUSB_FADDR             USB_OFFSET(USB_FADDR)   /* 8-bit */
+#define MUSB_POWER             USB_OFFSET(USB_POWER)   /* 8-bit */
+#define MUSB_INTRTX            USB_OFFSET(USB_INTRTX)  /* 16-bit */
+#define MUSB_INTRRX            USB_OFFSET(USB_INTRRX)
+#define MUSB_INTRTXE           USB_OFFSET(USB_INTRTXE)
+#define MUSB_INTRRXE           USB_OFFSET(USB_INTRRXE)
+#define MUSB_INTRUSB           USB_OFFSET(USB_INTRUSB) /* 8 bit */
+#define MUSB_INTRUSBE          USB_OFFSET(USB_INTRUSBE)/* 8 bit */
+#define MUSB_FRAME             USB_OFFSET(USB_FRAME)
+#define MUSB_INDEX             USB_OFFSET(USB_INDEX)   /* 8 bit */
+#define MUSB_TESTMODE          USB_OFFSET(USB_TESTMODE)/* 8 bit */
+
+/* Get offset for a given FIFO from musb->mregs */
+#define MUSB_FIFO_OFFSET(epnum)        \
+       (USB_OFFSET(USB_EP0_FIFO) + ((epnum) * 8))
+
+/*
+ * Additional Control Registers
+ */
+
+#define MUSB_DEVCTL            USB_OFFSET(USB_OTG_DEV_CTL)     /* 8 bit */
+
+#define MUSB_LINKINFO          USB_OFFSET(USB_LINKINFO)/* 8 bit */
+#define MUSB_VPLEN             USB_OFFSET(USB_VPLEN)   /* 8 bit */
+#define MUSB_HS_EOF1           USB_OFFSET(USB_HS_EOF1) /* 8 bit */
+#define MUSB_FS_EOF1           USB_OFFSET(USB_FS_EOF1) /* 8 bit */
+#define MUSB_LS_EOF1           USB_OFFSET(USB_LS_EOF1) /* 8 bit */
+
+/* Offsets to endpoint registers */
+#define MUSB_TXMAXP            0x00
+#define MUSB_TXCSR             0x04
+#define MUSB_CSR0              MUSB_TXCSR      /* Re-used for EP0 */
+#define MUSB_RXMAXP            0x08
+#define MUSB_RXCSR             0x0C
+#define MUSB_RXCOUNT           0x10
+#define MUSB_COUNT0            MUSB_RXCOUNT    /* Re-used for EP0 */
+#define MUSB_TXTYPE            0x14
+#define MUSB_TYPE0             MUSB_TXTYPE     /* Re-used for EP0 */
+#define MUSB_TXINTERVAL                0x18
+#define MUSB_NAKLIMIT0         MUSB_TXINTERVAL /* Re-used for EP0 */
+#define MUSB_RXTYPE            0x1C
+#define MUSB_RXINTERVAL                0x20
+#define MUSB_TXCOUNT           0x28
+
+/* Offsets to endpoint registers in indexed model (using INDEX register) */
+#define MUSB_INDEXED_OFFSET(_epnum, _offset)   \
+       (0x40 + (_offset))
+
+/* Offsets to endpoint registers in flat models */
+#define MUSB_FLAT_OFFSET(_epnum, _offset)      \
+       (USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset))
+
+/* Not implemented - HW has separate Tx/Rx FIFO */
+#define MUSB_TXCSR_MODE                        0x0000
+
+static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
+{
+}
+
+static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off)
+{
+}
+
+static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size)
+{
+}
+
+static inline void  musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
+{
+}
+
+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
+{
+}
+
+static inline u8 musb_read_txfifosz(void __iomem *mbase)
+{
+       return 0;
+}
+
+static inline u16 musb_read_txfifoadd(void __iomem *mbase)
+{
+       return 0;
+}
+
+static inline u8 musb_read_rxfifosz(void __iomem *mbase)
+{
+       return 0;
+}
+
+static inline u16  musb_read_rxfifoadd(void __iomem *mbase)
+{
+       return 0;
+}
+
+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
+{
+       return 0;
+}
+
+static inline u8 musb_read_configdata(void __iomem *mbase)
+{
+       return 0;
+}
+
+static inline u16 musb_read_hwvers(void __iomem *mbase)
+{
+       /*
+        * This register is invisible on Blackfin, actually the MUSB
+        * RTL version of Blackfin is 1.9, so just harcode its value.
+        */
+       return MUSB_HWVERS_1900;
+}
+
+static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
+{
+       return NULL;
+}
+
+static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+               u8 qh_addr_req)
+{
+}
+
+static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+               u8 qh_h_addr_reg)
+{
+}
+
+static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+               u8 qh_h_port_reg)
+{
+}
+
+static inline void  musb_write_txfunaddr(void __iomem *mbase, u8 epnum,
+               u8 qh_addr_reg)
+{
+}
+
+static inline void  musb_write_txhubaddr(void __iomem *mbase, u8 epnum,
+               u8 qh_addr_reg)
+{
+}
+
+static inline void  musb_write_txhubport(void __iomem *mbase, u8 epnum,
+               u8 qh_h_port_reg)
+{
+}
+
+static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum)
+{
+       return 0;
+}
+
+static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum)
+{
+       return 0;
+}
+
+static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum)
+{
+       return 0;
+}
+
+static inline u8  musb_read_txfunaddr(void __iomem *mbase, u8 epnum)
+{
+       return 0;
+}
+
+static inline u8  musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
+{
+       return 0;
+}
+
+static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum)
+{
+       return 0;
+}
+
+#endif /* CONFIG_BLACKFIN */
+
+#endif /* __MUSB_REGS_H__ */
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
new file mode 100644 (file)
index 0000000..762cbc1
--- /dev/null
@@ -0,0 +1,237 @@
+#include <common.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#define __UBOOT__
+#include <usb.h>
+#include "linux-compat.h"
+#include "usb-compat.h"
+#include "musb_core.h"
+#include "musb_host.h"
+#include "musb_gadget.h"
+
+#ifdef CONFIG_MUSB_HOST
+static struct musb *host;
+static struct usb_hcd hcd;
+static enum usb_device_speed host_speed;
+
+static void musb_host_complete_urb(struct urb *urb)
+{
+       urb->dev->status &= ~USB_ST_NOT_PROC;
+       urb->dev->act_len = urb->actual_length;
+}
+
+static struct usb_host_endpoint hep;
+static struct urb urb;
+
+static struct urb *construct_urb(struct usb_device *dev, int endpoint_type,
+                               unsigned long pipe, void *buffer, int len,
+                               struct devrequest *setup, int interval)
+{
+       int epnum = usb_pipeendpoint(pipe);
+       int is_in = usb_pipein(pipe);
+
+       memset(&urb, 0, sizeof(struct urb));
+       memset(&hep, 0, sizeof(struct usb_host_endpoint));
+       INIT_LIST_HEAD(&hep.urb_list);
+       INIT_LIST_HEAD(&urb.urb_list);
+       urb.ep = &hep;
+       urb.complete = musb_host_complete_urb;
+       urb.status = -EINPROGRESS;
+       urb.dev = dev;
+       urb.pipe = pipe;
+       urb.transfer_buffer = buffer;
+       urb.transfer_dma = (unsigned long)buffer;
+       urb.transfer_buffer_length = len;
+       urb.setup_packet = (unsigned char *)setup;
+
+       urb.ep->desc.wMaxPacketSize =
+               __cpu_to_le16(is_in ? dev->epmaxpacketin[epnum] :
+                               dev->epmaxpacketout[epnum]);
+       urb.ep->desc.bmAttributes = endpoint_type;
+       urb.ep->desc.bEndpointAddress =
+               (is_in ? USB_DIR_IN : USB_DIR_OUT) | epnum;
+       urb.ep->desc.bInterval = interval;
+
+       return &urb;
+}
+
+#define MUSB_HOST_TIMEOUT      0x3ffffff
+
+static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
+{
+       struct musb *host = hcd->hcd_priv;
+       int ret;
+       int timeout;
+
+       ret = musb_urb_enqueue(hcd, urb, 0);
+       if (ret < 0) {
+               printf("Failed to enqueue URB to controller\n");
+               return ret;
+       }
+
+       timeout = MUSB_HOST_TIMEOUT;
+       do {
+               if (ctrlc())
+                       return -EIO;
+               host->isr(0, host);
+       } while ((urb->dev->status & USB_ST_NOT_PROC) && --timeout);
+
+       return urb->status;
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe,
+                       void *buffer, int len, struct devrequest *setup)
+{
+       struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_CONTROL, pipe,
+                                       buffer, len, setup, 0);
+
+       /* Fix speed for non hub-attached devices */
+       if (!dev->parent)
+               dev->speed = host_speed;
+
+       return submit_urb(&hcd, urb);
+}
+
+
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+                                       void *buffer, int len)
+{
+       struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_BULK, pipe,
+                                       buffer, len, NULL, 0);
+       return submit_urb(&hcd, urb);
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe,
+                               void *buffer, int len, int interval)
+{
+       struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_INT, pipe,
+                                       buffer, len, NULL, interval);
+       return submit_urb(&hcd, urb);
+}
+
+int usb_lowlevel_init(int index, void **controller)
+{
+       u8 power;
+       void *mbase;
+       int timeout = MUSB_HOST_TIMEOUT;
+
+       if (!host) {
+               printf("MUSB host is not registered\n");
+               return -ENODEV;
+       }
+
+       musb_start(host);
+       mbase = host->mregs;
+       do {
+               if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM)
+                       break;
+       } while (--timeout);
+       if (!timeout)
+               return -ENODEV;
+
+       power = musb_readb(mbase, MUSB_POWER);
+       musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
+       udelay(30000);
+       power = musb_readb(mbase, MUSB_POWER);
+       musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
+       host->isr(0, host);
+       host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
+                       USB_SPEED_HIGH :
+                       (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
+                       USB_SPEED_FULL : USB_SPEED_LOW;
+       host->is_active = 1;
+       hcd.hcd_priv = host;
+
+       return 0;
+}
+
+int usb_lowlevel_stop(int index)
+{
+       if (!host) {
+               printf("MUSB host is not registered\n");
+               return -ENODEV;
+       }
+
+       musb_stop(host);
+       return 0;
+}
+#endif /* CONFIG_MUSB_HOST */
+
+#ifdef CONFIG_MUSB_GADGET
+static struct musb *gadget;
+
+int usb_gadget_handle_interrupts(void)
+{
+       if (!gadget || !gadget->isr)
+               return -EINVAL;
+
+       return gadget->isr(0, gadget);
+}
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+       int ret;
+
+       if (!driver || driver->speed < USB_SPEED_HIGH || !driver->bind ||
+           !driver->setup) {
+               printf("bad parameter.\n");
+               return -EINVAL;
+       }
+
+       if (!gadget) {
+               printf("Controller uninitialized\n");
+               return -ENXIO;
+       }
+
+       ret = musb_gadget_start(&gadget->g, driver);
+       if (ret < 0) {
+               printf("gadget_start failed with %d\n", ret);
+               return ret;
+       }
+
+       ret = driver->bind(&gadget->g);
+       if (ret < 0) {
+               printf("bind failed with %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+       /* TODO: implement me */
+       return 0;
+}
+#endif /* CONFIG_MUSB_GADGET */
+
+int musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
+                       void *ctl_regs)
+{
+       struct musb **musbp;
+
+       switch (plat->mode) {
+#ifdef CONFIG_MUSB_HOST
+       case MUSB_HOST:
+               musbp = &host;
+               break;
+#endif
+#ifdef CONFIG_MUSB_GADGET
+       case MUSB_PERIPHERAL:
+               musbp = &gadget;
+               break;
+#endif
+       default:
+               return -EINVAL;
+       }
+
+       *musbp = musb_init_controller(plat, (struct device *)bdata, ctl_regs);
+       if (!musbp) {
+               printf("Failed to init the controller\n");
+               return -EIO;
+       }
+
+       return 0;
+}
diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c
new file mode 100644 (file)
index 0000000..b1c4dc7
--- /dev/null
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2005-2007 by Texas Instruments
+ * Some code has been taken from tusb6010.c
+ * Copyrights for that are attributable to:
+ * Copyright (C) 2006 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ *
+ * This file is part of the Inventra Controller Driver for Linux.
+ *
+ * The Inventra Controller Driver for Linux 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.
+ *
+ * The Inventra Controller Driver for Linux 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 The Inventra Controller Driver for Linux ; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#define __UBOOT__
+#ifndef __UBOOT__
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
+#include <linux/err.h>
+#include <linux/usb/musb-omap.h>
+#else
+#include <common.h>
+#include <asm/omap_musb.h>
+#include <twl4030.h>
+#include "linux-compat.h"
+#endif
+
+#include "musb_core.h"
+#include "omap2430.h"
+
+#ifndef __UBOOT__
+struct omap2430_glue {
+       struct device           *dev;
+       struct platform_device  *musb;
+       enum omap_musb_vbus_id_status status;
+       struct work_struct      omap_musb_mailbox_work;
+};
+#define glue_to_musb(g)                platform_get_drvdata(g->musb)
+
+struct omap2430_glue           *_glue;
+
+static struct timer_list musb_idle_timer;
+
+static void musb_do_idle(unsigned long _musb)
+{
+       struct musb     *musb = (void *)_musb;
+       unsigned long   flags;
+       u8      power;
+       u8      devctl;
+
+       spin_lock_irqsave(&musb->lock, flags);
+
+       switch (musb->xceiv->state) {
+       case OTG_STATE_A_WAIT_BCON:
+
+               devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+               if (devctl & MUSB_DEVCTL_BDEVICE) {
+                       musb->xceiv->state = OTG_STATE_B_IDLE;
+                       MUSB_DEV_MODE(musb);
+               } else {
+                       musb->xceiv->state = OTG_STATE_A_IDLE;
+                       MUSB_HST_MODE(musb);
+               }
+               break;
+       case OTG_STATE_A_SUSPEND:
+               /* finish RESUME signaling? */
+               if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
+                       power = musb_readb(musb->mregs, MUSB_POWER);
+                       power &= ~MUSB_POWER_RESUME;
+                       dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power);
+                       musb_writeb(musb->mregs, MUSB_POWER, power);
+                       musb->is_active = 1;
+                       musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
+                                               | MUSB_PORT_STAT_RESUME);
+                       musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
+                       usb_hcd_poll_rh_status(musb_to_hcd(musb));
+                       /* NOTE: it might really be A_WAIT_BCON ... */
+                       musb->xceiv->state = OTG_STATE_A_HOST;
+               }
+               break;
+       case OTG_STATE_A_HOST:
+               devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+               if (devctl &  MUSB_DEVCTL_BDEVICE)
+                       musb->xceiv->state = OTG_STATE_B_IDLE;
+               else
+                       musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
+       default:
+               break;
+       }
+       spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+
+static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
+{
+       unsigned long           default_timeout = jiffies + msecs_to_jiffies(3);
+       static unsigned long    last_timer;
+
+       if (timeout == 0)
+               timeout = default_timeout;
+
+       /* Never idle if active, or when VBUS timeout is not set as host */
+       if (musb->is_active || ((musb->a_wait_bcon == 0)
+                       && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
+               dev_dbg(musb->controller, "%s active, deleting timer\n",
+                       otg_state_string(musb->xceiv->state));
+               del_timer(&musb_idle_timer);
+               last_timer = jiffies;
+               return;
+       }
+
+       if (time_after(last_timer, timeout)) {
+               if (!timer_pending(&musb_idle_timer))
+                       last_timer = timeout;
+               else {
+                       dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n");
+                       return;
+               }
+       }
+       last_timer = timeout;
+
+       dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
+               otg_state_string(musb->xceiv->state),
+               (unsigned long)jiffies_to_msecs(timeout - jiffies));
+       mod_timer(&musb_idle_timer, timeout);
+}
+
+static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
+{
+       struct usb_otg  *otg = musb->xceiv->otg;
+       u8              devctl;
+       unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+       int ret = 1;
+       /* HDRC controls CPEN, but beware current surges during device
+        * connect.  They can trigger transient overcurrent conditions
+        * that must be ignored.
+        */
+
+       devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+
+       if (is_on) {
+               if (musb->xceiv->state == OTG_STATE_A_IDLE) {
+                       /* start the session */
+                       devctl |= MUSB_DEVCTL_SESSION;
+                       musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+                       /*
+                        * Wait for the musb to set as A device to enable the
+                        * VBUS
+                        */
+                       while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
+
+                               cpu_relax();
+
+                               if (time_after(jiffies, timeout)) {
+                                       dev_err(musb->controller,
+                                       "configured as A device timeout");
+                                       ret = -EINVAL;
+                                       break;
+                               }
+                       }
+
+                       if (ret && otg->set_vbus)
+                               otg_set_vbus(otg, 1);
+               } else {
+                       musb->is_active = 1;
+                       otg->default_a = 1;
+                       musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+                       devctl |= MUSB_DEVCTL_SESSION;
+                       MUSB_HST_MODE(musb);
+               }
+       } else {
+               musb->is_active = 0;
+
+               /* NOTE:  we're skipping A_WAIT_VFALL -> A_IDLE and
+                * jumping right to B_IDLE...
+                */
+
+               otg->default_a = 0;
+               musb->xceiv->state = OTG_STATE_B_IDLE;
+               devctl &= ~MUSB_DEVCTL_SESSION;
+
+               MUSB_DEV_MODE(musb);
+       }
+       musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+       dev_dbg(musb->controller, "VBUS %s, devctl %02x "
+               /* otg %3x conf %08x prcm %08x */ "\n",
+               otg_state_string(musb->xceiv->state),
+               musb_readb(musb->mregs, MUSB_DEVCTL));
+}
+
+static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
+{
+       u8      devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+
+       devctl |= MUSB_DEVCTL_SESSION;
+       musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+       return 0;
+}
+#endif
+
+static inline void omap2430_low_level_exit(struct musb *musb)
+{
+       u32 l;
+
+       /* in any role */
+       l = musb_readl(musb->mregs, OTG_FORCESTDBY);
+       l |= ENABLEFORCE;       /* enable MSTANDBY */
+       musb_writel(musb->mregs, OTG_FORCESTDBY, l);
+}
+
+static inline void omap2430_low_level_init(struct musb *musb)
+{
+       u32 l;
+
+       l = musb_readl(musb->mregs, OTG_FORCESTDBY);
+       l &= ~ENABLEFORCE;      /* disable MSTANDBY */
+       musb_writel(musb->mregs, OTG_FORCESTDBY, l);
+}
+
+#ifndef __UBOOT__
+void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
+{
+       struct omap2430_glue    *glue = _glue;
+       struct musb             *musb = glue_to_musb(glue);
+
+       glue->status = status;
+       if (!musb) {
+               dev_err(glue->dev, "musb core is not yet ready\n");
+               return;
+       }
+
+       schedule_work(&glue->omap_musb_mailbox_work);
+}
+EXPORT_SYMBOL_GPL(omap_musb_mailbox);
+
+static void omap_musb_set_mailbox(struct omap2430_glue *glue)
+{
+       struct musb *musb = glue_to_musb(glue);
+       struct device *dev = musb->controller;
+       struct musb_hdrc_platform_data *pdata = dev->platform_data;
+       struct omap_musb_board_data *data = pdata->board_data;
+       struct usb_otg *otg = musb->xceiv->otg;
+
+       switch (glue->status) {
+       case OMAP_MUSB_ID_GROUND:
+               dev_dbg(dev, "ID GND\n");
+
+               otg->default_a = true;
+               musb->xceiv->state = OTG_STATE_A_IDLE;
+               musb->xceiv->last_event = USB_EVENT_ID;
+               if (!is_otg_enabled(musb) || musb->gadget_driver) {
+                       pm_runtime_get_sync(dev);
+                       usb_phy_init(musb->xceiv);
+                       omap2430_musb_set_vbus(musb, 1);
+               }
+               break;
+
+       case OMAP_MUSB_VBUS_VALID:
+               dev_dbg(dev, "VBUS Connect\n");
+
+               otg->default_a = false;
+               musb->xceiv->state = OTG_STATE_B_IDLE;
+               musb->xceiv->last_event = USB_EVENT_VBUS;
+               if (musb->gadget_driver)
+                       pm_runtime_get_sync(dev);
+               usb_phy_init(musb->xceiv);
+               break;
+
+       case OMAP_MUSB_ID_FLOAT:
+       case OMAP_MUSB_VBUS_OFF:
+               dev_dbg(dev, "VBUS Disconnect\n");
+
+               musb->xceiv->last_event = USB_EVENT_NONE;
+               if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
+                       if (musb->gadget_driver) {
+                               pm_runtime_mark_last_busy(dev);
+                               pm_runtime_put_autosuspend(dev);
+                       }
+
+               if (data->interface_type == MUSB_INTERFACE_UTMI) {
+                       if (musb->xceiv->otg->set_vbus)
+                               otg_set_vbus(musb->xceiv->otg, 0);
+               }
+               usb_phy_shutdown(musb->xceiv);
+               break;
+       default:
+               dev_dbg(dev, "ID float\n");
+       }
+}
+
+
+static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
+{
+       struct omap2430_glue *glue = container_of(mailbox_work,
+                               struct omap2430_glue, omap_musb_mailbox_work);
+       omap_musb_set_mailbox(glue);
+}
+#endif
+
+static int omap2430_musb_init(struct musb *musb)
+{
+       u32 l;
+       int status = 0;
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
+       struct musb_hdrc_platform_data *plat = dev->platform_data;
+       struct omap_musb_board_data *data = plat->board_data;
+#else
+       struct omap_musb_board_data *data =
+               (struct omap_musb_board_data *)musb->controller;
+#endif
+
+
+#ifndef __UBOOT__
+       /* We require some kind of external transceiver, hooked
+        * up through ULPI.  TWL4030-family PMICs include one,
+        * which needs a driver, drivers aren't always needed.
+        */
+       musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv)) {
+               pr_err("HS USB OTG: no transceiver configured\n");
+               return -ENODEV;
+       }
+
+       status = pm_runtime_get_sync(dev);
+       if (status < 0) {
+               dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
+               goto err1;
+       }
+#endif
+
+       l = musb_readl(musb->mregs, OTG_INTERFSEL);
+
+       if (data->interface_type == MUSB_INTERFACE_UTMI) {
+               /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
+               l &= ~ULPI_12PIN;       /* Disable ULPI */
+               l |= UTMI_8BIT;         /* Enable UTMI  */
+       } else {
+               l |= ULPI_12PIN;
+       }
+
+       musb_writel(musb->mregs, OTG_INTERFSEL, l);
+
+       pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
+                       "sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
+                       musb_readl(musb->mregs, OTG_REVISION),
+                       musb_readl(musb->mregs, OTG_SYSCONFIG),
+                       musb_readl(musb->mregs, OTG_SYSSTATUS),
+                       musb_readl(musb->mregs, OTG_INTERFSEL),
+                       musb_readl(musb->mregs, OTG_SIMENABLE));
+
+#ifndef __UBOOT__
+       setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
+
+       if (glue->status != OMAP_MUSB_UNKNOWN)
+               omap_musb_set_mailbox(glue);
+
+       pm_runtime_put_noidle(musb->controller);
+#endif
+       return 0;
+
+err1:
+       return status;
+}
+
+static void omap2430_musb_enable(struct musb *musb)
+{
+#ifndef __UBOOT__
+       u8              devctl;
+       unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+       struct device *dev = musb->controller;
+       struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
+       struct musb_hdrc_platform_data *pdata = dev->platform_data;
+       struct omap_musb_board_data *data = pdata->board_data;
+
+       switch (glue->status) {
+
+       case OMAP_MUSB_ID_GROUND:
+               usb_phy_init(musb->xceiv);
+               if (data->interface_type != MUSB_INTERFACE_UTMI)
+                       break;
+               devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+               /* start the session */
+               devctl |= MUSB_DEVCTL_SESSION;
+               musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+               while (musb_readb(musb->mregs, MUSB_DEVCTL) &
+                               MUSB_DEVCTL_BDEVICE) {
+                       cpu_relax();
+
+                       if (time_after(jiffies, timeout)) {
+                               dev_err(dev, "configured as A device timeout");
+                               break;
+                       }
+               }
+               break;
+
+       case OMAP_MUSB_VBUS_VALID:
+               usb_phy_init(musb->xceiv);
+               break;
+
+       default:
+               break;
+       }
+#else
+#ifdef CONFIG_TWL4030_USB
+       if (twl4030_usb_ulpi_init()) {
+               serial_printf("ERROR: %s Could not initialize PHY\n",
+                               __PRETTY_FUNCTION__);
+       }
+#endif
+#endif
+}
+
+static void omap2430_musb_disable(struct musb *musb)
+{
+#ifndef __UBOOT__
+       struct device *dev = musb->controller;
+       struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
+
+       if (glue->status != OMAP_MUSB_UNKNOWN)
+               usb_phy_shutdown(musb->xceiv);
+#endif
+}
+
+static int omap2430_musb_exit(struct musb *musb)
+{
+       del_timer_sync(&musb_idle_timer);
+
+       omap2430_low_level_exit(musb);
+
+       return 0;
+}
+
+#ifndef __UBOOT__
+static const struct musb_platform_ops omap2430_ops = {
+#else
+const struct musb_platform_ops omap2430_ops = {
+#endif
+       .init           = omap2430_musb_init,
+       .exit           = omap2430_musb_exit,
+
+#ifndef __UBOOT__
+       .set_mode       = omap2430_musb_set_mode,
+       .try_idle       = omap2430_musb_try_idle,
+
+       .set_vbus       = omap2430_musb_set_vbus,
+#endif
+
+       .enable         = omap2430_musb_enable,
+       .disable        = omap2430_musb_disable,
+};
+
+#ifndef __UBOOT__
+static u64 omap2430_dmamask = DMA_BIT_MASK(32);
+
+static int __devinit omap2430_probe(struct platform_device *pdev)
+{
+       struct musb_hdrc_platform_data  *pdata = pdev->dev.platform_data;
+       struct platform_device          *musb;
+       struct omap2430_glue            *glue;
+       int                             ret = -ENOMEM;
+
+       glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
+       if (!glue) {
+               dev_err(&pdev->dev, "failed to allocate glue context\n");
+               goto err0;
+       }
+
+       musb = platform_device_alloc("musb-hdrc", -1);
+       if (!musb) {
+               dev_err(&pdev->dev, "failed to allocate musb device\n");
+               goto err0;
+       }
+
+       musb->dev.parent                = &pdev->dev;
+       musb->dev.dma_mask              = &omap2430_dmamask;
+       musb->dev.coherent_dma_mask     = omap2430_dmamask;
+
+       glue->dev                       = &pdev->dev;
+       glue->musb                      = musb;
+       glue->status                    = OMAP_MUSB_UNKNOWN;
+
+       pdata->platform_ops             = &omap2430_ops;
+
+       platform_set_drvdata(pdev, glue);
+
+       /*
+        * REVISIT if we ever have two instances of the wrapper, we will be
+        * in big trouble
+        */
+       _glue   = glue;
+
+       INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
+
+       ret = platform_device_add_resources(musb, pdev->resource,
+                       pdev->num_resources);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add resources\n");
+               goto err1;
+       }
+
+       ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add platform_data\n");
+               goto err1;
+       }
+
+       pm_runtime_enable(&pdev->dev);
+
+       ret = platform_device_add(musb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register musb device\n");
+               goto err1;
+       }
+
+       return 0;
+
+err1:
+       platform_device_put(musb);
+
+err0:
+       return ret;
+}
+
+static int __devexit omap2430_remove(struct platform_device *pdev)
+{
+       struct omap2430_glue            *glue = platform_get_drvdata(pdev);
+
+       cancel_work_sync(&glue->omap_musb_mailbox_work);
+       platform_device_del(glue->musb);
+       platform_device_put(glue->musb);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int omap2430_runtime_suspend(struct device *dev)
+{
+       struct omap2430_glue            *glue = dev_get_drvdata(dev);
+       struct musb                     *musb = glue_to_musb(glue);
+
+       if (musb) {
+               musb->context.otg_interfsel = musb_readl(musb->mregs,
+                               OTG_INTERFSEL);
+
+               omap2430_low_level_exit(musb);
+               usb_phy_set_suspend(musb->xceiv, 1);
+       }
+
+       return 0;
+}
+
+static int omap2430_runtime_resume(struct device *dev)
+{
+       struct omap2430_glue            *glue = dev_get_drvdata(dev);
+       struct musb                     *musb = glue_to_musb(glue);
+
+       if (musb) {
+               omap2430_low_level_init(musb);
+               musb_writel(musb->mregs, OTG_INTERFSEL,
+                               musb->context.otg_interfsel);
+
+               usb_phy_set_suspend(musb->xceiv, 0);
+       }
+
+       return 0;
+}
+
+static struct dev_pm_ops omap2430_pm_ops = {
+       .runtime_suspend = omap2430_runtime_suspend,
+       .runtime_resume = omap2430_runtime_resume,
+};
+
+#define DEV_PM_OPS     (&omap2430_pm_ops)
+#else
+#define DEV_PM_OPS     NULL
+#endif
+
+static struct platform_driver omap2430_driver = {
+       .probe          = omap2430_probe,
+       .remove         = __devexit_p(omap2430_remove),
+       .driver         = {
+               .name   = "musb-omap2430",
+               .pm     = DEV_PM_OPS,
+       },
+};
+
+MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
+MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
+MODULE_LICENSE("GPL v2");
+
+static int __init omap2430_init(void)
+{
+       return platform_driver_register(&omap2430_driver);
+}
+subsys_initcall(omap2430_init);
+
+static void __exit omap2430_exit(void)
+{
+       platform_driver_unregister(&omap2430_driver);
+}
+module_exit(omap2430_exit);
+#endif
diff --git a/drivers/usb/musb-new/omap2430.h b/drivers/usb/musb-new/omap2430.h
new file mode 100644 (file)
index 0000000..3b795c2
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005-2006 by Texas Instruments
+ *
+ * The Inventra Controller Driver for Linux 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 __MUSB_OMAP243X_H__
+#define __MUSB_OMAP243X_H__
+
+#ifndef __UBOOT__
+#include <plat/usb.h>
+#else
+#undef RESETDONE
+#endif
+
+/*
+ * OMAP2430-specific definitions
+ */
+
+#define OTG_REVISION           0x400
+
+#define OTG_SYSCONFIG          0x404
+#      define  MIDLEMODE       12      /* bit position */
+#      define  FORCESTDBY              (0 << MIDLEMODE)
+#      define  NOSTDBY                 (1 << MIDLEMODE)
+#      define  SMARTSTDBY              (2 << MIDLEMODE)
+
+#      define  SIDLEMODE               3       /* bit position */
+#      define  FORCEIDLE               (0 << SIDLEMODE)
+#      define  NOIDLE                  (1 << SIDLEMODE)
+#      define  SMARTIDLE               (2 << SIDLEMODE)
+
+#      define  ENABLEWAKEUP            (1 << 2)
+#      define  SOFTRST                 (1 << 1)
+#      define  AUTOIDLE                (1 << 0)
+
+#define OTG_SYSSTATUS          0x408
+#      define  RESETDONE               (1 << 0)
+
+#define OTG_INTERFSEL          0x40c
+#      define  EXTCP                   (1 << 2)
+#      define  PHYSEL                  0       /* bit position */
+#      define  UTMI_8BIT               (0 << PHYSEL)
+#      define  ULPI_12PIN              (1 << PHYSEL)
+#      define  ULPI_8PIN               (2 << PHYSEL)
+
+#define OTG_SIMENABLE          0x410
+#      define  TM1                     (1 << 0)
+
+#define OTG_FORCESTDBY         0x414
+#      define  ENABLEFORCE             (1 << 0)
+
+#endif /* __MUSB_OMAP243X_H__ */
diff --git a/drivers/usb/musb-new/usb-compat.h b/drivers/usb/musb-new/usb-compat.h
new file mode 100644 (file)
index 0000000..27f656f
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef __USB_COMPAT_H__
+#define __USB_COMPAT_H__
+
+#include "usb.h"
+
+struct usb_hcd {
+       void *hcd_priv;
+};
+
+struct usb_host_endpoint {
+       struct usb_endpoint_descriptor          desc;
+       struct list_head urb_list;
+       void *hcpriv;
+};
+
+/*
+ * urb->transfer_flags:
+ *
+ * Note: URB_DIR_IN/OUT is automatically set in usb_submit_urb().
+ */
+#define URB_SHORT_NOT_OK       0x0001  /* report short reads as errors */
+#define URB_ZERO_PACKET                0x0040  /* Finish bulk OUT with short packet */
+
+struct urb;
+
+typedef void (*usb_complete_t)(struct urb *);
+
+struct urb {
+       void *hcpriv;                   /* private data for host controller */
+       struct list_head urb_list;      /* list head for use by the urb's
+                                        * current owner */
+       struct usb_device *dev;         /* (in) pointer to associated device */
+       struct usb_host_endpoint *ep;   /* (internal) pointer to endpoint */
+       unsigned int pipe;              /* (in) pipe information */
+       int status;                     /* (return) non-ISO status */
+       unsigned int transfer_flags;    /* (in) URB_SHORT_NOT_OK | ...*/
+       void *transfer_buffer;          /* (in) associated data buffer */
+       dma_addr_t transfer_dma;        /* (in) dma addr for transfer_buffer */
+       u32 transfer_buffer_length;     /* (in) data buffer length */
+       u32 actual_length;              /* (return) actual transfer length */
+       unsigned char *setup_packet;    /* (in) setup packet (control only) */
+       int start_frame;                /* (modify) start frame (ISO) */
+       usb_complete_t complete;        /* (in) completion routine */
+};
+
+#define usb_hcd_link_urb_to_ep(hcd, urb)       ({              \
+       int ret = 0;                                            \
+       list_add_tail(&urb->urb_list, &urb->ep->urb_list);      \
+       ret; })
+#define usb_hcd_unlink_urb_from_ep(hcd, urb)   list_del_init(&urb->urb_list)
+
+static inline void usb_hcd_giveback_urb(struct usb_hcd *hcd,
+                                       struct urb *urb,
+                                       int status)
+{
+       urb->status = status;
+       if (urb->complete)
+               urb->complete(urb);
+}
+
+static inline int usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd,
+                                       struct urb *urb)
+{
+       /* TODO: add cache invalidation here */
+       return 0;
+}
+
+static inline u16 find_tt(struct usb_device *dev)
+{
+       u8 chid;
+       u8 hub;
+
+       /* Find out the nearest parent which is high speed */
+       while (dev->parent->parent != NULL)
+               if (dev->parent->speed != USB_SPEED_HIGH)
+                       dev = dev->parent;
+               else
+                       break;
+
+       /* determine the port address at that hub */
+       hub = dev->parent->devnum;
+       for (chid = 0; chid < USB_MAXCHILDREN; chid++)
+               if (dev->parent->children[chid] == dev)
+                       break;
+
+       return (hub << 8) | chid;
+}
+#endif /* __USB_COMPAT_H__ */
index e914369297047fcfcfa10ba0037fe30ab9820d83..ec8a038c74c10e08383b6854729ad72231049eaa 100644 (file)
@@ -34,7 +34,6 @@
 #ifndef __MUSB_HDRC_DEFS_H__
 #define __MUSB_HDRC_DEFS_H__
 
-#include <usb.h>
 #include <usb_defs.h>
 #include <asm/io.h>
 
@@ -145,7 +144,7 @@ struct musb_regs {
                struct musb_epN_regs epN;
        } ep[16];
 
-} __attribute__((packed, aligned(USB_DMA_MINALIGN)));
+} __attribute__((packed));
 #endif
 
 /*
index 06be38d1cf96928b043f0b92fedbc8ec4d91bb9c..60e03a4bf73a5d755a5d68f05b8198b4600746e8 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <common.h>
+#include <usb.h>
 #include "musb_hcd.h"
 
 /* MSC control transfers */
@@ -485,8 +486,8 @@ static int ctrlreq_in_status_phase(struct usb_device *dev)
  */
 static u8 get_dev_speed(struct usb_device *dev)
 {
-       return (dev->speed & USB_SPEED_HIGH) ? MUSB_TYPE_SPEED_HIGH :
-               ((dev->speed & USB_SPEED_LOW) ? MUSB_TYPE_SPEED_LOW :
+       return (dev->speed == USB_SPEED_HIGH) ? MUSB_TYPE_SPEED_HIGH :
+               ((dev->speed == USB_SPEED_LOW) ? MUSB_TYPE_SPEED_LOW :
                                                MUSB_TYPE_SPEED_FULL);
 }
 
index ebb6da823cee9e945da43e4f76b4549c59cbe7df..cc3022a2c73a9e8c6578b8ac99951ae50976633a 100644 (file)
@@ -39,6 +39,7 @@ COBJS-$(CONFIG_S6E8AX0) += s6e8ax0.o
 COBJS-$(CONFIG_S6E63D6) += s6e63d6.o
 COBJS-$(CONFIG_SED156X) += sed156x.o
 COBJS-$(CONFIG_VIDEO_AMBA) += amba.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
 COBJS-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o
index beb7fa396ea94dc60a071aa3b9ce70241b268798..b10ca4b67719b33368b540ef941e4e09ffd8349f 100644 (file)
@@ -51,6 +51,18 @@ short console_row;
 #define lcdc_readl(reg)                __raw_readl((reg))
 #define lcdc_writel(reg, val)  __raw_writel((val), (reg))
 
+/*
+ * the CLUT register map as following
+ * RCLUT(24 ~ 16), GCLUT(15 ~ 8), BCLUT(7 ~ 0)
+ */
+void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
+{
+       lcdc_writel(((red << LCDC_BASECLUT_RCLUT_Pos) & LCDC_BASECLUT_RCLUT_Msk)
+               | ((green << LCDC_BASECLUT_GCLUT_Pos) & LCDC_BASECLUT_GCLUT_Msk)
+               | ((blue << LCDC_BASECLUT_BCLUT_Pos) & LCDC_BASECLUT_BCLUT_Msk),
+               panel_info.mmio + ATMEL_LCDC_LUT(regno));
+}
+
 void lcd_ctrl_init(void *lcdbase)
 {
        unsigned long value;
index 9c4714d50a5a444aa7128f08805163f385994270..a0607cf433660d143acebe51846d48601d8bca8b 100644 (file)
@@ -153,7 +153,7 @@ int vcxk_init(unsigned long width, unsigned long height)
 #ifdef CONFIG_SYS_VCXK_DOUBLEBUFFERED
        double_bws_word  = (u_short *)double_bws;
        double_bws_long  = (u_long *)double_bws;
-       debug("%lx %lx %lx \n", double_bws, double_bws_word, double_bws_long);
+       debug("%px %px %px\n", double_bws, double_bws_word, double_bws_long);
 #endif
        display_width  = width;
        display_height = height;
index 9c67b63bf4504e2345f733a9cec5485a7f52be69..26f673a96a9b8937932df50395cecbac87b0e23f 100644 (file)
@@ -1515,6 +1515,13 @@ int video_display_bitmap(ulong bmp_image, int x, int y)
 
        padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3;
 
+       /*
+        * Just ignore elements which are completely beyond screen
+        * dimensions.
+        */
+       if ((x >= VIDEO_VISIBLE_COLS) || (y >= VIDEO_VISIBLE_ROWS))
+               return 0;
+
 #ifdef CONFIG_SPLASH_SCREEN_ALIGN
        if (x == BMP_ALIGN_CENTER)
                x = max(0, (VIDEO_VISIBLE_COLS - width) / 2);
@@ -2257,3 +2264,47 @@ int drv_video_init(void)
        /* Return success */
        return 1;
 }
+
+void video_position_cursor(unsigned col, unsigned row)
+{
+       console_col = min(col, CONSOLE_COLS - 1);
+       console_row = min(row, CONSOLE_ROWS - 1);
+}
+
+int video_get_pixel_width(void)
+{
+       return VIDEO_VISIBLE_COLS;
+}
+
+int video_get_pixel_height(void)
+{
+       return VIDEO_VISIBLE_ROWS;
+}
+
+int video_get_screen_rows(void)
+{
+       return CONSOLE_ROWS;
+}
+
+int video_get_screen_columns(void)
+{
+       return CONSOLE_COLS;
+}
+
+void video_clear(void)
+{
+       if (!video_fb_address)
+               return;
+#ifdef VIDEO_HW_RECTFILL
+       video_hw_rectfill(VIDEO_PIXEL_SIZE,     /* bytes per pixel */
+                         0,                    /* dest pos x */
+                         0,                    /* dest pos y */
+                         VIDEO_VISIBLE_COLS,   /* frame width */
+                         VIDEO_VISIBLE_ROWS,   /* frame height */
+                         bgx                   /* fill color */
+       );
+#else
+       memsetl(video_fb_address,
+               (VIDEO_VISIBLE_ROWS * VIDEO_LINE_LEN) / sizeof(int), bgx);
+#endif
+}
diff --git a/drivers/video/coreboot_fb.c b/drivers/video/coreboot_fb.c
new file mode 100644 (file)
index 0000000..d93bd89
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * coreboot Framebuffer driver.
+ *
+ * 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/arch/tables.h>
+#include <asm/arch/sysinfo.h>
+#include <video_fb.h>
+#include "videomodes.h"
+
+/*
+ * The Graphic Device
+ */
+GraphicDevice ctfb;
+
+static int parse_coreboot_table_fb(GraphicDevice *gdev)
+{
+       struct cb_framebuffer *fb = lib_sysinfo.framebuffer;
+
+       /* If there is no framebuffer structure, bail out and keep
+        * running on the serial console.
+        */
+       if (!fb)
+               return 0;
+
+       gdev->winSizeX = fb->x_resolution;
+       gdev->winSizeY = fb->y_resolution;
+
+       gdev->plnSizeX = fb->x_resolution;
+       gdev->plnSizeY = fb->y_resolution;
+
+       gdev->gdfBytesPP = fb->bits_per_pixel / 8;
+
+       switch (fb->bits_per_pixel) {
+       case 24:
+               gdev->gdfIndex = GDF_32BIT_X888RGB;
+               break;
+       case 16:
+               gdev->gdfIndex = GDF_16BIT_565RGB;
+               break;
+       default:
+               gdev->gdfIndex = GDF__8BIT_INDEX;
+               break;
+       }
+
+       gdev->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS;
+       gdev->pciBase = (unsigned int)fb->physical_address;
+
+       gdev->frameAdrs = (unsigned int)fb->physical_address;
+       gdev->memSize = fb->bytes_per_line * fb->y_resolution;
+
+       gdev->vprBase = (unsigned int)fb->physical_address;
+       gdev->cprBase = (unsigned int)fb->physical_address;
+
+       return 1;
+}
+
+void *video_hw_init(void)
+{
+       GraphicDevice *gdev = &ctfb;
+       int bits_per_pixel;
+
+       printf("Video: ");
+
+       if (!parse_coreboot_table_fb(gdev)) {
+               printf("No video mode configured in coreboot!\n");
+               return NULL;
+       }
+
+       bits_per_pixel = gdev->gdfBytesPP * 8;
+
+       /* fill in Graphic device struct */
+       sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY,
+                bits_per_pixel);
+       printf("%s\n", gdev->modeIdent);
+
+       memset((void *)gdev->pciBase, 0,
+               gdev->winSizeX * gdev->winSizeY * gdev->gdfBytesPP);
+
+       return (void *)gdev;
+}
index 0f2d113a6f18d0e2ecc32eb00b2f13ad6d7454a1..ad4af5283a97d2985f39443c0e5053000fb7bca2 100644 (file)
@@ -94,6 +94,7 @@ struct ipu_ch_param {
        temp1; \
 })
 
+#define IPU_SW_RST_TOUT_USEC   (10000)
 
 void clk_enable(struct clk *clk)
 {
@@ -398,11 +399,20 @@ void ipu_reset(void)
 {
        u32 *reg;
        u32 value;
+       int timeout = IPU_SW_RST_TOUT_USEC;
 
        reg = (u32 *)SRC_BASE_ADDR;
        value = __raw_readl(reg);
        value = value | SW_IPU_RST;
        __raw_writel(value, reg);
+
+       while (__raw_readl(reg) & SW_IPU_RST) {
+               udelay(1);
+               if (!(timeout--)) {
+                       printf("ipu software reset timeout\n");
+                       break;
+               }
+       };
 }
 
 /*
index 2be8a6880b73eb939caee408eb21dea8e5e7d48e..e0e6de69faf1823fab4272cb3954bff8639641d9 100644 (file)
@@ -1,6 +1,4 @@
-#
-# See file CREDITS for list of people who contributed to this
-# project.
+# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
index cae6d56db796db06684a4981af1ab11ce8bbc445..1b25a15e48848081c34c396eb7e060d150327a61 100644 (file)
@@ -1,9 +1,6 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
  *
- * 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
index 1596a92b9ada611fd6889741f5b5d421b290f0fc..464a67d5319cf771da2aad2036fb5abf46a3e42a 100644 (file)
@@ -52,6 +52,7 @@ void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
        part_info = info;
        part_offset = info->start;
        get_fs()->total_sect = (info->size * info->blksz) / SECTOR_SIZE;
+       get_fs()->dev_desc = rbdd;
 }
 
 int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
index 323875fa9452e9863b8fa21376b519c28f1729da..f12b8056cc02abb788bf4d9d6b70cf1f3e0ee8f1 100644 (file)
@@ -378,7 +378,6 @@ void ext4fs_update_parent_dentry(char *filename, int *p_ino, int file_type)
        struct ext_filesystem *fs = get_fs();
        /* directory entry */
        struct ext2_dirent *dir;
-       char *ptr = NULL;
        char *temp_dir = NULL;
 
        zero_buffer = zalloc(fs->blksz);
@@ -415,7 +414,6 @@ restart:
        if (ext4fs_log_journal(root_first_block_buffer, first_block_no_of_root))
                goto fail;
        dir = (struct ext2_dirent *)root_first_block_buffer;
-       ptr = (char *)dir;
        totalbytes = 0;
        while (dir->direntlen > 0) {
                /*
@@ -483,14 +481,12 @@ restart:
                        break;
 
                dir = (struct ext2_dirent *)((char *)dir + templength);
-               ptr = (char *)dir;
        }
 
        /* make a pointer ready for creating next directory entry */
        templength = dir->direntlen;
        totalbytes = totalbytes + templength;
        dir = (struct ext2_dirent *)((char *)dir + templength);
-       ptr = (char *)dir;
 
        /* get the next available inode number */
        inodeno = ext4fs_get_new_inode_no();
@@ -1200,6 +1196,11 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
                status = ext4fs_devread(di_blockno_parent *
                                        fs->sect_perblk, 0,
                                        fs->blksz, (char *)di_parent_buffer);
+
+               if (!status) {
+                       printf("%s: Device read error!\n", __func__);
+                       goto fail;
+               }
                memset(di_parent_buffer, '\0', fs->blksz);
 
                /*
@@ -1227,6 +1228,11 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
                                                fs->sect_perblk, 0,
                                                fs->blksz,
                                                (char *)di_child_buff);
+
+                       if (!status) {
+                               printf("%s: Device read error!\n", __func__);
+                               goto fail;
+                       }
                        memset(di_child_buff, '\0', fs->blksz);
                        /* filling of actual datablocks for each child */
                        for (j = 0; j < (fs->blksz / sizeof(int)); j++) {
index 8a252d66c336d813d6d13ddaee0f2d56877d8cbf..9f017084f17e37c1949947f557861d4f7b2c02ec 100644 (file)
@@ -410,7 +410,7 @@ int ext4fs_check_journal_state(int recovery_flag)
        int transaction_state = TRANSACTION_COMPLETE;
        int prev_desc_logical_no = 0;
        int curr_desc_logical_no = 0;
-       int ofs, flags, block;
+       int ofs, flags;
        struct ext2_inode inode_journal;
        struct journal_superblock_t *jsb = NULL;
        struct journal_header_t *jdb = NULL;
@@ -453,7 +453,6 @@ int ext4fs_check_journal_state(int recovery_flag)
 
        i = be32_to_cpu(jsb->s_first);
        while (1) {
-               block = be32_to_cpu(jsb->s_first);
                blknr = read_allocated_block(&inode_journal, i);
                memset(temp_buff1, '\0', fs->blksz);
                ext4fs_devread(blknr * fs->sect_perblk,
index 06536baf625b375e5843e8af08fb4e6d354857aa..f02c215ccc2e5676dd1c8fd6783b4d582ae32b69 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/stat.h>
 #include <linux/time.h>
 #include <asm/byteorder.h>
+#include <div64.h>
 #include "ext4_common.h"
 
 int ext4fs_symlinknest;
@@ -930,7 +931,6 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
        int previous_block_number = -1;
        int delayed_start = 0;
        int delayed_extent = 0;
-       int delayed_skipfirst = 0;
        int delayed_next = 0;
        char *delayed_buf = NULL;
 
@@ -963,7 +963,6 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
                                        previous_block_number = blknr;
                                        delayed_start = blknr;
                                        delayed_extent = blockend;
-                                       delayed_skipfirst = skipfirst;
                                        delayed_buf = buf;
                                        delayed_next = blknr +
                                            (blockend >> SECTOR_BITS);
@@ -972,7 +971,6 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
                                previous_block_number = blknr;
                                delayed_start = blknr;
                                delayed_extent = blockend;
-                               delayed_skipfirst = skipfirst;
                                delayed_buf = buf;
                                delayed_next = blknr +
                                    (blockend >> SECTOR_BITS);
@@ -1013,8 +1011,6 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
        unsigned int blks_reqd_for_file;
        unsigned int blocks_remaining;
        int existing_file_inodeno;
-       char filename[256];
-
        char *temp_ptr = NULL;
        long int itable_blkno;
        long int parent_itable_blkno;
@@ -1023,6 +1019,9 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
        unsigned int inodes_per_block;
        unsigned int ibmap_idx;
        struct ext_filesystem *fs = get_fs();
+       ALLOC_CACHE_ALIGN_BUFFER(char, filename, 256);
+       memset(filename, 0x00, sizeof(filename));
+
        g_parent_inode = zalloc(sizeof(struct ext2_inode));
        if (!g_parent_inode)
                goto fail;
@@ -1051,8 +1050,8 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
        }
        /* calucalate how many blocks required */
        bytes_reqd_for_file = sizebytes;
-       blks_reqd_for_file = bytes_reqd_for_file / fs->blksz;
-       if (bytes_reqd_for_file % fs->blksz != 0) {
+       blks_reqd_for_file = lldiv(bytes_reqd_for_file, fs->blksz);
+       if (do_div(bytes_reqd_for_file, fs->blksz) != 0) {
                blks_reqd_for_file++;
                debug("total bytes for a file %u\n", blks_reqd_for_file);
        }
diff --git a/fs/fs.c b/fs/fs.c
index ff360afd4b072a22fbe0ab7355206fc2d9e482a6..023e7ef16a3e86a12b48b416638bbcd972b84fc9 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -257,6 +257,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
        unsigned long pos;
        int len_read;
        char buf[12];
+       unsigned long time;
 
        if (argc < 2)
                return CMD_RET_USAGE;
@@ -293,11 +294,19 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
        else
                pos = 0;
 
+       time = get_timer(0);
        len_read = fs_read(filename, addr, pos, bytes);
+       time = get_timer(time);
        if (len_read <= 0)
                return 1;
 
-       printf("%d bytes read\n", len_read);
+       printf("%d bytes read in %lu ms", len_read, time);
+       if (time > 0) {
+               puts(" (");
+               print_size(len_read / time * 1000, "/s");
+               puts(")");
+       }
+       puts("\n");
 
        sprintf(buf, "0x%x", len_read);
        setenv("filesize", buf);
index 2db45b19286a081c030b3f43cad85920b38b81d7..1b73244c004732e3de0edbe717b650c3992e4908 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
 #include "zfs_common.h"
+#include "div64.h"
 
 block_dev_desc_t *zfs_dev_desc;
 
@@ -2115,7 +2116,8 @@ zfs_read(zfs_file_t file, char *buf, uint64_t len)
                /*
                 * Find requested blkid and the offset within that block.
                 */
-               uint64_t blkid = (file->offset + red) /  blksz;
+               uint64_t blkid = file->offset + red;
+               blkid = do_div(blkid, blksz);
                free(data->file_buf);
                data->file_buf = 0;
 
index 945b30acb01b1969b56ddceba7d2c45394935da7..fbd2f92457e18239fccd460c7e1830a765995e4f 100644 (file)
@@ -217,6 +217,13 @@ struct atmel_hlcd_regs {
 #define LCDC_BASECFG3_RDEF(value) \
        ((LCDC_BASECFG3_RDEF_Msk & ((value) << LCDC_BASECFG3_RDEF_Pos)))
 
+#define LCDC_BASECLUT_BCLUT_Pos 0
+#define LCDC_BASECLUT_BCLUT_Msk (0xff << LCDC_BASECLUT_BCLUT_Pos)
+#define LCDC_BASECLUT_GCLUT_Pos 8
+#define LCDC_BASECLUT_GCLUT_Msk (0xff << LCDC_BASECLUT_GCLUT_Pos)
+#define LCDC_BASECLUT_RCLUT_Pos 16
+#define LCDC_BASECLUT_RCLUT_Msk (0xff << LCDC_BASECLUT_RCLUT_Pos)
+
 #define LCDC_BASECFG4_DMA      (0x1 << 8)
 #define LCDC_BASECFG4_REP      (0x1 << 9)
 
index 31021c5b85e68149d9187730967e6b4d36d7790f..707b588c733c06d936a0a2fa517b9c4fad47095a 100644 (file)
@@ -25,6 +25,8 @@
 #ifndef __INCLUDE_BOUNCEBUF_H__
 #define __INCLUDE_BOUNCEBUF_H__
 
+#include <linux/types.h>
+
 /*
  * GEN_BB_READ -- Data are read from the buffer eg. by DMA hardware.
  * The source buffer is copied into the bounce buffer (if unaligned, otherwise
  */
 #define GEN_BB_RW      (GEN_BB_READ | GEN_BB_WRITE)
 
-#ifdef CONFIG_BOUNCE_BUFFER
+struct bounce_buffer {
+       /* Copy of data parameter passed to start() */
+       void *user_buffer;
+       /*
+        * DMA-aligned buffer. This field is always set to the value that
+        * should be used for DMA; either equal to .user_buffer, or to a
+        * freshly allocated aligned buffer.
+        */
+       void *bounce_buffer;
+       /* Copy of len parameter passed to start() */
+       size_t len;
+       /* DMA-aligned buffer length */
+       size_t len_aligned;
+       /* Copy of flags parameter passed to start() */
+       unsigned int flags;
+};
+
 /**
  * bounce_buffer_start() -- Start the bounce buffer session
+ * state:      stores state passed between bounce_buffer_{start,stop}
  * data:       pointer to buffer to be aligned
  * len:                length of the buffer
- * backup:     pointer to backup buffer (the original value is stored here if
- *              needed
  * flags:      flags describing the transaction, see above.
  */
-int bounce_buffer_start(void **data, size_t len, void **backup, uint8_t flags);
+int bounce_buffer_start(struct bounce_buffer *state, void *data,
+                       size_t len, unsigned int flags);
 /**
  * bounce_buffer_stop() -- Finish the bounce buffer session
- * data:       pointer to buffer that was aligned
- * len:                length of the buffer
- * backup:     pointer to backup buffer (the original value is stored here if
- *              needed
- * flags:      flags describing the transaction, see above.
+ * state:      stores state passed between bounce_buffer_{start,stop}
  */
-int bounce_buffer_stop(void **data, size_t len, void **backup, uint8_t flags);
-#else
-static inline int bounce_buffer_start(void **data, size_t len, void **backup,
-                                       uint8_t flags)
-{
-       return 0;
-}
-
-static inline int bounce_buffer_stop(void **data, size_t len, void **backup,
-                                       uint8_t flags)
-{
-       return 0;
-}
-#endif
+int bounce_buffer_stop(struct bounce_buffer *state);
 
 #endif
index 6ea3f351196118a8b96d8e280cdbfe6d13d76771..5bb12c355c2f390276bb28bb355914dcf2199e1e 100644 (file)
@@ -1,9 +1,6 @@
 /*
  * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
  *
- * 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
@@ -77,46 +74,47 @@ struct cbfs_cachenode {
 
 extern enum cbfs_result file_cbfs_result;
 
-/*
- * Return a string describing the most recent error condition.
+/**
+ * file_cbfs_error() - Return a string describing the most recent error
+ * condition.
  *
  * @return A pointer to the constant string.
  */
 const char *file_cbfs_error(void);
 
-/*
- * Initialize the CBFS driver and load metadata into RAM.
+/**
+ * file_cbfs_init() - Initialize the CBFS driver and load metadata into RAM.
  *
- * @param end_of_rom   Points to the end of the ROM the CBFS should be read
+ * @end_of_rom: Points to the end of the ROM the CBFS should be read
  *                      from.
  */
 void file_cbfs_init(uintptr_t end_of_rom);
 
-/*
- * Get the header structure for the current CBFS.
+/**
+ * file_cbfs_get_header() - Get the header structure for the current CBFS.
  *
  * @return A pointer to the constant structure, or NULL if there is none.
  */
 const struct cbfs_header *file_cbfs_get_header(void);
 
-/*
- * Get a handle for the first file in CBFS.
+/**
+ * file_cbfs_get_first() - Get a handle for the first file in CBFS.
  *
  * @return A handle for the first file in CBFS, NULL on error.
  */
 const struct cbfs_cachenode *file_cbfs_get_first(void);
 
-/*
- * Get a handle to the file after this one in CBFS.
+/**
+ * file_cbfs_get_next() - Get a handle to the file after this one in CBFS.
  *
- * @param file         A pointer to the handle to advance.
+ * @file:              A pointer to the handle to advance.
  */
 void file_cbfs_get_next(const struct cbfs_cachenode **file);
 
-/*
- * Find a file with a particular name in CBFS.
+/**
+ * file_cbfs_find() - Find a file with a particular name in CBFS.
  *
- * @param name         The name to search for.
+ * @name:              The name to search for.
  *
  * @return A handle to the file, or NULL on error.
  */
@@ -127,53 +125,55 @@ const struct cbfs_cachenode *file_cbfs_find(const char *name);
 /* All of the functions below can be used without first initializing CBFS. */
 /***************************************************************************/
 
-/*
- * Find a file with a particular name in CBFS without using the heap.
+/**
+ * file_cbfs_find_uncached() - Find a file with a particular name in CBFS
+ * without using the heap.
  *
- * @param end_of_rom   Points to the end of the ROM the CBFS should be read
+ * @end_of_rom:                Points to the end of the ROM the CBFS should be read
  *                      from.
- * @param name         The name to search for.
+ * @name:              The name to search for.
  *
  * @return A handle to the file, or NULL on error.
  */
 const struct cbfs_cachenode *file_cbfs_find_uncached(uintptr_t end_of_rom,
                                                     const char *name);
 
-/*
- * Get the name of a file in CBFS.
+/**
+ * file_cbfs_name() - Get the name of a file in CBFS.
  *
- * @param file         The handle to the file.
+ * @file:              The handle to the file.
  *
  * @return The name of the file, NULL on error.
  */
 const char *file_cbfs_name(const struct cbfs_cachenode *file);
 
-/*
- * Get the size of a file in CBFS.
+/**
+ * file_cbfs_size() - Get the size of a file in CBFS.
  *
- * @param file         The handle to the file.
+ * @file:              The handle to the file.
  *
  * @return The size of the file, zero on error.
  */
 u32 file_cbfs_size(const struct cbfs_cachenode *file);
 
-/*
- * Get the type of a file in CBFS.
+/**
+ * file_cbfs_type() - Get the type of a file in CBFS.
  *
- * @param file         The handle to the file.
+ * @file:              The handle to the file.
  *
  * @return The type of the file, zero on error.
  */
 u32 file_cbfs_type(const struct cbfs_cachenode *file);
 
-/*
- * Read a file from CBFS into RAM
+/**
+ * file_cbfs_read() - Read a file from CBFS into RAM
  *
- * @param file         A handle to the file to read.
- * @param buffer       Where to read it into memory.
+ * @file:              A handle to the file to read.
+ * @buffer:            Where to read it into memory.
+ * @maxsize:           Maximum number of bytes to read
  *
  * @return If positive or zero, the number of characters read. If negative, an
- *         error occurred.
+ *        error occurred.
  */
 long file_cbfs_read(const struct cbfs_cachenode *file, void *buffer,
                    unsigned long maxsize);
index 9ecdad9c9748c696ec8f9f573c33923d4d277e33..e3e5ebc53c33b37979ff248ebfd9ac1645359f80 100644 (file)
 #define CONFIG_SYS_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
 #define CONFIG_SYS_PCI_PTM2LA  0xffc00000      /* point to flash               */
 #define CONFIG_SYS_PCI_PTM2MS  0xffc00001      /* 4MB, enable                  */
-#define CONFIG_SYS_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+#define CONFIG_SYS_PCI_PTM2PCI (bd->bi_memsize) /* host use this pci address */
 
 #define CONFIG_PCI_4xx_PTM_OVERWRITE   1 /* overwrite PTMx settings by env */
 
index efab11991d508cf15176435ac05410cdcd0e2854..c4fff486d88616e88079c6b72af8a195910a29f2 100644 (file)
 #define CONFIG_SYS_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
 #define CONFIG_SYS_PCI_PTM2LA  0xffc00000      /* point to flash               */
 #define CONFIG_SYS_PCI_PTM2MS  0xffc00001      /* 4MB, enable                  */
-#define CONFIG_SYS_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+#define CONFIG_SYS_PCI_PTM2PCI (bd->bi_memsize) /* host use this pci address */
 
 #define CONFIG_PCI_4xx_PTM_OVERWRITE   1 /* overwrite PTMx settings by env */
 
index 83e9a046ad02a236fc9f6a89191442ebb298ee99..9122cbd8779ec5a27020b1a44b6c9c3d55d6c193 100644 (file)
 #define CONFIG_SYS_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
 #define CONFIG_SYS_PCI_PTM2LA  0xffc00000      /* point to flash               */
 #define CONFIG_SYS_PCI_PTM2MS  0xffc00001      /* 4MB, enable                  */
-#define CONFIG_SYS_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+#define CONFIG_SYS_PCI_PTM2PCI (bd->bi_memsize) /* host use this pci address */
 
 #define CONFIG_PCI_4xx_PTM_OVERWRITE   1 /* overwrite PTMx settings by env */
 
index 1944a071b47dd5614138f51fa7bc9f3410f4ffbe..f778af7e363874e98ad2ba815d163d1ae22e98d1 100644 (file)
 #define CONFIG_SYS_PCI_PTM1PCI 0x00000000      /* Host: use this pci address   */
 #define CONFIG_SYS_PCI_PTM2LA  0xffc00000      /* point to flash               */
 #define CONFIG_SYS_PCI_PTM2MS  0xffc00001      /* 4MB, enable                  */
-#define CONFIG_SYS_PCI_PTM2PCI 0x04000000      /* Host: use this pci address   */
+#define CONFIG_SYS_PCI_PTM2PCI (bd->bi_memsize) /* host use this pci address */
 
 #define CONFIG_PCI_4xx_PTM_OVERWRITE   1 /* overwrite PTMx settings by env */
 
index 57aef21e96c9d4de5fe3337340454a700f1bbfd7..437ee6ee6b934c10e09e4dfd8c86285eaee23cec 100644 (file)
@@ -553,6 +553,7 @@ extern unsigned long get_sdram_size(void);
 
 /* SATA */
 #define CONFIG_FSL_SATA
+#define CONFIG_FSL_SATA_V2
 #define CONFIG_LIBATA
 
 #ifdef CONFIG_FSL_SATA
index b3c850d584ed73a4d77ffcaf666f7af301baf468..14d597aad26a0e5885f1e61caa89698cff96bc35 100644 (file)
 /* SATA */
 #define CONFIG_LIBATA
 #define CONFIG_FSL_SATA
+#define CONFIG_FSL_SATA_V2
 
 #define CONFIG_SYS_SATA_MAX_DEVICE     2
 #define CONFIG_SATA1
index 800d666ab232e36396ac52eb3111edbd07ae4d5e..878bd5fa5e6e9b7627be2466fefd8b1e560b491b 100644 (file)
@@ -524,7 +524,7 @@ extern unsigned long get_clock_freq(void);
 /* Default address of microcode for the Linux Fman driver */
 /* QE microcode/firmware address */
 #define CONFIG_SYS_QE_FMAN_FW_IN_NOR
-#define CONFIG_SYS_QE_FMAN_FW_ADDR     0xEF000000
+#define CONFIG_SYS_QE_FMAN_FW_ADDR     0xEFF40000
 #else
 #define CONFIG_SYS_QE_FMAN_FW_IN_NAND
 #define CONFIG_SYS_QE_FMAN_FW_ADDR     0x1f00000
index 5cdb628ab1760165a551c78e4999727752544f3f..8b9b0dbc22153404b76a52a90688ed90511964cb 100644 (file)
@@ -202,15 +202,21 @@ unsigned long get_board_sys_clk(unsigned long dummy);
 /* Set the local bus clock 1/8 of platform clock */
 #define CONFIG_SYS_LBC_LCRR            LCRR_CLKDIV_8
 
-#define CONFIG_SYS_FLASH_BASE          0xe8000000      /* Start of PromJet */
+/*
+ * This board doesn't have a promjet connector.
+ * However, it uses commone corenet board LAW and TLB.
+ * It is necessary to use the same start address with proper offset.
+ */
+#define CONFIG_SYS_FLASH_BASE          0xe0000000
 #ifdef CONFIG_PHYS_64BIT
-#define CONFIG_SYS_FLASH_BASE_PHYS     0xfe8000000ull
+#define CONFIG_SYS_FLASH_BASE_PHYS     0xfe0000000ull
 #else
 #define CONFIG_SYS_FLASH_BASE_PHYS     CONFIG_SYS_FLASH_BASE
 #endif
 
 #define CONFIG_SYS_FLASH_BR_PRELIM \
-               (BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | BR_PS_16 | BR_V)
+               (BR_PHYS_ADDR((CONFIG_SYS_FLASH_BASE_PHYS + 0x8000000)) | \
+               BR_PS_16 | BR_V)
 #define CONFIG_SYS_FLASH_OR_PRELIM \
                ((0xf8000ff7 & ~OR_GPCM_SCY & ~OR_GPCM_EHTR) \
                 | OR_GPCM_SCY_8 | OR_GPCM_EHTR_CLEAR)
@@ -294,7 +300,7 @@ unsigned long get_board_sys_clk(unsigned long dummy);
 
 #define CONFIG_SYS_FLASH_EMPTY_INFO
 #define CONFIG_SYS_FLASH_AMD_CHECK_DQ7
-#define CONFIG_SYS_FLASH_BANKS_LIST    {CONFIG_SYS_FLASH_BASE_PHYS}
+#define CONFIG_SYS_FLASH_BANKS_LIST    {CONFIG_SYS_FLASH_BASE_PHYS + 0x8000000}
 
 #define CONFIG_BOARD_EARLY_INIT_F
 #define CONFIG_BOARD_EARLY_INIT_R      /* call board_early_init_r function */
@@ -539,7 +545,7 @@ unsigned long get_board_sys_clk(unsigned long dummy);
 #define CONFIG_SYS_QE_FMAN_FW_ADDR     0xFFE00000
 #else
 #define CONFIG_SYS_QE_FMAN_FW_IN_NOR
-#define CONFIG_SYS_QE_FMAN_FW_ADDR     0xEF000000
+#define CONFIG_SYS_QE_FMAN_FW_ADDR     0xEFF40000
 #endif
 #define CONFIG_SYS_QE_FMAN_FW_LENGTH   0x10000
 #define CONFIG_SYS_FDT_PAD             (0x3000 + CONFIG_SYS_QE_FMAN_FW_LENGTH)
@@ -560,8 +566,10 @@ unsigned long get_board_sys_clk(unsigned long dummy);
 #endif /* CONFIG_PCI */
 
 /* SATA */
+#define CONFIG_FSL_SATA_V2
+
+#ifdef CONFIG_FSL_SATA_V2
 #define CONFIG_FSL_SATA
-#ifdef CONFIG_FSL_SATA
 #define CONFIG_LIBATA
 
 #define CONFIG_SYS_SATA_MAX_DEVICE     2
index cf184e74ab8c2f60432d65afb2b02bc94309fba4..ce8f9b0b2eba190c0e11a41bed6a4c054945fc89 100644 (file)
@@ -32,6 +32,7 @@
 
 #define CONFIG_MMC
 #define CONFIG_NAND_FSL_ELBC
+#define CONFIG_FSL_SATA_V2
 #define CONFIG_PCIE3
 #define CONFIG_PCIE4
 #define CONFIG_SYS_DPAA_RMAN
index 7018d7a32212aae267a2ff88fa4ad5f804a34d47..778230d3356c13ced57cc25bde618650f6c9c190 100644 (file)
@@ -32,6 +32,7 @@
 
 #define CONFIG_MMC
 #define CONFIG_NAND_FSL_ELBC
+#define CONFIG_FSL_SATA_V2
 #define CONFIG_PCIE3
 #define CONFIG_PCIE4
 #define CONFIG_SYS_FSL_RAID_ENGINE
diff --git a/include/configs/P5040DS.h b/include/configs/P5040DS.h
new file mode 100644 (file)
index 0000000..50d9e54
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * P5040 DS board configuration file
+ *
+ */
+#define CONFIG_P5040DS
+#define CONFIG_PHYS_64BIT
+#define CONFIG_PPC_P5040
+
+#define CONFIG_FSL_NGPIXIS             /* use common ngPIXIS code */
+
+#define CONFIG_MMC
+#define CONFIG_NAND_FSL_ELBC
+#define CONFIG_PCIE3
+#define CONFIG_SYS_FSL_RAID_ENGINE
+
+#define CONFIG_ICS307_REFCLK_HZ                25000000  /* ICS307 ref clk freq */
+
+#include "corenet_ds.h"
index 403fafa2f52b4cf2654549d17754c17d381a3dd2..aced85b6606e70c087b1d7571f1b50fb9b7b8c83 100644 (file)
  *----------------------------------------------------------------------*/
 #define CONFIG_SYS_LEDPIO_ADDR         0x02120870      /* LED PIO base addr    */
 #define CONFIG_STATUS_LED                      /* Enable status driver */
+#define CONFIG_BOARD_SPECIFIC_LED
 
 #define STATUS_LED_BIT         1               /* Bit-0 on PIO         */
 #define STATUS_LED_STATE       1               /* Blinking             */
diff --git a/include/configs/a3m071.h b/include/configs/a3m071.h
new file mode 100644 (file)
index 0000000..df3b4ae
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2012 Stefan Roese <sr@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.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#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_SYS_MPC5XXX_CLKIN       33000000 /* ... running at 33MHz */
+
+#define CONFIG_MISC_INIT_R
+#define CONFIG_SYS_LOWBOOT             /* Enable lowboot       */
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_PSC_CONSOLE     1           /* console is on PSC1 */
+#define CONFIG_BAUDRATE                115200  /* ... at 115200 bps */
+#define CONFIG_SYS_BAUDRATE_TABLE              \
+       { 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/*
+ * Command line configuration.
+ */
+#include <config_cmd_default.h>
+
+#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
+
+/*
+ * IPB Bus clocking configuration.
+ */
+#define CONFIG_SYS_IPBCLK_EQUALS_XLBCLK                /* define for 133MHz speed */
+/* define for 66MHz speed - undef for 33MHz PCI clock speed */
+#undef CONFIG_SYS_PCICLK_EQUALS_IPBCLK_DIV2
+
+/* pass open firmware flat tree */
+#define CONFIG_OF_LIBFDT
+#define CONFIG_OF_BOARD_SETUP
+
+/* maximum size of the flat tree (8K) */
+#define OF_FLAT_TREE_MAX_SIZE  8192
+
+#define OF_CPU                 "PowerPC,5200@0"
+#define OF_SOC                 "soc5200@f0000000"
+#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_ENV_ADDR                        (CONFIG_SYS_FLASH_BASE + 0x40000)
+
+#define CONFIG_SYS_MAX_FLASH_BANKS     1
+#define CONFIG_SYS_MAX_FLASH_SECT      256
+#define CONFIG_SYS_FLASH_ERASE_TOUT    240000
+#define CONFIG_SYS_FLASH_WRITE_TOUT    500
+#define CONFIG_SYS_FLASH_LOCK_TOUT     5
+#define CONFIG_SYS_FLASH_UNLOCK_TOUT   10000
+#define CONFIG_SYS_FLASH_PROTECTION
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_SYS_FLASH_EMPTY_INFO
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+
+/*
+ * Environment settings
+ */
+#define CONFIG_ENV_IS_IN_FLASH
+#define CONFIG_ENV_SIZE                0x10000
+#define CONFIG_ENV_SECT_SIZE   0x20000
+#define CONFIG_ENV_OVERWRITE
+
+/*
+ * Memory map
+ */
+#define CONFIG_SYS_MBAR                        0xf0000000
+#define CONFIG_SYS_SDRAM_BASE          0x00000000
+#define CONFIG_SYS_DEFAULT_MBAR                0x80000000
+
+/* Use SRAM until RAM will be available */
+#define CONFIG_SYS_INIT_RAM_ADDR       MPC5XXX_SRAM
+#define CONFIG_SYS_INIT_RAM_END                MPC5XXX_SRAM_SIZE
+
+
+#define CONFIG_SYS_GBL_DATA_SIZE       128
+#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 << 10)
+#define CONFIG_SYS_MALLOC_LEN          (1 << 20)
+#define CONFIG_SYS_BOOTMAPSZ           (8 << 20)
+
+/*
+ * Ethernet configuration
+ */
+#define CONFIG_MPC5xxx_FEC
+#define CONFIG_MPC5xxx_FEC_MII100
+#define CONFIG_PHY_ADDR                        0x00
+
+/*
+ * GPIO configuration
+ */
+
+/*
+ * GPIO-config depends on failsave-level
+ * failsave 0 means just MPX-config, no digiboard, no fpga
+ *          1 means digiboard ok
+ *          2 means fpga ok
+ */
+
+/* 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
+
+/*
+ * Configuration matrix
+ *                        MSB                          LSB
+ * failsave 0  0x1005C005  00010000000001011100000001100101  ( full failsave )
+ * failsave 1  0x1005C005  00010000000001011100000001100101  ( digib.-ver ok )
+ * failsave 2  0x1005C005  00010000000001011100000001100101  ( all ok )
+ *                         || ||| ||  |   ||| |   |   |   |
+ *                         || ||| ||  |   ||| |   |   |   |  bit rev name
+ *                         ++-+++-++--+---+++-+---+---+---+-  0   31 CS1
+ *                          +-+++-++--+---+++-+---+---+---+-  1   30 LPTZ
+ *                            ||| ||  |   ||| |   |   |   |   2   29 ALTs
+ *                            +++-++--+---+++-+---+---+---+-  3   28 ALTs
+ *                             ++-++--+---+++-+---+---+---+-  4   27 CS7
+ *                              +-++--+---+++-+---+---+---+-  5   26 CS6
+ *                                ||  |   ||| |   |   |   |   6   25 ATA
+ *                                ++--+---+++-+---+---+---+-  7   24 ATA
+ *                                 +--+---+++-+---+---+---+-  8   23 IR_USB_CLK
+ *                                    |   ||| |   |   |   |   9   22 IRDA
+ *                                    |   ||| |   |   |   |  10   21 IRDA
+ *                                    +---+++-+---+---+---+- 11   20 IRDA
+ *                                        ||| |   |   |   |  12   19 Ether
+ *                                        ||| |   |   |   |  13   18 Ether
+ *                                        ||| |   |   |   |  14   17 Ether
+ *                                        +++-+---+---+---+- 15   16 Ether
+ *                                         ++-+---+---+---+- 16   15 PCI_DIS
+ *                                          +-+---+---+---+- 17   14 USB_SE
+ *                                            |   |   |   |  18   13 USB
+ *                                            +---+---+---+- 19   12 USB
+ *                                                |   |   |  20   11 PSC3
+ *                                                |   |   |  21   10 PSC3
+ *                                                |   |   |  22    9 PSC3
+ *                                                +---+---+- 23    8 PSC3
+ *                                                    |   |  24    7 -
+ *                                                    |   |  25    6 PSC2
+ *                                                    |   |  26    5 PSC2
+ *                                                    +---+- 27    4 PSC2
+ *                                                        |  28    3 -
+ *                                                        |  29    2 PSC1
+ *                                                        |  30    1 PSC1
+ *                                                        +- 31    0 PSC1
+ */
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT              "=> "
+
+#define CONFIG_CMDLINE_EDITING
+#define        CONFIG_SYS_HUSH_PARSER
+#define        CONFIG_SYS_PROMPT_HUSH_PS2      "> "
+
+#if defined(CONFIG_CMD_KGDB)
+#define CONFIG_SYS_CBSIZE              1024
+#else
+#define CONFIG_SYS_CBSIZE              256
+#endif
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
+#define CONFIG_SYS_MAXARGS             16
+#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
+
+#define CONFIG_SYS_MEMTEST_START       0x00100000
+#define CONFIG_SYS_MEMTEST_END         0x00f00000
+
+#define CONFIG_SYS_LOAD_ADDR           0x00100000
+
+#define CONFIG_SYS_HZ                  1000
+#define CONFIG_LOOPW
+#define CONFIG_SYS_CONSOLE_INFO_QUIET  /* don't print console @ startup*/
+
+/*
+ * Various low-level settings
+ */
+#define CONFIG_SYS_HID0_INIT           (HID0_ICE | HID0_ICFI)
+#define CONFIG_SYS_HID0_FINAL          HID0_ICE
+
+#define CONFIG_SYS_BOOTCS_START                CONFIG_SYS_FLASH_BASE
+#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
+#define CONFIG_SYS_CS2_START           0xe0000000
+#define CONFIG_SYS_CS2_SIZE            0x00100000
+
+/* FPGA slave io (512kiB) - see ticket #66 */
+#define CONFIG_SYS_CS3_START           0xE9000000
+#define CONFIG_SYS_CS3_SIZE            0x00080000
+/* 00000000 00110010 1 0 1 1 10 01 00 00 0 0 0 0  = 0x0032B900 */
+#define CONFIG_SYS_CS3_CFG             0x0032B900
+
+/* 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
+
+/* FPGA master io (64kiB) - see ticket #66 */
+#define CONFIG_SYS_CS5_START           0xE8000000
+#define CONFIG_SYS_CS5_SIZE            0x00010000
+/* 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_CS2_CFG             0x0006F90C
+#else  /* for pci_clk = 33 MHz */
+#define CONFIG_SYS_BOOTCS_CFG          0x0002F900
+#define CONFIG_SYS_CS1_CFG             0x0001FB00
+#define CONFIG_SYS_CS2_CFG             0x0002F90C
+#endif
+
+#define CONFIG_SYS_CS_BURST            0x00000000
+/* set DC for FPGA CS5 and CS3 to 0 - see ticket #66 */
+/* R  7  R  6  R  5  R  4  R  3  R  2  R  1  R  0  */
+/* 00 11 00 11 00 00 00 11 00 00 00 00 00 00 00 00 */
+#define CONFIG_SYS_CS_DEADCYCLE                0x33030000
+
+#define CONFIG_SYS_RESET_ADDRESS       0xff000000
+
+/*
+ * Environment Configuration
+ */
+
+#define CONFIG_BOOTDELAY       0       /* -1 disables auto-boot */
+#undef  CONFIG_BOOTARGS
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#define CONFIG_PREBOOT "echo;" \
+       "echo Type \"run flash_mtd\" to boot from flash with mtd filesystem;" \
+       "echo Type \"run net_nfs\" to boot from tftp with nfs filesystem;" \
+       "echo"
+
+#undef CONFIG_BOOTARGS
+
+#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                                       \
+       "netdev=eth0\0"                                                 \
+       "verify=no\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"\
+       "addip=setenv bootargs ${bootargs} "                            \
+               "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"      \
+               ":${hostname}:${netdev}:off panic=1\0"                  \
+       "addtty=setenv bootargs ${bootargs} "                           \
+               "console=${consoledev},${baudrate}\0"                   \
+       "flash_nfs=run nfsargs addip addtty;"                           \
+               "bootm ${kernel_addr} - ${fdtaddr}\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};"                               \
+               "run nfsargs addip addtty;"                             \
+               "bootm ${loadaddr} - c00000\0"                          \
+       "load=tftp ${loadaddr} u-boot.bin\0"                            \
+       "update=protect off fc000000 fc03ffff; "                        \
+               "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"                    \
+       ""
+
+#define CONFIG_BOOTCOMMAND     "run flash_mtd"
+
+/*
+ * SPL related defines
+ */
+#define CONFIG_SPL
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_NOR_SUPPORT
+#define CONFIG_SPL_TEXT_BASE   0xfc000000
+#define        CONFIG_SPL_START_S_PATH "arch/powerpc/cpu/mpc5xxx"
+#define CONFIG_SPL_LDSCRIPT    "arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds"
+#define CONFIG_SPL_LIBCOMMON_SUPPORT   /* image.c */
+#define CONFIG_SPL_LIBGENERIC_SUPPORT  /* string.c */
+#define CONFIG_SPL_SERIAL_SUPPORT
+
+/* Place BSS for SPL near end of SDRAM */
+#define CONFIG_SPL_BSS_START_ADDR      ((128 - 1) << 20)
+#define CONFIG_SPL_BSS_MAX_SIZE                (64 << 10)
+
+#define CONFIG_SPL_OS_BOOT
+/* Place patched DT blob (fdt) at this address */
+#define CONFIG_SYS_SPL_ARGS_ADDR       0x01800000
+
+/* Settings for real U-Boot to be loaded from NOR flash */
+#ifndef __ASSEMBLY__
+extern char __spl_flash_end[];
+#endif
+#define CONFIG_SYS_UBOOT_BASE          __spl_flash_end
+#define CONFIG_SYS_SPL_MAX_LEN         (32 << 10)
+#define CONFIG_SYS_UBOOT_START         0x1000100
+
+#endif /* __CONFIG_H */
index b6e48f8a63e0b01818884e31334554ed1692096a..ab9549b93b8ffe3ce419844a730cfc5920c30dde 100644 (file)
 #define CONFIG_SKIP_LOWLEVEL_INIT
 #endif
 
+/*
+ * USB configuration
+ */
+#define CONFIG_USB_MUSB_DSPS
+#define CONFIG_ARCH_MISC_INIT
+#define CONFIG_MUSB_GADGET
+#define CONFIG_MUSB_PIO_ONLY
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_MUSB_HOST
+#define CONFIG_AM335X_USB0
+#define CONFIG_AM335X_USB0_MODE        MUSB_PERIPHERAL
+#define CONFIG_AM335X_USB1
+#define CONFIG_AM335X_USB1_MODE MUSB_HOST
+
+#ifdef CONFIG_MUSB_HOST
+#define CONFIG_CMD_USB
+#define CONFIG_USB_STORAGE
+#endif
+
+#ifdef CONFIG_MUSB_GADGET
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETH_RNDIS
+#endif /* CONFIG_MUSB_GADGET */
+
+/* Unsupported features */
+#undef CONFIG_USE_IRQ
+
 #define CONFIG_CMD_NET
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_PING
index 20a3df5db28acf98049474c0f294297251d15ff1..e1ad1e58ff63bbb4cbe95b3f8a742a480f4a878e 100644 (file)
 #define CONFIG_SPL_FAT_SUPPORT
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_POWER_SUPPORT
 #define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
 
index ce71d1335c58ebd1bc4480b9f1c74b45e8eba972..ba1532540e6b6e76bac3d2b97f69090b43ebb8d5 100644 (file)
 
 /*
  * USB configuration
- * Enable CONFIG_MUSB_HCD for Host functionalities MSC, keyboard
- * Enable CONFIG_MUSB_UDC for Device functionalities.
+ * Enable CONFIG_MUSB_HOST for Host functionalities MSC, keyboard
+ * Enable CONFIG_MUSB_GADGET for Device functionalities.
  */
-#define CONFIG_USB_AM35X               1
-#define CONFIG_MUSB_HCD                        1
+#define CONFIG_USB_MUSB_AM35X
+#define CONFIG_MUSB_HOST
+#define CONFIG_MUSB_PIO_ONLY
 
-#ifdef CONFIG_USB_AM35X
+#ifdef CONFIG_USB_MUSB_AM35X
 
-#ifdef CONFIG_MUSB_HCD
+#ifdef CONFIG_MUSB_HOST
 #define CONFIG_CMD_USB
 
 #define CONFIG_USB_STORAGE
 #define CONFIG_PREBOOT "usb start"
 #endif /* CONFIG_USB_KEYBOARD */
 
-#endif /* CONFIG_MUSB_HCD */
+#endif /* CONFIG_MUSB_HOST */
 
-#ifdef CONFIG_MUSB_UDC
-/* USB device configuration */
-#define CONFIG_USB_DEVICE              1
-#define CONFIG_USB_TTY                 1
-#define CONFIG_SYS_CONSOLE_IS_IN_ENV   1
-/* Change these to suit your needs */
-#define CONFIG_USBD_VENDORID           0x0451
-#define CONFIG_USBD_PRODUCTID          0x5678
-#define CONFIG_USBD_MANUFACTURER       "Texas Instruments"
-#define CONFIG_USBD_PRODUCT_NAME       "AM3517EVM"
-#endif /* CONFIG_MUSB_UDC */
+#ifdef CONFIG_MUSB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETH_RNDIS
+#endif /* CONFIG_MUSB_GADGET */
 
-#endif /* CONFIG_USB_AM35X */
+#endif /* CONFIG_USB_MUSB_AM35X */
 
 /* commands to include */
 #include <config_cmd_default.h>
 #define CONFIG_SPL_FAT_SUPPORT
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_POWER_SUPPORT
 #define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
 
index 71f765b49422208da2b46b62cade585a83071250..131758279ca9b7547d91d2c4be1d9f3673e77eb0 100644 (file)
 #define CONFIG_BOOTCOMMAND     "nand read " \
                                "0x22000000 0x200000 0x300000; " \
                                "bootm 0x22000000"
-#else
-#ifdef CONFIG_SYS_USE_SPIFLASH
+#elif defined(CONFIG_SYS_USE_SPIFLASH)
 /* bootstrap + u-boot + env + linux in spi flash */
 #define CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_ENV_OFFSET      0x5000
 #define CONFIG_BOOTCOMMAND     "sf probe 0; " \
                                "sf read 0x22000000 0x100000 0x300000; " \
                                "bootm 0x22000000"
-#endif
+#else /* CONFIG_SYS_USE_MMC */
+/* bootstrap + u-boot + env + linux in mmc */
+#define CONFIG_ENV_IS_IN_MMC
+/* For FAT system, most cases it should be in the reserved sector */
+#define CONFIG_ENV_OFFSET      0x2000
+#define CONFIG_ENV_SIZE                0x1000
+#define CONFIG_SYS_MMC_ENV_DEV 0
 #endif
 
+#ifdef CONFIG_SYS_USE_MMC
+#define CONFIG_BOOTARGS                "mem=128M console=ttyS0,115200 " \
+                               "mtdparts=atmel_nand:" \
+                               "8M(bootstrap/uboot/kernel)ro,-(rootfs) " \
+                               "root=/dev/mmcblk0p2 " \
+                               "rw rootfstype=ext4 rootwait"
+#else
 #define CONFIG_BOOTARGS                "mem=128M console=ttyS0,115200 " \
                                "mtdparts=atmel_nand:" \
                                "8M(bootstrap/uboot/kernel)ro,-(rootfs) " \
                                "root=/dev/mtdblock1 rw " \
                                "rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"
+#endif
 
 #define CONFIG_BAUDRATE                115200
 
index 56dc1cbbd51d9309f099c4e7f3275331cb26571b..a7a698c0caa6b593f9bbb85d61b636bfeaaee8eb 100644 (file)
 #define CONFIG_SPL_BOARD_INIT
 #define CONFIG_SPL_LIBGENERIC_SUPPORT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_NAND_SIMPLE
 #define CONFIG_SYS_NAND_HW_ECC_OOBFIRST
 #define CONFIG_SPL_SERIAL_SUPPORT
index cc95e2be987212014e6b6cffc23365f3c23c45cd..adeace0cf2ef8211ab5bbae66d3e7adfd23d0b0a 100644 (file)
  * (easy to change)
  */
 #define CONFIG_SYS_COREBOOT
-#undef CONFIG_SHOW_BOOT_PROGRESS
+#define CONFIG_SHOW_BOOT_PROGRESS
 #define CONFIG_LAST_STAGE_INIT
-
+#define CONFIG_X86_NO_RESET_VECTOR
+#define CONFIG_SYS_VSNPRINTF
+#define CONFIG_INTEL_CORE_ARCH /* Sandy bridge and ivy bridge chipsets. */
+#define CONFIG_ZBOOT_32
+#define CONFIG_PHYSMEM
 
 /*-----------------------------------------------------------------------
  * Watchdog Configuration
                                         CONFIG_SYS_SCSI_MAX_LUN)
 #endif
 
+/* Generic TPM interfaced through LPC bus */
+#define CONFIG_GENERIC_LPC_TPM
+#define CONFIG_TPM_TIS_BASE_ADDRESS        0xfed40000
+
 /*-----------------------------------------------------------------------
  * Real Time Clock Configuration
  */
 #define CONFIG_RTC_MC146818
 #define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0
+#define CONFIG_SYS_ISA_IO      CONFIG_SYS_ISA_IO_BASE_ADDRESS
 
 /*-----------------------------------------------------------------------
  * Serial Configuration
 #define CONFIG_SYS_NS16550_COM2        UART1_BASE
 #define CONFIG_SYS_NS16550_PORT_MAPPED
 
-/* max. 1 IDE bus      */
-#define CONFIG_SYS_IDE_MAXBUS          1
-/* max. 1 drive per IDE bus */
-#define CONFIG_SYS_IDE_MAXDEVICE       (CONFIG_SYS_IDE_MAXBUS * 1)
+#define CONFIG_STD_DEVICES_SETTINGS     "stdin=usbkbd,vga,eserial0\0" \
+                                       "stdout=vga,eserial0,cbmem\0" \
+                                       "stderr=vga,eserial0,cbmem\0"
 
-#define CONFIG_SYS_ATA_BASE_ADDR       CONFIG_SYS_ISA_IO_BASE_ADDRESS
-#define CONFIG_SYS_ATA_IDE0_OFFSET     0x01f0
-#define CONFIG_SYS_ATA_IDE1_OFFSET     0x0170
-#define CONFIG_SYS_ATA_DATA_OFFSET     0
-#define CONFIG_SYS_ATA_REG_OFFSET      0
-#define CONFIG_SYS_ATA_ALT_OFFSET      0x200
+#define CONFIG_CONSOLE_MUX
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_SYS_STDIO_DEREGISTER
+#define CONFIG_CBMEM_CONSOLE
 
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_COMMAND_HISTORY
+#define CONFIG_AUTOCOMPLETE
 
 #define CONFIG_SUPPORT_VFAT
 /************************************************************
 /************************************************************
  * DISK Partition support
  ************************************************************/
+#define CONFIG_EFI_PARTITION
 #define CONFIG_DOS_PARTITION
 #define CONFIG_MAC_PARTITION
 #define CONFIG_ISO_PARTITION           /* Experimental */
 
+#define CONFIG_CMD_PART
 #define CONFIG_CMD_CBFS
 #define CONFIG_CMD_EXT4
 #define CONFIG_CMD_EXT4_WRITE
+#define CONFIG_PARTITION_UUIDS
 
 /*-----------------------------------------------------------------------
  * Video Configuration
  */
-#undef CONFIG_VIDEO
-#undef CONFIG_CFB_CONSOLE
+#define CONFIG_VIDEO
+#define CONFIG_VIDEO_COREBOOT
+#define CONFIG_VIDEO_SW_CURSOR
+#define VIDEO_FB_16BPP_WORD_SWAP
+#define CONFIG_I8042_KBD
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/* x86 GPIOs are accessed through a PCI device */
+#define CONFIG_INTEL_ICH6_GPIO
 
 /*-----------------------------------------------------------------------
  * Command line configuration.
 #define CONFIG_CMD_ECHO
 #undef CONFIG_CMD_FLASH
 #define CONFIG_CMD_FPGA
+#define CONFIG_CMD_GPIO
 #define CONFIG_CMD_IMI
 #undef CONFIG_CMD_IMLS
 #define CONFIG_CMD_IRQ
 #define CONFIG_CMD_SETGETDCR
 #define CONFIG_CMD_SOURCE
 #define CONFIG_CMD_XIMG
-#define CONFIG_CMD_IDE
+#define CONFIG_CMD_SCSI
+
 #define CONFIG_CMD_FAT
 #define CONFIG_CMD_EXT2
 
+#define CONFIG_CMD_ZBOOT
+
 #define CONFIG_BOOTDELAY       2
-#define CONFIG_BOOTARGS                "root=/dev/mtdblock0 console=ttyS0,9600"
+#define CONFIG_BOOTARGS                \
+       "root=/dev/sdb3 init=/sbin/init rootwait ro"
+#define CONFIG_BOOTCOMMAND     \
+       "ext2load scsi 0:3 01000000 /boot/vmlinuz; zboot 01000000"
+
 
 #if defined(CONFIG_CMD_KGDB)
 #define CONFIG_KGDB_BAUDRATE                   115200
  * (128kB + Environment Sector Size) malloc pool
  */
 #define CONFIG_SYS_STACK_SIZE                  (32 * 1024)
-#define CONFIG_SYS_INIT_SP_ADDR                (256 * 1024 + 16 * 1024)
+#define CONFIG_SYS_CAR_ADDR                    0x19200000
+#define CONFIG_SYS_CAR_SIZE                    (16 * 1024)
 #define CONFIG_SYS_MONITOR_BASE                CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_MONITOR_LEN                 (256 * 1024)
 #define CONFIG_SYS_MALLOC_LEN                  (0x20000 + 128 * 1024)
-/* Address of temporary Global Data */
-#define CONFIG_SYS_INIT_GD_ADDR                (256 * 1024)
 
 
 /* allow to overwrite serial and ethaddr */
  */
 #define CONFIG_PCI
 
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       CONFIG_STD_DEVICES_SETTINGS
+
 #endif /* __CONFIG_H */
index c41b03999642e5867a979ae88e0aaff3f1ef6d62..3f42cd9a38ecc939dc9e55853f092eb4e71580a4 100644 (file)
 #define CONFIG_SYS_QE_FMAN_FW_ADDR     0xFFE00000
 #else
 #define CONFIG_SYS_QE_FMAN_FW_IN_NOR
-#define CONFIG_SYS_QE_FMAN_FW_ADDR             0xEF000000
+#define CONFIG_SYS_QE_FMAN_FW_ADDR             0xEFF40000
 #endif
 #define CONFIG_SYS_QE_FMAN_FW_LENGTH   0x10000
 #define CONFIG_SYS_FDT_PAD             (0x3000 + CONFIG_SYS_QE_FMAN_FW_LENGTH)
index ddd615509fe406bc2b6d5a22d7329057f9edc764..99b4de72887b45a508a7e72a9eb5263917a5eebe 100644 (file)
 #define CONFIG_SYS_NAND_ECCBYTES       10
 #define CONFIG_SYS_NAND_OOBSIZE                64
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_NAND_SIMPLE
 #define CONFIG_SPL_NAND_LOAD
 #endif
index da3263f4f59745a74cbe4094c827838be6038562..83a8b5d59feec8f5f01117e270f914e0d339d120 100644 (file)
 #define CONFIG_SPL_GPIO_SUPPORT
 #define CONFIG_SPL_POWER_SUPPORT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_MMC_SUPPORT
 #define CONFIG_SPL_FAT_SUPPORT
 #define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
index 4b1c21904cb05f68492539a93b244db27d86f27c..28cf95b7788549063d86a189844f942c894b7b7f 100644 (file)
 #define CONFIG_SYS_STACK_SIZE                  (32 * 1024)
 #define CONFIG_SYS_CAR_ADDR                    0x19200000
 #define CONFIG_SYS_CAR_SIZE                    (16 * 1024)
-#define CONFIG_SYS_INIT_SP_ADDR                        (CONFIG_SYS_CAR_ADDR + \
-                                                CONFIG_SYS_CAR_SIZE)
 #define CONFIG_SYS_MONITOR_BASE                        CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_MONITOR_LEN                 (256 * 1024)
 #define CONFIG_SYS_MALLOC_LEN                  (CONFIG_ENV_SECT_SIZE + \
                                                 128*1024)
-/* Address of temporary Global Data */
-#define CONFIG_SYS_INIT_GD_ADDR                        CONFIG_SYS_CAR_ADDR
-
-
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE
 
index 9ecc10bd1b5866f46fbc513891886f5862665336..5a0d321f739de147b862aa3586832a48d175ac7c 100644 (file)
@@ -38,7 +38,7 @@
 
 #define CONFIG_MCFUART
 #define CONFIG_SYS_UART_PORT           (0)
-#define CONFIG_BAUDRATE 9600
+#define CONFIG_BAUDRATE                        115200
 
 #undef CONFIG_MONITOR_IS_IN_RAM                /* starts uboot direct */
 
 #define CONFIG_RESET_TO_RETRY
 #define CONFIG_SPLASH_SCREEN
 
+#define CONFIG_HW_WATCHDOG
+
+#define CONFIG_STATUS_LED
+#define CONFIG_BOARD_SPECIFIC_LED
+#define STATUS_LED_ACTIVE              0
+#define STATUS_LED_BIT                 0x0008  /* Timer7 GPIO */
+#define STATUS_LED_BOOT                        0
+#define STATUS_LED_PERIOD              (CONFIG_SYS_HZ / 2)
+#define STATUS_LED_STATE               STATUS_LED_OFF
+
 /*----------------------------------------------------------------------*
  * Configuration for environment                                       *
  * Environment is in the second sector of the first 256k of flash      *
  *----------------------------------------------------------------------*/
 
-#ifndef CONFIG_MONITOR_IS_IN_RAM
-#define CONFIG_ENV_ADDR                0xF003C000      /* End of 256K */
-#define CONFIG_ENV_SECT_SIZE   0x4000
-#define CONFIG_ENV_IS_IN_FLASH 1
-#else
-#define CONFIG_ENV_ADDR                0xFFE04000
-#define CONFIG_ENV_SECT_SIZE   0x2000
+#define CONFIG_ENV_ADDR                0xFF040000
+#define CONFIG_ENV_SECT_SIZE   0x00020000
 #define CONFIG_ENV_IS_IN_FLASH 1
-#endif
 
 /*
  * BOOTP options
 /*
  * Command line configuration.
  */
+#define CONFIG_CMDLINE_EDITING
 #include <config_cmd_default.h>
 
 #undef CONFIG_CMD_LOADB
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_LED
 #define CONFIG_CMD_MII
 #define CONFIG_CMD_NET
 
 #define CONFIG_MCFTMR
 
-
 #define CONFIG_BOOTDELAY       5
-#define CONFIG_SYS_HUSH_PARSER
-#define CONFIG_SYS_PROMPT_HUSH_PS2     "> "
 #define CONFIG_SYS_PROMPT      "\nEB+CPU5282> "
 #define        CONFIG_SYS_LONGHELP     1
 
-#if defined(CONFIG_CMD_KGDB)
 #define        CONFIG_SYS_CBSIZE       1024    /* Console I/O Buffer Size      */
-#else
-#define        CONFIG_SYS_CBSIZE       256     /* Console I/O Buffer Size      */
-#endif
 #define        CONFIG_SYS_PBSIZE       (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
 #define        CONFIG_SYS_MAXARGS      16      /* max number of command args   */
 #define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
 /*----------------------------------------------------------------------*
  * Clock and PLL Configuration                                         *
  *----------------------------------------------------------------------*/
-#define CONFIG_SYS_HZ                  10000000
-#define        CONFIG_SYS_CLK                  58982400       /* 9,8304MHz * 6 */
+#define CONFIG_SYS_HZ                  1000
+#define        CONFIG_SYS_CLK                  80000000      /* 8MHz * 8 */
 
-/* PLL Configuration: Ext Clock * 6 (see table 9-4 of MCF user manual) */
+/* PLL Configuration: Ext Clock * 8 (see table 9-4 of MCF user manual) */
 
-#define CONFIG_SYS_MFD         0x01    /* PLL Multiplication Factor Devider */
+#define CONFIG_SYS_MFD         0x02    /* PLL Multiplication Factor Devider */
 #define CONFIG_SYS_RFD         0x00    /* PLL Reduce Frecuency Devider */
 
 /*----------------------------------------------------------------------*
 #define CONFIG_SYS_FEC0_MIIBASE                CONFIG_SYS_FEC0_IOBASE
 #define MCFFEC_TOUT_LOOP               50000
 
-#define CONFIG_ETHADDR                 00:CF:52:82:EB:01
 #define CONFIG_OVERWRITE_ETHADDR_ONCE
 
 /*-------------------------------------------------------------------------
  *-----------------------------------------------------------------------*/
 
 #define CONFIG_SYS_INIT_RAM_ADDR       0x20000000
-#define CONFIG_SYS_INIT_RAM_SIZE               0x10000
+#define CONFIG_SYS_INIT_RAM_SIZE       0x10000
 #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
  * (Set up by the startup code)
  * Please note that CONFIG_SYS_SDRAM_BASE _must_ start at 0
  */
-#define CONFIG_SYS_SDRAM_BASE1         0x00000000
-#define        CONFIG_SYS_SDRAM_SIZE1          16      /* SDRAM size in MB */
-
-#define CONFIG_SYS_SDRAM_BASE          CONFIG_SYS_SDRAM_BASE1
-#define        CONFIG_SYS_SDRAM_SIZE           CONFIG_SYS_SDRAM_SIZE1
+#define CONFIG_SYS_SDRAM_BASE0         0x00000000
+#define        CONFIG_SYS_SDRAM_SIZE0          16      /* SDRAM size in MB */
 
+#define CONFIG_SYS_SDRAM_BASE          CONFIG_SYS_SDRAM_BASE0
+#define        CONFIG_SYS_SDRAM_SIZE           CONFIG_SYS_SDRAM_SIZE0
 
 /* If M5282 port is fully implemented the monitor base will be behind
  * the vector table. */
 /*-----------------------------------------------------------------------
  * FLASH organization
  */
+#define CONFIG_FLASH_SHOW_PROGRESS     45
 
 #define CONFIG_SYS_FLASH_BASE          CONFIG_SYS_CS0_BASE
 #define        CONFIG_SYS_INT_FLASH_BASE       0xF0000000
 #define CONFIG_SYS_INT_FLASH_ENABLE    0x21
 
-#define        CONFIG_SYS_MAX_FLASH_SECT       35
-#define        CONFIG_SYS_MAX_FLASH_BANKS      2
+#define        CONFIG_SYS_MAX_FLASH_SECT       128
+#define        CONFIG_SYS_MAX_FLASH_BANKS      1
 #define        CONFIG_SYS_FLASH_ERASE_TOUT     10000000
 #define        CONFIG_SYS_FLASH_PROTECTION
 
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_FLASH_SIZE          16*1024*1024
+#define CONFIG_SYS_FLASH_CFI_WIDTH     FLASH_CFI_16BIT
+
+#define CONFIG_SYS_FLASH_BANKS_LIST    { CONFIG_SYS_FLASH_BASE }
+
 /*-----------------------------------------------------------------------
  * Cache Configuration
  */
  * Memory bank definitions
  */
 
-#define CONFIG_SYS_CS0_BASE            0xFFE00000
+#define CONFIG_SYS_CS0_BASE            0xFF000000
 #define CONFIG_SYS_CS0_CTRL            0x00001980
-#define CONFIG_SYS_CS0_MASK            0x001F0001
+#define CONFIG_SYS_CS0_MASK            0x00FF0001
 
-#define CONFIG_SYS_CS3_BASE            0xE0000000
-#define CONFIG_SYS_CS0_CTRL            0x00001980
+#define CONFIG_SYS_CS2_BASE            0xE0000000
+#define CONFIG_SYS_CS2_CTRL            0x00001980
+#define CONFIG_SYS_CS2_MASK            0x000F0001
+
+#define CONFIG_SYS_CS3_BASE            0xE0100000
+#define CONFIG_SYS_CS3_CTRL            0x00001980
 #define CONFIG_SYS_CS3_MASK            0x000F0001
 
 /*-----------------------------------------------------------------------
 #define CONFIG_SYS_PCDDR               0x0000000
 #define CONFIG_SYS_PCDAT               0x0000000
 
+#define CONFIG_SYS_PASPAR              0x0F0F
 #define CONFIG_SYS_PEHLPAR             0xC0
 #define CONFIG_SYS_PUAPAR              0x0F
 #define CONFIG_SYS_DDRUA               0x05
 #define CONFIG_SYS_PJPAR               0xFF
 
+/*-----------------------------------------------------------------------
+ * I2C
+ */
+
+#define CONFIG_HARD_I2C
+#define CONFIG_FSL_I2C
+
+#define CONFIG_SYS_I2C_OFFSET          0x00000300
+#define CONFIG_SYS_IMMR                        CONFIG_SYS_MBAR
+
+#define CONFIG_SYS_I2C_SPEED           100000
+#define CONFIG_SYS_I2C_SLAVE           0
+
+#ifdef CONFIG_CMD_DATE
+#define CONFIG_RTC_DS1338
+#define CONFIG_I2C_RTC_ADDR            0x68
+#endif
+
 /*-----------------------------------------------------------------------
  * VIDEO configuration
  */
 #define CONFIG_VIDEO
 
 #ifdef CONFIG_VIDEO
-#define        CONFIG_VIDEO_VCXK                       1
+#define CONFIG_VIDEO_VCXK                      1
 
 #define CONFIG_SYS_VCXK_DEFAULT_LINEALIGN      2
 #define        CONFIG_SYS_VCXK_DOUBLEBUFFERED          1
-#define CONFIG_SYS_VCXK_BASE                   CONFIG_SYS_CS3_BASE
-#define CONFIG_SYS_VCXK_AUTODETECT             1
+#define CONFIG_SYS_VCXK_BASE                   CONFIG_SYS_CS2_BASE
 
 #define CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT       MCFGPTB_GPTPORT
 #define CONFIG_SYS_VCXK_ACKNOWLEDGE_DDR                MCFGPTB_GPTDDR
index c0e3ed3efcefa1e88b143552c56bd998a496e8cb..8d27590278abc31b2e5b2fbca934c970371a76e2 100644 (file)
@@ -63,6 +63,9 @@
 #define CONFIG_SPL_FRAMEWORK
 #define CONFIG_SPL_BOARD_INIT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_NAND_SIMPLE
 #define CONFIG_SPL_LIBGENERIC_SUPPORT  /* for udelay and __div64_32 for NAND */
 #define CONFIG_SPL_SERIAL_SUPPORT
index 85856f290edecc8f83241d4ac929b4a5d94eda1b..f646ae57764de475ae23d701c8a74eed675a1041 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2011-2012
  * Gerald Kerma <dreagle@doukki.net>
- * Luka Perkov <uboot@lukaperkov.net>
+ * Luka Perkov <luka@openwrt.org>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
index 2b523c9fc97f3a22e4596e60da0a9599153cfd35..ba57849a602f32223b42df8601da632e3eac5745 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * (C) Copyright 2009-2012
  * Wojciech Dubowik <wojciech.dubowik@neratec.com>
- * Luka Perkov <uboot@lukaperkov.net>
+ * Luka Perkov <luka@openwrt.org>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
index c81ab7622eba58c79db128817b93654ea7167532..be7937d70ea718392942e02949f8b2a66fd0b939 100644 (file)
 
 #ifdef CONFIG_BOOT_NAND
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 
 /* NAND boot config */
 #define CONFIG_SYS_NAND_5_ADDR_CYCLE
index 6ae764a2d4a59e85a58fdba6900099c338519335..8fc394245078085f7c0ab164b40edaada00a5223 100644 (file)
@@ -72,9 +72,9 @@
 #define CONFIG_DEFAULT_SPI_MODE        (SPI_MODE_0 | SPI_CS_HIGH)
 
 /* PMIC Controller */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_SPI
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_SPI
+#define CONFIG_POWER_FSL
 #define CONFIG_FSL_PMIC_BUS    1
 #define CONFIG_FSL_PMIC_CS     0
 #define CONFIG_FSL_PMIC_CLK    1000000
index 2d33ebcd711892cf45dde32c39aae2899f5a9fe5..2ebcd1615f083962dbb0df14f36acf98d22f3e45 100644 (file)
 #define CONFIG_USB_EHCI                        /* Enable EHCI USB support      */
 #define CONFIG_USB_EHCI_PPC4XX         /* on PPC4xx platform           */
 #define CONFIG_SYS_PPC4XX_USB_ADDR     0xe0000300
-#define CONFIG_EHCI_DCACHE             /* with dcache handling support */
 #define CONFIG_EHCI_MMIO_BIG_ENDIAN
 #define CONFIG_EHCI_DESC_BIG_ENDIAN
 #define CONFIG_EHCI_HCD_INIT_AFTER_RESET /* re-init HCD after CMD_RESET */
index bf49cc138138c04ffaff06c90448de22cadbf103..e304c994171697e8030196d9b8e2c0a622a6dce3 100644 (file)
 #define CONFIG_USB_EHCI_OMAP
 #define CONFIG_USB_ULPI
 #define CONFIG_USB_ULPI_VIEWPORT_OMAP
-/*#define CONFIG_EHCI_DCACHE*/ /* leave it disabled for now */
 #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO       57
 #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
 
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_POWER_SUPPORT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
 
 #define CONFIG_SPL_TEXT_BASE           0x40200000 /*CONFIG_SYS_SRAM_START*/
index 9d9f4a782290918430c3b865adf240418d5edfef..9e4006b44190a89815a60e7b4d5ad4a9438db4ab 100644 (file)
@@ -68,9 +68,9 @@
 #define CONFIG_MXC_GPIO
 
 /* PMIC Controller */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_SPI
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_SPI
+#define CONFIG_POWER_FSL
 #define CONFIG_FSL_PMIC_BUS    1
 #define CONFIG_FSL_PMIC_CS     0
 #define CONFIG_FSL_PMIC_CLK    1000000
index 6572676970c1835dd45c8f02946680c041958cff..138a94137303fc20e581addf80d143aa42d2f691 100644 (file)
@@ -69,9 +69,9 @@
 #define CONFIG_DEFAULT_SPI_MODE        (SPI_MODE_0 | SPI_CS_HIGH)
 
 /* PMIC Controller */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_SPI
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_SPI
+#define CONFIG_POWER_FSL
 #define CONFIG_FSL_PMIC_BUS    1
 #define CONFIG_FSL_PMIC_CS     2
 #define CONFIG_FSL_PMIC_CLK    1000000
index 1c2f5993d8c1f46555a0ccea43d2b081126056c0..88b2bd6ed4407a76c720c8eb03af539e41460388 100644 (file)
@@ -65,9 +65,9 @@
 /*
  * PMIC Configs
  */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_I2C
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_FSL
 #define CONFIG_PMIC_FSL_MC13892
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR   0x08
 #define CONFIG_RTC_MC13XXX
index a056566efcd8d5b23a88bc68ffc94ccc3d273f36..a74a0a71f199ea61b0c859cedef8c9d5c41c5d54 100644 (file)
 #endif
 
 /* SPI PMIC */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_SPI
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_SPI
+#define CONFIG_POWER_FSL
 #define CONFIG_FSL_PMIC_BUS            0
 #define CONFIG_FSL_PMIC_CS             (0 | 120 << 8)
 #define CONFIG_FSL_PMIC_CLK            25000000
index 4e823553349470b461d09564feeb43cb4ba46c4f..fa0db3824b53449f3e1b9c3b89193b7bb2b955b4 100644 (file)
@@ -69,9 +69,9 @@
 #define CONFIG_MXC_SPI
 
 /* PMIC Controller */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_SPI
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_SPI
+#define CONFIG_POWER_FSL
 #define CONFIG_FSL_PMIC_BUS    0
 #define CONFIG_FSL_PMIC_CS     0
 #define CONFIG_FSL_PMIC_CLK    2500000
index c472075c9adcf9189b85efe02360b0f670b41c44..a0af3eeb26f2783b64b6eca380e0c6894170be77 100644 (file)
@@ -55,9 +55,9 @@
 #define CONFIG_SYS_I2C_SPEED            100000
 
 /* PMIC Configs */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_I2C
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_FSL
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR    8
 #define CONFIG_PMIC_FSL_MC13892
 #define CONFIG_RTC_MC13XXX
index 37f9d69e2609d5afe2154207acbd0363d4716421..e30502b4e216a176f1d1f085e92ebae196151a68 100644 (file)
 #define CONFIG_SYS_I2C_SPEED           100000
 
 /* PMIC Controller */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_I2C
-#define CONFIG_DIALOG_PMIC
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_DIALOG_POWER
+#define CONFIG_POWER_FSL
 #define CONFIG_PMIC_FSL_MC13892
 #define CONFIG_SYS_DIALOG_PMIC_I2C_ADDR        0x48
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR   0x8
index 6ebdaa8768ae2b498db881aae130c796a630f3c2..138e4601807db08ec7231ca54c1b70c882ec678f 100644 (file)
@@ -51,7 +51,7 @@
 #define CONFIG_MMC
 #define CONFIG_CMD_MMC
 #define CONFIG_GENERIC_MMC
-#define CONFIG_MMC_BOUNCE_BUFFER
+#define CONFIG_BOUNCE_BUFFER
 #define CONFIG_CMD_FAT
 #define CONFIG_DOS_PARTITION
 
index b8621b8e1cd4537be1160f4ce35370f431830d40..0f226f790ec0ba32e7553bd7d92090c08aa6bf70 100644 (file)
@@ -46,7 +46,7 @@
 #define CONFIG_MMC
 #define CONFIG_CMD_MMC
 #define CONFIG_GENERIC_MMC
-#define CONFIG_MMC_BOUNCE_BUFFER
+#define CONFIG_BOUNCE_BUFFER
 #define CONFIG_CMD_EXT2
 #define CONFIG_CMD_FAT
 #define CONFIG_DOS_PARTITION
index 759275a03aca33a6f58c9434721b0e8cb9bd62da..4ce4d4c086580a683e53195df7b7155b8c4225d9 100644 (file)
@@ -73,7 +73,7 @@
 #define CONFIG_MMC
 #define CONFIG_CMD_MMC
 #define CONFIG_GENERIC_MMC
-#define CONFIG_MMC_BOUNCE_BUFFER
+#define CONFIG_BOUNCE_BUFFER
 #define CONFIG_CMD_EXT2
 #define CONFIG_CMD_FAT
 #define CONFIG_DOS_PARTITION
index 69ff3efb5045c665d8fafec4ca4bdc84e94adcb0..624bd5c7eee122e916db772b65108bae4381d1c9 100644 (file)
@@ -68,6 +68,7 @@
 #define CONFIG_SYS_ALTERA_PIO_GPIO_NUM LED_PIO_WIDTH
 
 #define CONFIG_STATUS_LED              /* Enable status driver */
+#define CONFIG_BOARD_SPECIFIC_LED
 #define CONFIG_GPIO_LED                /* Enable GPIO LED driver */
 #define CONFIG_GPIO                    /* Enable GPIO driver */
 
index 7a3cc16a09ba2e4ec6c2af060589e90a77753d6e..12d65f2c4e7d344c1ab6fe4387aed6a6903f846b 100644 (file)
 #define CONFIG_SYS_I2C_NOPROBES                {{0x0, 0x0}}
 
 /* USB */
-#define CONFIG_MUSB_UDC                        1
-#define CONFIG_USB_OMAP3               1
+#define CONFIG_MUSB_GADGET
+#define CONFIG_USB_MUSB_OMAP2PLUS
+#define CONFIG_MUSB_PIO_ONLY
+#define CONFIG_USB_GADGET_DUALSPEED
 #define CONFIG_TWL4030_USB             1
-
-/* USB device configuration */
-#define CONFIG_USB_DEVICE              1
-#define CONFIG_USB_TTY                 1
-#define CONFIG_SYS_CONSOLE_IS_IN_ENV   1
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETHER_RNDIS
 
 /* USB EHCI */
 #define CONFIG_CMD_USB
 #define CONFIG_USB_EHCI
 
 #define CONFIG_USB_EHCI_OMAP
-/*#define CONFIG_EHCI_DCACHE*/ /* leave it disabled for now */
 #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO       147
 
 #define CONFIG_USB_ULPI
 #define CONFIG_SPL_FAT_SUPPORT
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_GPIO_SUPPORT
 #define CONFIG_SPL_POWER_SUPPORT
 #define CONFIG_SPL_OMAP3_ID_NAND
index f6e4236998f35cb80f03cebc6daedefdf8e18ed8..b4d925ed9008431710f73222a32261c9e73f64af 100644 (file)
 /* NAND SPL */
 #define CONFIG_SPL_NAND_SIMPLE
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SYS_NAND_5_ADDR_CYCLE
 #define CONFIG_SYS_NAND_PAGE_COUNT     64
 #define CONFIG_SYS_NAND_PAGE_SIZE      2048
index 362fa1d720a06d7940f5f603e75205018d7893aa..8f0258491efa22c546e82e27ae85e188df8e7755 100644 (file)
@@ -81,6 +81,9 @@
  */
 #define CONFIG_SPL_NAND_SIMPLE
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SYS_NAND_5_ADDR_CYCLE
 #define CONFIG_SYS_NAND_PAGE_COUNT     64
 #define CONFIG_SYS_NAND_PAGE_SIZE      2048
index 626cf7afd5c3cce3c2848484fc836fb675faeecb..fd31c739642b5698f3b7e4da0334aef0c9b1058c 100644 (file)
 #define CONFIG_SPL_FAT_SUPPORT
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_GPIO_SUPPORT
 #define CONFIG_SPL_POWER_SUPPORT
 #define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
index 350150b11555a41477061dda9363a4d3e1e9f2c2..964bfcd440bed222e46e74053a320534b4ffff87 100644 (file)
@@ -38,6 +38,7 @@
 #define __SW_BOOT_MASK         0x03
 #define __SW_BOOT_NOR          0xe4
 #define __SW_BOOT_SD           0x54
+#define CONFIG_SYS_L2_SIZE     (256 << 10)
 #endif
 
 #if defined(CONFIG_P1020UTM)
@@ -46,6 +47,7 @@
 #define __SW_BOOT_MASK         0x03
 #define __SW_BOOT_NOR          0xe0
 #define __SW_BOOT_SD           0x50
+#define CONFIG_SYS_L2_SIZE     (256 << 10)
 #endif
 
 #if defined(CONFIG_P1020RDB)
@@ -61,6 +63,7 @@
 #define __SW_BOOT_SD           0x9c
 #define __SW_BOOT_NAND         0xec
 #define __SW_BOOT_PCIE         0x6c
+#define CONFIG_SYS_L2_SIZE     (256 << 10)
 #endif
 
 #if defined(CONFIG_P1021RDB)
@@ -78,6 +81,7 @@
 #define __SW_BOOT_SD           0x9c
 #define __SW_BOOT_NAND         0xec
 #define __SW_BOOT_PCIE         0x6c
+#define CONFIG_SYS_L2_SIZE     (256 << 10)
 #endif
 
 #if defined(CONFIG_P1024RDB)
@@ -91,6 +95,7 @@
 #define __SW_BOOT_SPI          0x08
 #define __SW_BOOT_SD           0x04
 #define __SW_BOOT_NAND         0x0c
+#define CONFIG_SYS_L2_SIZE     (256 << 10)
 #endif
 
 #if defined(CONFIG_P1025RDB)
 #define __SW_BOOT_SPI          0x08
 #define __SW_BOOT_SD           0x04
 #define __SW_BOOT_NAND         0x0c
+#define CONFIG_SYS_L2_SIZE     (256 << 10)
 #endif
 
 #if defined(CONFIG_P2020RDB)
 #define __SW_BOOT_SD           0x68 /* or 0x18 */
 #define __SW_BOOT_NAND         0xe8
 #define __SW_BOOT_PCIE         0xa8
+#define CONFIG_SYS_L2_SIZE     (512 << 10)
+#endif
+
+#if CONFIG_SYS_L2_SIZE >= (512 << 10)
+/* must be 32-bit */
+#define CONFIG_SYS_INIT_L2_ADDR        0xf8f80000
+#define CONFIG_SYS_INIT_L2_ADDR_PHYS CONFIG_SYS_INIT_L2_ADDR
+#define CONFIG_SYS_INIT_L2_END  (CONFIG_SYS_INIT_L2_ADDR + CONFIG_SYS_L2_SIZE)
 #endif
 
 #ifdef CONFIG_SDCARD
 #define CONFIG_RESET_VECTOR_ADDRESS    0x1107fffc
 #endif
 
-#if defined(CONFIG_NAND) && defined(CONFIG_NAND_FSL_ELBC)
-#define CONFIG_NAND_U_BOOT
-#define CONFIG_SYS_EXTRA_ENV_RELOC
-#define CONFIG_SYS_RAMBOOT
-#define CONFIG_SYS_TEXT_BASE_SPL       0xff800000
-#ifdef CONFIG_NAND_SPL
-#define CONFIG_SYS_MONITOR_BASE                CONFIG_SYS_TEXT_BASE_SPL
+#ifdef CONFIG_NAND
+#define CONFIG_SPL
+#define CONFIG_SPL_INIT_MINIMAL
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_MINIMAL
+#define CONFIG_SPL_FLUSH_IMAGE
+#define CONFIG_SPL_TARGET              "u-boot-with-spl.bin"
+
+#define CONFIG_SPL_TEXT_BASE           0xfffff000
+#define CONFIG_SPL_MAX_SIZE            (4 * 1024)
+
+#ifdef CONFIG_SYS_INIT_L2_ADDR
+/* We multiply CONFIG_SPL_MAX_SIZE by two to leave some room for BSS. */
+#define CONFIG_SYS_TEXT_BASE           0xf8f82000
+#define CONFIG_SPL_RELOC_TEXT_BASE     \
+       (CONFIG_SYS_INIT_L2_END - CONFIG_SPL_MAX_SIZE * 2)
+#define CONFIG_SPL_RELOC_STACK         \
+       (CONFIG_SYS_INIT_L2_END - CONFIG_SPL_MAX_SIZE * 2)
+#define CONFIG_SYS_NAND_U_BOOT_DST     (CONFIG_SYS_INIT_L2_ADDR)
+#define CONFIG_SYS_NAND_U_BOOT_START   \
+       (CONFIG_SYS_INIT_L2_ADDR + CONFIG_SPL_MAX_SIZE)
 #else
-#define CONFIG_SYS_TEXT_BASE           0x11001000
-#endif /* CONFIG_NAND_SPL */
+#define CONFIG_SYS_TEXT_BASE           0x00201000
+#define CONFIG_SPL_RELOC_TEXT_BASE     0x00100000
+#define CONFIG_SPL_RELOC_STACK         0x00100000
+#define CONFIG_SYS_NAND_U_BOOT_DST     (0x00200000 - CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SYS_NAND_U_BOOT_START   0x00200000
+#endif
+
+#define CONFIG_SYS_NAND_U_BOOT_SIZE    ((512 << 10) - 0x2000)
+#define CONFIG_SYS_NAND_U_BOOT_OFFS    0
+#define CONFIG_SYS_LDSCRIPT            "arch/powerpc/cpu/mpc85xx/u-boot-nand.lds"
 #endif
 
 #ifndef CONFIG_SYS_TEXT_BASE
 #endif
 
 #ifndef CONFIG_SYS_MONITOR_BASE
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_MONITOR_BASE        CONFIG_SPL_TEXT_BASE
+#else
 #define CONFIG_SYS_MONITOR_BASE        CONFIG_SYS_TEXT_BASE    /* start of monitor */
 #endif
+#endif
 
 /* High Level Configuration Options */
 #define CONFIG_BOOKE
 
 /* IN case of NAND bootloader relocate CCSRBAR in RAMboot code not in the 4k
        SPL code*/
-#if defined(CONFIG_NAND_SPL)
+#ifdef CONFIG_SPL_BUILD
 #define CONFIG_SYS_CCSR_DO_NOT_RELOCATE
 #endif
 
 #define CONFIG_DIMM_SLOTS_PER_CTLR     1
 
 /* Default settings for DDR3 */
-#ifdef CONFIG_P2020RDB
-#define CONFIG_SYS_DDR_CS0_BNDS                0x0000003f
-#define CONFIG_SYS_DDR_CS0_CONFIG      0x80014202
-#define CONFIG_SYS_DDR_CS0_CONFIG_2    0x00000000
-#define CONFIG_SYS_DDR_CS1_BNDS                0x00000000
-#define CONFIG_SYS_DDR_CS1_CONFIG      0x00000000
-#define CONFIG_SYS_DDR_CS1_CONFIG_2    0x00000000
-
-#define CONFIG_SYS_DDR_DATA_INIT       0xdeadbeef
-#define CONFIG_SYS_DDR_INIT_ADDR       0x00000000
-#define CONFIG_SYS_DDR_INIT_EXT_ADDR   0x00000000
-#define CONFIG_SYS_DDR_MODE_CONTROL    0x00000000
-
-#define CONFIG_SYS_DDR_ZQ_CONTROL      0x89080600
-#define CONFIG_SYS_DDR_WRLVL_CONTROL   0x8645F607
-#define CONFIG_SYS_DDR_SR_CNTR         0x00000000
-#define CONFIG_SYS_DDR_RCW_1           0x00000000
-#define CONFIG_SYS_DDR_RCW_2           0x00000000
-#define CONFIG_SYS_DDR_CONTROL         0xC7000000      /* Type = DDR3  */
-#define CONFIG_SYS_DDR_CONTROL_2       0x24401000
-#define CONFIG_SYS_DDR_TIMING_4                0x00220001
-#define CONFIG_SYS_DDR_TIMING_5                0x02401400
-
-#define CONFIG_SYS_DDR_TIMING_3                0x00020000
-#define CONFIG_SYS_DDR_TIMING_0                0x00330104
-#define CONFIG_SYS_DDR_TIMING_1                0x6f6B4644
-#define CONFIG_SYS_DDR_TIMING_2                0x0FA88CCF
-#define CONFIG_SYS_DDR_CLK_CTRL                0x02000000
-#define CONFIG_SYS_DDR_MODE_1          0x00421422
-#define CONFIG_SYS_DDR_MODE_2          0x04000000
-#define CONFIG_SYS_DDR_INTERVAL                0x0C300100
-
-#else
+#ifndef CONFIG_P2020RDB
 #define CONFIG_SYS_DDR_CS0_BNDS                0x0000003f
 #define CONFIG_SYS_DDR_CS0_CONFIG      0x80014302
 #define CONFIG_SYS_DDR_CS0_CONFIG_2    0x00000000
 /*
  * Memory map
  *
- * 0x0000_0000 0x7fff_ffff     DDR     Up to 2GB cacheable
+ * 0x0000_0000 0x7fff_ffff     DDR             Up to 2GB cacheable
  * 0x8000_0000 0xdfff_ffff     PCI Express Mem 1.5G non-cacheable(PCIe * 3)
+ * 0xec00_0000 0xefff_ffff     NOR flash       Up to 64M non-cacheable CS0/1
+ * 0xf8f8_0000 0xf8ff_ffff     L2 SRAM         Up to 512K cacheable
+ *   (early boot only)
+ * 0xff80_0000 0xff80_7fff     NAND flash      32K non-cacheable       CS1/0
+ * 0xff98_0000 0xff98_ffff     PMC             64K non-cacheable       CS2
+ * 0xffa0_0000 0xffaf_ffff     CPLD            1M non-cacheable        CS3
+ * 0xffb0_0000 0xffbf_ffff     VSC7385 switch  1M non-cacheable        CS2
  * 0xffc0_0000 0xffc3_ffff     PCI IO range    256k non-cacheable
- *
- * Localbus cacheable (TBD)
- * 0xXXXX_XXXX 0xXXXX_XXXX     SRAM    YZ M Cacheable
- *
- * Localbus non-cacheable
- * 0xec00_0000 0xefff_ffff     FLASH   Up to 64M non-cacheable
- * 0xff80_0000 0xff8f_ffff     NAND flash      1M non-cacheable
- * 0xff90_0000 0xff97_ffff     L2 SDRAM(REV.)  512K cacheable(optional)
- * 0xffa0_0000 0xffaf_ffff     CPLD    1M non-cacheable
- * 0xffb0_0000 0xffbf_ffff     VSC7385 switch  1M non-cacheable
- * 0xffd0_0000 0xffd0_3fff     L1 for stack    16K Cacheable TLB0
- * 0xffe0_0000 0xffef_ffff     CCSR    1M non-cacheable
+ * 0xffd0_0000 0xffd0_3fff     L1 for stack    16K cacheable
+ * 0xffe0_0000 0xffef_ffff     CCSR            1M non-cacheable
  */
 
 
 #define CONFIG_CMD_NAND
 #define CONFIG_SYS_NAND_BLOCK_SIZE     (16 * 1024)
 
-/* NAND boot: 4K NAND loader config */
-#define CONFIG_SYS_NAND_SPL_SIZE       0x1000
-#define CONFIG_SYS_NAND_U_BOOT_SIZE    ((512 << 10) + CONFIG_SYS_NAND_SPL_SIZE)
-#define CONFIG_SYS_NAND_U_BOOT_DST     (0x11000000 - CONFIG_SYS_NAND_SPL_SIZE)
-#define CONFIG_SYS_NAND_U_BOOT_START   0x11000000
-#define CONFIG_SYS_NAND_U_BOOT_OFFS    (0)
-#define CONFIG_SYS_NAND_U_BOOT_RELOC   0x00010000
-#define CONFIG_SYS_NAND_U_BOOT_RELOC_SP        (CONFIG_SYS_NAND_U_BOOT_RELOC + 0x10000)
-
 #define CONFIG_SYS_NAND_BR_PRELIM (BR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \
        | (2<<BR_DECC_SHIFT)    /* Use HW ECC */ \
        | BR_PS_8       /* Port Size = 8 bit */ \
                                 OR_GPCM_SCY | OR_GPCM_TRLX | OR_GPCM_EHTR | \
                                 OR_GPCM_EAD)
 
-#ifdef CONFIG_NAND_U_BOOT
+#ifdef CONFIG_NAND
 #define CONFIG_SYS_BR0_PRELIM  CONFIG_SYS_NAND_BR_PRELIM /* NAND Base Addr */
 #define CONFIG_SYS_OR0_PRELIM  CONFIG_SYS_NAND_OR_PRELIM /* NAND Options */
 #define CONFIG_SYS_BR1_PRELIM  CONFIG_FLASH_BR_PRELIM  /* NOR Base Address */
 #define CONFIG_SYS_NS16550_SERIAL
 #define CONFIG_SYS_NS16550_REG_SIZE    1
 #define CONFIG_SYS_NS16550_CLK         get_bus_freq(0)
-#ifdef CONFIG_NAND_SPL
+#ifdef CONFIG_SPL_BUILD
 #define CONFIG_NS16550_MIN_FUNCTIONS
 #endif
 
 /*
  * Environment
  */
-#ifdef CONFIG_SYS_RAMBOOT
 #ifdef CONFIG_RAMBOOT_SPIFLASH
 #define CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_ENV_SPI_BUS     0
 #define CONFIG_FSL_FIXED_MMC_LOCATION
 #define CONFIG_ENV_SIZE                0x2000
 #define CONFIG_SYS_MMC_ENV_DEV 0
-#elif defined(CONFIG_NAND_U_BOOT)
+#elif defined(CONFIG_NAND)
 #define CONFIG_ENV_IS_IN_NAND
 #define CONFIG_ENV_SIZE                CONFIG_SYS_NAND_BLOCK_SIZE
 #define CONFIG_ENV_OFFSET      ((512 * 1024) + CONFIG_SYS_NAND_BLOCK_SIZE)
 #define CONFIG_ENV_RANGE       (3 * CONFIG_ENV_SIZE)
-#else
+#elif defined(CONFIG_SYS_RAMBOOT)
 #define CONFIG_ENV_IS_NOWHERE  /* Store ENV in memory only */
 #define CONFIG_ENV_ADDR                (CONFIG_SYS_MONITOR_BASE - 0x1000)
 #define CONFIG_ENV_SIZE                0x2000
-#endif
 #else
 #define CONFIG_ENV_IS_IN_FLASH
 #if CONFIG_SYS_MONITOR_BASE > 0xfff80000
index e43a02110ec84337f3d383d7daab20dfa133f91a..d9bf2010b833ec81c4011a541b9d50916a5981d5 100644 (file)
@@ -58,9 +58,9 @@
 #define CONFIG_DEFAULT_SPI_MODE        (SPI_MODE_0 | SPI_CS_HIGH)
 #define CONFIG_RTC_MC13XXX
 
-#define CONFIG_PMIC
-#define CONFIG_PMIC_SPI
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_SPI
+#define CONFIG_POWER_FSL
 #define CONFIG_FSL_PMIC_BUS    1
 #define CONFIG_FSL_PMIC_CS     0
 #define CONFIG_FSL_PMIC_CLK    100000
index 7e0b30293560a251e230877fe03a759720b6438d..56e83478f8e857fe975e42f610758c0c3a8d2ee8 100644 (file)
 
 #define CONFIG_SYS_CACHELINE_SIZE       64
 
-#define CONFIG_PMIC
-#define CONFIG_PMIC_I2C
-#define CONFIG_PMIC_MAX8998
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_MAX8998
 
 #include <asm/arch/gpio.h>
 /*
index 5fc61364355b367e6aa89ac82945f47db16a5496..894f38bd7db05804f09c6edb046dbe5cb8234e63 100644 (file)
 #define CONFIG_I2C_MULTI_BUS
 #define CONFIG_SYS_MAX_I2C_BUS 7
 
-#define CONFIG_PMIC
-#define CONFIG_PMIC_I2C
-#define CONFIG_PMIC_MAX8998
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_MAX8998
 
 #define CONFIG_USB_GADGET
 #define CONFIG_USB_GADGET_S3C_UDC_OTG
index f5dc3930209b954fb3695a14ec0e91bbb36c6239..cb99d58644da741f33180b3ef6cef00ae38d5697 100644 (file)
 #ifdef CONFIG_CMD_MMC
 #define CONFIG_APBH_DMA
 #define CONFIG_MMC
-#define CONFIG_MMC_BOUNCE_BUFFER
+#define CONFIG_BOUNCE_BUFFER
 #define CONFIG_GENERIC_MMC
 #define CONFIG_MXS_MMC
 #endif
index 74d3b94887701ebd97961a78ed57fad9c56185c6..ab10bd0abc7e57a24e2115eb3fd3698899016dd6 100644 (file)
 #define CONFIG_TEGRA_KEYBOARD
 #define CONFIG_KEYBOARD
 
-#undef TEGRA_DEVICE_SETTINGS
-#define TEGRA_DEVICE_SETTINGS  "stdin=serial,tegra-kbc\0" \
-                               "stdout=serial\0" \
-                               "stderr=serial\0"
+/* USB keyboard */
+#define CONFIG_USB_KEYBOARD
 
 #include "tegra-common-post.h"
 
index 8e6954e3aa774d036a08d5053a20e2563b2d43fb..dd5d7cd260222d8f6c6428b2822f2e82f98c085b 100644 (file)
 #define CONFIG_EHCI_HCD_INIT_AFTER_RESET
 #define CONFIG_EHCI_MMIO_BIG_ENDIAN
 #define CONFIG_EHCI_DESC_BIG_ENDIAN
-#ifdef CONFIG_4xx_DCACHE
-#define CONFIG_EHCI_DCACHE
-#endif
 #else /* CONFIG_USB_EHCI */
 #define CONFIG_USB_OHCI_NEW
 #define CONFIG_SYS_OHCI_BE_CONTROLLER
index dd7757cb97550ffe01d61268a9d014b34a3dc90b..ee73c277b95ad955ea68abef4013cefdf9449b4a 100644 (file)
 #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
 #define CONFIG_USB_STORAGE
 
-/* #define CONFIG_EHCI_DCACHE */
-
 /* commands to include */
 #include <config_cmd_default.h>
 
 #define CONFIG_SPL_GPIO_SUPPORT
 #define CONFIG_SPL_POWER_SUPPORT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
 
 #define CONFIG_SPL_TEXT_BASE           0x40200000 /*CONFIG_SYS_SRAM_START*/
index 6835155d111614804cf5007d7453aa91a00786bb..6f310bee601328b3eab4e492e1c9cbe5b1a6ca80 100644 (file)
        "fdt_addr_r=0x02000000\0" \
        "ramdisk_addr_r=0x02100000\0" \
 
+#ifdef CONFIG_TEGRA_KEYBOARD
+#define STDIN_KBD_KBC ",tegra-kbc"
+#else
+#define STDIN_KBD_KBC ""
+#endif
+
+#ifdef CONFIG_USB_KEYBOARD
+#define STDIN_KBD_USB ",usbkbd"
+#define CONFIG_SYS_USB_EVENT_POLL
+#define CONFIG_PREBOOT                 "usb start"
+#else
+#define STDIN_KBD_USB ""
+#endif
+
+#define TEGRA_DEVICE_SETTINGS \
+       "stdin=serial" STDIN_KBD_KBC STDIN_KBD_USB "\0" \
+       "stdout=serial\0" \
+       "stderr=serial\0" \
+
 #define CONFIG_EXTRA_ENV_SETTINGS \
        TEGRA_DEVICE_SETTINGS \
        MEM_LAYOUT_ENV_SETTINGS \
index 15bd9bb1460dfe1d6b91fc9fe7d376096cef4cea..5c0833a4d8ccfa32e4a893d5d05d337e426e6557 100644 (file)
  */
 #define CONFIG_USB_EHCI_TXFIFO_THRESH  10
 #define CONFIG_EHCI_IS_TDI
-#define CONFIG_EHCI_DCACHE
 
 /* Total I2C ports on Tegra20 */
 #define TEGRA_I2C_NUM_CONTROLLERS      4
 
 #define CONFIG_SYS_NO_FLASH
 
-/* Environment information, boards can override if required */
 #define CONFIG_CONSOLE_MUX
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
-#define TEGRA_DEVICE_SETTINGS  "stdin=serial\0" \
-                               "stdout=serial\0" \
-                               "stderr=serial\0"
 
 #define CONFIG_LOADADDR                0x408000        /* def. location for kernel */
 #define CONFIG_BOOTDELAY       2               /* -1 to disable auto boot */
 #define CONFIG_SYS_NAND_SELF_INIT
 #define CONFIG_SYS_NAND_ONFI_DETECTION
 
+/* Misc utility code */
+#define CONFIG_BOUNCE_BUFFER
+
 #endif /* __TEGRA20_COMMON_H */
index d7808aa7123770c1b227376f84f7e3d8d1dfd86e..355029e8d835a0d4a495c4c1e694472c0e031055 100644 (file)
 #define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin()
 #define I2C_INIT multi_i2c_init()
 
-#define CONFIG_PMIC
-#define CONFIG_PMIC_I2C
-#define CONFIG_PMIC_MAX8997
-
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_MAX8997
+
+#define CONFIG_POWER_FG
+#define CONFIG_POWER_FG_MAX17042
+#define CONFIG_POWER_MUIC
+#define CONFIG_POWER_MUIC_MAX8997
+#define CONFIG_POWER_BATTERY
+#define CONFIG_POWER_BATTERY_TRATS
 #define CONFIG_USB_GADGET
 #define CONFIG_USB_GADGET_S3C_UDC_OTG
 #define CONFIG_USB_GADGET_DUALSPEED
index 5859a7337b724b233e6ea9159581b44c33780a94..be0d2ec3c7c09ff86249f4b054ada87c02a8c216 100644 (file)
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_POWER_SUPPORT
 #define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
 #define CONFIG_SPL_MMC_SUPPORT
 #define CONFIG_SPL_FAT_SUPPORT
 #define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
index f46efa55f1651bfec653bc376b9e51762fa7cd62..9f8f240f82274897935e2593f4790ea08e3a9901 100644 (file)
 #define CONFIG_MXC_GPIO
 
 /* MC13783 connected to CSPI3 and SS0 */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_SPI
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_SPI
+#define CONFIG_POWER_FSL
 
 #define CONFIG_FSL_PMIC_BUS            2
 #define CONFIG_FSL_PMIC_CS             0
index b4b0949522539278617dbde9ff13029f4e64a2c3..7aeb66801eeef1877b01ebc4b1ade5f339696ac2 100644 (file)
  */
 #define CONFIG_USB_EHCI                        /* Enable EHCI USB support      */
 #define CONFIG_USB_EHCI_VCT            /* on VCT platform              */
-#define CONFIG_EHCI_DCACHE             /* with dcache handling support */
 #define CONFIG_EHCI_MMIO_BIG_ENDIAN
 #define CONFIG_EHCI_DESC_BIG_ENDIAN
 #define CONFIG_EHCI_IS_TDI
index b751d58bc890982cf658a745009fc83e5f6c2e74..4c9b31cce30d497864828ba23dcf0d7fee37f440 100644 (file)
@@ -75,6 +75,9 @@
 #define CONFIG_CMD_NET
 #define CONFIG_CMD_DHCP
 
+/* USB keyboard */
+#define CONFIG_USB_KEYBOARD
+
 #include "tegra-common-post.h"
 
 #endif /* __CONFIG_H */
index 13c570299fe54873e7d10f5825c21c443d88da7d..226d04901f5fd58a6a395770efb02d6d713a04df 100644 (file)
@@ -87,9 +87,9 @@
 #define CONFIG_ENV_IS_IN_SPI_FLASH
 
 /* PMIC Controller */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_SPI
-#define CONFIG_PMIC_FSL
+#define CONFIG_POWER
+#define CONFIG_POWER_SPI
+#define CONFIG_POWER_FSL
 #define CONFIG_FSL_PMIC_BUS    0
 #define CONFIG_FSL_PMIC_CS     0
 #define CONFIG_FSL_PMIC_CLK    2500000
index 58a96cffce628653a575677e02fc331974f5d4fd..a1452b96cfebba27b2b0da6fe84ddecdcd339f9f 100644 (file)
 #define CONFIG_MXC_GPIO
 
 /* PMIC Controller */
-#define CONFIG_PMIC
-#define CONFIG_PMIC_I2C
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_FSL
 #define CONFIG_PMIC_FSL_MC13892
-#define CONFIG_PMIC_FSL
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR   0x8
 #define CONFIG_RTC_MC13XXX
 
index 0b140752ffb058c4fa673b10fe6a3ff6e751aab8..5164ce24e61e2686ae6fb664862dfc8363a4238f 100644 (file)
 typedef u64 fdt_addr_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;
 #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)
 #endif
 
 /* Information obtained about memory from the FDT */
@@ -87,6 +89,22 @@ struct fdt_gpio_state {
 /* This tells us whether a fdt_gpio_state record is valid or not */
 #define fdt_gpio_isvalid(x) ((x)->gpio != FDT_GPIO_NONE)
 
+/**
+ * Read the GPIO taking into account the polarity of the pin.
+ *
+ * @param gpio         pointer to the decoded gpio
+ * @return value of the gpio if successful, < 0 if unsuccessful
+ */
+int fdtdec_get_gpio(struct fdt_gpio_state *gpio);
+
+/**
+ * Write the GPIO taking into account the polarity of the pin.
+ *
+ * @param gpio         pointer to the decoded gpio
+ * @return 0 if successful
+ */
+int fdtdec_set_gpio(struct fdt_gpio_state *gpio, int val);
+
 /**
  * Find the next numbered alias for a peripheral. This is used to enumerate
  * all the peripherals of a certain type.
@@ -107,6 +125,19 @@ struct fdt_gpio_state {
 int fdtdec_next_alias(const void *blob, const char *name,
                enum fdt_compat_id id, int *upto);
 
+/**
+ * Find the compatible ID for a given node.
+ *
+ * Generally each node has at least one compatible string attached to it.
+ * This function looks through our list of known compatible strings and
+ * returns the corresponding ID which matches the compatible string.
+ *
+ * @param blob         FDT blob to use
+ * @param node         Node containing compatible string to find
+ * @return compatible ID, or COMPAT_UNKNOWN if we cannot find a match
+ */
+enum fdt_compat_id fdtdec_lookup(const void *blob, int node);
+
 /**
  * Find the next compatible node for a peripheral.
  *
@@ -166,6 +197,21 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node,
 s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
                s32 default_val);
 
+/**
+ * Look up a 64-bit integer property in a node and return it. The property
+ * must have at least 8 bytes of data (2 cells). The first two cells are
+ * concatenated to form a 8 bytes value, where the first cell is top half and
+ * the second cell is bottom half.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name    name of property to find
+ * @param default_val  default value to return if the property is not found
+ * @return integer value, if found, or default_val if not
+ */
+uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name,
+               uint64_t default_val);
+
 /**
  * Checks whether a node is enabled.
  * This looks for a 'status' property. If this exists, then returns 1 if
@@ -342,6 +388,22 @@ int fdtdec_get_bool(const void *blob, int node, const char *prop_name);
 int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
                struct fdt_gpio_state *gpio);
 
+/**
+ * Decode a list of GPIOs from an FDT. This creates a list of GPIOs with no
+ * terminating item.
+ *
+ * @param blob         FDT blob to use
+ * @param node         Node to look at
+ * @param prop_name    Node property name
+ * @param gpio         Array of gpio elements to fill from FDT. This will be
+ *                     untouched if either 0 or an error is returned
+ * @param max_count    Maximum number of elements allowed
+ * @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would
+ * be exceeded, or -FDT_ERR_NOTFOUND if the property is missing.
+ */
+int fdtdec_decode_gpios(const void *blob, int node, const char *prop_name,
+               struct fdt_gpio_state *gpio, int max_count);
+
 /**
  * Set up a GPIO pin according to the provided gpio information. At present this
  * just requests the GPIO.
@@ -354,6 +416,39 @@ int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
  */
 int fdtdec_setup_gpio(struct fdt_gpio_state *gpio);
 
+/**
+ * Look in the FDT for a config item with the given name and return its value
+ * as a 32-bit integer. The property must have at least 4 bytes of data. The
+ * value of the first cell is returned.
+ *
+ * @param blob         FDT blob to use
+ * @param prop_name    Node property name
+ * @param default_val  default value to return if the property is not found
+ * @return integer value, if found, or default_val if not
+ */
+int fdtdec_get_config_int(const void *blob, const char *prop_name,
+               int default_val);
+
+/**
+ * Look in the FDT for a config item with the given name
+ * and return whether it exists.
+ *
+ * @param blob         FDT blob
+ * @param prop_name    property name to look up
+ * @return 1, if it exists, or 0 if not
+ */
+int fdtdec_get_config_bool(const void *blob, const char *prop_name);
+
+/**
+ * Look in the FDT for a config item with the given name and return its value
+ * as a string.
+ *
+ * @param blob          FDT blob
+ * @param prop_name     property name to look up
+ * @returns property string, NULL on error.
+ */
+char *fdtdec_get_config_string(const void *blob, const char *prop_name);
+
 /*
  * Look up a property in a node and return its contents in a byte
  * array of given length. The property must have at least enough data for
@@ -385,4 +480,21 @@ int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name,
  */
 const u8 *fdtdec_locate_byte_array(const void *blob, int node,
                             const char *prop_name, int count);
+
+/**
+ * Look up a property in a node which contains a memory region address and
+ * size. Then return a pointer to this 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
+ * @param ptrp         returns pointer to region, or NULL if no address
+ * @param size         returns size of region
+ * @return 0 if ok, -1 on error (propery not found)
+ */
+int fdtdec_decode_region(const void *blob, int node,
+               const char *prop_name, void **ptrp, size_t *size);
 #endif
index 0ec74403064a19a09df7066cecb676b5918f502e..f47395f35d3133510093080033237ebf54db1aa6 100644 (file)
@@ -22,7 +22,6 @@
 #define __G_DOWNLOAD_H_
 
 #include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
 #include <linux/usb/gadget.h>
 
 int g_dnl_register(const char *s);
index 0a895f2044c21a4b81245caae79ef95af6a6b999..f54d98330634acb99c56c791d674c3cdb6816c70 100644 (file)
@@ -615,6 +615,7 @@ int fit_image_check_type(const void *fit, int noffset, uint8_t type);
 int fit_image_check_comp(const void *fit, int noffset, uint8_t comp);
 int fit_check_format(const void *fit);
 
+int fit_conf_find_compat(const void *fit, const void *fdt);
 int fit_conf_get_node(const void *fit, const char *conf_uname);
 int fit_conf_get_kernel_node(const void *fit, int noffset);
 int fit_conf_get_ramdisk_node(const void *fit, int noffset);
index 42070d76366e8465a84baf3e90a7e95bff429a62..2517d39d4144a5f3d760c9bcb53029b3460c4316 100644 (file)
@@ -294,6 +294,42 @@ void       lcd_printf      (const char *fmt, ...);
 void   lcd_clear(void);
 int    lcd_display_bitmap(ulong bmp_image, int x, int y);
 
+/**
+ * Get the width of the LCD in pixels
+ *
+ * @return width of LCD in pixels
+ */
+int lcd_get_pixel_width(void);
+
+/**
+ * Get the height of the LCD in pixels
+ *
+ * @return height of LCD in pixels
+ */
+int lcd_get_pixel_height(void);
+
+/**
+ * Get the number of text lines/rows on the LCD
+ *
+ * @return number of rows
+ */
+int lcd_get_screen_rows(void);
+
+/**
+ * Get the number of text columns on the LCD
+ *
+ * @return number of columns
+ */
+int lcd_get_screen_columns(void);
+
+/**
+ * Set the position of the text cursor
+ *
+ * @param col  Column to place cursor (0 = left side)
+ * @param row  Row to place cursor (0 = top line)
+ */
+void lcd_position_cursor(unsigned col, unsigned row);
+
 /* Allow boards to customize the information displayed */
 void lcd_show_board_info(void);
 
index bb4a046937a8c08d169b8464c6593f064f4ac5d7..4334fa77e3f6469f7f4d555e0407a4de98c30670 100644 (file)
@@ -122,7 +122,6 @@ static __inline__ void __swab32s(__u32 *addr)
        __arch__swab32s(addr);
 }
 
-#ifdef __BYTEORDER_HAS_U64__
 static __inline__ __attribute__((const)) __u64 __fswab64(__u64 x)
 {
 #  ifdef __SWAB_64_THRU_32__
@@ -141,7 +140,6 @@ static __inline__ void __swab64s(__u64 *addr)
 {
        __arch__swab64s(addr);
 }
-#endif /* __BYTEORDER_HAS_U64__ */
 
 #if defined(__KERNEL__)
 #define swab16 __swab16
index f63e04b634d0195313e96801a645653e118ea71c..e9e904523a5acca89277321383521429e33f0930 100644 (file)
@@ -194,6 +194,9 @@ typedef enum {
 /* Device behaves just like nand, but is readonly */
 #define NAND_ROM               0x00000800
 
+/* Device supports subpage reads */
+#define NAND_SUBPAGE_READ       0x00001000
+
 /* Options valid for Samsung large page devices */
 #define NAND_SAMSUNG_LP_OPTIONS \
        (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
@@ -203,9 +206,7 @@ typedef enum {
 #define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
 #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
 #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
-/* Large page NAND with SOFT_ECC should support subpage reads */
-#define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \
-                                       && (chip->page_shift > 9))
+#define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
 
 /* Non chip related options */
 /*
index ce1d1e10ba63edaa9b5deb43078187c5aa59a9d7..d1d732c2838d3a48788c16fe87bd9552a8558ab8 100644 (file)
  * [c] for consistency, removing all doubt even when it appears to
  *     someone that the two other points are non-issues for that
  *     particular descriptor type.
- *
- * Ported to U-boot by: Thomas Smits <ts.smits@gmail.com> and
- *                      Remy Bohmer <linux@bohmer.net>
  */
 
 #ifndef __LINUX_USB_CH9_H
 #define __LINUX_USB_CH9_H
 
 #include <linux/types.h>       /* __u8 etc */
+#include <asm/byteorder.h>     /* le16_to_cpu */
 
 /*-------------------------------------------------------------------------*/
 
@@ -70,7 +68,7 @@
 #define USB_RECIP_OTHER                        0x03
 /* From Wireless USB 1.0 */
 #define USB_RECIP_PORT                 0x04
-#define USB_RECIP_RPIPE                        0x05
+#define USB_RECIP_RPIPE                0x05
 
 /*
  * Standard requests, for the bRequest field of a SETUP packet.
@@ -90,6 +88,8 @@
 #define USB_REQ_GET_INTERFACE          0x0A
 #define USB_REQ_SET_INTERFACE          0x0B
 #define USB_REQ_SYNCH_FRAME            0x0C
+#define USB_REQ_SET_SEL                        0x30
+#define USB_REQ_SET_ISOCH_DELAY                0x31
 
 #define USB_REQ_SET_ENCRYPTION         0x0D    /* Wireless USB */
 #define USB_REQ_GET_ENCRYPTION         0x0E
 #define USB_REQ_LOOPBACK_DATA_READ     0x16
 #define USB_REQ_SET_INTERFACE_DS       0x17
 
+/* The Link Power Management (LPM) ECN defines USB_REQ_TEST_AND_SET command,
+ * used by hubs to put ports into a new L1 suspend state, except that it
+ * forgot to define its number ...
+ */
+
 /*
  * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
  * are read as a bit array returned by USB_REQ_GET_STATUS.  (So there
- * are at most sixteen features of each type.)
+ * are at most sixteen features of each type.)  Hubs may also support a
+ * new USB_REQ_TEST_AND_SET_FEATURE to put ports into L1 suspend.
  */
 #define USB_DEVICE_SELF_POWERED                0       /* (read only) */
 #define USB_DEVICE_REMOTE_WAKEUP       1       /* dev may initiate wakeup */
 #define USB_DEVICE_A_ALT_HNP_SUPPORT   5       /* (otg) other RH port does */
 #define USB_DEVICE_DEBUG_MODE          6       /* (special devices only) */
 
+/*
+ * Test Mode Selectors
+ * See USB 2.0 spec Table 9-7
+ */
+#define        TEST_J          1
+#define        TEST_K          2
+#define        TEST_SE0_NAK    3
+#define        TEST_PACKET     4
+#define        TEST_FORCE_EN   5
+
+/*
+ * New Feature Selectors as added by USB 3.0
+ * See USB 3.0 spec Table 9-6
+ */
+#define USB_DEVICE_U1_ENABLE   48      /* dev may initiate U1 transition */
+#define USB_DEVICE_U2_ENABLE   49      /* dev may initiate U2 transition */
+#define USB_DEVICE_LTM_ENABLE  50      /* dev may send LTM */
+#define USB_INTRF_FUNC_SUSPEND 0       /* function suspend */
+
+#define USB_INTR_FUNC_SUSPEND_OPT_MASK 0xFF00
+/*
+ * Suspend Options, Table 9-7 USB 3.0 spec
+ */
+#define USB_INTRF_FUNC_SUSPEND_LP      (1 << (8 + 0))
+#define USB_INTRF_FUNC_SUSPEND_RW      (1 << (8 + 1))
+
 #define USB_ENDPOINT_HALT              0       /* IN/OUT will STALL */
 
+/* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
+#define USB_DEV_STAT_U1_ENABLED                2       /* transition into U1 state */
+#define USB_DEV_STAT_U2_ENABLED                3       /* transition into U2 state */
+#define USB_DEV_STAT_LTM_ENABLED       4       /* Latency tolerance messages */
 
 /**
  * struct usb_ctrlrequest - SETUP data for a USB device control request
  * For most devices, interfaces don't coordinate with each other, so
  * such requests may be made at any time.
  */
-#if defined(__BIG_ENDIAN) || defined(__ARMEB__)
-#error (functionality not verified for big endian targets, todo...)
-#endif
-
 struct usb_ctrlrequest {
        __u8 bRequestType;
        __u8 bRequest;
@@ -159,8 +191,12 @@ struct usb_ctrlrequest {
  * (rarely) accepted by SET_DESCRIPTOR.
  *
  * Note that all multi-byte values here are encoded in little endian
- * byte order "on the wire".  But when exposed through Linux-USB APIs,
- * they've been converted to cpu byte order.
+ * byte order "on the wire".  Within the kernel and when exposed
+ * through the Linux-USB APIs, they are not converted to cpu byte
+ * order; it is the responsibility of the client code to do this.
+ * The single exception is when device and configuration descriptors (but
+ * not other descriptors) are read from usbfs (i.e. /proc/bus/usb/BBB/DDD);
+ * in this case the fields are converted to host endianness by the kernel.
  */
 
 /*
@@ -187,6 +223,11 @@ struct usb_ctrlrequest {
 #define USB_DT_WIRELESS_ENDPOINT_COMP  0x11
 #define USB_DT_WIRE_ADAPTER            0x21
 #define USB_DT_RPIPE                   0x22
+#define USB_DT_CS_RADIO_CONTROL                0x23
+/* From the T10 UAS specification */
+#define USB_DT_PIPE_USAGE              0x24
+/* From the USB 3.0 spec */
+#define        USB_DT_SS_ENDPOINT_COMP         0x30
 
 /* Conventional codes for class-specific descriptors.  The convention is
  * defined in the USB "Common Class" Spec (3.11).  Individual class specs
@@ -204,6 +245,28 @@ struct usb_descriptor_header {
        __u8  bDescriptorType;
 } __attribute__ ((packed));
 
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_DEVICE: Device descriptor */
+struct usb_device_descriptor {
+       __u8  bLength;
+       __u8  bDescriptorType;
+
+       __le16 bcdUSB;
+       __u8  bDeviceClass;
+       __u8  bDeviceSubClass;
+       __u8  bDeviceProtocol;
+       __u8  bMaxPacketSize0;
+       __le16 idVendor;
+       __le16 idProduct;
+       __le16 bcdDevice;
+       __u8  iManufacturer;
+       __u8  iProduct;
+       __u8  iSerialNumber;
+       __u8  bNumConfigurations;
+} __attribute__ ((packed));
+
 #define USB_DT_DEVICE_SIZE             18
 
 
@@ -230,6 +293,8 @@ struct usb_descriptor_header {
 #define USB_CLASS_APP_SPEC             0xfe
 #define USB_CLASS_VENDOR_SPEC          0xff
 
+#define USB_SUBCLASS_VENDOR_SPEC       0xff
+
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_CONFIG: Configuration descriptor information.
@@ -260,11 +325,56 @@ struct usb_config_descriptor {
 #define USB_CONFIG_ATT_WAKEUP          (1 << 5)        /* can wakeup */
 #define USB_CONFIG_ATT_BATTERY         (1 << 4)        /* battery powered */
 
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_STRING: String descriptor */
+struct usb_string_descriptor {
+       __u8  bLength;
+       __u8  bDescriptorType;
+
+       __le16 wData[1];                /* UTF-16LE encoded */
+} __attribute__ ((packed));
+
 /* note that "string" zero is special, it holds language codes that
  * the device supports, not Unicode characters.
  */
 
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_INTERFACE: Interface descriptor */
+struct usb_interface_descriptor {
+       __u8  bLength;
+       __u8  bDescriptorType;
+
+       __u8  bInterfaceNumber;
+       __u8  bAlternateSetting;
+       __u8  bNumEndpoints;
+       __u8  bInterfaceClass;
+       __u8  bInterfaceSubClass;
+       __u8  bInterfaceProtocol;
+       __u8  iInterface;
+} __attribute__ ((packed));
+
 #define USB_DT_INTERFACE_SIZE          9
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_ENDPOINT: Endpoint descriptor */
+struct usb_endpoint_descriptor {
+       __u8  bLength;
+       __u8  bDescriptorType;
+
+       __u8  bEndpointAddress;
+       __u8  bmAttributes;
+       __le16 wMaxPacketSize;
+       __u8  bInterval;
+
+       /* NOTE:  these two are _only_ in audio endpoints. */
+       /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
+       __u8  bRefresh;
+       __u8  bSynchAddress;
+} __attribute__ ((packed));
+
 #define USB_DT_ENDPOINT_SIZE           7
 #define USB_DT_ENDPOINT_AUDIO_SIZE     9       /* Audio extension */
 
@@ -282,6 +392,254 @@ struct usb_config_descriptor {
 #define USB_ENDPOINT_XFER_INT          3
 #define USB_ENDPOINT_MAX_ADJUSTABLE    0x80
 
+/* The USB 3.0 spec redefines bits 5:4 of bmAttributes as interrupt ep type. */
+#define USB_ENDPOINT_INTRTYPE          0x30
+#define USB_ENDPOINT_INTR_PERIODIC     (0 << 4)
+#define USB_ENDPOINT_INTR_NOTIFICATION (1 << 4)
+
+#define USB_ENDPOINT_SYNCTYPE          0x0c
+#define USB_ENDPOINT_SYNC_NONE         (0 << 2)
+#define USB_ENDPOINT_SYNC_ASYNC                (1 << 2)
+#define USB_ENDPOINT_SYNC_ADAPTIVE     (2 << 2)
+#define USB_ENDPOINT_SYNC_SYNC         (3 << 2)
+
+#define USB_ENDPOINT_USAGE_MASK                0x30
+#define USB_ENDPOINT_USAGE_DATA                0x00
+#define USB_ENDPOINT_USAGE_FEEDBACK    0x10
+#define USB_ENDPOINT_USAGE_IMPLICIT_FB 0x20    /* Implicit feedback Data endpoint */
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_endpoint_num - get the endpoint's number
+ * @epd: endpoint to be checked
+ *
+ * Returns @epd's number: 0 to 15.
+ */
+static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
+{
+       return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+}
+
+/**
+ * usb_endpoint_type - get the endpoint's transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns one of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according
+ * to @epd's transfer type.
+ */
+static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
+{
+       return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+}
+
+/**
+ * usb_endpoint_dir_in - check if the endpoint has IN direction
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type IN, otherwise it returns false.
+ */
+static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
+}
+
+/**
+ * usb_endpoint_dir_out - check if the endpoint has OUT direction
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type OUT, otherwise it returns false.
+ */
+static inline int usb_endpoint_dir_out(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
+}
+
+/**
+ * usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type bulk, otherwise it returns false.
+ */
+static inline int usb_endpoint_xfer_bulk(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+               USB_ENDPOINT_XFER_BULK);
+}
+
+/**
+ * usb_endpoint_xfer_control - check if the endpoint has control transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type control, otherwise it returns false.
+ */
+static inline int usb_endpoint_xfer_control(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+               USB_ENDPOINT_XFER_CONTROL);
+}
+
+/**
+ * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type interrupt, otherwise it returns
+ * false.
+ */
+static inline int usb_endpoint_xfer_int(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+               USB_ENDPOINT_XFER_INT);
+}
+
+/**
+ * usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type isochronous, otherwise it returns
+ * false.
+ */
+static inline int usb_endpoint_xfer_isoc(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+               USB_ENDPOINT_XFER_ISOC);
+}
+
+/**
+ * usb_endpoint_is_bulk_in - check if the endpoint is bulk IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has bulk transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_bulk_in(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd);
+}
+
+/**
+ * usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has bulk transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_bulk_out(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd);
+}
+
+/**
+ * usb_endpoint_is_int_in - check if the endpoint is interrupt IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has interrupt transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_int_in(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd);
+}
+
+/**
+ * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has interrupt transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_int_out(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd);
+}
+
+/**
+ * usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has isochronous transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_isoc_in(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd);
+}
+
+/**
+ * usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has isochronous transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_isoc_out(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd);
+}
+
+/**
+ * usb_endpoint_maxp - get endpoint's max packet size
+ * @epd: endpoint to be checked
+ *
+ * Returns @epd's max packet
+ */
+static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd)
+{
+       return __le16_to_cpu(epd->wMaxPacketSize);
+}
+
+static inline int usb_endpoint_interrupt_type(
+               const struct usb_endpoint_descriptor *epd)
+{
+       return epd->bmAttributes & USB_ENDPOINT_INTRTYPE;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_SS_ENDPOINT_COMP: SuperSpeed Endpoint Companion descriptor */
+struct usb_ss_ep_comp_descriptor {
+       __u8  bLength;
+       __u8  bDescriptorType;
+
+       __u8  bMaxBurst;
+       __u8  bmAttributes;
+       __le16 wBytesPerInterval;
+} __attribute__ ((packed));
+
+#define USB_DT_SS_EP_COMP_SIZE         6
+
+/* Bits 4:0 of bmAttributes if this is a bulk endpoint */
+static inline int
+usb_ss_max_streams(const struct usb_ss_ep_comp_descriptor *comp)
+{
+       int             max_streams;
+
+       if (!comp)
+               return 0;
+
+       max_streams = comp->bmAttributes & 0x1f;
+
+       if (!max_streams)
+               return 0;
+
+       max_streams = 1 << max_streams;
+
+       return max_streams;
+}
+
+/* Bits 1:0 of bmAttributes if this is an isoc endpoint */
+#define USB_SS_MULT(p)                 (1 + ((p) & 0x3))
 
 /*-------------------------------------------------------------------------*/
 
@@ -388,7 +746,7 @@ struct usb_encryption_descriptor {
 
 /*-------------------------------------------------------------------------*/
 
-/* USB_DT_BOS:  group of wireless capabilities */
+/* USB_DT_BOS:  group of device-level capabilities */
 struct usb_bos_descriptor {
        __u8  bLength;
        __u8  bDescriptorType;
@@ -397,6 +755,7 @@ struct usb_bos_descriptor {
        __u8  bNumDeviceCaps;
 } __attribute__((packed));
 
+#define USB_DT_BOS_SIZE                5
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_DEVICE_CAPABILITY:  grouped with BOS */
@@ -434,6 +793,61 @@ struct usb_wireless_cap_descriptor {       /* Ultra Wide Band */
        __u8  bReserved;
 } __attribute__((packed));
 
+/* USB 2.0 Extension descriptor */
+#define        USB_CAP_TYPE_EXT                2
+
+struct usb_ext_cap_descriptor {                /* Link Power Management */
+       __u8  bLength;
+       __u8  bDescriptorType;
+       __u8  bDevCapabilityType;
+       __le32 bmAttributes;
+#define USB_LPM_SUPPORT                        (1 << 1)        /* supports LPM */
+#define USB_BESL_SUPPORT               (1 << 2)        /* supports BESL */
+#define USB_BESL_BASELINE_VALID                (1 << 3)        /* Baseline BESL valid*/
+#define USB_BESL_DEEP_VALID            (1 << 4)        /* Deep BESL valid */
+#define USB_GET_BESL_BASELINE(p)       (((p) & (0xf << 8)) >> 8)
+#define USB_GET_BESL_DEEP(p)           (((p) & (0xf << 12)) >> 12)
+} __attribute__((packed));
+
+#define USB_DT_USB_EXT_CAP_SIZE        7
+
+/*
+ * SuperSpeed USB Capability descriptor: Defines the set of SuperSpeed USB
+ * specific device level capabilities
+ */
+#define                USB_SS_CAP_TYPE         3
+struct usb_ss_cap_descriptor {         /* Link Power Management */
+       __u8  bLength;
+       __u8  bDescriptorType;
+       __u8  bDevCapabilityType;
+       __u8  bmAttributes;
+#define USB_LTM_SUPPORT                        (1 << 1) /* supports LTM */
+       __le16 wSpeedSupported;
+#define USB_LOW_SPEED_OPERATION                (1)      /* Low speed operation */
+#define USB_FULL_SPEED_OPERATION       (1 << 1) /* Full speed operation */
+#define USB_HIGH_SPEED_OPERATION       (1 << 2) /* High speed operation */
+#define USB_5GBPS_OPERATION            (1 << 3) /* Operation at 5Gbps */
+       __u8  bFunctionalitySupport;
+       __u8  bU1devExitLat;
+       __le16 bU2DevExitLat;
+} __attribute__((packed));
+
+#define USB_DT_USB_SS_CAP_SIZE 10
+
+/*
+ * Container ID Capability descriptor: Defines the instance unique ID used to
+ * identify the instance across all operating modes
+ */
+#define        CONTAINER_ID_TYPE       4
+struct usb_ss_container_id_descriptor {
+       __u8  bLength;
+       __u8  bDescriptorType;
+       __u8  bDevCapabilityType;
+       __u8  bReserved;
+       __u8  ContainerID[16]; /* 128-bit number */
+} __attribute__((packed));
+
+#define USB_DT_USB_SS_CONTN_ID_SIZE    20
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_WIRELESS_ENDPOINT_COMP:  companion descriptor associated with
@@ -491,9 +905,22 @@ enum usb_device_speed {
        USB_SPEED_UNKNOWN = 0,                  /* enumerating */
        USB_SPEED_LOW, USB_SPEED_FULL,          /* usb 1.1 */
        USB_SPEED_HIGH,                         /* usb 2.0 */
-       USB_SPEED_VARIABLE,                     /* wireless (usb 2.5) */
+       USB_SPEED_WIRELESS,                     /* wireless (usb 2.5) */
+       USB_SPEED_SUPER,                        /* usb 3.0 */
 };
 
+#ifdef __KERNEL__
+
+/**
+ * usb_speed_string() - Returns human readable-name of the speed.
+ * @speed: The speed to return human-readable name for.  If it's not
+ *   any of the speeds defined in usb_device_speed enum, string for
+ *   USB_SPEED_UNKNOWN will be returned.
+ */
+extern const char *usb_speed_string(enum usb_device_speed speed);
+
+#endif
+
 enum usb_device_state {
        /* NOTATTACHED isn't in the USB spec, and this state acts
         * the same as ATTACHED ... but it's clearer this way.
@@ -503,8 +930,8 @@ enum usb_device_state {
        /* chapter 9 and authentication (wireless) device states */
        USB_STATE_ATTACHED,
        USB_STATE_POWERED,                      /* wired */
-       USB_STATE_UNAUTHENTICATED,              /* auth */
        USB_STATE_RECONNECTING,                 /* auth */
+       USB_STATE_UNAUTHENTICATED,              /* auth */
        USB_STATE_DEFAULT,                      /* limited function */
        USB_STATE_ADDRESS,
        USB_STATE_CONFIGURED,                   /* most functions */
@@ -514,7 +941,64 @@ enum usb_device_state {
        /* NOTE:  there are actually four different SUSPENDED
         * states, returning to POWERED, DEFAULT, ADDRESS, or
         * CONFIGURED respectively when SOF tokens flow again.
+        * At this level there's no difference between L1 and L2
+        * suspend states.  (L2 being original USB 1.1 suspend.)
         */
 };
 
-#endif /* __LINUX_USB_CH9_H */
+enum usb3_link_state {
+       USB3_LPM_U0 = 0,
+       USB3_LPM_U1,
+       USB3_LPM_U2,
+       USB3_LPM_U3
+};
+
+/*
+ * A U1 timeout of 0x0 means the parent hub will reject any transitions to U1.
+ * 0xff means the parent hub will accept transitions to U1, but will not
+ * initiate a transition.
+ *
+ * A U1 timeout of 0x1 to 0x7F also causes the hub to initiate a transition to
+ * U1 after that many microseconds.  Timeouts of 0x80 to 0xFE are reserved
+ * values.
+ *
+ * A U2 timeout of 0x0 means the parent hub will reject any transitions to U2.
+ * 0xff means the parent hub will accept transitions to U2, but will not
+ * initiate a transition.
+ *
+ * A U2 timeout of 0x1 to 0xFE also causes the hub to initiate a transition to
+ * U2 after N*256 microseconds.  Therefore a U2 timeout value of 0x1 means a U2
+ * idle timer of 256 microseconds, 0x2 means 512 microseconds, 0xFE means
+ * 65.024ms.
+ */
+#define USB3_LPM_DISABLED              0x0
+#define USB3_LPM_U1_MAX_TIMEOUT                0x7F
+#define USB3_LPM_U2_MAX_TIMEOUT                0xFE
+#define USB3_LPM_DEVICE_INITIATED      0xFF
+
+struct usb_set_sel_req {
+       __u8    u1_sel;
+       __u8    u1_pel;
+       __le16  u2_sel;
+       __le16  u2_pel;
+} __attribute__ ((packed));
+
+/*
+ * The Set System Exit Latency control transfer provides one byte each for
+ * U1 SEL and U1 PEL, so the max exit latency is 0xFF.  U2 SEL and U2 PEL each
+ * are two bytes long.
+ */
+#define USB3_LPM_MAX_U1_SEL_PEL                0xFF
+#define USB3_LPM_MAX_U2_SEL_PEL                0xFFFF
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * As per USB compliance update, a device that is actively drawing
+ * more than 100mA from USB must report itself as bus-powered in
+ * the GetStatus(DEVICE) call.
+ * http://compliance.usb.org/index.asp?UpdateFile=Electrical&Format=Standard#34
+ */
+#define USB_SELF_POWER_VBUS_MAX_DRAW           100
+
+#endif /* __LINUX_USB_CH9_H */
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
new file mode 100644 (file)
index 0000000..9f65ef9
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * This is used to for host and peripheral modes of the driver for
+ * Inventra (Multidrop) Highspeed Dual-Role Controllers:  (M)HDRC.
+ *
+ * Board initialization should put one of these into dev->platform_data,
+ * probably on some platform_device named "musb-hdrc".  It encapsulates
+ * key configuration differences between boards.
+ */
+
+#ifndef __LINUX_USB_MUSB_H
+#define __LINUX_USB_MUSB_H
+
+#ifndef __deprecated
+#define __deprecated
+#endif
+
+/* The USB role is defined by the connector used on the board, so long as
+ * standards are being followed.  (Developer boards sometimes won't.)
+ */
+enum musb_mode {
+       MUSB_UNDEFINED = 0,
+       MUSB_HOST,              /* A or Mini-A connector */
+       MUSB_PERIPHERAL,        /* B or Mini-B connector */
+       MUSB_OTG                /* Mini-AB connector */
+};
+
+struct clk;
+
+enum musb_fifo_style {
+       FIFO_RXTX,
+       FIFO_TX,
+       FIFO_RX
+} __attribute__ ((packed));
+
+enum musb_buf_mode {
+       BUF_SINGLE,
+       BUF_DOUBLE
+} __attribute__ ((packed));
+
+struct musb_fifo_cfg {
+       u8                      hw_ep_num;
+       enum musb_fifo_style    style;
+       enum musb_buf_mode      mode;
+       u16                     maxpacket;
+};
+
+#define MUSB_EP_FIFO(ep, st, m, pkt)           \
+{                                              \
+       .hw_ep_num      = ep,                   \
+       .style          = st,                   \
+       .mode           = m,                    \
+       .maxpacket      = pkt,                  \
+}
+
+#define MUSB_EP_FIFO_SINGLE(ep, st, pkt)       \
+       MUSB_EP_FIFO(ep, st, BUF_SINGLE, pkt)
+
+#define MUSB_EP_FIFO_DOUBLE(ep, st, pkt)       \
+       MUSB_EP_FIFO(ep, st, BUF_DOUBLE, pkt)
+
+struct musb_hdrc_eps_bits {
+       const char      name[16];
+       u8              bits;
+};
+
+struct musb_hdrc_config {
+       struct musb_fifo_cfg    *fifo_cfg;      /* board fifo configuration */
+       unsigned                fifo_cfg_size;  /* size of the fifo configuration */
+
+       /* MUSB configuration-specific details */
+       unsigned        multipoint:1;   /* multipoint device */
+       unsigned        dyn_fifo:1 __deprecated; /* supports dynamic fifo sizing */
+       unsigned        soft_con:1 __deprecated; /* soft connect required */
+       unsigned        utm_16:1 __deprecated; /* utm data witdh is 16 bits */
+       unsigned        big_endian:1;   /* true if CPU uses big-endian */
+       unsigned        mult_bulk_tx:1; /* Tx ep required for multbulk pkts */
+       unsigned        mult_bulk_rx:1; /* Rx ep required for multbulk pkts */
+       unsigned        high_iso_tx:1;  /* Tx ep required for HB iso */
+       unsigned        high_iso_rx:1;  /* Rx ep required for HD iso */
+       unsigned        dma:1 __deprecated; /* supports DMA */
+       unsigned        vendor_req:1 __deprecated; /* vendor registers required */
+
+       u8              num_eps;        /* number of endpoints _with_ ep0 */
+       u8              dma_channels __deprecated; /* number of dma channels */
+       u8              dyn_fifo_size;  /* dynamic size in bytes */
+       u8              vendor_ctrl __deprecated; /* vendor control reg width */
+       u8              vendor_stat __deprecated; /* vendor status reg witdh */
+       u8              dma_req_chan __deprecated; /* bitmask for required dma channels */
+       u8              ram_bits;       /* ram address size */
+
+       struct musb_hdrc_eps_bits *eps_bits __deprecated;
+#ifdef CONFIG_BLACKFIN
+       /* A GPIO controlling VRSEL in Blackfin */
+       unsigned int    gpio_vrsel;
+       unsigned int    gpio_vrsel_active;
+       /* musb CLKIN in Blackfin in MHZ */
+       unsigned char   clkin;
+#endif
+
+};
+
+struct musb_hdrc_platform_data {
+       /* MUSB_HOST, MUSB_PERIPHERAL, or MUSB_OTG */
+       u8              mode;
+
+       /* for clk_get() */
+       const char      *clock;
+
+       /* (HOST or OTG) switch VBUS on/off */
+       int             (*set_vbus)(struct device *dev, int is_on);
+
+       /* (HOST or OTG) mA/2 power supplied on (default = 8mA) */
+       u8              power;
+
+       /* (PERIPHERAL) mA/2 max power consumed (default = 100mA) */
+       u8              min_power;
+
+       /* (HOST or OTG) msec/2 after VBUS on till power good */
+       u8              potpgt;
+
+       /* (HOST or OTG) program PHY for external Vbus */
+       unsigned        extvbus:1;
+
+       /* Power the device on or off */
+       int             (*set_power)(int state);
+
+       /* MUSB configuration-specific details */
+       struct musb_hdrc_config *config;
+
+       /* Architecture specific board data     */
+       void            *board_data;
+
+       /* Platform specific struct musb_ops pointer */
+       const void      *platform_ops;
+};
+
+
+/* TUSB 6010 support */
+
+#define        TUSB6010_OSCCLK_60      16667   /* psec/clk @ 60.0 MHz */
+#define        TUSB6010_REFCLK_24      41667   /* psec/clk @ 24.0 MHz XI */
+#define        TUSB6010_REFCLK_19      52083   /* psec/clk @ 19.2 MHz CLKIN */
+
+#ifdef CONFIG_ARCH_OMAP2
+
+extern int __init tusb6010_setup_interface(
+               struct musb_hdrc_platform_data *data,
+               unsigned ps_refclk, unsigned waitpin,
+               unsigned async_cs, unsigned sync_cs,
+               unsigned irq, unsigned dmachan);
+
+extern int tusb6010_platform_retime(unsigned is_refclk);
+
+#endif /* OMAP2 */
+
+/*
+ * U-Boot specfic stuff
+ */
+int musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
+                       void *ctl_regs);
+
+#endif /* __LINUX_USB_MUSB_H */
index bbe28b20bbcfbb552abff3c0845cd01658ca19b6..dded4e27f059d6c6fb4e3987009a722433cf2ad6 100644 (file)
@@ -139,6 +139,7 @@ int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
                        u_char *buffer, int flags);
 int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);
+int nand_torture(nand_info_t *nand, loff_t offset);
 
 #define NAND_LOCK_STATUS_TIGHT 0x01
 #define NAND_LOCK_STATUS_UNLOCK 0x04
index df8126a66e4753f84f4299e8a15f78e173c7b57b..cbca0dc01fca50ec88d247f60d25c1b2ec3c1872 100644 (file)
@@ -24,8 +24,6 @@
 #ifndef __NIOS2_H__
 #define __NIOS2_H__
 
-#include <linux/stringify.h>
-
 /*------------------------------------------------------------------------
  * Control registers -- use with wrctl() & rdctl()
  *----------------------------------------------------------------------*/
  * Access to control regs
  *----------------------------------------------------------------------*/
 
-#define rdctl(reg)\
-       ({unsigned int val;\
-       asm volatile("rdctl %0, ctl" __stringify(reg) \
-               : "=r" (val) ); val;})
-
-#define wrctl(reg,val)\
-       asm volatile( "wrctl ctl" _str_(reg) ",%0"\
-               : : "r" (val))
+#define rdctl(reg) __builtin_rdctl(reg)
+#define wrctl(reg, val) __builtin_wrctl(reg, val)
 
 /*------------------------------------------------------------------------
  * Control reg bit masks
index eba122f8c0e14b48d405e5fd8e55ac607fbf6e08..15f583f069d4ca1c45f09893542af487cb37f998 100644 (file)
 #define PCI_CLASS_PROG         0x09    /* Reg. Level Programming Interface */
 #define PCI_CLASS_DEVICE       0x0a    /* Device class */
 #define PCI_CLASS_CODE         0x0b    /* Device class code */
+#define  PCI_CLASS_CODE_TOO_OLD        0x00
+#define  PCI_CLASS_CODE_STORAGE 0x01
+#define  PCI_CLASS_CODE_NETWORK 0x02
+#define  PCI_CLASS_CODE_DISPLAY        0x03
+#define  PCI_CLASS_CODE_MULTIMEDIA 0x04
+#define  PCI_CLASS_CODE_MEMORY 0x05
+#define  PCI_CLASS_CODE_BRIDGE 0x06
+#define  PCI_CLASS_CODE_COMM   0x07
+#define  PCI_CLASS_CODE_PERIPHERAL 0x08
+#define  PCI_CLASS_CODE_INPUT  0x09
+#define  PCI_CLASS_CODE_DOCKING        0x0A
+#define  PCI_CLASS_CODE_PROCESSOR 0x0B
+#define  PCI_CLASS_CODE_SERIAL 0x0C
+#define  PCI_CLASS_CODE_WIRELESS 0x0D
+#define  PCI_CLASS_CODE_I2O    0x0E
+#define  PCI_CLASS_CODE_SATELLITE 0x0F
+#define  PCI_CLASS_CODE_CRYPTO 0x10
+#define  PCI_CLASS_CODE_DATA   0x11
+/* Base Class 0x12 - 0xFE is reserved */
+#define  PCI_CLASS_CODE_OTHER  0xFF
+
 #define PCI_CLASS_SUB_CODE     0x0a    /* Device sub-class code */
+#define  PCI_CLASS_SUB_CODE_TOO_OLD_NOTVGA     0x00
+#define  PCI_CLASS_SUB_CODE_TOO_OLD_VGA                0x01
+#define  PCI_CLASS_SUB_CODE_STORAGE_SCSI       0x00
+#define  PCI_CLASS_SUB_CODE_STORAGE_IDE                0x01
+#define  PCI_CLASS_SUB_CODE_STORAGE_FLOPPY     0x02
+#define  PCI_CLASS_SUB_CODE_STORAGE_IPIBUS     0x03
+#define  PCI_CLASS_SUB_CODE_STORAGE_RAID       0x04
+#define  PCI_CLASS_SUB_CODE_STORAGE_ATA                0x05
+#define  PCI_CLASS_SUB_CODE_STORAGE_SATA       0x06
+#define  PCI_CLASS_SUB_CODE_STORAGE_SAS                0x07
+#define  PCI_CLASS_SUB_CODE_STORAGE_OTHER      0x80
+#define  PCI_CLASS_SUB_CODE_NETWORK_ETHERNET   0x00
+#define  PCI_CLASS_SUB_CODE_NETWORK_TOKENRING  0x01
+#define  PCI_CLASS_SUB_CODE_NETWORK_FDDI       0x02
+#define  PCI_CLASS_SUB_CODE_NETWORK_ATM                0x03
+#define  PCI_CLASS_SUB_CODE_NETWORK_ISDN       0x04
+#define  PCI_CLASS_SUB_CODE_NETWORK_WORLDFIP   0x05
+#define  PCI_CLASS_SUB_CODE_NETWORK_PICMG      0x06
+#define  PCI_CLASS_SUB_CODE_NETWORK_OTHER      0x80
+#define  PCI_CLASS_SUB_CODE_DISPLAY_VGA                0x00
+#define  PCI_CLASS_SUB_CODE_DISPLAY_XGA                0x01
+#define  PCI_CLASS_SUB_CODE_DISPLAY_3D         0x02
+#define  PCI_CLASS_SUB_CODE_DISPLAY_OTHER      0x80
+#define  PCI_CLASS_SUB_CODE_MULTIMEDIA_VIDEO   0x00
+#define  PCI_CLASS_SUB_CODE_MULTIMEDIA_AUDIO   0x01
+#define  PCI_CLASS_SUB_CODE_MULTIMEDIA_PHONE   0x02
+#define  PCI_CLASS_SUB_CODE_MULTIMEDIA_OTHER   0x80
+#define  PCI_CLASS_SUB_CODE_MEMORY_RAM         0x00
+#define  PCI_CLASS_SUB_CODE_MEMORY_FLASH       0x01
+#define  PCI_CLASS_SUB_CODE_MEMORY_OTHER       0x80
+#define  PCI_CLASS_SUB_CODE_BRIDGE_HOST                0x00
+#define  PCI_CLASS_SUB_CODE_BRIDGE_ISA         0x01
+#define  PCI_CLASS_SUB_CODE_BRIDGE_EISA                0x02
+#define  PCI_CLASS_SUB_CODE_BRIDGE_MCA         0x03
+#define  PCI_CLASS_SUB_CODE_BRIDGE_PCI         0x04
+#define  PCI_CLASS_SUB_CODE_BRIDGE_PCMCIA      0x05
+#define  PCI_CLASS_SUB_CODE_BRIDGE_NUBUS       0x06
+#define  PCI_CLASS_SUB_CODE_BRIDGE_CARDBUS     0x07
+#define  PCI_CLASS_SUB_CODE_BRIDGE_RACEWAY     0x08
+#define  PCI_CLASS_SUB_CODE_BRIDGE_SEMI_PCI    0x09
+#define  PCI_CLASS_SUB_CODE_BRIDGE_INFINIBAND  0x0A
+#define  PCI_CLASS_SUB_CODE_BRIDGE_OTHER       0x80
+#define  PCI_CLASS_SUB_CODE_COMM_SERIAL                0x00
+#define  PCI_CLASS_SUB_CODE_COMM_PARALLEL      0x01
+#define  PCI_CLASS_SUB_CODE_COMM_MULTIPORT     0x02
+#define  PCI_CLASS_SUB_CODE_COMM_MODEM         0x03
+#define  PCI_CLASS_SUB_CODE_COMM_GPIB          0x04
+#define  PCI_CLASS_SUB_CODE_COMM_SMARTCARD     0x05
+#define  PCI_CLASS_SUB_CODE_COMM_OTHER         0x80
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_PIC     0x00
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_DMA     0x01
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_TIMER   0x02
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_RTC     0x03
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_HOTPLUG 0x04
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_SD      0x05
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_OTHER   0x80
+#define  PCI_CLASS_SUB_CODE_INPUT_KEYBOARD     0x00
+#define  PCI_CLASS_SUB_CODE_INPUT_DIGITIZER    0x01
+#define  PCI_CLASS_SUB_CODE_INPUT_MOUSE                0x02
+#define  PCI_CLASS_SUB_CODE_INPUT_SCANNER      0x03
+#define  PCI_CLASS_SUB_CODE_INPUT_GAMEPORT     0x04
+#define  PCI_CLASS_SUB_CODE_INPUT_OTHER                0x80
+#define  PCI_CLASS_SUB_CODE_DOCKING_GENERIC    0x00
+#define  PCI_CLASS_SUB_CODE_DOCKING_OTHER      0x80
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_386      0x00
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_486      0x01
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_PENTIUM  0x02
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_ALPHA    0x10
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_POWERPC  0x20
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_MIPS     0x30
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_COPROC   0x40
+#define  PCI_CLASS_SUB_CODE_SERIAL_1394                0x00
+#define  PCI_CLASS_SUB_CODE_SERIAL_ACCESSBUS   0x01
+#define  PCI_CLASS_SUB_CODE_SERIAL_SSA         0x02
+#define  PCI_CLASS_SUB_CODE_SERIAL_USB         0x03
+#define  PCI_CLASS_SUB_CODE_SERIAL_FIBRECHAN   0x04
+#define  PCI_CLASS_SUB_CODE_SERIAL_SMBUS       0x05
+#define  PCI_CLASS_SUB_CODE_SERIAL_INFINIBAND  0x06
+#define  PCI_CLASS_SUB_CODE_SERIAL_IPMI                0x07
+#define  PCI_CLASS_SUB_CODE_SERIAL_SERCOS      0x08
+#define  PCI_CLASS_SUB_CODE_SERIAL_CANBUS      0x09
+#define  PCI_CLASS_SUB_CODE_WIRELESS_IRDA      0x00
+#define  PCI_CLASS_SUB_CODE_WIRELESS_IR                0x01
+#define  PCI_CLASS_SUB_CODE_WIRELESS_RF                0x10
+#define  PCI_CLASS_SUB_CODE_WIRELESS_BLUETOOTH 0x11
+#define  PCI_CLASS_SUB_CODE_WIRELESS_BROADBAND 0x12
+#define  PCI_CLASS_SUB_CODE_WIRELESS_80211A    0x20
+#define  PCI_CLASS_SUB_CODE_WIRELESS_80211B    0x21
+#define  PCI_CLASS_SUB_CODE_WIRELESS_OTHER     0x80
+#define  PCI_CLASS_SUB_CODE_I2O_V1_0           0x00
+#define  PCI_CLASS_SUB_CODE_SATELLITE_TV       0x01
+#define  PCI_CLASS_SUB_CODE_SATELLITE_AUDIO    0x02
+#define  PCI_CLASS_SUB_CODE_SATELLITE_VOICE    0x03
+#define  PCI_CLASS_SUB_CODE_SATELLITE_DATA     0x04
+#define  PCI_CLASS_SUB_CODE_CRYPTO_NETWORK     0x00
+#define  PCI_CLASS_SUB_CODE_CRYPTO_ENTERTAINMENT 0x10
+#define  PCI_CLASS_SUB_CODE_CRYPTO_OTHER       0x80
+#define  PCI_CLASS_SUB_CODE_DATA_DPIO          0x00
+#define  PCI_CLASS_SUB_CODE_DATA_PERFCNTR      0x01
+#define  PCI_CLASS_SUB_CODE_DATA_COMMSYNC      0x10
+#define  PCI_CLASS_SUB_CODE_DATA_MGMT          0x20
+#define  PCI_CLASS_SUB_CODE_DATA_OTHER         0x80
 
 #define PCI_CACHE_LINE_SIZE    0x0c    /* 8 bits */
 #define PCI_LATENCY_TIMER      0x0d    /* 8 bits */
diff --git a/include/physmem.h b/include/physmem.h
new file mode 100644 (file)
index 0000000..03d3a78
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+/*
+ * These functions work like memset but operate on physical memory which may
+ * not be accessible directly.
+ *
+ * @param s    The physical address to start setting memory at.
+ * @param c    The character to set each byte of the region to.
+ * @param n    The number of bytes to set.
+ *
+ * @return     The physical address of the memory which was set.
+ */
+phys_addr_t arch_phys_memset(phys_addr_t s, int c, phys_size_t n);
similarity index 71%
rename from drivers/misc/pmic_max8997.c
rename to include/power/battery.h
index 62dbc05311c2c59be8bea3c49f3300ac5166fbe0..e2fec687dabff20464d7fe0f3e3d235d5c1f5af8 100644 (file)
  * MA 02111-1307 USA
  */
 
-#include <common.h>
-#include <pmic.h>
-#include <max8997_pmic.h>
+#ifndef __POWER_BATTERY_H_
+#define __POWER_BATTERY_H_
 
-int pmic_init(void)
-{
-       struct pmic *p = get_pmic();
-       static const char name[] = "MAX8997_PMIC";
+struct battery {
+       unsigned int version;
+       unsigned int state_of_chrg;
+       unsigned int time_to_empty;
+       unsigned int capacity;
+       unsigned int voltage_uV;
 
-       puts("Board PMIC init\n");
+       unsigned int state;
+};
 
-       p->name = name;
-       p->interface = PMIC_I2C;
-       p->number_of_regs = PMIC_NUM_OF_REGS;
-       p->hw.i2c.addr = MAX8997_I2C_ADDR;
-       p->hw.i2c.tx_num = 1;
-       p->bus = I2C_PMIC;
-
-       return 0;
-}
+int power_bat_init(unsigned char bus);
+#endif /* __POWER_BATTERY_H_ */
diff --git a/include/power/fg_battery_cell_params.h b/include/power/fg_battery_cell_params.h
new file mode 100644 (file)
index 0000000..7ddf6f2
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __FG_BATTERY_CELL_PARAMS_H_
+#define __FG_BATTERY_CELL_PARAMS_H_
+
+#if  defined(CONFIG_POWER_FG_MAX17042) && defined(CONFIG_TRATS)
+
+/* Cell characteristics - Exynos4 TRATS development board */
+/* Shall be written to addr 0x80h */
+u16 cell_character0[16] = {
+       0xA2A0,
+       0xB6E0,
+       0xB850,
+       0xBAD0,
+       0xBB20,
+       0xBB70,
+       0xBBC0,
+       0xBC20,
+       0xBC80,
+       0xBCE0,
+       0xBD80,
+       0xBE20,
+       0xC090,
+       0xC420,
+       0xC910,
+       0xD070
+};
+
+/* Shall be written to addr 0x90h */
+u16 cell_character1[16] = {
+       0x0090,
+       0x1A50,
+       0x02F0,
+       0x2060,
+       0x2060,
+       0x2E60,
+       0x26A0,
+       0x2DB0,
+       0x2DB0,
+       0x1870,
+       0x2A20,
+       0x16F0,
+       0x08F0,
+       0x0D40,
+       0x08C0,
+       0x08C0
+};
+
+/* Shall be written to addr 0xA0h */
+u16 cell_character2[16] = {
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100,
+       0x0100
+};
+#endif
+#endif /* __FG_BATTERY_CELL_PARAMS_H_ */
diff --git a/include/power/max17042_fg.h b/include/power/max17042_fg.h
new file mode 100644 (file)
index 0000000..1103a48
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MAX17042_FG_H_
+#define __MAX17042_FG_H_
+
+/* MAX 17042 registers */
+enum {
+       MAX17042_STATUS         = 0x00,
+       MAX17042_SOCREP         = 0x06,
+       MAX17042_VCELL          = 0x09,
+       MAX17042_CURRENT        = 0x0A,
+       MAX17042_AVG_CURRENT    = 0x0B,
+       MAX17042_SOCMIX = 0x0D,
+       MAX17042_SOCAV          = 0x0E,
+       MAX17042_DESIGN_CAP     = 0x18,
+       MAX17042_AVG_VCELL      = 0x19,
+       MAX17042_CONFIG = 0x1D,
+       MAX17042_VERSION        = 0x21,
+       MAX17042_LEARNCFG       = 0x28,
+       MAX17042_FILTERCFG      = 0x29,
+       MAX17042_RELAXCFG       = 0x2A,
+       MAX17042_MISCCFG        = 0x2B,
+       MAX17042_CGAIN          = 0x2E,
+       MAX17042_COFF           = 0x2F,
+       MAX17042_RCOMP0 = 0x38,
+       MAX17042_TEMPCO = 0x39,
+       MAX17042_FSTAT          = 0x3D,
+       MAX17042_MLOCKReg1      = 0x62,
+       MAX17042_MLOCKReg2      = 0x63,
+       MAX17042_MODEL1         = 0x80,
+       MAX17042_MODEL2         = 0x90,
+       MAX17042_MODEL3         = 0xA0,
+       MAX17042_VFOCV          = 0xFB,
+       MAX17042_VFSOC          = 0xFF,
+
+       FG_NUM_OF_REGS = 0x100,
+};
+
+#define RCOMP0                 0x0060
+#define TempCo                 0x1015
+
+
+#define MAX17042_POR (1 << 1)
+
+#define MODEL_UNLOCK1          0x0059
+#define MODEL_UNLOCK2          0x00c4
+#define MODEL_LOCK1            0x0000
+#define MODEL_LOCK2            0x0000
+
+#define MAX17042_I2C_ADDR      (0x6C >> 1)
+
+int power_fg_init(unsigned char bus);
+#endif /* __MAX17042_FG_H_ */
diff --git a/include/power/max8997_muic.h b/include/power/max8997_muic.h
new file mode 100644 (file)
index 0000000..0149c12
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MAX8997_MUIC_H_
+#define __MAX8997_MUIC_H_
+
+#include <power/power_chrg.h>
+
+/* MAX8997_MUIC_STATUS2 */
+#define MAX8997_MUIC_CHG_NO    0x00
+#define MAX8997_MUIC_CHG_USB   0x01
+#define MAX8997_MUIC_CHG_USB_D 0x02
+#define MAX8997_MUIC_CHG_TA    0x03
+#define MAX8997_MUIC_CHG_TA_500 0x04
+#define MAX8997_MUIC_CHG_TA_1A 0x05
+#define MAX8997_MUIC_CHG_MASK  0x07
+
+/* MAX 8997 MUIC registers */
+enum {
+       MAX8997_MUIC_ID         = 0x00,
+       MAX8997_MUIC_INT1       = 0x01,
+       MAX8997_MUIC_INT2       = 0x02,
+       MAX8997_MUIC_INT3       = 0x03,
+       MAX8997_MUIC_STATUS1    = 0x04,
+       MAX8997_MUIC_STATUS2    = 0x05,
+       MAX8997_MUIC_STATUS3    = 0x06,
+       MAX8997_MUIC_INTMASK1   = 0x07,
+       MAX8997_MUIC_INTMASK2   = 0x08,
+       MAX8997_MUIC_INTMASK3   = 0x09,
+       MAX8997_MUIC_CDETCTRL   = 0x0A,
+       MAX8997_MUIC_CONTROL1   = 0x0C,
+       MAX8997_MUIC_CONTROL2   = 0x0D,
+       MAX8997_MUIC_CONTROL3   = 0x0E,
+
+       MUIC_NUM_OF_REGS = 0x0F,
+};
+
+#define MAX8997_MUIC_I2C_ADDR  (0x4A >> 1)
+
+int power_muic_init(unsigned int bus);
+#endif /* __MAX8997_MUIC_H_ */
similarity index 88%
rename from include/max8997_pmic.h
rename to include/power/max8997_pmic.h
index 17ae24ea6a0b895ad51e4add1cbf20df7e5412e5..5d2d94df9bcae0e6b5d17af239d2261cb6914379 100644 (file)
@@ -111,7 +111,7 @@ enum {
        MAX8997_REG_MBCCTRL6    = 0x55,
        MAX8997_REG_OTPCGHCVS   = 0x56,
 
-       MAX8997_REG_SAFEOUTCTRL = 0x5a,
+       MAX8997_REG_SAFEOUTCTRL = 0x5a,
 
        MAX8997_REG_LBCNFG1     = 0x5e,
        MAX8997_REG_LBCNFG2     = 0x5f,
@@ -171,9 +171,31 @@ enum {
        PMIC_NUM_OF_REGS = 0x9b,
 };
 
+#define ACTDISSAFEO1 (1 << 4)
+#define ACTDISSAFEO2 (1 << 5)
 #define ENSAFEOUT1 (1 << 6)
 #define ENSAFEOUT2 (1 << 7)
 
+#define ENBUCK (1 << 0)
+#define ACTIVE_DISCHARGE (1 << 3)
+#define GNSLCT (1 << 2)
+#define LDO_ADE (1 << 1)
+#define SAFEOUT_4_85V 0x00
+#define SAFEOUT_4_90V 0x01
+#define SAFEOUT_4_95V 0x02
+#define SAFEOUT_3_30V 0x03
+
+/* Charger */
+enum {CHARGER_ENABLE, CHARGER_DISABLE};
+#define DETBAT                  (1 << 2)
+#define MBCICHFCSET             (1 << 4)
+#define MBCHOSTEN               (1 << 6)
+#define VCHGR_FC                (1 << 7)
+
+#define CHARGER_MIN_CURRENT 200
+#define CHARGER_MAX_CURRENT 950
+#define CHARGER_CURRENT_RESOLUTION 50
+
 #define MAX8997_I2C_ADDR        (0xCC >> 1)
 #define MAX8997_RTC_ADDR       (0x0C >> 1)
 #define MAX8997_MUIC_ADDR      (0x4A >> 1)
@@ -187,4 +209,6 @@ enum {
        EN_LDO = (0x3 << 6),
 };
 
+#define MAX8997_LDO_MAX_VAL 0x3F
+unsigned char max8997_reg_ldo(int uV);
 #endif /* __MAX8997_PMIC_H_ */
similarity index 58%
rename from include/pmic.h
rename to include/power/pmic.h
index 6a05b40aefe34f05a7bd1265772b7b0e2b7e4b3c..1ecfc0543cc51de03d44b30be855856fd12c12bc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2011 Samsung Electronics
+ *  Copyright (C) 2011-2012 Samsung Electronics
  *  Lukasz Majewski <l.majewski@samsung.com>
  *
  * See file CREDITS for list of people who contributed to this
 #ifndef __CORE_PMIC_H_
 #define __CORE_PMIC_H_
 
-enum { PMIC_I2C, PMIC_SPI, };
+#include <common.h>
+#include <linux/list.h>
+#include <i2c.h>
+#include <power/power_chrg.h>
+
+enum { PMIC_I2C, PMIC_SPI, PMIC_NONE};
 enum { I2C_PMIC, I2C_NUM, };
 enum { PMIC_READ, PMIC_WRITE, };
+enum { PMIC_SENSOR_BYTE_ORDER_LITTLE, PMIC_SENSOR_BYTE_ORDER_BIG, };
 
 struct p_i2c {
        unsigned char addr;
@@ -43,21 +49,52 @@ struct p_spi {
        u32 (*prepare_tx)(u32 reg, u32 *val, u32 write);
 };
 
+struct pmic;
+struct power_fg {
+       int (*fg_battery_check) (struct pmic *p, struct pmic *bat);
+       int (*fg_battery_update) (struct pmic *p, struct pmic *bat);
+};
+
+struct power_chrg {
+       int (*chrg_type) (struct pmic *p);
+       int (*chrg_bat_present) (struct pmic *p);
+       int (*chrg_state) (struct pmic *p, int state, int current);
+};
+
+struct power_battery {
+       struct battery *bat;
+       int (*battery_init) (struct pmic *bat, struct pmic *p1,
+                            struct pmic *p2, struct pmic *p3);
+       int (*battery_charge) (struct pmic *bat);
+       /* Keep info about power devices involved with battery operation */
+       struct pmic *chrg, *fg, *muic;
+};
+
 struct pmic {
        const char *name;
        unsigned char bus;
        unsigned char interface;
-       unsigned char number_of_regs;
+       unsigned char sensor_byte_order;
+       unsigned int number_of_regs;
        union hw {
                struct p_i2c i2c;
                struct p_spi spi;
        } hw;
+
+       void (*low_power_mode) (void);
+       struct power_battery *pbat;
+       struct power_chrg *chrg;
+       struct power_fg *fg;
+
+       struct pmic *parent;
+       struct list_head list;
 };
 
-int pmic_init(void);
-int pmic_dialog_init(void);
-int check_reg(u32 reg);
-struct pmic *get_pmic(void);
+int pmic_init(unsigned char bus);
+int pmic_dialog_init(unsigned char bus);
+int check_reg(struct pmic *p, u32 reg);
+struct pmic *pmic_alloc(void);
+struct pmic *pmic_get(const char *s);
 int pmic_probe(struct pmic *p);
 int pmic_reg_read(struct pmic *p, u32 reg, u32 *val);
 int pmic_reg_write(struct pmic *p, u32 reg, u32 val);
similarity index 59%
rename from nand_spl/board/freescale/common.c
rename to include/power/power_chrg.h
index 0e099bc7c67b1a20ee41beba80f135aeef038a95..24c4cde739ea8c36a32f9cbf3da28f7b97f14dca 100644 (file)
@@ -1,6 +1,9 @@
 /*
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Author: Matthew McClintock <msm@freescale.com>
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Lukasz Majewski <l.majewski@samsung.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
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
- *
  */
 
-#include <common.h>
-#include <asm/processor.h>
-#include <asm/global_data.h>
-
-DECLARE_GLOBAL_DATA_PTR;
+#ifndef __POWER_CHARGER_H_
+#define __POWER_CHARGER_H_
 
-#ifndef CONFIG_SYS_FSL_TBCLK_DIV
-#define CONFIG_SYS_FSL_TBCLK_DIV 8
-#endif
+/* Type of available chargers */
+enum {
+       CHARGER_NO = 0,
+       CHARGER_TA,
+       CHARGER_USB,
+       CHARGER_TA_500,
+       CHARGER_UNKNOWN,
+};
 
-void udelay(unsigned long usec)
-{
-       u32 ticks_per_usec = gd->bus_clk / (CONFIG_SYS_FSL_TBCLK_DIV * 1000000);
-       u32 ticks = ticks_per_usec * usec;
-       u32 s = mfspr(SPRN_TBRL);
+enum {
+       UNKNOWN,
+       EXT_SOURCE,
+       CHARGE,
+       NORMAL,
+};
 
-       while ((mfspr(SPRN_TBRL) - s) < ticks);
-}
+#endif /* __POWER_CHARGER_H_ */
index c44793d5ecf773b8baea5dd5daf860687e38648c..cffbe53621aee9c9691f9f5ec39d9c8fe98f047b 100644 (file)
 #define SDHCI_QUIRK_BROKEN_VOLTAGE     (1 << 4)
 #define SDHCI_QUIRK_NO_CD              (1 << 5)
 #define SDHCI_QUIRK_WAIT_SEND_CMD      (1 << 6)
+#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1 << 7)
 
 /* to make gcc happy */
 struct sdhci_host;
index da9fae9203ff52120fcd1e1692d7d860739b24ca..27e9127694c7e5208e26dd5ae58d9ed11806cb77 100644 (file)
@@ -273,9 +273,6 @@ void status_led_set  (int led, int state);
 #elif defined(CONFIG_STXXTC)
 /* XXX empty just to avoid the error */
 /************************************************************************/
-#elif defined(CONFIG_NIOS2)
-/* XXX empty just to avoid the error */
-/************************************************************************/
 #elif defined(CONFIG_V38B)
 
 # define STATUS_LED_BIT                0x0010                  /* Timer7 GPIO */
index 23e0ee15f280d1dba02fbe99e61915606d97866b..932d093345e59ade1c175b13fe677dfdcee935dc 100644 (file)
@@ -120,5 +120,8 @@ int drv_nc_init (void);
 #ifdef CONFIG_JTAG_CONSOLE
 int drv_jtag_console_init (void);
 #endif
+#ifdef CONFIG_CBMEM_CONSOLE
+int cbmemc_init(void);
+#endif
 
 #endif
index 9dd879194752a829f93cb5b1cfadf4e9df55a2ab..8d8a2c9b9da63421b59a7eeb9e02c6a2be285c76 100644 (file)
@@ -27,7 +27,7 @@
 #define _USB_H_
 
 #include <usb_defs.h>
-#include <usbdescriptors.h>
+#include <linux/usb/ch9.h>
 
 /*
  * The EHCI spec says that we must align to at least 32 bytes.  However,
@@ -67,12 +67,6 @@ struct devrequest {
        unsigned short  length;
 } __attribute__ ((packed));
 
-/* All standard descriptors have these 2 fields in common */
-struct usb_descriptor_header {
-       unsigned char   bLength;
-       unsigned char   bDescriptorType;
-} __attribute__ ((packed));
-
 /* Interface */
 struct usb_interface {
        struct usb_interface_descriptor desc;
@@ -86,7 +80,7 @@ struct usb_interface {
 
 /* Configuration information.. */
 struct usb_config {
-       struct usb_configuration_descriptor desc;
+       struct usb_config_descriptor desc;
 
        unsigned char   no_of_if;       /* number of interfaces */
        struct usb_interface if_desc[USB_MAXINTERFACES];
@@ -153,7 +147,9 @@ struct usb_device {
        defined(CONFIG_USB_SL811HS) || defined(CONFIG_USB_ISP116X_HCD) || \
        defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI) || \
        defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
-       defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X)
+       defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
+       defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
+       defined(CONFIG_USB_MUSB_OMAP2PLUS)
 
 int usb_lowlevel_init(int index, void **controller);
 int usb_lowlevel_stop(int index);
@@ -285,7 +281,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
  *  - device:          bits 8-14
  *  - endpoint:                bits 15-18
  *  - Data0/1:         bit 19
- *  - speed:           bit 26          (0 = Full, 1 = Low Speed, 2 = High)
  *  - pipe type:       bits 30-31      (00 = isochronous, 01 = interrupt,
  *                                      10 = control, 11 = bulk)
  *
@@ -297,7 +292,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 /* Create various pipes... */
 #define create_pipe(dev,endpoint) \
                (((dev)->devnum << 8) | ((endpoint) << 15) | \
-               ((dev)->speed << 26) | (dev)->maxpacketsize)
+               (dev)->maxpacketsize)
 #define default_pipe(dev) ((dev)->speed << 26)
 
 #define usb_sndctrlpipe(dev, endpoint) ((PIPE_CONTROL << 30) | \
@@ -348,8 +343,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 #define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff)
 #define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf)
 #define usb_pipedata(pipe)     (((pipe) >> 19) & 1)
-#define usb_pipespeed(pipe)    (((pipe) >> 26) & 3)
-#define usb_pipeslow(pipe)     (usb_pipespeed(pipe) == USB_SPEED_LOW)
 #define usb_pipetype(pipe)     (((pipe) >> 30) & 3)
 #define usb_pipeisoc(pipe)     (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
 #define usb_pipeint(pipe)      (usb_pipetype((pipe)) == PIPE_INTERRUPT)
index 6a8fd4424415cecc770a4ca3de2e2cf4b8070d4f..7114dae75dd20ec0e6cc7e5f0067abc169f4404f 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <asm/errno.h>
 #include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
 #include <linux/usb/gadget.h>
 #include <linux/list.h>
 #include <usb/lin_gadget_compat.h>
index 8032e5712524ee322842e3eebf16a438eb4d99a7..9502544b21bd1b41a034193de822f1345045acc7 100644 (file)
 #define USB_DIR_OUT           0
 #define USB_DIR_IN            0x80
 
-/* USB device speeds */
-#define USB_SPEED_FULL         0x0     /* 12Mbps */
-#define USB_SPEED_LOW          0x1     /* 1.5Mbps */
-#define USB_SPEED_HIGH         0x2     /* 480Mbps */
-#define USB_SPEED_RESERVED     0x3
-
 /* Descriptor types */
 #define USB_DT_DEVICE        0x01
 #define USB_DT_CONFIG        0x02
index 9519ceaf98bf1da91404d1aa21df15b1dd667f9e..f7e27f8477b0e5d3c4acae8175b080db88a78eca 100644 (file)
@@ -15,4 +15,52 @@ int  video_init      (void *videobase);
 void   video_putc      (const char c);
 void   video_puts      (const char *s);
 
+/**
+ * Display a BMP format bitmap on the screen
+ *
+ * @param bmp_image    Address of BMP image
+ * @param x            X position to draw image
+ * @param y            Y position to draw image
+ */
+int video_display_bitmap(ulong bmp_image, int x, int y);
+
+/**
+ * Get the width of the screen in pixels
+ *
+ * @return width of screen in pixels
+ */
+int video_get_pixel_width(void);
+
+/**
+ * Get the height of the screen in pixels
+ *
+ * @return height of screen in pixels
+ */
+int video_get_pixel_height(void);
+
+/**
+ * Get the number of text lines/rows on the screen
+ *
+ * @return number of rows
+ */
+int video_get_screen_rows(void);
+
+/**
+ * Get the number of text columns on the screen
+ *
+ * @return number of columns
+ */
+int video_get_screen_columns(void);
+
+/**
+ * Set the position of the text cursor
+ *
+ * @param col  Column to place cursor (0 = left side)
+ * @param row  Row to place cursor (0 = top line)
+ */
+void video_position_cursor(unsigned col, unsigned row);
+
+/* Clear the display */
+void video_clear(void);
+
 #endif
index e44e04523313af357b039330409fb475aca09b65..f83f6e8d8c50cf410632ba7f17635047355606c0 100644 (file)
@@ -48,6 +48,7 @@ COBJS-$(CONFIG_LMB) += lmb.o
 COBJS-y += ldiv.o
 COBJS-$(CONFIG_MD5) += md5.o
 COBJS-y += net_utils.o
+COBJS-$(CONFIG_PHYSMEM) += physmem.o
 COBJS-y += qsort.o
 COBJS-$(CONFIG_SHA1) += sha1.o
 COBJS-$(CONFIG_SHA256) += sha256.o
index 4c23f458f0f51b5ce52345333cdb44557a358859..348144aa705836f3f9ca2a6eb4e0ff7bd63f0d6e 100644 (file)
@@ -52,28 +52,6 @@ const char *fdtdec_get_compatible(enum fdt_compat_id id)
        return compat_names[id];
 }
 
-/**
- * Look in the FDT for an alias with the given name and return its node.
- *
- * @param blob FDT blob
- * @param name alias name to look up
- * @return node offset if found, or an error code < 0 otherwise
- */
-static int find_alias_node(const void *blob, const char *name)
-{
-       const char *path;
-       int alias_node;
-
-       debug("find_alias_node: %s\n", name);
-       alias_node = fdt_path_offset(blob, "/aliases");
-       if (alias_node < 0)
-               return alias_node;
-       path = fdt_getprop(blob, alias_node, name, NULL);
-       if (!path)
-               return -FDT_ERR_NOTFOUND;
-       return fdt_path_offset(blob, path);
-}
-
 fdt_addr_t fdtdec_get_addr(const void *blob, int node,
                const char *prop_name)
 {
@@ -111,6 +89,19 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
        return default_val;
 }
 
+uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name,
+               uint64_t default_val)
+{
+       const uint64_t *cell64;
+       int length;
+
+       cell64 = fdt_getprop(blob, node, prop_name, &length);
+       if (!cell64 || length < sizeof(*cell64))
+               return default_val;
+
+       return fdt64_to_cpu(*cell64);
+}
+
 int fdtdec_get_is_enabled(const void *blob, int node)
 {
        const char *cell;
@@ -128,7 +119,7 @@ int fdtdec_get_is_enabled(const void *blob, int node)
        return 1;
 }
 
-enum fdt_compat_id fd_dec_lookup(const void *blob, int node)
+enum fdt_compat_id fdtdec_lookup(const void *blob, int node)
 {
        enum fdt_compat_id id;
 
@@ -171,7 +162,7 @@ int fdtdec_next_alias(const void *blob, const char *name,
        /* snprintf() is not available */
        assert(strlen(name) < MAX_STR_LEN);
        sprintf(str, "%.*s%d", MAX_STR_LEN, name, *upto);
-       node = find_alias_node(blob, str);
+       node = fdt_path_offset(blob, str);
        if (node < 0)
                return node;
        err = fdt_node_check_compatible(blob, node, compat_names[id]);
@@ -426,9 +417,8 @@ int fdtdec_get_bool(const void *blob, int node, const char *prop_name)
  * @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would
  * be exceeded, or -FDT_ERR_NOTFOUND if the property is missing.
  */
-static int fdtdec_decode_gpios(const void *blob, int node,
-               const char *prop_name, struct fdt_gpio_state *gpio,
-               int max_count)
+int fdtdec_decode_gpios(const void *blob, int node, const char *prop_name,
+               struct fdt_gpio_state *gpio, int max_count)
 {
        const struct fdt_property *prop;
        const u32 *cell;
@@ -475,6 +465,26 @@ int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
        return err == 1 ? 0 : err;
 }
 
+int fdtdec_get_gpio(struct fdt_gpio_state *gpio)
+{
+       int val;
+
+       if (!fdt_gpio_isvalid(gpio))
+               return -1;
+
+       val = gpio_get_value(gpio->gpio);
+       return gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val;
+}
+
+int fdtdec_set_gpio(struct fdt_gpio_state *gpio, int val)
+{
+       if (!fdt_gpio_isvalid(gpio))
+               return -1;
+
+       val = gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val;
+       return gpio_set_value(gpio->gpio, val);
+}
+
 int fdtdec_setup_gpio(struct fdt_gpio_state *gpio)
 {
        /*
@@ -512,3 +522,64 @@ const u8 *fdtdec_locate_byte_array(const void *blob, int node,
                return NULL;
        return cell;
 }
+
+int fdtdec_get_config_int(const void *blob, const char *prop_name,
+               int default_val)
+{
+       int config_node;
+
+       debug("%s: %s\n", __func__, prop_name);
+       config_node = fdt_path_offset(blob, "/config");
+       if (config_node < 0)
+               return default_val;
+       return fdtdec_get_int(blob, config_node, prop_name, default_val);
+}
+
+int fdtdec_get_config_bool(const void *blob, const char *prop_name)
+{
+       int config_node;
+       const void *prop;
+
+       debug("%s: %s\n", __func__, prop_name);
+       config_node = fdt_path_offset(blob, "/config");
+       if (config_node < 0)
+               return 0;
+       prop = fdt_get_property(blob, config_node, prop_name, NULL);
+
+       return prop != NULL;
+}
+
+char *fdtdec_get_config_string(const void *blob, const char *prop_name)
+{
+       const char *nodep;
+       int nodeoffset;
+       int len;
+
+       debug("%s: %s\n", __func__, prop_name);
+       nodeoffset = fdt_path_offset(blob, "/config");
+       if (nodeoffset < 0)
+               return NULL;
+
+       nodep = fdt_getprop(blob, nodeoffset, prop_name, &len);
+       if (!nodep)
+               return NULL;
+
+       return (char *)nodep;
+}
+
+int fdtdec_decode_region(const void *blob, int node,
+               const char *prop_name, void **ptrp, size_t *size)
+{
+       const fdt_addr_t *cell;
+       int len;
+
+       debug("%s: %s\n", __func__, prop_name);
+       cell = fdt_getprop(blob, node, prop_name, &len);
+       if (!cell || (len != sizeof(fdt_addr_t) * 2))
+               return -1;
+
+       *ptrp = (void *)fdt_addr_to_cpu(*cell);
+       *size = fdt_size_to_cpu(cell[1]);
+       debug("%s: size=%zx\n", __func__, *size);
+       return 0;
+}
index f941da27dd0bdad1c78e2ed77825797a29f8bfd4..4f45f80fe26477f04b516cff23ffb417551cd30d 100644 (file)
@@ -1,5 +1,5 @@
 /* LzmaDec.c -- LZMA Decoder
-2008-11-06 : Igor Pavlov : Public domain */
+2009-09-20 : Igor Pavlov : Public domain */
 
 #include <config.h>
 #include <common.h>
 StopCompilingDueBUG
 #endif
 
-static const Byte kLiteralNextStates[kNumStates * 2] =
-{
-  0, 0, 0, 0, 1, 2, 3,  4,  5,  6,  4,  5,
-  7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
-};
-
 #define LZMA_DIC_MIN (1 << 12)
 
 /* First LZMA-symbol is always decoded.
@@ -180,6 +174,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
 
       if (state < kNumLitStates)
       {
+        state -= (state < 4) ? state : 3;
         symbol = 1;
 
         WATCHDOG_RESET();
@@ -190,6 +185,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
       {
         unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
         unsigned offs = 0x100;
+        state -= (state < 10) ? 3 : 6;
         symbol = 1;
 
         WATCHDOG_RESET();
@@ -207,9 +203,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
       }
       dic[dicPos++] = (Byte)symbol;
       processedPos++;
-
-      state = kLiteralNextStates[state];
-      /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
       continue;
     }
     else
@@ -395,7 +388,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
         else if (distance >= checkDicSize)
           return SZ_ERROR_DATA;
         state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
-        /* state = kLiteralNextStates[state]; */
       }
 
       len += kMatchMinLen;
index 7fba87f076e397790c7af75effeb43b348f27dc3..63aa505e8ca5a8aa6ed4087aa6f262ac147c40a4 100644 (file)
@@ -1,8 +1,8 @@
 /* LzmaDec.h -- LZMA Decoder
-2008-10-04 : Igor Pavlov : Public domain */
+2009-02-07 : Igor Pavlov : Public domain */
 
-#ifndef __LZMADEC_H
-#define __LZMADEC_H
+#ifndef __LZMA_DEC_H
+#define __LZMA_DEC_H
 
 #include "Types.h"
 
index 1af5cfc4d86871403ce279a3b395aba9ba811588..8afcba556eb404fc92355f2edb880f44e39e8350 100644 (file)
@@ -1,5 +1,5 @@
 /* Types.h -- Basic types
-2008-11-23 : Igor Pavlov : Public domain */
+2010-10-09 : Igor Pavlov : Public domain */
 
 #ifndef __7Z_TYPES_H
 #define __7Z_TYPES_H
@@ -65,9 +65,11 @@ typedef unsigned long UInt64;
 #if defined(_MSC_VER) || defined(__BORLANDC__)
 typedef __int64 Int64;
 typedef unsigned __int64 UInt64;
+#define UINT64_CONST(n) n
 #else
 typedef long long int Int64;
 typedef unsigned long long int UInt64;
+#define UINT64_CONST(n) n ## ULL
 #endif
 
 #endif
@@ -92,13 +94,11 @@ typedef int Bool;
 #endif
 
 #define MY_CDECL __cdecl
-#define MY_STD_CALL __stdcall
-#define MY_FAST_CALL MY_NO_INLINE __fastcall
+#define MY_FAST_CALL __fastcall
 
 #else
 
 #define MY_CDECL
-#define MY_STD_CALL
 #define MY_FAST_CALL
 
 #endif
@@ -106,6 +106,16 @@ typedef int Bool;
 
 /* The following interfaces use first parameter as pointer to structure */
 
+typedef struct
+{
+  Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
+} IByteIn;
+
+typedef struct
+{
+  void (*Write)(void *p, Byte b);
+} IByteOut;
+
 typedef struct
 {
   SRes (*Read)(void *p, void *buf, size_t *size);
@@ -140,7 +150,7 @@ typedef struct
 
 typedef struct
 {
-  SRes (*Look)(void *p, void **buf, size_t *size);
+  SRes (*Look)(void *p, const void **buf, size_t *size);
     /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
        (output(*size) > input(*size)) is not allowed
        (output(*size) < input(*size)) is allowed */
@@ -205,4 +215,20 @@ typedef struct
 #define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
 #define IAlloc_Free(p, a) (p)->Free((p), a)
 
+#ifdef _WIN32
+
+#define CHAR_PATH_SEPARATOR '\\'
+#define WCHAR_PATH_SEPARATOR L'\\'
+#define STRING_PATH_SEPARATOR "\\"
+#define WSTRING_PATH_SEPARATOR L"\\"
+
+#else
+
+#define CHAR_PATH_SEPARATOR '/'
+#define WCHAR_PATH_SEPARATOR L'/'
+#define STRING_PATH_SEPARATOR "/"
+#define WSTRING_PATH_SEPARATOR L"/"
+
+#endif
+
 #endif
index aadf8255edb395d58b1cd7beab31569110ef7b3c..443511bdd49cc19f8ebffd11dc9153a6b2e23168 100644 (file)
@@ -1,6 +1,41 @@
 HISTORY of the LZMA SDK
 -----------------------
 
+9.18 beta      2010-11-02
+-------------------------
+- New small SFX module for installers (SfxSetup).
+
+
+9.12 beta      2010-03-24
+-------------------------
+- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work,
+  if more than 10 threads were used (or more than 20 threads in some modes).
+
+
+9.11 beta      2010-03-15
+-------------------------
+- PPMd compression method support
+
+
+9.09           2009-12-12
+-------------------------
+- The bug was fixed:
+   Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c
+   incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8.
+- Some bugs were fixed
+
+
+9.06           2009-08-17
+-------------------------
+- Some changes in ANSI-C 7z Decoder interfaces.
+
+
+9.04           2009-05-30
+-------------------------
+- LZMA2 compression method support
+- xz format support
+
+
 4.65           2009-02-03
 -------------------------
 - Some minor fixes
index aa20f9dc5ce902f594db59e505aec9801136d675..144cd9aee2ecc718086b16f3bae63e9073521813 100644 (file)
@@ -1,4 +1,4 @@
-LZMA SDK 4.65
+LZMA SDK 9.20
 -------------
 
 LZMA SDK provides the documentation, samples, header files, libraries,
@@ -20,6 +20,10 @@ LICENSE
 
 LZMA SDK is written and placed in the public domain by Igor Pavlov.
 
+Some code in LZMA SDK is based on public domain code from another developers:
+  1) PPMd var.H (2001): Dmitry Shkarin
+  2) SHA-256: Wei Dai (Crypto++ library)
+
 
 LZMA SDK Contents
 -----------------
@@ -33,7 +37,7 @@ LZMA SDK includes:
 UNIX/Linux version
 ------------------
 To compile C++ version of file->file LZMA encoding, go to directory
-C++/7zip/Compress/LZMA_Alone
+CPP/7zip/Bundles/LzmaCon
 and call make to recompile it:
   make -f makefile.gcc clean all
 
@@ -49,6 +53,7 @@ lzma.txt     - LZMA SDK description (this file)
 7zC.txt      - 7z ANSI-C Decoder description
 methods.txt  - Compression method IDs for .7z
 lzma.exe     - Compiled file->file LZMA encoder/decoder for Windows
+7zr.exe      - 7-Zip with 7z/lzma/xz support.
 history.txt  - history of the LZMA SDK
 
 
@@ -66,7 +71,7 @@ C/  - C files
         LzmaEnc.*  - LZMA encoding
         LzmaLib.*  - LZMA Library for DLL calling
         Types.h    - Basic types for another .c files
-       Threads.*  - The code for multithreading.
+        Threads.*  - The code for multithreading.
 
     LzmaLib  - LZMA Library (.DLL for Windows)
 
@@ -86,12 +91,6 @@ CPP/ -- CPP files
 
     Compress - files related to compression/decompression
 
-      Copy         - Copy coder
-      RangeCoder   - Range Coder (special code of compression/decompression)
-      LZMA         - LZMA compression/decompression on C++
-      LZMA_Alone   - file->file LZMA compression/decompression
-      Branch       - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
-
     Archive - files related to archiving
 
       Common   - common files for archive handling
@@ -100,6 +99,7 @@ CPP/ -- CPP files
     Bundles    - Modules that are bundles of other modules
 
       Alone7z           - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
+      LzmaCon           - lzma.exe: LZMA compression/decompression
       Format7zR         - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
       Format7zExtractR  - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
 
@@ -369,8 +369,8 @@ Interface:
     propData - LZMA properties  (5 bytes)
     propSize - size of propData buffer (5 bytes)
     finishMode - It has meaning only if the decoding reaches output limit (*destLen).
-        LZMA_FINISH_ANY - Decode just destLen bytes.
-        LZMA_FINISH_END - Stream must be finished after (*destLen).
+         LZMA_FINISH_ANY - Decode just destLen bytes.
+         LZMA_FINISH_END - Stream must be finished after (*destLen).
                            You can use LZMA_FINISH_END, when you know that
                            current output buffer covers last bytes of stream.
     alloc    - Memory allocator.
@@ -431,7 +431,7 @@ Memory Requirements:
   {
     ...
     int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
-       const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
+        const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
     ...
   }
 
@@ -527,7 +527,8 @@ static ISzAlloc g_Alloc = { SzAlloc, SzFree };
   LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
 
 
-If callback function return some error code, LzmaEnc_Encode also returns that code.
+If callback function return some error code, LzmaEnc_Encode also returns that code
+or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS.
 
 
 Single-call RAM->RAM Compression
@@ -549,8 +550,8 @@ Return code:
 
 
 
-LZMA Defines
-------------
+Defines
+-------
 
 _LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
 
@@ -562,6 +563,9 @@ _LZMA_UINT32_IS_ULONG  - Define it if int is 16-bit on your compiler and long is
 _LZMA_NO_SYSTEM_SIZE_T  - Define it if you don't want to use size_t type.
 
 
+_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder.
+
+
 C++ LZMA Encoder/Decoder
 ~~~~~~~~~~~~~~~~~~~~~~~~
 C++ LZMA code use COM-like interfaces. So if you want to use it,
diff --git a/lib/physmem.c b/lib/physmem.c
new file mode 100644 (file)
index 0000000..0f035ed
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#include <common.h>
+#include <physmem.h>
+
+static phys_addr_t __arch_phys_memset(phys_addr_t s, int c, phys_size_t n)
+{
+       void *s_ptr = (void *)(uintptr_t)s;
+
+       assert(((phys_addr_t)(uintptr_t)s) == s);
+       assert(((phys_addr_t)(uintptr_t)(s + n)) == s + n);
+       return (phys_addr_t)(uintptr_t)memset(s_ptr, c, n);
+}
+
+phys_addr_t arch_phys_memset(phys_addr_t s, int c, phys_size_t n)
+       __attribute__((weak, alias("__arch_phys_memset")));
index e5388d89c859bfd6092489e915e9ee3f66b4ffd9..9c778261b6f7e8fa19d8c7dc7a0274b8d7a4074f 100644 (file)
@@ -39,7 +39,7 @@ AFLAGS        += -DCONFIG_NAND_SPL
 CFLAGS += -DCONFIG_NAND_SPL
 
 SOBJS  = start.o resetvec.o
-COBJS  = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \
+COBJS  = cache.o cpu_init_early.o spl_minimal.o fsl_law.o law.o \
          nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o
 
 SRCS   := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
@@ -67,7 +67,8 @@ $(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot-nand_spl.lds
 # $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
 $(eval $(call make_u_boot_list, $(LSTSCRIPT), $(OBJS)))
 $(nandobj)u-boot-nand_spl.lds: $(LDSCRIPT) $(LSTSCRIPT)
-       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj) -ansi -D__ASSEMBLY__ -P - <$< >$@
+       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(nandobj)/board/$(BOARDDIR) \
+               -ansi -D__ASSEMBLY__ -P - <$< >$@
 
 # create symbolic links for common files
 
@@ -79,13 +80,13 @@ $(obj)cpu_init_early.c:
        @rm -f $(obj)cpu_init_early.c
        ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/cpu_init_early.c $(obj)cpu_init_early.c
 
-$(obj)cpu_init_nand.c:
-       @rm -f $(obj)cpu_init_nand.c
-       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c $(obj)cpu_init_nand.c
+$(obj)spl_minimal.c:
+       @rm -f $(obj)spl_minimal.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/spl_minimal.c $(obj)spl_minimal.c
 
 $(obj)fsl_law.c:
        @rm -f $(obj)fsl_law.c
-       ln -sf $(SRCTREE)/drivers/misc/fsl_law.c $(obj)fsl_law.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc8xxx/law.c $(obj)fsl_law.c
 
 $(obj)law.c:
        @rm -f $(obj)law.c
index e5388d89c859bfd6092489e915e9ee3f66b4ffd9..9c778261b6f7e8fa19d8c7dc7a0274b8d7a4074f 100644 (file)
@@ -39,7 +39,7 @@ AFLAGS        += -DCONFIG_NAND_SPL
 CFLAGS += -DCONFIG_NAND_SPL
 
 SOBJS  = start.o resetvec.o
-COBJS  = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \
+COBJS  = cache.o cpu_init_early.o spl_minimal.o fsl_law.o law.o \
          nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o
 
 SRCS   := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
@@ -67,7 +67,8 @@ $(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot-nand_spl.lds
 # $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
 $(eval $(call make_u_boot_list, $(LSTSCRIPT), $(OBJS)))
 $(nandobj)u-boot-nand_spl.lds: $(LDSCRIPT) $(LSTSCRIPT)
-       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj) -ansi -D__ASSEMBLY__ -P - <$< >$@
+       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(nandobj)/board/$(BOARDDIR) \
+               -ansi -D__ASSEMBLY__ -P - <$< >$@
 
 # create symbolic links for common files
 
@@ -79,13 +80,13 @@ $(obj)cpu_init_early.c:
        @rm -f $(obj)cpu_init_early.c
        ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/cpu_init_early.c $(obj)cpu_init_early.c
 
-$(obj)cpu_init_nand.c:
-       @rm -f $(obj)cpu_init_nand.c
-       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c $(obj)cpu_init_nand.c
+$(obj)spl_minimal.c:
+       @rm -f $(obj)spl_minimal.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/spl_minimal.c $(obj)spl_minimal.c
 
 $(obj)fsl_law.c:
        @rm -f $(obj)fsl_law.c
-       ln -sf $(SRCTREE)/drivers/misc/fsl_law.c $(obj)fsl_law.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc8xxx/law.c $(obj)fsl_law.c
 
 $(obj)law.c:
        @rm -f $(obj)law.c
index e5388d89c859bfd6092489e915e9ee3f66b4ffd9..9c778261b6f7e8fa19d8c7dc7a0274b8d7a4074f 100644 (file)
@@ -39,7 +39,7 @@ AFLAGS        += -DCONFIG_NAND_SPL
 CFLAGS += -DCONFIG_NAND_SPL
 
 SOBJS  = start.o resetvec.o
-COBJS  = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \
+COBJS  = cache.o cpu_init_early.o spl_minimal.o fsl_law.o law.o \
          nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o
 
 SRCS   := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
@@ -67,7 +67,8 @@ $(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot-nand_spl.lds
 # $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
 $(eval $(call make_u_boot_list, $(LSTSCRIPT), $(OBJS)))
 $(nandobj)u-boot-nand_spl.lds: $(LDSCRIPT) $(LSTSCRIPT)
-       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj) -ansi -D__ASSEMBLY__ -P - <$< >$@
+       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(nandobj)/board/$(BOARDDIR) \
+               -ansi -D__ASSEMBLY__ -P - <$< >$@
 
 # create symbolic links for common files
 
@@ -79,13 +80,13 @@ $(obj)cpu_init_early.c:
        @rm -f $(obj)cpu_init_early.c
        ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/cpu_init_early.c $(obj)cpu_init_early.c
 
-$(obj)cpu_init_nand.c:
-       @rm -f $(obj)cpu_init_nand.c
-       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c $(obj)cpu_init_nand.c
+$(obj)spl_minimal.c:
+       @rm -f $(obj)spl_minimal.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/spl_minimal.c $(obj)spl_minimal.c
 
 $(obj)fsl_law.c:
        @rm -f $(obj)fsl_law.c
-       ln -sf $(SRCTREE)/drivers/misc/fsl_law.c $(obj)fsl_law.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc8xxx/law.c $(obj)fsl_law.c
 
 $(obj)law.c:
        @rm -f $(obj)law.c
index 43e72c42d48f44515c4e57f0cd7c81f06d969093..f67ed09d039ad8407d0065ccd632504225ea2c85 100644 (file)
@@ -42,7 +42,8 @@ $(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot.lds
 # $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
 $(eval $(call make_u_boot_list, $(LSTSCRIPT), $(OBJS)))
 $(nandobj)u-boot.lds: $(LDSCRIPT) $(LSTSCRIPT)
-       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj) -ansi -D__ASSEMBLY__ -P - <$< >$@
+       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(nandobj)/board/$(BOARDDIR) \
+               -ansi -D__ASSEMBLY__ -P - <$< >$@
 
 #########################################################################
 
index f270faae02454e0c4eb45ff07feb20f3d22c1c55..c3495ec0dff7dcb72fedaa09d6cf7b14850d482a 100644 (file)
@@ -39,9 +39,8 @@ AFLAGS        += -DCONFIG_NAND_SPL
 CFLAGS += -DCONFIG_NAND_SPL
 
 SOBJS  = start.o resetvec.o ticks.o
-COBJS  = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \
-         nand_boot.o nand_boot_fsl_ifc.o ns16550.o tlb.o tlb_table.o \
-         ../common.o
+COBJS  = cache.o cpu_init_early.o spl_minimal.o fsl_law.o law.o \
+         nand_boot.o nand_boot_fsl_ifc.o ns16550.o tlb.o tlb_table.o
 
 SRCS   := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
@@ -68,7 +67,8 @@ $(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot-nand_spl.lds
 # $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
 $(eval $(call make_u_boot_list, $(LSTSCRIPT), $(OBJS)))
 $(nandobj)u-boot-nand_spl.lds: $(LDSCRIPT) $(LSTSCRIPT)
-       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj) -ansi -D__ASSEMBLY__ -P - <$< >$@
+       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(nandobj)board/$(BOARDDIR) \
+                -ansi -D__ASSEMBLY__ -P - <$< >$@
 
 # create symbolic links for common files
 
@@ -80,13 +80,13 @@ $(obj)cpu_init_early.c:
        @rm -f $(obj)cpu_init_early.c
        ln -sf $(SRCTREE)/$(CPUDIR)/cpu_init_early.c $(obj)cpu_init_early.c
 
-$(obj)cpu_init_nand.c:
-       @rm -f $(obj)cpu_init_nand.c
-       ln -sf $(SRCTREE)/$(CPUDIR)/cpu_init_nand.c $(obj)cpu_init_nand.c
+$(obj)spl_minimal.c:
+       @rm -f $(obj)spl_minimal.c
+       ln -sf $(SRCTREE)/$(CPUDIR)/spl_minimal.c $(obj)spl_minimal.c
 
 $(obj)fsl_law.c:
        @rm -f $(obj)fsl_law.c
-       ln -sf $(SRCTREE)/drivers/misc/fsl_law.c $(obj)fsl_law.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc8xxx/law.c $(obj)fsl_law.c
 
 $(obj)law.c:
        @rm -f $(obj)law.c
@@ -129,9 +129,6 @@ ifneq ($(OBJTREE), $(SRCTREE))
 $(obj)nand_boot.c:
        @rm -f $(obj)nand_boot.c
        ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c
-$(obj)../common.c:
-       @rm -f $(obj)../common.c
-       ln -s $(SRCTREE)/nand_spl/board/freescale/common.c $(obj)../common.c
 endif
 
 #########################################################################
index 9c356901b13f60ba0ba90b5c580cfb4196c2f8a4..3c7bc2bc6536d55c2725a522346e3ae0f3d444b1 100644 (file)
@@ -35,7 +35,7 @@ unsigned long ddr_freq_mhz;
 
 void sdram_init(void)
 {
-       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
        /* mask off E bit */
        u32 svr = SVR_SOC_VER(mfspr(SPRN_SVR));
 
index b2882844b3b470f5de253ca2608ee2d12426eb19..9b2c0d7f35711b81fcef00fc19bfb9cf64299370 100644 (file)
@@ -34,9 +34,8 @@ AFLAGS        += -DCONFIG_NAND_SPL
 CFLAGS += -DCONFIG_NAND_SPL
 
 SOBJS  = start.o resetvec.o
-COBJS  = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \
-         nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o \
-         ../common.o
+COBJS  = cache.o cpu_init_early.o spl_minimal.o fsl_law.o law.o \
+         nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o
 
 SRCS   := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
@@ -63,7 +62,8 @@ $(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot-nand_spl.lds
 # $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
 $(eval $(call make_u_boot_list, $(LSTSCRIPT), $(OBJS)))
 $(nandobj)u-boot-nand_spl.lds: $(LDSCRIPT) $(LSTSCRIPT)
-       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj) -ansi -D__ASSEMBLY__ -P - <$< >$@
+       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(nandobj)/board/$(BOARDDIR) \
+               -ansi -D__ASSEMBLY__ -P - <$< >$@
 
 # create symbolic links for common files
 
@@ -75,13 +75,13 @@ $(obj)cpu_init_early.c:
        @rm -f $(obj)cpu_init_early.c
        ln -sf $(SRCTREE)/$(CPUDIR)/cpu_init_early.c $(obj)cpu_init_early.c
 
-$(obj)cpu_init_nand.c:
-       @rm -f $(obj)cpu_init_nand.c
-       ln -sf $(SRCTREE)/$(CPUDIR)/cpu_init_nand.c $(obj)cpu_init_nand.c
+$(obj)spl_minimal.c:
+       @rm -f $(obj)spl_minimal.c
+       ln -sf $(SRCTREE)/$(CPUDIR)/spl_minimal.c $(obj)spl_minimal.c
 
 $(obj)fsl_law.c:
        @rm -f $(obj)fsl_law.c
-       ln -sf $(SRCTREE)/drivers/misc/fsl_law.c $(obj)fsl_law.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc8xxx/law.c $(obj)fsl_law.c
 
 $(obj)law.c:
        @rm -f $(obj)law.c
@@ -120,9 +120,6 @@ ifneq ($(OBJTREE), $(SRCTREE))
 $(obj)nand_boot.c:
        @rm -f $(obj)nand_boot.c
        ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c
-$(obj)../common.c:
-       @rm -f $(obj)../common.c
-       ln -s $(SRCTREE)/nand_spl/board/freescale/common.c $(obj)../common.c
 endif
 
 #########################################################################
index 89e339d51207462533ee1d235b9e5b5dbdd15ed7..d6756fbf806773f37e9d44367be7f24fadea035a 100644 (file)
@@ -33,7 +33,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Fixed sdram init -- doesn't use serial presence detect. */
 void sdram_init(void)
 {
-       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+       ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
 
        set_next_law(0, LAW_SIZE_2G, LAW_TRGT_IF_DDR_1);
 
index e5388d89c859bfd6092489e915e9ee3f66b4ffd9..9c778261b6f7e8fa19d8c7dc7a0274b8d7a4074f 100644 (file)
@@ -39,7 +39,7 @@ AFLAGS        += -DCONFIG_NAND_SPL
 CFLAGS += -DCONFIG_NAND_SPL
 
 SOBJS  = start.o resetvec.o
-COBJS  = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \
+COBJS  = cache.o cpu_init_early.o spl_minimal.o fsl_law.o law.o \
          nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o
 
 SRCS   := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
@@ -67,7 +67,8 @@ $(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot-nand_spl.lds
 # $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
 $(eval $(call make_u_boot_list, $(LSTSCRIPT), $(OBJS)))
 $(nandobj)u-boot-nand_spl.lds: $(LDSCRIPT) $(LSTSCRIPT)
-       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj) -ansi -D__ASSEMBLY__ -P - <$< >$@
+       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(nandobj)/board/$(BOARDDIR) \
+               -ansi -D__ASSEMBLY__ -P - <$< >$@
 
 # create symbolic links for common files
 
@@ -79,13 +80,13 @@ $(obj)cpu_init_early.c:
        @rm -f $(obj)cpu_init_early.c
        ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/cpu_init_early.c $(obj)cpu_init_early.c
 
-$(obj)cpu_init_nand.c:
-       @rm -f $(obj)cpu_init_nand.c
-       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c $(obj)cpu_init_nand.c
+$(obj)spl_minimal.c:
+       @rm -f $(obj)spl_minimal.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc85xx/spl_minimal.c $(obj)spl_minimal.c
 
 $(obj)fsl_law.c:
        @rm -f $(obj)fsl_law.c
-       ln -sf $(SRCTREE)/drivers/misc/fsl_law.c $(obj)fsl_law.c
+       ln -sf $(SRCTREE)/arch/powerpc/cpu/mpc8xxx/law.c $(obj)fsl_law.c
 
 $(obj)law.c:
        @rm -f $(obj)law.c
diff --git a/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile b/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile
deleted file mode 100644 (file)
index 7146d16..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-#
-# (C) Copyright 2007
-# Stefan Roese, DENX Software Engineering, sr@denx.de.
-#
-# Copyright 2011 Freescale Semiconductor, Inc.
-#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-
-NAND_SPL := y
-CONFIG_SYS_TEXT_BASE_SPL := 0xfff00000
-PAD_TO := 0xff801000
-
-include $(TOPDIR)/config.mk
-
-nandobj        := $(OBJTREE)/nand_spl/
-
-LDSCRIPT= $(TOPDIR)/$(CPUDIR)/u-boot-nand_spl.lds
-LSTSCRIPT= $(nandobj)/board/$(BOARDDIR)/u-boot.lst
-LDFLAGS := -T $(nandobj)u-boot-nand_spl.lds -Ttext $(CONFIG_SYS_TEXT_BASE_SPL) \
-               $(LDFLAGS) $(LDFLAGS_FINAL)
-AFLAGS += -DCONFIG_NAND_SPL
-CFLAGS += -DCONFIG_NAND_SPL
-
-SOBJS  = start.o resetvec.o
-COBJS  = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \
-         nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o \
-         ../common.o
-
-SRCS   := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
-OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
-__OBJS := $(SOBJS) $(COBJS)
-LNDIR  := $(nandobj)board/$(BOARDDIR)
-
-ALL    = $(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin
-
-all:   $(obj).depend $(ALL)
-
-$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl
-       $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $< $@
-
-$(nandobj)u-boot-spl.bin:      $(nandobj)u-boot-spl
-       $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
-
-$(nandobj)u-boot-spl:  $(OBJS) $(nandobj)u-boot-nand_spl.lds
-       cd $(LNDIR) && $(LD) $(LDFLAGS) $(__OBJS) $(PLATFORM_LIBS) \
-               -Map $(nandobj)u-boot-spl.map \
-               -o $(nandobj)u-boot-spl
-
-# The following line expands into whole rule which generates $(LSTSCRIPT),
-# the file containing u-boots LG-array linker section. This is included into
-# $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
-$(eval $(call make_u_boot_list, $(LSTSCRIPT), $(OBJS)))
-$(nandobj)u-boot-nand_spl.lds: $(LDSCRIPT) $(LSTSCRIPT)
-       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj) -ansi -D__ASSEMBLY__ -P - <$< >$@
-
-# create symbolic links for common files
-
-$(obj)cache.c:
-       @rm -f $(obj)cache.c
-       ln -sf $(SRCTREE)/arch/powerpc/lib/cache.c $(obj)cache.c
-
-$(obj)cpu_init_early.c:
-       @rm -f $(obj)cpu_init_early.c
-       ln -sf $(SRCTREE)/$(CPUDIR)/cpu_init_early.c $(obj)cpu_init_early.c
-
-$(obj)cpu_init_nand.c:
-       @rm -f $(obj)cpu_init_nand.c
-       ln -sf $(SRCTREE)/$(CPUDIR)/cpu_init_nand.c $(obj)cpu_init_nand.c
-
-$(obj)fsl_law.c:
-       @rm -f $(obj)fsl_law.c
-       ln -sf $(SRCTREE)/drivers/misc/fsl_law.c $(obj)fsl_law.c
-
-$(obj)law.c:
-       @rm -f $(obj)law.c
-       ln -sf $(SRCTREE)/board/$(BOARDDIR)/law.c $(obj)law.c
-
-$(obj)nand_boot_fsl_elbc.c:
-       @rm -f $(obj)nand_boot_fsl_elbc.c
-       ln -sf $(SRCTREE)/nand_spl/nand_boot_fsl_elbc.c \
-              $(obj)nand_boot_fsl_elbc.c
-
-$(obj)ns16550.c:
-       @rm -f $(obj)ns16550.c
-       ln -sf $(SRCTREE)/drivers/serial/ns16550.c $(obj)ns16550.c
-
-$(obj)resetvec.S:
-       @rm -f $(obj)resetvec.S
-       ln -s $(SRCTREE)/$(CPUDIR)/resetvec.S $(obj)resetvec.S
-
-$(obj)fixed_ivor.S:
-       @rm -f $(obj)fixed_ivor.S
-       ln -sf $(SRCTREE)/$(CPUDIR)/fixed_ivor.S $(obj)fixed_ivor.S
-
-$(obj)start.S: $(obj)fixed_ivor.S
-       @rm -f $(obj)start.S
-       ln -sf $(SRCTREE)/$(CPUDIR)/start.S $(obj)start.S
-
-$(obj)tlb.c:
-       @rm -f $(obj)tlb.c
-       ln -sf $(SRCTREE)/$(CPUDIR)/tlb.c $(obj)tlb.c
-
-$(obj)tlb_table.c:
-       @rm -f $(obj)tlb_table.c
-       ln -sf $(SRCTREE)/board/$(BOARDDIR)/tlb.c $(obj)tlb_table.c
-
-ifneq ($(OBJTREE), $(SRCTREE))
-$(obj)nand_boot.c:
-       @rm -f $(obj)nand_boot.c
-       ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c
-$(obj)../common.c:
-       @rm -f $(obj)../common.c
-       ln -s $(SRCTREE)/nand_spl/board/freescale/common.c $(obj)../common.c
-endif
-
-#########################################################################
-
-$(obj)%.o:     $(obj)%.S
-       $(CC) $(AFLAGS) -c -o $@ $<
-
-$(obj)%.o:     $(obj)%.c
-       $(CC) $(CFLAGS) -c -o $@ $<
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
index becf7fa99ebf4bbf93494c329110bfb8bb07d673..b27189d9b50edc9247eabb353ca3d34c9e5569f0 100644 (file)
@@ -63,7 +63,8 @@ $(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot.lds
 # $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
 $(eval $(call make_u_boot_list, $(LSTSCRIPT), $(OBJS)))
 $(nandobj)u-boot.lds: $(LDSCRIPT) $(LSTSCRIPT)
-       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj) -ansi -D__ASSEMBLY__ -P - <$< >$@
+       $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(nandobj)/board/$(BOARDDIR) \
+               -ansi -D__ASSEMBLY__ -P - <$< >$@
 
 #########################################################################
 
index 6a79c3cd38f052079106271a109c288c0d574665..6dbb1055b6dfc7bf6a58cc0f1a5c93b395c610e2 100644 (file)
@@ -32,9 +32,30 @@ START_PATH := $(CPUDIR)
 endif
 
 START := $(START_PATH)/start.o
+ifeq ($(CPU),x86)
+START += $(START_PATH)/start16.o
+START += $(START_PATH)/resetvec.o
+endif
+ifeq ($(CPU),ppc4xx)
+START += $(START_PATH)/resetvec.o
+endif
+ifeq ($(CPU),mpc85xx)
+START += $(START_PATH)/resetvec.o
+endif
 
 LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).o
+
 LIBS-y += $(CPUDIR)/lib$(CPU).o
+ifeq ($(CPU),mpc83xx)
+LIBS-y += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
+endif
+ifeq ($(CPU),mpc85xx)
+LIBS-y += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
+endif
+ifeq ($(CPU),mpc86xx)
+LIBS-y += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
+endif
+
 ifdef SOC
 LIBS-y += $(CPUDIR)/$(SOC)/lib$(SOC).o
 endif
index a283a2d1f4b2e0bdbb519f58c3a5af9bb87fb0e5..d2971f48983afe05f259be47284360442cbac552 100644 (file)
@@ -145,10 +145,11 @@ class Series(dict):
         Return:
             The change log as a list of strings, one per line
 
-            Changes in v2:
+            Changes in v4:
             - Jog the dial back closer to the widget
 
-            Changes in v1:
+            Changes in v3: None
+            Changes in v2:
             - Fix the widget
             - Jog the dial
 
@@ -162,12 +163,16 @@ class Series(dict):
                 if commit and this_commit != commit:
                     continue
                 out.append(text)
-            if out:
-                out = ['Changes in v%d:' % change] + out
-                if need_blank:
-                    out = [''] + out
-                final += out
-                need_blank = True
+            line = 'Changes in v%d:' % change
+            have_changes = len(out) > 0
+            if have_changes:
+                out.insert(0, line)
+            else:
+                out = [line + ' None']
+            if need_blank:
+                out.insert(0, '')
+            final += out
+            need_blank = have_changes
         if self.changes:
             final.append('')
         return final