]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'u-boot-ti/master' into 'u-boot-arm/master'
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>
Tue, 8 Jan 2013 12:15:45 +0000 (13:15 +0100)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Tue, 8 Jan 2013 12:15:45 +0000 (13:15 +0100)
This required manual merging drivers/mtd/nand/Makefile
and adding am335x_evm support for CONFIG_SPL_NAND_DRIVERS

500 files changed:
.gitignore
MAINTAINERS
MAKEALL
Makefile
README
arch/arm/cpu/arm926ejs/mxs/clock.c
arch/arm/cpu/arm926ejs/mxs/spl_boot.c
arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock.c
arch/arm/cpu/armv7/exynos/clock.c
arch/arm/cpu/armv7/exynos/pinmux.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/cpu.h
arch/arm/include/asm/arch-exynos/dwmmc.h [new file with mode: 0644]
arch/arm/include/asm/arch-mxs/clock.h
arch/arm/include/asm/arch-mxs/imx-regs.h
arch/arm/include/asm/arch-mxs/regs-clkctrl-mx28.h
arch/arm/include/asm/arch-mxs/regs-power-mx28.h [moved from arch/arm/include/asm/arch-mxs/regs-power.h with 100% similarity]
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/m68k/include/asm/string.h
arch/m68k/lib/board.c
arch/microblaze/lib/board.c
arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
arch/mips/cpu/mips32/time.c
arch/mips/cpu/mips64/start.S
arch/mips/cpu/mips64/time.c
arch/mips/include/asm/bitops.h
arch/mips/lib/board.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/mp.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/include/asm/string.h
arch/powerpc/lib/Makefile
arch/powerpc/lib/board.c
arch/powerpc/lib/bootm.c
arch/powerpc/lib/spl.c [new file with mode: 0644]
arch/sh/include/asm/system.h
arch/sparc/include/asm/string.h
arch/sparc/lib/board.c
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/Marvell/db64360/db64360.c
board/Marvell/db64460/db64460.c
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/esd/cpci750/cpci750.c
board/esd/pmc440/cmd_pmc440.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/mx25pdk/mx25pdk.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/gw8260/gw8260.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/prodrive/p3mx/p3mx.c
board/raidsonic/ib62x0/ib62x0.c
board/raidsonic/ib62x0/ib62x0.h
board/raidsonic/ib62x0/kwbimage.cfg
board/samsung/goni/goni.c
board/samsung/smdk5250/smdk5250.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_gettime.c [new file with mode: 0644]
common/cmd_gpt.c [new file with mode: 0644]
common/cmd_hash.c [new file with mode: 0644]
common/cmd_i2c.c
common/cmd_io.c [new file with mode: 0644]
common/cmd_led.c
common/cmd_mmc.c
common/cmd_nand.c
common/cmd_nvedit.c
common/cmd_read.c [new file with mode: 0644]
common/cmd_sha1sum.c
common/cmd_spl.c
common/cmd_tpm.c
common/cmd_usb.c
common/console.c
common/edid.c [new file with mode: 0644]
common/env_attr.c [new file with mode: 0644]
common/env_callback.c [new file with mode: 0644]
common/env_common.c
common/env_dataflash.c
common/env_eeprom.c
common/env_fat.c
common/env_flags.c [new file with mode: 0644]
common/env_flash.c
common/env_mmc.c
common/env_nand.c
common/env_nvram.c
common/env_onenand.c
common/env_sf.c
common/fdt_support.c
common/hash.c [new file with mode: 0644]
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
disk/part_efi.c
doc/DocBook/Makefile
doc/README.gpt [new file with mode: 0644]
doc/README.mpc85xx
doc/README.nand
doc/README.silent
doc/kwboot.1
drivers/gpio/Makefile
drivers/gpio/intel_ich6_gpio.c [new file with mode: 0644]
drivers/i2c/designware_i2c.c
drivers/i2c/designware_i2c.h
drivers/i2c/mxc_i2c.c
drivers/i2c/mxs_i2c.c
drivers/i2c/omap24xx_i2c.c
drivers/i2c/s3c24x0_i2c.c
drivers/i2c/soft_i2c.c
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/mxs_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_util.c
drivers/net/e1000.c
drivers/net/e1000.h
drivers/net/fm/Makefile
drivers/net/fm/p5040.c [new file with mode: 0644]
drivers/net/phy/marvell.c
drivers/net/sh_eth.c
drivers/net/sh_eth.h
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_max77686.c [moved from drivers/misc/pmic_max77686.c with 82% similarity]
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.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/asm-generic/gpio.h
include/atmel_hlcdc.h
include/bouncebuf.h
include/cbfs.h
include/command.h
include/common.h
include/config_cmd_all.h
include/configs/CPCI405.h
include/configs/CPCI4052.h
include/configs/CPCI405AB.h
include/configs/CPCI405DT.h
include/configs/CRAYL1.h
include/configs/GEN860T.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/TOP860.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/ep8260.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/m28evk.h
include/configs/mcx.h
include/configs/mx25pdk.h
include/configs/mx28evk.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/smdk5250.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/utx8245.h
include/configs/vct.h
include/configs/ventana.h
include/configs/vision2.h
include/configs/woodburn_common.h
include/edid.h [new file with mode: 0644]
include/env_attr.h [new file with mode: 0644]
include/env_callback.h [new file with mode: 0644]
include/env_default.h
include/env_flags.h [new file with mode: 0644]
include/environment.h
include/exports.h
include/fdtdec.h
include/g_dnl.h
include/hash.h [new file with mode: 0644]
include/image.h
include/lcd.h
include/linux/byteorder/swab.h
include/linux/linux_string.h [new file with mode: 0644]
include/linux/mtd/nand.h
include/linux/string.h
include/linux/usb/ch9.h
include/linux/usb/musb.h [new file with mode: 0644]
include/nand.h
include/nios2.h
include/part.h
include/part_efi.h [moved from disk/part_efi.h with 66% similarity]
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/max77686_pmic.h [moved from include/max77686_pmic.h with 100% similarity]
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/search.h
include/sha1.h
include/sha256.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/hashtable.c
lib/linux_string.c [new file with mode: 0644]
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]
lib/sha1.c
lib/sha256.c
lib/string.c
lib/vsprintf.c
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
net/link_local.c
net/net.c
net/tftp.c
spl/Makefile
tools/env/Makefile
tools/env/fw_env.c
tools/fit_image.c
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 8a04727f62da8433c940dd3cf9e2cf47bd0bc793..a7b6cd1cbad361ecfa6f71faff567ebae86c449d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@
 VERSION = 2013
 PATCHLEVEL = 01
 SUBLEVEL =
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 ifneq "$(SUBLEVEL)" ""
 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 else
@@ -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)
@@ -320,6 +323,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
@@ -387,12 +391,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
@@ -405,6 +409,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
@@ -446,9 +451,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 $< $@
@@ -472,14 +486,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 \
@@ -496,7 +511,7 @@ $(obj)u-boot.ais:       $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
 ELFTOSB_TARGET-$(CONFIG_MX28) = imx28
 
 $(obj)u-boot.sb:       $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin
-               elftosb -zdf $(ELFTOSB_TARGET-y) -c $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot-$(ELFTOSB_TARGET-y).bd \
+               elftosb -zf $(ELFTOSB_TARGET-y) -c $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot-$(ELFTOSB_TARGET-y).bd \
                        -o $(obj)u-boot.sb
 
 # On x600 (SPEAr600) U-Boot is appended to U-Boot SPL.
@@ -530,6 +545,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 \
@@ -639,6 +657,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)
 #
@@ -812,7 +840,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 037513a1340c1a250aa3ec02ca7cbc6ad5f09236..653ef6aa4a55d57686165e56eeec847dcd40b3f1 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:
 ==================
@@ -810,6 +815,8 @@ The following options need to be configured:
                CONFIG_CMD_EDITENV        edit env variable
                CONFIG_CMD_EEPROM       * EEPROM read/write support
                CONFIG_CMD_ELF          * bootelf, bootvx
+               CONFIG_CMD_ENV_CALLBACK * display details about env callbacks
+               CONFIG_CMD_ENV_FLAGS    * display details about env flags
                CONFIG_CMD_EXPORTENV    * export the environment
                CONFIG_CMD_EXT2         * ext2 command support
                CONFIG_CMD_EXT4         * ext4 command support
@@ -819,8 +826,10 @@ The following options need to be configured:
                CONFIG_CMD_FDOS         * Dos diskette Support
                CONFIG_CMD_FLASH          flinfo, erase, protect
                CONFIG_CMD_FPGA           FPGA device initialization support
+               CONFIG_CMD_GETTIME      * Get time since boot
                CONFIG_CMD_GO           * the 'go' command (exec code)
                CONFIG_CMD_GREPENV      * search environment
+               CONFIG_CMD_HASH         * calculate hash / digest
                CONFIG_CMD_HWFLOW       * RTS/CTS hw flow control
                CONFIG_CMD_I2C          * I2C serial bus support
                CONFIG_CMD_IDE          * IDE harddisk support
@@ -855,6 +864,7 @@ The following options need to be configured:
                CONFIG_CMD_PING         * send ICMP ECHO_REQUEST to network
                                          host
                CONFIG_CMD_PORTIO       * Port I/O
+               CONFIG_CMD_READ         * Read raw data from partition
                CONFIG_CMD_REGINFO      * Register dump
                CONFIG_CMD_RUN            run command in env variable
                CONFIG_CMD_SAVES        * save S record dump
@@ -1409,6 +1419,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,7 +1486,6 @@ CBFS (Coreboot Filesystem) support
                Normally display is black on white background; define
                CONFIG_SYS_WHITE_ON_BLACK to get it inverted.
 
-
                CONFIG_LCD_ALIGNMENT
 
                Normally the LCD is page-aligned (tyically 4KB). If this is
@@ -1485,6 +1501,15 @@ CBFS (Coreboot Filesystem) support
                the console jump but can help speed up operation when scrolling
                is slow.
 
+               CONFIG_LCD_BMP_RLE8
+
+               Support drawing of RLE8-compressed bitmaps on the LCD.
+
+               CONFIG_I2C_EDID
+
+               Enables an 'i2c edid' command which can read EDID
+               information over I2C from an attached LCD display.
+
 - Splash Screen Support: CONFIG_SPLASH_SCREEN
 
                If this option is set, the environment is checked for
@@ -2178,6 +2203,11 @@ CBFS (Coreboot Filesystem) support
                serial# is unaffected by this, i. e. it remains
                read-only.]
 
+               The same can be accomplished in a more flexible way
+               for any variable by configuring the type of access
+               to allow for those variables in the ".flags" variable
+               or define CONFIG_ENV_FLAGS_LIST_STATIC.
+
 - Protected RAM:
                CONFIG_PRAM
 
@@ -2211,6 +2241,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
 
@@ -2400,6 +2438,23 @@ CBFS (Coreboot Filesystem) support
                A better solution is to properly configure the firewall,
                but sometimes that is not allowed.
 
+- Hashing support:
+               CONFIG_CMD_HASH
+
+               This enables a generic 'hash' command which can produce
+               hashes / digests from a few algorithms (e.g. SHA1, SHA256).
+
+               CONFIG_HASH_VERIFY
+
+               Enable the hash verify command (hash -v). This adds to code
+               size a little.
+
+               CONFIG_SHA1 - support SHA1 hashing
+               CONFIG_SHA256 - support SHA256 hashing
+
+               Note: There is also a sha1sum command, which should perhaps
+               be deprecated in favour of 'hash sha1'.
+
 - Show boot progress:
                CONFIG_SHOW_BOOT_PROGRESS
 
@@ -2613,6 +2668,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
 
@@ -2664,6 +2730,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.
 
@@ -2673,6 +2743,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.
 
@@ -2688,6 +2763,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
 
@@ -2715,8 +2793,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,
@@ -2724,15 +2813,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
@@ -2757,6 +2850,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:
 --------------
 
@@ -2891,9 +2989,6 @@ Configuration Settings:
                non page size aligned address and this could cause major
                problems.
 
-- CONFIG_SYS_TFTP_LOADADDR:
-               Default load address for network file downloads
-
 - CONFIG_SYS_LOADS_BAUD_CHANGE:
                Enable temporary baudrate change while serial download
 
@@ -3035,6 +3130,49 @@ Configuration Settings:
        cases. This setting can be used to tune behaviour; see
        lib/hashtable.c for details.
 
+- CONFIG_ENV_FLAGS_LIST_DEFAULT
+- CONFIG_ENV_FLAGS_LIST_STATIC
+       Enable validation of the values given to enviroment variables when
+       calling env set.  Variables can be restricted to only decimal,
+       hexadecimal, or boolean.  If CONFIG_CMD_NET is also defined,
+       the variables can also be restricted to IP address or MAC address.
+
+       The format of the list is:
+               type_attribute = [s|d|x|b|i|m]
+               access_atribute = [a|r|o|c]
+               attributes = type_attribute[access_atribute]
+               entry = variable_name[:attributes]
+               list = entry[,list]
+
+       The type attributes are:
+               s - String (default)
+               d - Decimal
+               x - Hexadecimal
+               b - Boolean ([1yYtT|0nNfF])
+               i - IP address
+               m - MAC address
+
+       The access attributes are:
+               a - Any (default)
+               r - Read-only
+               o - Write-once
+               c - Change-default
+
+       - CONFIG_ENV_FLAGS_LIST_DEFAULT
+               Define this to a list (string) to define the ".flags"
+               envirnoment variable in the default or embedded environment.
+
+       - CONFIG_ENV_FLAGS_LIST_STATIC
+               Define this to a list (string) to define validation that
+               should be done if an entry is not found in the ".flags"
+               environment variable.  To override a setting in the static
+               list, simply add an entry for the same variable name to the
+               ".flags" variable.
+
+- CONFIG_ENV_ACCESS_IGNORE_FORCE
+       If defined, don't allow the -f switch to env set override variable
+       access flags.
+
 The following definitions that deal with the placement and management
 of environment data (variable area); in general, we support the
 following configurations:
@@ -3632,6 +3770,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:
 -----------------------------------
 
@@ -3859,6 +4007,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
@@ -4125,6 +4274,36 @@ Please note that changes to some configuration parameters may take
 only effect after the next boot (yes, that's just like Windoze :-).
 
 
+Callback functions for environment variables:
+---------------------------------------------
+
+For some environment variables, the behavior of u-boot needs to change
+when their values are changed.  This functionailty allows functions to
+be associated with arbitrary variables.  On creation, overwrite, or
+deletion, the callback will provide the opportunity for some side
+effect to happen or for the change to be rejected.
+
+The callbacks are named and associated with a function using the
+U_BOOT_ENV_CALLBACK macro in your board or driver code.
+
+These callbacks are associated with variables in one of two ways.  The
+static list can be added to by defining CONFIG_ENV_CALLBACK_LIST_STATIC
+in the board configuration to a string that defines a list of
+associations.  The list must be in the following format:
+
+       entry = variable_name[:callback_name]
+       list = entry[,list]
+
+If the callback name is not specified, then the callback is deleted.
+Spaces are also allowed anywhere in the list.
+
+Callbacks can also be associated by defining the ".callbacks" variable
+with the same list format above.  Any association in ".callbacks" will
+override any association in the static list. You can define
+CONFIG_ENV_CALLBACK_LIST_DEFAULT to a list (string) to define the
+".callbacks" envirnoment variable in the default or embedded environment.
+
+
 Command Line Parsing:
 =====================
 
index bfea6abeb0714e38dc02351bb32fd6ec7031fef2..4ff19c37efe91ac7247f2b48c0d78097de9fd9e1 100644 (file)
@@ -333,6 +333,8 @@ uint32_t mxc_get_clock(enum mxc_clock clk)
                return mx28_get_sspclk(MXC_SSPCLK2);
        case MXC_SSP3_CLK:
                return mx28_get_sspclk(MXC_SSPCLK3);
+       case MXC_XTAL_CLK:
+               return XTAL_FREQ_KHZ * 1000;
        }
 
        return 0;
index 8ea7c36f46f8d94ed5b5953362fead3f431ba254..1b8502eb9dc03bf3e4edcc1914830db5dc2ed3ef 100644 (file)
@@ -50,7 +50,7 @@ void early_delay(int delay)
 }
 
 #define        MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
-const iomux_cfg_t iomux_boot[] = {
+static const iomux_cfg_t iomux_boot[] = {
        MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD,
        MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD,
        MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD,
@@ -59,7 +59,7 @@ const iomux_cfg_t iomux_boot[] = {
        MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD,
 };
 
-uint8_t mxs_get_bootmode_index(void)
+static uint8_t mxs_get_bootmode_index(void)
 {
        uint8_t bootmode = 0;
        int i;
index e693145b90cf07ccc7afe007d9daaf5648d70c53..401c51362bfd6bf6c0c04a68dce15973adcfe20a 100644 (file)
 
 #include "mxs_init.h"
 
-static uint32_t mx28_dram_vals[] = {
+static uint32_t dram_vals[] = {
+/*
+ * i.MX28 DDR2 at 200MHz
+ */
+#if defined(CONFIG_MX28)
        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -79,6 +83,9 @@ static uint32_t mx28_dram_vals[] = {
        0x06120612, 0x04320432, 0x04320432, 0x00040004,
        0x00040004, 0x00000000, 0x00000000, 0x00000000,
        0x00000000, 0x00010001
+#else
+#error Unsupported memory initialization
+#endif
 };
 
 void __mxs_adjust_memory_params(uint32_t *dram_vals)
@@ -87,17 +94,17 @@ void __mxs_adjust_memory_params(uint32_t *dram_vals)
 void mxs_adjust_memory_params(uint32_t *dram_vals)
        __attribute__((weak, alias("__mxs_adjust_memory_params")));
 
-void init_mx28_200mhz_ddr2(void)
+static void initialize_dram_values(void)
 {
        int i;
 
-       mxs_adjust_memory_params(mx28_dram_vals);
+       mxs_adjust_memory_params(dram_vals);
 
-       for (i = 0; i < ARRAY_SIZE(mx28_dram_vals); i++)
-               writel(mx28_dram_vals[i], MXS_DRAM_BASE + (4 * i));
+       for (i = 0; i < ARRAY_SIZE(dram_vals); i++)
+               writel(dram_vals[i], MXS_DRAM_BASE + (4 * i));
 }
 
-void mxs_mem_init_clock(void)
+static void mxs_mem_init_clock(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -128,7 +135,7 @@ void mxs_mem_init_clock(void)
        early_delay(10000);
 }
 
-void mxs_mem_setup_cpu_and_hbus(void)
+static void mxs_mem_setup_cpu_and_hbus(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -160,7 +167,7 @@ void mxs_mem_setup_cpu_and_hbus(void)
        early_delay(15000);
 }
 
-void mxs_mem_setup_vdda(void)
+static void mxs_mem_setup_vdda(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -171,17 +178,6 @@ void mxs_mem_setup_vdda(void)
                &power_regs->hw_power_vddactrl);
 }
 
-void mxs_mem_setup_vddd(void)
-{
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
-       writel((0x1c << POWER_VDDDCTRL_TRG_OFFSET) |
-               (0x7 << POWER_VDDDCTRL_BO_OFFSET_OFFSET) |
-               POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW,
-               &power_regs->hw_power_vdddctrl);
-}
-
 uint32_t mxs_mem_get_size(void)
 {
        uint32_t sz, da;
@@ -229,7 +225,7 @@ void mxs_mem_init(void)
        /* Clear START bit from DRAM_CTL16 */
        clrbits_le32(MXS_DRAM_BASE + 0x40, 1);
 
-       init_mx28_200mhz_ddr2();
+       initialize_dram_values();
 
        /* Clear SREFRESH bit from DRAM_CTL17 */
        clrbits_le32(MXS_DRAM_BASE + 0x44, 1);
@@ -241,8 +237,6 @@ void mxs_mem_init(void)
        while (!(readl(MXS_DRAM_BASE + 0xe8) & (1 << 20)))
                ;
 
-       mxs_mem_setup_vddd();
-
        early_delay(10000);
 
        mxs_mem_setup_cpu_and_hbus();
index 4b917bd186df4ea62651690c1a99c91ff2b0118a..be44c22976352fdfec2e193acd6d8402b12484c0 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "mxs_init.h"
 
-void mxs_power_clock2xtal(void)
+static void mxs_power_clock2xtal(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -40,7 +40,7 @@ void mxs_power_clock2xtal(void)
                &clkctrl_regs->hw_clkctrl_clkseq_set);
 }
 
-void mxs_power_clock2pll(void)
+static void mxs_power_clock2pll(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -52,7 +52,7 @@ void mxs_power_clock2pll(void)
                        CLKCTRL_CLKSEQ_BYPASS_CPU);
 }
 
-void mxs_power_clear_auto_restart(void)
+static void mxs_power_clear_auto_restart(void)
 {
        struct mxs_rtc_regs *rtc_regs =
                (struct mxs_rtc_regs *)MXS_RTC_BASE;
@@ -85,7 +85,7 @@ void mxs_power_clear_auto_restart(void)
                ;
 }
 
-void mxs_power_set_linreg(void)
+static void mxs_power_set_linreg(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -104,7 +104,7 @@ void mxs_power_set_linreg(void)
                        POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
 }
 
-int mxs_get_batt_volt(void)
+static int mxs_get_batt_volt(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -115,12 +115,12 @@ int mxs_get_batt_volt(void)
        return volt;
 }
 
-int mxs_is_batt_ready(void)
+static int mxs_is_batt_ready(void)
 {
        return (mxs_get_batt_volt() >= 3600);
 }
 
-int mxs_is_batt_good(void)
+static int mxs_is_batt_good(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -160,7 +160,7 @@ int mxs_is_batt_good(void)
        return 0;
 }
 
-void mxs_power_setup_5v_detect(void)
+static void mxs_power_setup_5v_detect(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -172,7 +172,7 @@ void mxs_power_setup_5v_detect(void)
                        POWER_5VCTRL_PWRUP_VBUS_CMPS);
 }
 
-void mxs_src_power_init(void)
+static void mxs_src_power_init(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -203,7 +203,7 @@ void mxs_src_power_init(void)
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
 }
 
-void mxs_power_init_4p2_params(void)
+static void mxs_power_init_4p2_params(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -227,7 +227,7 @@ void mxs_power_init_4p2_params(void)
                0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
 }
 
-void mxs_enable_4p2_dcdc_input(int xfer)
+static void mxs_enable_4p2_dcdc_input(int xfer)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -323,7 +323,7 @@ void mxs_enable_4p2_dcdc_input(int xfer)
                                POWER_CTRL_ENIRQ_VDD5V_DROOP);
 }
 
-void mxs_power_init_4p2_regulator(void)
+static void mxs_power_init_4p2_regulator(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -407,7 +407,7 @@ void mxs_power_init_4p2_regulator(void)
        writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
 }
 
-void mxs_power_init_dcdc_4p2_source(void)
+static void mxs_power_init_dcdc_4p2_source(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -429,7 +429,7 @@ void mxs_power_init_dcdc_4p2_source(void)
        }
 }
 
-void mxs_power_enable_4p2(void)
+static void mxs_power_enable_4p2(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -488,7 +488,7 @@ void mxs_power_enable_4p2(void)
                        &power_regs->hw_power_charge_clr);
 }
 
-void mxs_boot_valid_5v(void)
+static void mxs_boot_valid_5v(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -511,7 +511,7 @@ void mxs_boot_valid_5v(void)
        mxs_power_enable_4p2();
 }
 
-void mxs_powerdown(void)
+static void mxs_powerdown(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -520,7 +520,7 @@ void mxs_powerdown(void)
                &power_regs->hw_power_reset);
 }
 
-void mxs_batt_boot(void)
+static void mxs_batt_boot(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -564,7 +564,7 @@ void mxs_batt_boot(void)
                0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
 }
 
-void mxs_handle_5v_conflict(void)
+static void mxs_handle_5v_conflict(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -600,7 +600,7 @@ void mxs_handle_5v_conflict(void)
        }
 }
 
-void mxs_5v_boot(void)
+static void mxs_5v_boot(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -623,7 +623,7 @@ void mxs_5v_boot(void)
        mxs_handle_5v_conflict();
 }
 
-void mxs_init_batt_bo(void)
+static void mxs_init_batt_bo(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -637,7 +637,7 @@ void mxs_init_batt_bo(void)
        writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
 }
 
-void mxs_switch_vddd_to_dcdc_source(void)
+static void mxs_switch_vddd_to_dcdc_source(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -651,7 +651,7 @@ void mxs_switch_vddd_to_dcdc_source(void)
                POWER_VDDDCTRL_DISABLE_STEPPING);
 }
 
-void mxs_power_configure_power_source(void)
+static void mxs_power_configure_power_source(void)
 {
        int batt_ready, batt_good;
        struct mxs_power_regs *power_regs =
@@ -689,7 +689,7 @@ void mxs_power_configure_power_source(void)
        mxs_switch_vddd_to_dcdc_source();
 }
 
-void mxs_enable_output_rail_protection(void)
+static void mxs_enable_output_rail_protection(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -707,7 +707,7 @@ void mxs_enable_output_rail_protection(void)
                        POWER_VDDIOCTRL_PWDN_BRNOUT);
 }
 
-int mxs_get_vddio_power_source_off(void)
+static int mxs_get_vddio_power_source_off(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -735,7 +735,7 @@ int mxs_get_vddio_power_source_off(void)
 
 }
 
-int mxs_get_vddd_power_source_off(void)
+static int mxs_get_vddd_power_source_off(void)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
@@ -766,201 +766,115 @@ int mxs_get_vddd_power_source_off(void)
        return 0;
 }
 
-void mxs_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
+struct mxs_vddx_cfg {
+       uint32_t                *reg;
+       uint8_t                 step_mV;
+       uint16_t                lowest_mV;
+       int                     (*powered_by_linreg)(void);
+       uint32_t                trg_mask;
+       uint32_t                bo_irq;
+       uint32_t                bo_enirq;
+       uint32_t                bo_offset_mask;
+       uint32_t                bo_offset_offset;
+};
+
+static const struct mxs_vddx_cfg mxs_vddio_cfg = {
+       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
+                                       hw_power_vddioctrl),
+       .step_mV                = 50,
+       .lowest_mV              = 2800,
+       .powered_by_linreg      = mxs_get_vddio_power_source_off,
+       .trg_mask               = POWER_VDDIOCTRL_TRG_MASK,
+       .bo_irq                 = POWER_CTRL_VDDIO_BO_IRQ,
+       .bo_enirq               = POWER_CTRL_ENIRQ_VDDIO_BO,
+       .bo_offset_mask         = POWER_VDDIOCTRL_BO_OFFSET_MASK,
+       .bo_offset_offset       = POWER_VDDIOCTRL_BO_OFFSET_OFFSET,
+};
+
+static const struct mxs_vddx_cfg mxs_vddd_cfg = {
+       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
+                                       hw_power_vdddctrl),
+       .step_mV                = 25,
+       .lowest_mV              = 800,
+       .powered_by_linreg      = mxs_get_vddd_power_source_off,
+       .trg_mask               = POWER_VDDDCTRL_TRG_MASK,
+       .bo_irq                 = POWER_CTRL_VDDD_BO_IRQ,
+       .bo_enirq               = POWER_CTRL_ENIRQ_VDDD_BO,
+       .bo_offset_mask         = POWER_VDDDCTRL_BO_OFFSET_MASK,
+       .bo_offset_offset       = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
+};
+
+static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
+                               uint32_t new_target, uint32_t new_brownout)
 {
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t cur_target, diff, bo_int = 0;
        uint32_t powered_by_linreg = 0;
+       int adjust_up, tmp;
 
-       new_brownout = (new_target - new_brownout + 25) / 50;
+       new_brownout = DIV_ROUND(new_target - new_brownout, cfg->step_mV);
 
-       cur_target = readl(&power_regs->hw_power_vddioctrl);
-       cur_target &= POWER_VDDIOCTRL_TRG_MASK;
-       cur_target *= 50;       /* 50 mV step*/
-       cur_target += 2800;     /* 2800 mV lowest */
+       cur_target = readl(cfg->reg);
+       cur_target &= cfg->trg_mask;
+       cur_target *= cfg->step_mV;
+       cur_target += cfg->lowest_mV;
 
-       powered_by_linreg = mxs_get_vddio_power_source_off();
-       if (new_target > cur_target) {
+       adjust_up = new_target > cur_target;
+       powered_by_linreg = cfg->powered_by_linreg();
 
+       if (adjust_up) {
                if (powered_by_linreg) {
-                       bo_int = readl(&power_regs->hw_power_vddioctrl);
-                       clrbits_le32(&power_regs->hw_power_vddioctrl,
-                                       POWER_CTRL_ENIRQ_VDDIO_BO);
+                       bo_int = readl(cfg->reg);
+                       clrbits_le32(cfg->reg, cfg->bo_enirq);
                }
+               setbits_le32(cfg->reg, cfg->bo_offset_mask);
+       }
 
-               setbits_le32(&power_regs->hw_power_vddioctrl,
-                               POWER_VDDIOCTRL_BO_OFFSET_MASK);
-               do {
-                       if (new_target - cur_target > 100)
+       do {
+               if (abs(new_target - cur_target) > 100) {
+                       if (adjust_up)
                                diff = cur_target + 100;
                        else
-                               diff = new_target;
-
-                       diff -= 2800;
-                       diff /= 50;
-
-                       clrsetbits_le32(&power_regs->hw_power_vddioctrl,
-                               POWER_VDDIOCTRL_TRG_MASK, diff);
-
-                       if (powered_by_linreg ||
-                               (readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_VDD5V_GT_VDDIO))
-                               early_delay(500);
-                       else {
-                               while (!(readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_DC_OK))
-                                       ;
-
-                       }
-
-                       cur_target = readl(&power_regs->hw_power_vddioctrl);
-                       cur_target &= POWER_VDDIOCTRL_TRG_MASK;
-                       cur_target *= 50;       /* 50 mV step*/
-                       cur_target += 2800;     /* 2800 mV lowest */
-               } while (new_target > cur_target);
-
-               if (powered_by_linreg) {
-                       writel(POWER_CTRL_VDDIO_BO_IRQ,
-                               &power_regs->hw_power_ctrl_clr);
-                       if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO)
-                               setbits_le32(&power_regs->hw_power_vddioctrl,
-                                               POWER_CTRL_ENIRQ_VDDIO_BO);
-               }
-       } else {
-               do {
-                       if (cur_target - new_target > 100)
                                diff = cur_target - 100;
-                       else
-                               diff = new_target;
-
-                       diff -= 2800;
-                       diff /= 50;
-
-                       clrsetbits_le32(&power_regs->hw_power_vddioctrl,
-                               POWER_VDDIOCTRL_TRG_MASK, diff);
-
-                       if (powered_by_linreg ||
-                               (readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_VDD5V_GT_VDDIO))
-                               early_delay(500);
-                       else {
-                               while (!(readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_DC_OK))
-                                       ;
-
-                       }
-
-                       cur_target = readl(&power_regs->hw_power_vddioctrl);
-                       cur_target &= POWER_VDDIOCTRL_TRG_MASK;
-                       cur_target *= 50;       /* 50 mV step*/
-                       cur_target += 2800;     /* 2800 mV lowest */
-               } while (new_target < cur_target);
-       }
-
-       clrsetbits_le32(&power_regs->hw_power_vddioctrl,
-                       POWER_VDDIOCTRL_BO_OFFSET_MASK,
-                       new_brownout << POWER_VDDIOCTRL_BO_OFFSET_OFFSET);
-}
-
-void mxs_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
-{
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-       uint32_t cur_target, diff, bo_int = 0;
-       uint32_t powered_by_linreg = 0;
-
-       new_brownout = (new_target - new_brownout + 12) / 25;
-
-       cur_target = readl(&power_regs->hw_power_vdddctrl);
-       cur_target &= POWER_VDDDCTRL_TRG_MASK;
-       cur_target *= 25;       /* 25 mV step*/
-       cur_target += 800;      /* 800 mV lowest */
-
-       powered_by_linreg = mxs_get_vddd_power_source_off();
-       if (new_target > cur_target) {
-               if (powered_by_linreg) {
-                       bo_int = readl(&power_regs->hw_power_vdddctrl);
-                       clrbits_le32(&power_regs->hw_power_vdddctrl,
-                                       POWER_CTRL_ENIRQ_VDDD_BO);
+               } else {
+                       diff = new_target;
                }
 
-               setbits_le32(&power_regs->hw_power_vdddctrl,
-                               POWER_VDDDCTRL_BO_OFFSET_MASK);
-
-               do {
-                       if (new_target - cur_target > 100)
-                               diff = cur_target + 100;
-                       else
-                               diff = new_target;
-
-                       diff -= 800;
-                       diff /= 25;
-
-                       clrsetbits_le32(&power_regs->hw_power_vdddctrl,
-                               POWER_VDDDCTRL_TRG_MASK, diff);
+               diff -= cfg->lowest_mV;
+               diff /= cfg->step_mV;
 
-                       if (powered_by_linreg ||
-                               (readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_VDD5V_GT_VDDIO))
-                               early_delay(500);
-                       else {
-                               while (!(readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_DC_OK))
-                                       ;
+               clrsetbits_le32(cfg->reg, cfg->trg_mask, diff);
 
+               if (powered_by_linreg ||
+                       (readl(&power_regs->hw_power_sts) &
+                               POWER_STS_VDD5V_GT_VDDIO))
+                       early_delay(500);
+               else {
+                       for (;;) {
+                               tmp = readl(&power_regs->hw_power_sts);
+                               if (tmp & POWER_STS_DC_OK)
+                                       break;
                        }
-
-                       cur_target = readl(&power_regs->hw_power_vdddctrl);
-                       cur_target &= POWER_VDDDCTRL_TRG_MASK;
-                       cur_target *= 25;       /* 25 mV step*/
-                       cur_target += 800;      /* 800 mV lowest */
-               } while (new_target > cur_target);
-
-               if (powered_by_linreg) {
-                       writel(POWER_CTRL_VDDD_BO_IRQ,
-                               &power_regs->hw_power_ctrl_clr);
-                       if (bo_int & POWER_CTRL_ENIRQ_VDDD_BO)
-                               setbits_le32(&power_regs->hw_power_vdddctrl,
-                                               POWER_CTRL_ENIRQ_VDDD_BO);
                }
-       } else {
-               do {
-                       if (cur_target - new_target > 100)
-                               diff = cur_target - 100;
-                       else
-                               diff = new_target;
 
-                       diff -= 800;
-                       diff /= 25;
+               cur_target = readl(cfg->reg);
+               cur_target &= cfg->trg_mask;
+               cur_target *= cfg->step_mV;
+               cur_target += cfg->lowest_mV;
+       } while (new_target > cur_target);
 
-                       clrsetbits_le32(&power_regs->hw_power_vdddctrl,
-                                       POWER_VDDDCTRL_TRG_MASK, diff);
-
-                       if (powered_by_linreg ||
-                               (readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_VDD5V_GT_VDDIO))
-                               early_delay(500);
-                       else {
-                               while (!(readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_DC_OK))
-                                       ;
-
-                       }
-
-                       cur_target = readl(&power_regs->hw_power_vdddctrl);
-                       cur_target &= POWER_VDDDCTRL_TRG_MASK;
-                       cur_target *= 25;       /* 25 mV step*/
-                       cur_target += 800;      /* 800 mV lowest */
-               } while (new_target < cur_target);
+       if (adjust_up && powered_by_linreg) {
+               writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
+               if (bo_int & cfg->bo_enirq)
+                       setbits_le32(cfg->reg, cfg->bo_enirq);
        }
 
-       clrsetbits_le32(&power_regs->hw_power_vdddctrl,
-                       POWER_VDDDCTRL_BO_OFFSET_MASK,
-                       new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
+       clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
+                       new_brownout << cfg->bo_offset_offset);
 }
 
-void mxs_setup_batt_detect(void)
+static void mxs_setup_batt_detect(void)
 {
        mxs_lradc_init();
        mxs_lradc_enable_batt_measurement();
@@ -982,9 +896,8 @@ void mxs_power_init(void)
        mxs_power_configure_power_source();
        mxs_enable_output_rail_protection();
 
-       mxs_power_set_vddio(3300, 3150);
-
-       mxs_power_set_vddd(1350, 1200);
+       mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
+       mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000);
 
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
index c756c09754e249e5adcc7853e42ae40a3f96bc4a..ab313265d0c43553cc89b507570b05e3c0acfadb 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;
 
@@ -64,3 +69,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 2b7c910d90e7f9a7c9ad2a08a53ce783c19366b7..d7d98d1111e0ed5495caa98045bbc5ab8bb897fc 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;
@@ -204,6 +205,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)
@@ -300,6 +306,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 fe61f88af4954015b14c478ffa08c53bfc2fcd4b..74599798c435ff84ee4e05117c13936e57351ed7 100644 (file)
@@ -921,6 +921,21 @@ static int exynos5_set_spi_clk(enum periph_id periph_id,
        return 0;
 }
 
+static unsigned long exynos4_get_i2c_clk(void)
+{
+       struct exynos4_clock *clk =
+               (struct exynos4_clock *)samsung_get_base_clock();
+       unsigned long sclk, aclk_100;
+       unsigned int ratio;
+
+       sclk = get_pll_clk(APLL);
+
+       ratio = (readl(&clk->div_top)) >> 4;
+       ratio &= 0xf;
+       aclk_100 = sclk / (ratio + 1);
+       return aclk_100;
+}
+
 unsigned long get_pll_clk(int pllreg)
 {
        if (cpu_is_exynos5())
@@ -941,6 +956,8 @@ unsigned long get_i2c_clk(void)
 {
        if (cpu_is_exynos5()) {
                return exynos5_get_i2c_clk();
+       } else if (cpu_is_exynos4()) {
+               return exynos4_get_i2c_clk();
        } else {
                debug("I2C clock is not set for this CPU\n");
                return 0;
index f02f441a8b7dd563a72b0fe79adba047748dc151..20a4b8414a9f5aff3d6a93844f1f8e2f6045706e 100644 (file)
@@ -329,54 +329,60 @@ static int exynos5_pinmux_config(int peripheral, int flags)
        return 0;
 }
 
-static int exynos4_mmc_config(int peripheral, int flags)
+static void exynos4_i2c_config(int peripheral, int flags)
 {
-       struct exynos4_gpio_part2 *gpio2 =
-               (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
-       struct s5p_gpio_bank *bank, *bank_ext;
-       int i;
+       struct exynos4_gpio_part1 *gpio1 =
+               (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1();
 
        switch (peripheral) {
-       case PERIPH_ID_SDMMC0:
-               bank = &gpio2->k0;
-               bank_ext = &gpio2->k1;
+       case PERIPH_ID_I2C0:
+               s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2));
+               s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2));
                break;
-       case PERIPH_ID_SDMMC2:
-               bank = &gpio2->k2;
-               bank_ext = &gpio2->k3;
+       case PERIPH_ID_I2C1:
+               s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2));
+               s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2));
+               break;
+       case PERIPH_ID_I2C2:
+               s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
+               s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
+               break;
+       case PERIPH_ID_I2C3:
+               s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
+               s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
+               break;
+       case PERIPH_ID_I2C4:
+               s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3));
+               s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3));
+               break;
+       case PERIPH_ID_I2C5:
+               s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3));
+               s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3));
+               break;
+       case PERIPH_ID_I2C6:
+               s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4));
+               s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4));
+               break;
+       case PERIPH_ID_I2C7:
+               s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3));
+               s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3));
                break;
-       default:
-               return -1;
-       }
-       for (i = 0; i < 7; i++) {
-               if (i == 2)
-                       continue;
-               s5p_gpio_cfg_pin(bank, i,  GPIO_FUNC(0x2));
-               s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
-               s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
-       }
-       if (flags & PINMUX_FLAG_8BIT_MODE) {
-               for (i = 3; i < 7; i++) {
-                       s5p_gpio_cfg_pin(bank_ext, i,  GPIO_FUNC(0x3));
-                       s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
-                       s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
-               }
        }
-
-       return 0;
 }
 
 static int exynos4_pinmux_config(int peripheral, int flags)
 {
        switch (peripheral) {
-       case PERIPH_ID_SDMMC0:
-       case PERIPH_ID_SDMMC2:
-               return exynos4_mmc_config(peripheral, flags);
-       case PERIPH_ID_SDMMC1:
-       case PERIPH_ID_SDMMC3:
-       case PERIPH_ID_SDMMC4:
-               printf("SDMMC device %d not implemented\n", peripheral);
-               return -1;
+       case PERIPH_ID_I2C0:
+       case PERIPH_ID_I2C1:
+       case PERIPH_ID_I2C2:
+       case PERIPH_ID_I2C3:
+       case PERIPH_ID_I2C4:
+       case PERIPH_ID_I2C5:
+       case PERIPH_ID_I2C6:
+       case PERIPH_ID_I2C7:
+               exynos4_i2c_config(peripheral, flags);
+               break;
        default:
                debug("%s: invalid peripheral %d", __func__, peripheral);
                return -1;
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 b91441fd63d1f57614707f52ff45e7a7ea9d6cd9..16e8a80700a497936f8c14cd4f023892b7a4c6b7 100644 (file)
@@ -135,7 +135,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 */
@@ -328,12 +329,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 b3922d9b47cf31b90b7f0e2387c0463dd2822a40..6dd3296907acce5671364bc09b8b6b65824108f0 100644 (file)
@@ -90,4 +90,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 */
index d1b2ea8023ddfa3fae9eb3f39c3b39b94e0cdc98..f06af2eb8592597944aa3b7393396545b9c45541 100644 (file)
@@ -28,6 +28,8 @@
 #define EXYNOS4_ADDR_BASE              0x10000000
 
 /* EXYNOS4 */
+#define EXYNOS4_I2C_SPACING            0x10000
+
 #define EXYNOS4_GPIO_PART3_BASE                0x03860000
 #define EXYNOS4_PRO_ID                 0x10000000
 #define EXYNOS4_SYSREG_BASE            0x10010000
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 1700fe39155f7a8fd982a38237f72b2eeb0e2a4e..3d39ef235d611ce17c3f466db61ce667e734bc99 100644 (file)
@@ -35,6 +35,7 @@ enum mxc_clock {
        MXC_SSP1_CLK,
        MXC_SSP2_CLK,
        MXC_SSP3_CLK,
+       MXC_XTAL_CLK,
 };
 
 enum mxs_ioclock {
index 5e1901e6c48110279b15858e9b6c670cac57b4b0..9764041b48b12dea2cdd0948c30077f9f1623d24 100644 (file)
@@ -26,7 +26,6 @@
 #include <asm/arch/regs-apbh.h>
 #include <asm/arch/regs-base.h>
 #include <asm/arch/regs-bch.h>
-#include <asm/arch/regs-clkctrl-mx28.h>
 #include <asm/arch/regs-digctl.h>
 #include <asm/arch/regs-gpmi.h>
 #include <asm/arch/regs-i2c.h>
 #include <asm/arch/regs-lradc.h>
 #include <asm/arch/regs-ocotp.h>
 #include <asm/arch/regs-pinctrl.h>
-#include <asm/arch/regs-power.h>
 #include <asm/arch/regs-rtc.h>
 #include <asm/arch/regs-ssp.h>
 #include <asm/arch/regs-timrot.h>
 
+#ifdef CONFIG_MX28
+#include <asm/arch/regs-clkctrl-mx28.h>
+#include <asm/arch/regs-power-mx28.h>
+#endif
+
 #endif /* __IMX_REGS_H__ */
index b662fbe440049cbb2d9a7743d099c29f867d57b1..23e9adc25a28ee1cf8251b4b00ef70fe6bb67d46 100644 (file)
 #ifndef        __ASSEMBLY__
 struct mxs_clkctrl_regs {
        mxs_reg_32(hw_clkctrl_pll0ctrl0)        /* 0x00 */
-       mxs_reg_32(hw_clkctrl_pll0ctrl1)        /* 0x10 */
+       uint32_t        hw_clkctrl_pll0ctrl1;   /* 0x10 */
+       uint32_t        reserved_pll0ctrl1[3];  /* 0x14-0x1c */
        mxs_reg_32(hw_clkctrl_pll1ctrl0)        /* 0x20 */
-       mxs_reg_32(hw_clkctrl_pll1ctrl1)        /* 0x30 */
+       uint32_t        hw_clkctrl_pll1ctrl1;   /* 0x30 */
+       uint32_t        reserved_pll1ctrl1[3];  /* 0x34-0x3c */
        mxs_reg_32(hw_clkctrl_pll2ctrl0)        /* 0x40 */
        mxs_reg_32(hw_clkctrl_cpu)              /* 0x50 */
        mxs_reg_32(hw_clkctrl_hbus)             /* 0x60 */
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..e0cb6353a3feb95fc35734875d53e16b633c3cd7 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: ");
@@ -532,15 +540,13 @@ void board_init_r(gd_t *id, ulong dest_addr)
        flash_size = flash_init();
        if (flash_size > 0) {
 # ifdef CONFIG_SYS_FLASH_CHECKSUM
-               char *s = getenv("flashchecksum");
-
                print_size(flash_size, "");
                /*
                 * Compute and print flash CRC if flashchecksum is set to 'y'
                 *
                 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
                 */
-               if (s && (*s == 'y')) {
+               if (getenv_yesno("flashchecksum") == 1) {
                        printf("  CRC: %08X", crc32(0,
                                (const unsigned char *) CONFIG_SYS_FLASH_BASE,
                                flash_size));
index e0773a88285a726c45a6f61f7a4f47557e227221..ecf5e56e1078d1fb583ca6421d16d919144bdd91 100644 (file)
@@ -16,7 +16,7 @@
 #endif
 
 extern int strcasecmp(const char *, const char *);
-extern int strncasecmp(const char *, const char *, int);
+extern int strncasecmp(const char *, const char *, __kernel_size_t);
 extern char * strcpy(char *,const char *);
 extern char * strncpy(char *,const char *, __kernel_size_t);
 extern __kernel_size_t strlen(const char *);
index 02d73fda6111045052d5be20e1efe19e833bbc14..794b8679fefe2696bef4a8857f5b6d036b0c8882 100644 (file)
@@ -462,8 +462,7 @@ void board_init_r (gd_t *id, ulong dest_addr)
                 *
                 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
                 */
-               s = getenv ("flashchecksum");
-               if (s && (*s == 'y')) {
+               if (getenv_yesno("flashchecksum") == 1) {
                        printf ("  CRC: %08X",
                                        crc32 (0,
                                                   (const unsigned char *) CONFIG_SYS_FLASH_BASE,
index efd63cd341213de1c81865cb6994b64367af5916..a7c2f7623392fc1fce53dd2eb992a6f74d8620d7 100644 (file)
@@ -74,7 +74,6 @@ void board_init_f(ulong not_used)
        gd = (gd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET);
        bd = (bd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET \
                                                - GENERATED_BD_INFO_SIZE);
-       __maybe_unused char *s;
 #if defined(CONFIG_CMD_FLASH)
        ulong flash_size = 0;
 #endif
@@ -143,8 +142,7 @@ void board_init_f(ulong not_used)
                 *
                 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
                 */
-               s = getenv ("flashchecksum");
-               if (s && (*s == 'y')) {
+               if (getenv_yesno("flashchecksum") == 1) {
                        printf ("  CRC: %08X",
                                crc32(0, (const u8 *)bd->bi_flashstart,
                                                        flash_size)
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 4112de7026a51f8c854a14414f9d9f920b7ef28f..2b8d531e73b84ef9d2e0280165ed1668dad9d318 100644 (file)
@@ -108,7 +108,12 @@ reset:
        mtc0    t0, CP0_CONFIG
 #endif
 
-       /* Initialize $gp */
+       /*
+        * Initialize $gp, force 8 byte alignment of bal instruction to forbid
+        * the compiler to put nop's between bal and _gp. This is required to
+        * keep _gp and ra aligned to 8 byte.
+        */
+       .align  3
        bal     1f
         nop
        .dword  _gp
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 1c8f4c05003ba83ff0aacf66d94268d901dbf21a..f2dc5335690de97517c58ff5bbaf7627fbc3636f 100644 (file)
@@ -566,7 +566,7 @@ static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
  * @nr: bit number to test
  * @addr: Address to start counting from
  */
-static __inline__ int test_bit(int nr, volatile void *addr)
+static __inline__ int test_bit(int nr, const volatile void *addr)
 {
        return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
 }
index 7ddd77832cc5f165111d5b553d212002fa6d1047..d79e1837d9a37c21c07556618a22dc9c60e173e7 100644 (file)
@@ -24,6 +24,7 @@
 #include <common.h>
 #include <command.h>
 #include <malloc.h>
+#include <serial.h>
 #include <stdio_dev.h>
 #include <version.h>
 #include <net.h>
@@ -46,7 +47,7 @@ static char *failed = "*** failed ***\n";
  * mips_io_port_base is the begin of the address space to which x86 style
  * I/O ports are mapped.
  */
-unsigned long mips_io_port_base = -1;
+const unsigned long mips_io_port_base = -1;
 
 int __board_early_init_f(void)
 {
@@ -262,6 +263,8 @@ void board_init_r(gd_t *id, ulong dest_addr)
 
        monitor_flash_len = (ulong)&uboot_end_data - dest_addr;
 
+       serial_initialize();
+
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
        /*
         * We have to relocate the command table manually
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 e1197ac9e5e70ac9e843298d9bf5e367a7fdb6be..43d4836303d4f02149ce6f9f117dbf5e395be17b 100644 (file)
@@ -46,10 +46,8 @@ u32 get_my_id()
  */
 int hold_cores_in_reset(int verbose)
 {
-       const char *s = getenv("mp_holdoff");
-
        /* Default to no, overriden by 'y', 'yes', 'Y', 'Yes', or '1' */
-       if (s && (*s == 'y' || *s == 'Y' || *s == '1')) {
+       if (getenv_yesno("mp_holdoff") == 1) {
                if (verbose) {
                        puts("Secondary cores are being held in reset.\n");
                        puts("See 'mp_holdoff' environment variable\n");
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 d912a6b5fed2649156f0658a7e8d1a500f8dc550..036805ede2990800288d83ff52bee364d0147b8e 100644 (file)
@@ -14,7 +14,7 @@
 #define __HAVE_ARCH_MEMCHR
 
 extern int strcasecmp(const char *, const char *);
-extern int strncasecmp(const char *, const char *, int);
+extern int strncasecmp(const char *, const char *, __kernel_size_t);
 extern char * strcpy(char *,const char *);
 extern char * strncpy(char *,const char *, __kernel_size_t);
 extern __kernel_size_t strlen(const char *);
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 1b051e11c4928b84ef5ee57b7d65d9fe7244749b..6a7bf4b6c21588a02b3d3bb57ed751948e5ceb73 100644 (file)
@@ -739,16 +739,13 @@ void board_init_r(gd_t *id, ulong dest_addr)
                flash_size = 0;
        } else if ((flash_size = flash_init()) > 0) {
 #ifdef CONFIG_SYS_FLASH_CHECKSUM
-               char *s;
-
                print_size(flash_size, "");
                /*
                 * Compute and print flash CRC if flashchecksum is set to 'y'
                 *
                 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
                 */
-               s = getenv("flashchecksum");
-               if (s && (*s == 'y')) {
+               if (getenv_yesno("flashchecksum") == 1) {
                        printf("  CRC: %08X",
                               crc32(0,
                                     (const unsigned char *)
@@ -841,9 +838,7 @@ void board_init_r(gd_t *id, ulong dest_addr)
         * "i2cfast" into account
         */
        {
-               char *s = getenv("i2cfast");
-
-               if (s && ((*s == 'y') || (*s == 'Y'))) {
+               if (getenv_yesno("i2cfast") == 1) {
                        bd->bi_iic_fast[0] = 1;
                        bd->bi_iic_fast[1] = 1;
                }
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 c6bbc203d5dc78f9cae96af7f18f22f89e8acbb8..af6faea234c9229f6c274b057e8911c28fcfb24a 100644 (file)
@@ -40,7 +40,7 @@
 */
 
 extern int strcasecmp(const char *, const char *);
-extern int strncasecmp(const char *, const char *, int);
+extern int strncasecmp(const char *, const char *, __kernel_size_t);
 extern char *strcpy(char *, const char *);
 extern char *strncpy(char *, const char *, __kernel_size_t);
 extern __kernel_size_t strlen(const char *);
index 32d025a34237c89c443314035f58c3f6264105f3..1b5e995b15aaae971624fa0b584084c182f646f0 100644 (file)
@@ -284,8 +284,7 @@ void board_init_f(ulong bootflag)
                 *
                 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
                 */
-               s = getenv("flashchecksum");
-               if (s && (*s == 'y')) {
+               if (getenv_yesno("flashchecksum") == 1) {
                        printf("  CRC: %08lX",
                               crc32(0, (const unsigned char *)CONFIG_SYS_FLASH_BASE,
                                     flash_size)
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
index 6cae68601d34bffdad9760746b0c97600066fbfa..38769e03c536b27ff3b4d6b89a9b11e2bf909141 100644 (file)
@@ -834,15 +834,11 @@ int mem_test_walk (void)
 /*********************************************************************/
 int testdram (void)
 {
-       char *s;
        int rundata, runaddress, runwalk;
 
-       s = getenv ("testdramdata");
-       rundata = (s && (*s == 'y')) ? 1 : 0;
-       s = getenv ("testdramaddress");
-       runaddress = (s && (*s == 'y')) ? 1 : 0;
-       s = getenv ("testdramwalk");
-       runwalk = (s && (*s == 'y')) ? 1 : 0;
+       rundata = getenv_yesno("testdramdata") == 1;
+       runaddress = getenv_yesno("testdramaddress") == 1;
+       runwalk = getenv_yesno("testdramwalk") == 1;
 
 /*    rundata = 1; */
 /*    runaddress = 0; */
index d4f58b3216adf0bdc1e622a71a769c1b64d01ab8..ddb7ed5551d83ebd8ea39e0afcede78730efea3a 100644 (file)
@@ -834,15 +834,11 @@ int mem_test_walk (void)
 /*********************************************************************/
 int testdram (void)
 {
-       char *s;
        int rundata, runaddress, runwalk;
 
-       s = getenv ("testdramdata");
-       rundata = (s && (*s == 'y')) ? 1 : 0;
-       s = getenv ("testdramaddress");
-       runaddress = (s && (*s == 'y')) ? 1 : 0;
-       s = getenv ("testdramwalk");
-       runwalk = (s && (*s == 'y')) ? 1 : 0;
+       rundata = getenv_yesno("testdramdata") == 1;
+       runaddress = getenv_yesno("testdramaddress") == 1;
+       runwalk = getenv_yesno("testdramwalk") == 1;
 
 /*    rundata = 1; */
 /*    runaddress = 0; */
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 98051fb3fbe426985b2a0c2e8ab1a318135d84c5..d7deae4a541c81790a065c6174a9bd12998fea4b 100644 (file)
@@ -953,22 +953,18 @@ int mem_test_walk (void)
 /*********************************************************************/
 int testdram (void)
 {
-       char *s;
        int rundata    = 0;
        int runaddress = 0;
        int runwalk    = 0;
 
 #ifdef CONFIG_SYS_DRAM_TEST_DATA
-       s = getenv ("testdramdata");
-       rundata = (s && (*s == 'y')) ? 1 : 0;
+       rundata = getenv_yesno("testdramdata") == 1;
 #endif
 #ifdef CONFIG_SYS_DRAM_TEST_ADDRESS
-       s = getenv ("testdramaddress");
-       runaddress = (s && (*s == 'y')) ? 1 : 0;
+       runaddress = getenv_yesno("testdramaddress") == 1;
 #endif
 #ifdef CONFIG_SYS_DRAM_TEST_WALK
-       s = getenv ("testdramwalk");
-       runwalk = (s && (*s == 'y')) ? 1 : 0;
+       runwalk = getenv_yesno("testdramwalk") == 1;
 #endif
 
        if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
index f1ffb7b540782d0578ca2cf0c4dd6bc5610c5352..e9a78a303ca9797624ea531db49261b759d5ce4c 100644 (file)
@@ -391,7 +391,7 @@ int do_painit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        nextbase -= ((CONFIG_ENV_SIZE + 4096 - 1) & ~(4096 - 1));
        envp = (env_t *)nextbase;
        res = (char *)envp->data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
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 72fa6bc82600109a28b5b037ed4932b4b48fe618..d73e27e5405ba24b1522bc7e998df5a777b02a8a 100644 (file)
@@ -27,7 +27,7 @@
 #include <mmc.h>
 #include <fsl_esdhc.h>
 #include <i2c.h>
-#include <pmic.h>
+#include <power/pmic.h>
 #include <fsl_pmic.h>
 #include <mc34704.h>
 
@@ -110,11 +110,18 @@ int board_init(void)
 int board_late_init(void)
 {
        struct pmic *p;
+       int ret;
 
        mx25pdk_fec_init();
 
-       pmic_init();
-       p = get_pmic();
+       ret = pmic_init(I2C_PMIC);
+       if (ret)
+               return ret;
+
+       p = pmic_get("FSL_PMIC");
+       if (!p)
+               return -ENODEV;
+
        /* Turn on Ethernet PHY supply */
        pmic_reg_write(p, MC34704_GENERAL2_REG, ONOFFE);
 
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..2c8cb7a1cc58d16bbacc7dd8376b59c76eba43be 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("FSL_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 77a1e1d3ac1624779e169ce77984eed5f8d8f1a9..64c54d5e8453554729447567b177f5836d37a0b5 100644 (file)
@@ -544,15 +544,11 @@ int mem_test_walk (void)
 /*********************************************************************/
 int testdram (void)
 {
-       char *s;
        int rundata, runaddress, runwalk;
 
-       s = getenv ("testdramdata");
-       rundata = (s && (*s == 'y')) ? 1 : 0;
-       s = getenv ("testdramaddress");
-       runaddress = (s && (*s == 'y')) ? 1 : 0;
-       s = getenv ("testdramwalk");
-       runwalk = (s && (*s == 'y')) ? 1 : 0;
+       rundata = getenv_yesno("testdramdata") == 1;
+       runaddress = getenv_yesno("testdramaddress") == 1;
+       runwalk = getenv_yesno("testdramwalk") == 1;
 
        if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
                printf ("Testing RAM ... ");
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 389affcde0fda0718c954bb638a1eddad1d5f63d..c3fd19169c95beaa8d22a2ac148c4bcbdfa5b4a8 100644 (file)
@@ -768,22 +768,18 @@ int mem_test_walk (void)
 /*********************************************************************/
 int testdram (void)
 {
-       char *s;
        int rundata    = 0;
        int runaddress = 0;
        int runwalk    = 0;
 
 #ifdef CONFIG_SYS_DRAM_TEST_DATA
-       s = getenv ("testdramdata");
-       rundata = (s && (*s == 'y')) ? 1 : 0;
+       rundata = getenv_yesno("testdramdata") == 1;
 #endif
 #ifdef CONFIG_SYS_DRAM_TEST_ADDRESS
-       s = getenv ("testdramaddress");
-       runaddress = (s && (*s == 'y')) ? 1 : 0;
+       runaddress = getenv_yesno("testdramaddress") == 1;
 #endif
 #ifdef CONFIG_SYS_DRAM_TEST_WALK
-       s = getenv ("testdramwalk");
-       runwalk = (s && (*s == 'y')) ? 1 : 0;
+       runwalk = getenv_yesno("testdramwalk") == 1;
 #endif
 
        if ((rundata == 1) || (runaddress == 1) || (runwalk == 1))
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 4c50342e5cdcb7145e3faa035243bab222688de4..9c926d6ecf2e9ae6f1db1bc390633b6cf3cb14d0 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/arch/mmc.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/sromc.h>
-#include <pmic.h>
+#include <power/pmic.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -65,9 +65,6 @@ static int smc9115_pre_init(void)
 int board_init(void)
 {
        gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
-#if defined(CONFIG_PMIC)
-       pmic_init();
-#endif
 #ifdef CONFIG_EXYNOS_SPI
        spi_init();
 #endif
@@ -87,6 +84,16 @@ int dram_init(void)
        return 0;
 }
 
+#if defined(CONFIG_POWER)
+int power_init_board(void)
+{
+       if (pmic_init(I2C_PMIC))
+               return -1;
+       else
+               return 0;
+}
+#endif
+
 void dram_init_banksize(void)
 {
        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
index d5c681c05e238ce53866249ee80f25c4415ca6ee..472402942442da0c16e2d530e33c89e36fed7927 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"
 
@@ -69,10 +72,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;
 }
 
@@ -91,6 +90,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) +
@@ -200,7 +468,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;
@@ -379,7 +649,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;
@@ -439,7 +711,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 afe3bb0aeb81eb38a0e1dad8c5d06770eab0cc2b..e742707f79659dca95b19fb4b6b91f27f093e0e8 100644 (file)
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/pinmux.h>
-#include <pmic.h>
-#include <usb/s3c_udc.h>
-#include <asm/arch/cpu.h>
-#include <max8998_pmic.h>
 #include <asm/arch/watchdog.h>
 #include <libtizen.h>
 #include <ld9040.h>
+#include <power/pmic.h>
+#include <usb/s3c_udc.h>
+#include <asm/arch/cpu.h>
+#include <power/max8998_pmic.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -55,7 +55,20 @@ static int get_hwrev(void)
        return board_rev & 0xFF;
 }
 
-static void check_hw_revision(void);
+static void init_pmic_lcd(void);
+
+int power_init_board(void)
+{
+       int ret;
+
+       ret = pmic_init(I2C_5);
+       if (ret)
+               return ret;
+
+       init_pmic_lcd();
+
+       return 0;
+}
 
 int dram_init(void)
 {
@@ -101,7 +114,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;
@@ -224,7 +239,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;
@@ -324,7 +341,10 @@ static void init_pmic_lcd(void)
        unsigned char val;
        int ret = 0;
 
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("MAX8998_PMIC");
+
+       if (!p)
+               return;
 
        if (pmic_probe(p))
                return;
@@ -415,7 +435,10 @@ static void reset_lcd(void)
 
 static void lcd_power_on(void)
 {
-       struct pmic *p = get_pmic();
+       struct pmic *p = pmic_get("MAX8998_PMIC");
+
+       if (!p)
+               return;
 
        if (pmic_probe(p))
                return;
@@ -489,10 +512,6 @@ 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();
-       init_pmic_lcd();
-#endif
 #ifdef CONFIG_SOFT_SPI
        soft_spi_init();
 #endif
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 135f1a2572e84dbe1575bd8b4941f637466e8ce3..ed4229e258d24e58584b059abbf720625ebffbc8 100644 (file)
@@ -381,9 +381,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;
 
@@ -402,7 +407,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()) {
@@ -415,6 +420,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 4adf9827c5f26a6ef769e30290f1af3f9d616847..b829a792b2c49b06e04508ce3b2bf9b4f3eb225a 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>
 
@@ -284,6 +289,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
@@ -465,6 +497,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;
 }
 
@@ -512,3 +548,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..d74f360e1309c61623c3169f7f5a562c76a30937 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>
@@ -133,8 +133,7 @@ int woodburn_init(void)
        mxc_request_iomux(MX35_PIN_SCKR, MUX_CONFIG_ALT5);
        gpio_direction_output(4, 1);
        mxc_request_iomux(MX35_PIN_HCKT, MUX_CONFIG_ALT5);
-       gpio_direction_output(9, 0);
-       gpio_set_value(9, 1);
+       gpio_direction_output(9, 1);
 
        return 0;
 }
@@ -178,12 +177,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 ded6318dc6033d63a5a82daebdf978e796d9ef8a..54fcc815889c2165d900d89802c8650cea74c188 100644 (file)
@@ -30,6 +30,7 @@ ifndef CONFIG_SPL_BUILD
 COBJS-y += main.o
 COBJS-y += command.o
 COBJS-y += exports.o
+COBJS-y += hash.o
 COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o
 COBJS-y += s_record.o
 COBJS-y += xyzModem.o
@@ -43,7 +44,10 @@ COBJS-y += cmd_nvedit.o
 COBJS-y += cmd_version.o
 
 # environment
+COBJS-y += env_attr.o
+COBJS-y += env_callback.o
 COBJS-y += env_common.o
+COBJS-y += env_flags.o
 COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o
 COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o
 XCOBJS-$(CONFIG_ENV_IS_EMBEDDED) += env_embedded.o
@@ -101,8 +105,10 @@ ifdef CONFIG_FPGA
 COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o
 endif
 COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o
+COBJS-$(CONFIG_CMD_GETTIME) += cmd_gettime.o
 COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
 COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
+COBJS-$(CONFIG_CMD_HASH) += cmd_hash.o
 COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o
 COBJS-$(CONFIG_CMD_IMMAP) += cmd_immap.o
 COBJS-$(CONFIG_CMD_INI) += cmd_ini.o
@@ -118,6 +124,7 @@ COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o
 COBJS-$(CONFIG_ID_EEPROM) += cmd_mac.o
 COBJS-$(CONFIG_CMD_MD5SUM) += cmd_md5sum.o
 COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o
+COBJS-$(CONFIG_CMD_IO) += cmd_io.o
 COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
 COBJS-$(CONFIG_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
@@ -142,6 +149,7 @@ endif
 COBJS-y += cmd_pcmcia.o
 COBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.o
 COBJS-$(CONFIG_CMD_PXE) += cmd_pxe.o
+COBJS-$(CONFIG_CMD_READ) += cmd_read.o
 COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o
 COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o
 COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o
@@ -185,6 +193,7 @@ COBJS-$(CONFIG_BOOTSTAGE) += bootstage.o
 COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
 COBJS-y += flash.o
 COBJS-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o
+COBJS-$(CONFIG_I2C_EDID) += edid.o
 COBJS-$(CONFIG_KALLSYMS) += kallsyms.o
 COBJS-$(CONFIG_LCD) += lcd.o
 COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
@@ -193,12 +202,19 @@ COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
 COBJS-$(CONFIG_UPDATE_TFTP) += update.o
 COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
+COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
 endif
 
 ifdef CONFIG_SPL_BUILD
+COBJS-y += cmd_nvedit.o
+COBJS-y += env_common.o
+COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
 COBJS-$(CONFIG_SPL_NET_SUPPORT) += cmd_nvedit.o
+COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_attr.o
+COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_callback.o
 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_common.o
+COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_flags.o
 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_nowhere.o
 COBJS-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o
 endif
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..f7595c0311955b58acffa6efd2b19a209576ec48 100644 (file)
@@ -537,7 +537,7 @@ static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc,
                }
                        break;
 #endif
-#if defined(CONFIG_OF_LIBFDT)
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB)
                case BOOTM_STATE_FDT:
                {
                        boot_fdt_add_mem_rsv_regions(&images.lmb,
@@ -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;
diff --git a/common/cmd_gettime.c b/common/cmd_gettime.c
new file mode 100644 (file)
index 0000000..d7d36a9
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ *
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * (C) Copyright 2001
+ * 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
+ */
+
+/*
+ * Get Timer overflows after 2^32 / CONFIG_SYS_HZ (32Khz) = 131072 sec
+ */
+#include <common.h>
+#include <command.h>
+
+static int do_gettime(cmd_tbl_t *cmdtp, int flag, int argc,
+                     char * const argv[])
+{
+       unsigned long int val = get_timer(0);
+
+#ifdef CONFIG_SYS_HZ
+       printf("Timer val: %lu\n", val);
+       printf("Seconds : %lu\n", val / CONFIG_SYS_HZ);
+       printf("Remainder : %lu\n", val % CONFIG_SYS_HZ);
+       printf("sys_hz = %lu\n", (unsigned long int)CONFIG_SYS_HZ);
+#else
+       printf("CONFIG_SYS_HZ not defined");
+       printf("Timer Val %lu", val);
+#endif
+
+       return 0;
+}
+
+U_BOOT_CMD(
+       gettime,        1,      1,      do_gettime,
+       "get timer val elapsed,\n",
+       "get time elapsed from uboot start\n"
+);
diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c
new file mode 100644 (file)
index 0000000..da7705d
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * cmd_gpt.c -- GPT (GUID Partition Table) handling command
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski <l.majewski@samsung.com>
+ * author: Piotr Wilczek <p.wilczek@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 <command.h>
+#include <mmc.h>
+#include <part_efi.h>
+#include <exports.h>
+#include <linux/ctype.h>
+
+#ifndef CONFIG_PARTITION_UUIDS
+#error CONFIG_PARTITION_UUIDS must be enabled for CONFIG_CMD_GPT to be enabled
+#endif
+
+/**
+ * extract_env(): Expand env name from string format '&{env_name}'
+ *                and return pointer to the env (if the env is set)
+ *
+ * @param str - pointer to string
+ * @param env - pointer to pointer to extracted env
+ *
+ * @return - zero on successful expand and env is set
+ */
+static char extract_env(const char *str, char **env)
+{
+       char *e, *s;
+
+       if (!str || strlen(str) < 4)
+               return -1;
+
+       if ((strncmp(str, "${", 2) == 0) && (str[strlen(str) - 1] == '}')) {
+               s = strdup(str);
+               if (s == NULL)
+                       return -1;
+               memset(s + strlen(s) - 1, '\0', 1);
+               memmove(s, s + 2, strlen(s) - 1);
+               e = getenv(s);
+               free(s);
+               if (e == NULL) {
+                       printf("Environmental '%s' not set\n", str);
+                       return -1; /* env not set */
+               }
+               *env = e;
+               return 0;
+       }
+
+       return -1;
+}
+
+/**
+ * extract_val(): Extract value from a key=value pair list (comma separated).
+ *                Only value for the given key is returend.
+ *                Function allocates memory for the value, remember to free!
+ *
+ * @param str - pointer to string with key=values pairs
+ * @param key - pointer to the key to search for
+ *
+ * @return - pointer to allocated string with the value
+ */
+static char *extract_val(const char *str, const char *key)
+{
+       char *v, *k;
+       char *s, *strcopy;
+       char *new = NULL;
+
+       strcopy = strdup(str);
+       if (strcopy == NULL)
+               return NULL;
+
+       s = strcopy;
+       while (s) {
+               v = strsep(&s, ",");
+               if (!v)
+                       break;
+               k = strsep(&v, "=");
+               if (!k)
+                       break;
+               if  (strcmp(k, key) == 0) {
+                       new = strdup(v);
+                       break;
+               }
+       }
+
+       free(strcopy);
+
+       return new;
+}
+
+/**
+ * set_gpt_info(): Fill partition information from string
+ *             function allocates memory, remember to free!
+ *
+ * @param dev_desc - pointer block device descriptor
+ * @param str_part - pointer to string with partition information
+ * @param str_disk_guid - pointer to pointer to allocated string with disk guid
+ * @param partitions - pointer to pointer to allocated partitions array
+ * @param parts_count - number of partitions
+ *
+ * @return - zero on success, otherwise error
+ *
+ */
+static int set_gpt_info(block_dev_desc_t *dev_desc,
+                       const char *str_part,
+                       char **str_disk_guid,
+                       disk_partition_t **partitions,
+                       u8 *parts_count)
+{
+       char *tok, *str, *s;
+       int i;
+       char *val, *p;
+       int p_count;
+       disk_partition_t *parts;
+       int errno = 0;
+
+       debug("%s: MMC lba num: 0x%x %d\n", __func__,
+             (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);
+
+       if (str_part == NULL)
+               return -1;
+
+       str = strdup(str_part);
+
+       /* extract disk guid */
+       s = str;
+       tok = strsep(&s, ";");
+       val = extract_val(tok, "uuid_disk");
+       if (!val) {
+               free(str);
+               return -2;
+       }
+       if (extract_env(val, &p))
+               p = val;
+       *str_disk_guid = strdup(p);
+       free(val);
+
+       if (strlen(s) == 0)
+               return -3;
+
+       i = strlen(s) - 1;
+       if (s[i] == ';')
+               s[i] = '\0';
+
+       /* calculate expected number of partitions */
+       p_count = 1;
+       p = s;
+       while (*p) {
+               if (*p++ == ';')
+                       p_count++;
+       }
+
+       /* allocate memory for partitions */
+       parts = calloc(sizeof(disk_partition_t), p_count);
+
+       /* retrive partions data from string */
+       for (i = 0; i < p_count; i++) {
+               tok = strsep(&s, ";");
+
+               if (tok == NULL)
+                       break;
+
+               /* uuid */
+               val = extract_val(tok, "uuid");
+               if (!val) { /* 'uuid' is mandatory */
+                       errno = -4;
+                       goto err;
+               }
+               if (extract_env(val, &p))
+                       p = val;
+               if (strlen(p) >= sizeof(parts[i].uuid)) {
+                       printf("Wrong uuid format for partition %d\n", i);
+                       errno = -4;
+                       goto err;
+               }
+               strcpy((char *)parts[i].uuid, p);
+               free(val);
+
+               /* name */
+               val = extract_val(tok, "name");
+               if (!val) { /* name is mandatory */
+                       errno = -4;
+                       goto err;
+               }
+               if (extract_env(val, &p))
+                       p = val;
+               if (strlen(p) >= sizeof(parts[i].name)) {
+                       errno = -4;
+                       goto err;
+               }
+               strcpy((char *)parts[i].name, p);
+               free(val);
+
+               /* size */
+               val = extract_val(tok, "size");
+               if (!val) { /* 'size' is mandatory */
+                       errno = -4;
+                       goto err;
+               }
+               if (extract_env(val, &p))
+                       p = val;
+               parts[i].size = ustrtoul(p, &p, 0);
+               parts[i].size /= dev_desc->blksz;
+               free(val);
+
+               /* start address */
+               val = extract_val(tok, "start");
+               if (val) { /* start address is optional */
+                       if (extract_env(val, &p))
+                               p = val;
+                       parts[i].start = ustrtoul(p, &p, 0);
+                       parts[i].start /= dev_desc->blksz;
+                       free(val);
+               }
+       }
+
+       *parts_count = p_count;
+       *partitions = parts;
+       free(str);
+
+       return 0;
+err:
+       free(str);
+       free(*str_disk_guid);
+       free(parts);
+
+       return errno;
+}
+
+static int gpt_mmc_default(int dev, const char *str_part)
+{
+       int ret;
+       char *str_disk_guid;
+       u8 part_count = 0;
+       disk_partition_t *partitions = NULL;
+
+       struct mmc *mmc = find_mmc_device(dev);
+
+       if (mmc == NULL) {
+               printf("%s: mmc dev %d NOT available\n", __func__, dev);
+               return CMD_RET_FAILURE;
+       }
+
+       if (!str_part)
+               return -1;
+
+       /* fill partitions */
+       ret = set_gpt_info(&mmc->block_dev, str_part,
+                       &str_disk_guid, &partitions, &part_count);
+       if (ret) {
+               if (ret == -1)
+                       printf("No partition list provided\n");
+               if (ret == -2)
+                       printf("Missing disk guid\n");
+               if ((ret == -3) || (ret == -4))
+                       printf("Partition list incomplete\n");
+               return -1;
+       }
+
+       /* save partitions layout to disk */
+       gpt_restore(&mmc->block_dev, str_disk_guid, partitions, part_count);
+       free(str_disk_guid);
+       free(partitions);
+
+       return 0;
+}
+
+/**
+ * do_gpt(): Perform GPT operations
+ *
+ * @param cmdtp - command name
+ * @param flag
+ * @param argc
+ * @param argv
+ *
+ * @return zero on success; otherwise error
+ */
+static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       int ret = CMD_RET_SUCCESS;
+       int dev = 0;
+       char *pstr;
+
+       if (argc < 5)
+               return CMD_RET_USAGE;
+
+       /* command: 'write' */
+       if ((strcmp(argv[1], "write") == 0) && (argc == 5)) {
+               /* device: 'mmc' */
+               if (strcmp(argv[2], "mmc") == 0) {
+                       /* check if 'dev' is a number */
+                       for (pstr = argv[3]; *pstr != '\0'; pstr++)
+                               if (!isdigit(*pstr)) {
+                                       printf("'%s' is not a number\n",
+                                               argv[3]);
+                                       return CMD_RET_USAGE;
+                               }
+                       dev = (int)simple_strtoul(argv[3], NULL, 10);
+                       /* write to mmc */
+                       if (gpt_mmc_default(dev, argv[4]))
+                               return CMD_RET_FAILURE;
+               }
+       } else {
+               return CMD_RET_USAGE;
+       }
+       return ret;
+}
+
+U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
+       "GUID Partition Table",
+       "<command> <interface> <dev> <partions_list>\n"
+       " - GUID partition table restoration\n"
+       " Restore GPT information on a device connected\n"
+       " to interface\n"
+);
diff --git a/common/cmd_hash.c b/common/cmd_hash.c
new file mode 100644 (file)
index 0000000..689c608
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * (C) Copyright 2011
+ * Joe Hershberger, National Instruments, joe.hershberger@ni.com
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <hash.h>
+
+static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+#ifdef CONFIG_HASH_VERIFY
+       int verify = 0;
+
+       if (!strcmp(argv[1], "-v")) {
+               verify = 1;
+               argc--;
+               argv++;
+       }
+#endif
+       /* Move forward to 'algorithm' parameter */
+       argc--;
+       argv++;
+       return hash_command(*argv, verify, cmdtp, flag, argc - 1, argv + 1);
+}
+
+#ifdef CONFIG_HASH_VERIFY
+U_BOOT_CMD(
+       hash,   6,      1,      do_hash,
+       "compute hash message digest",
+       "algorithm address count [[*]sum_dest]\n"
+               "    - compute message digest [save to env var / *address]\n"
+       "hash -v algorithm address count [*]sum\n"
+               "    - verify hash of memory area with env var / *address"
+);
+#else
+U_BOOT_CMD(
+       hash,   5,      1,      do_hash,
+       "compute message digest",
+       "algorithm address count [[*]sum_dest]\n"
+               "    - compute message digest [save to env var / *address]"
+);
+#endif
index 4438db594cfe007efc8f79e1882acfd6b42133c5..438079447479773abab4b615894a0d69c9a216b4 100644 (file)
 
 #include <common.h>
 #include <command.h>
+#include <edid.h>
 #include <environment.h>
 #include <i2c.h>
 #include <malloc.h>
 #include <asm/byteorder.h>
+#include <linux/compiler.h>
 
 /* Display values from last command.
  * Memory modify remembered values are different from display memory.
@@ -132,35 +134,65 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define DISP_LINE_LEN  16
 
-/* implement possible board specific board init */
-static void __def_i2c_init_board(void)
+/**
+ * i2c_init_board() - Board-specific I2C bus init
+ *
+ * This function is the default no-op implementation of I2C bus
+ * initialization. This function can be overriden by board-specific
+ * implementation if needed.
+ */
+__weak
+void i2c_init_board(void)
 {
        return;
 }
-void i2c_init_board(void)
-       __attribute__((weak, alias("__def_i2c_init_board")));
 
 /* TODO: Implement architecture-specific get/set functions */
-static unsigned int __def_i2c_get_bus_speed(void)
+
+/**
+ * i2c_get_bus_speed() - Return I2C bus speed
+ *
+ * This function is the default implementation of function for retrieveing
+ * the current I2C bus speed in Hz.
+ *
+ * A driver implementing runtime switching of I2C bus speed must override
+ * this function to report the speed correctly. Simple or legacy drivers
+ * can use this fallback.
+ *
+ * Returns I2C bus speed in Hz.
+ */
+__weak
+unsigned int i2c_get_bus_speed(void)
 {
        return CONFIG_SYS_I2C_SPEED;
 }
-unsigned int i2c_get_bus_speed(void)
-       __attribute__((weak, alias("__def_i2c_get_bus_speed")));
 
-static int __def_i2c_set_bus_speed(unsigned int speed)
+/**
+ * i2c_set_bus_speed() - Configure I2C bus speed
+ * @speed:     Newly set speed of the I2C bus in Hz
+ *
+ * This function is the default implementation of function for setting
+ * the I2C bus speed in Hz.
+ *
+ * A driver implementing runtime switching of I2C bus speed must override
+ * this function to report the speed correctly. Simple or legacy drivers
+ * can use this fallback.
+ *
+ * Returns zero on success, negative value on error.
+ */
+__weak
+int i2c_set_bus_speed(unsigned int speed)
 {
        if (speed != CONFIG_SYS_I2C_SPEED)
                return -1;
 
        return 0;
 }
-int i2c_set_bus_speed(unsigned int)
-       __attribute__((weak, alias("__def_i2c_set_bus_speed")));
 
-/*
- * get_alen: small parser helper function to get address length
- * returns the address length
+/**
+ * get_alen() - Small parser helper function to get address length
+ *
+ * Returns the address length.
  */
 static uint get_alen(char *arg)
 {
@@ -178,11 +210,19 @@ static uint get_alen(char *arg)
        return alen;
 }
 
-/*
+/**
+ * do_i2c_read() - Handle the "i2c read" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ *
  * Syntax:
  *     i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr}
  */
-
 static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        u_char  chip;
@@ -271,7 +311,16 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
        return 0;
 }
 
-/*
+/**
+ * do_i2c_md() - Handle the "i2c md" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ *
  * Syntax:
  *     i2c md {i2c_chip} {addr}{.0, .1, .2} {len}
  */
@@ -363,8 +412,15 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
        return 0;
 }
 
-
-/* Write (fill) memory
+/**
+ * do_i2c_mw() - Handle the "i2c mw" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
  *
  * Syntax:
  *     i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}]
@@ -421,10 +477,20 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
 #endif
        }
 
-       return (0);
+       return 0;
 }
 
-/* Calculate a CRC on memory
+/**
+ * do_i2c_crc() - Handle the "i2c crc32" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Calculate a CRC on memory
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
  *
  * Syntax:
  *     i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count}
@@ -481,13 +547,22 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
        return 0;
 }
 
-/* Modify memory.
+/**
+ * mod_i2c_mem() - Handle the "i2c mm" and "i2c nm" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Modify memory.
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
  *
  * Syntax:
  *     i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
  *     i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
  */
-
 static int
 mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
 {
@@ -603,7 +678,16 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg
        return 0;
 }
 
-/*
+/**
+ * do_i2c_probe() - Handle the "i2c probe" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ *
  * Syntax:
  *     i2c probe {addr}
  *
@@ -657,7 +741,16 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
        return (0 == found);
 }
 
-/*
+/**
+ * do_i2c_loop() - Handle the "i2c loop" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ *
  * Syntax:
  *     i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}]
  *     {length} - Number of bytes to read
@@ -718,6 +811,8 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
 /*
  * The SDRAM command is separately configured because many
  * (most?) embedded boards don't use SDRAM DIMMs.
+ *
+ * FIXME: Document and probably move elsewhere!
  */
 #if defined(CONFIG_CMD_SDRAM)
 static void print_ddr2_tcyc (u_char const b)
@@ -1246,7 +1341,48 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 }
 #endif
 
+/*
+ * Syntax:
+ *     i2c edid {i2c_chip}
+ */
+#if defined(CONFIG_I2C_EDID)
+int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       u_char chip;
+       struct edid1_info edid;
+
+       if (argc < 2) {
+               cmd_usage(cmdtp);
+               return 1;
+       }
+
+       chip = simple_strtoul(argv[1], NULL, 16);
+       if (i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)) != 0) {
+               puts("Error reading EDID content.\n");
+               return 1;
+       }
+
+       if (edid_check_info(&edid)) {
+               puts("Content isn't valid EDID.\n");
+               return 1;
+       }
+
+       edid_print_info(&edid);
+       return 0;
+
+}
+#endif /* CONFIG_I2C_EDID */
+
 #if defined(CONFIG_I2C_MUX)
+/**
+ * do_i2c_add_bus() - Handle the "i2c bus" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero always.
+ */
 static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        int ret=0;
@@ -1276,6 +1412,16 @@ static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar
 #endif  /* CONFIG_I2C_MUX */
 
 #if defined(CONFIG_I2C_MULTI_BUS)
+/**
+ * do_i2c_bus_num() - Handle the "i2c dev" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
 static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        int bus_idx, ret=0;
@@ -1294,6 +1440,16 @@ static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar
 }
 #endif  /* CONFIG_I2C_MULTI_BUS */
 
+/**
+ * do_i2c_bus_speed() - Handle the "i2c speed" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
 static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        int speed, ret=0;
@@ -1311,16 +1467,45 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const
        return ret;
 }
 
+/**
+ * do_i2c_mm() - Handle the "i2c mm" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
 static int do_i2c_mm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        return mod_i2c_mem (cmdtp, 1, flag, argc, argv);
 }
 
+/**
+ * do_i2c_nm() - Handle the "i2c nm" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
 static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        return mod_i2c_mem (cmdtp, 0, flag, argc, argv);
 }
 
+/**
+ * do_i2c_reset() - Handle the "i2c reset" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero always.
+ */
 static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
@@ -1335,6 +1520,9 @@ static cmd_tbl_t cmd_i2c_sub[] = {
 #if defined(CONFIG_I2C_MULTI_BUS)
        U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),
 #endif  /* CONFIG_I2C_MULTI_BUS */
+#if defined(CONFIG_I2C_EDID)
+       U_BOOT_CMD_MKENT(edid, 1, 1, do_edid, "", ""),
+#endif  /* CONFIG_I2C_EDID */
        U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", ""),
        U_BOOT_CMD_MKENT(md, 3, 1, do_i2c_md, "", ""),
        U_BOOT_CMD_MKENT(mm, 2, 1, do_i2c_mm, "", ""),
@@ -1356,6 +1544,16 @@ void i2c_reloc(void) {
 }
 #endif
 
+/**
+ * do_i2c() - Handle the "i2c" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
 static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        cmd_tbl_t *c;
@@ -1385,6 +1583,9 @@ static char i2c_help_text[] =
 #if defined(CONFIG_I2C_MULTI_BUS)
        "i2c dev [dev] - show or set current I2C bus\n"
 #endif  /* CONFIG_I2C_MULTI_BUS */
+#if defined(CONFIG_I2C_EDID)
+       "i2c edid chip - print EDID configuration information\n"
+#endif  /* CONFIG_I2C_EDID */
        "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n"
        "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n"
        "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n"
diff --git a/common/cmd_io.c b/common/cmd_io.c
new file mode 100644 (file)
index 0000000..6450cb5
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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
+ */
+
+/*
+ * IO space access commands.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/io.h>
+
+/*
+ * IO Display
+ *
+ * Syntax:
+ *     iod{.b, .w, .l} {addr}
+ */
+int do_io_iod(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       ulong addr;
+       int size;
+
+       if (argc != 2)
+               return CMD_RET_USAGE;
+
+       size = cmd_get_data_size(argv[0], 4);
+       if (size < 0)
+               return 1;
+
+       addr = simple_strtoul(argv[1], NULL, 16);
+
+       printf("%04x: ", (u16) addr);
+
+       if (size == 4)
+               printf("%08x\n", inl(addr));
+       else if (size == 2)
+               printf("%04x\n", inw(addr));
+       else
+               printf("%02x\n", inb(addr));
+
+       return 0;
+}
+
+int do_io_iow(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       ulong addr, size, val;
+
+       if (argc != 3)
+               return CMD_RET_USAGE;
+
+       size = cmd_get_data_size(argv[0], 4);
+       if (size < 0)
+               return 1;
+
+       addr = simple_strtoul(argv[1], NULL, 16);
+       val = simple_strtoul(argv[2], NULL, 16);
+
+       if (size == 4)
+               outl((u32) val, addr);
+       else if (size == 2)
+               outw((u16) val, addr);
+       else
+               outb((u8) val, addr);
+
+       return 0;
+}
+
+/**************************************************/
+U_BOOT_CMD(iod, 2, 0, do_io_iod,
+          "IO space display", "[.b, .w, .l] address [# of objects]");
+
+U_BOOT_CMD(iow, 3, 0, do_io_iow,
+          "IO space modify (auto-incrementing address)",
+          "[.b, .w, .l] address");
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 006131f45c1b20b793a9ced9bdc95383043a87e9..7633f0c44a7e3ecb4c8828fbb62af4ede1d9fa21 100644 (file)
 #include <errno.h>
 #include <malloc.h>
 #include <watchdog.h>
-#include <serial.h>
 #include <linux/stddef.h>
 #include <asm/byteorder.h>
-#if defined(CONFIG_CMD_NET)
-#include <net.h>
-#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -76,16 +72,6 @@ SPI_FLASH|NVRAM|MMC|FAT|REMOTE} or CONFIG_ENV_IS_NOWHERE
  */
 #define        MAX_ENV_SIZE    (1 << 20)       /* 1 MiB */
 
-ulong load_addr = CONFIG_SYS_LOAD_ADDR;        /* Default Load Address */
-ulong save_addr;                       /* Default Save Address */
-ulong save_size;                       /* Default Save Size (in bytes) */
-
-/*
- * Table with supported baudrates (defined in config_xyz.h)
- */
-static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
-#define        N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0]))
-
 /*
  * This variable is incremented on each do_env_set(), so it can
  * be used via get_env_id() as an indication, if the environment
@@ -106,7 +92,7 @@ int get_env_id(void)
  *
  * Returns 0 in case of error, or length of printed string
  */
-static int env_print(char *name)
+static int env_print(char *name, int flag)
 {
        char *res = NULL;
        size_t len;
@@ -116,7 +102,7 @@ static int env_print(char *name)
 
                e.key = name;
                e.data = NULL;
-               hsearch_r(e, FIND, &ep, &env_htab);
+               hsearch_r(e, FIND, &ep, &env_htab, flag);
                if (ep == NULL)
                        return 0;
                len = printf("%s=%s\n", ep->key, ep->data);
@@ -124,7 +110,7 @@ static int env_print(char *name)
        }
 
        /* print whole list */
-       len = hexport_r(&env_htab, '\n', &res, 0, 0, NULL);
+       len = hexport_r(&env_htab, '\n', flag, &res, 0, 0, NULL);
 
        if (len > 0) {
                puts(res);
@@ -141,10 +127,17 @@ static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc,
 {
        int i;
        int rcode = 0;
+       int env_flag = H_HIDE_DOT;
+
+       if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'a') {
+               argc--;
+               argv++;
+               env_flag &= ~H_HIDE_DOT;
+       }
 
        if (argc == 1) {
                /* print all env vars */
-               rcode = env_print(NULL);
+               rcode = env_print(NULL, env_flag);
                if (!rcode)
                        return 1;
                printf("\nEnvironment size: %d/%ld bytes\n",
@@ -153,8 +146,9 @@ static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc,
        }
 
        /* print selected env vars */
+       env_flag &= ~H_HIDE_DOT;
        for (i = 1; i < argc; ++i) {
-               int rc = env_print(argv[i]);
+               int rc = env_print(argv[i], env_flag);
                if (!rc) {
                        printf("## Error: \"%s\" not defined\n", argv[i]);
                        ++rcode;
@@ -197,138 +191,33 @@ static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
 #endif
 #endif /* CONFIG_SPL_BUILD */
 
-/*
- * Perform consistency checking before setting, replacing, or deleting an
- * environment variable, then (if successful) apply the changes to internals so
- * to make them effective.  Code for this function was taken out of
- * _do_env_set(), which now calls it instead.
- * Also called as a callback function by himport_r().
- * Returns 0 in case of success, 1 in case of failure.
- * When (flag & H_FORCE) is set, do not print out any error message and force
- * overwriting of write-once variables.
- */
-
-int env_check_apply(const char *name, const char *oldval,
-                       const char *newval, int flag)
-{
-       int   console = -1;
-
-       /* Default value for NULL to protect string-manipulating functions */
-       newval = newval ? : "";
-
-       /* Check for console redirection */
-       if (strcmp(name, "stdin") == 0)
-               console = stdin;
-       else if (strcmp(name, "stdout") == 0)
-               console = stdout;
-       else if (strcmp(name, "stderr") == 0)
-               console = stderr;
-
-       if (console != -1) {
-               if ((newval == NULL) || (*newval == '\0')) {
-                       /* We cannot delete stdin/stdout/stderr */
-                       if ((flag & H_FORCE) == 0)
-                               printf("Can't delete \"%s\"\n", name);
-                       return 1;
-               }
-
-#ifdef CONFIG_CONSOLE_MUX
-               if (iomux_doenv(console, newval))
-                       return 1;
-#else
-               /* Try assigning specified device */
-               if (console_assign(console, newval) < 0)
-                       return 1;
-#endif /* CONFIG_CONSOLE_MUX */
-       }
-
-       /*
-        * Some variables like "ethaddr" and "serial#" can be set only once and
-        * cannot be deleted, unless CONFIG_ENV_OVERWRITE is defined.
-        */
-#ifndef CONFIG_ENV_OVERWRITE
-       if (oldval != NULL &&                   /* variable exists */
-               (flag & H_FORCE) == 0) {        /* and we are not forced */
-               if (strcmp(name, "serial#") == 0 ||
-                   (strcmp(name, "ethaddr") == 0
-#if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
-                    && strcmp(oldval, __stringify(CONFIG_ETHADDR)) != 0
-#endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */
-                       )) {
-                       printf("Can't overwrite \"%s\"\n", name);
-                       return 1;
-               }
-       }
-#endif
-       /*
-        * When we change baudrate, or we are doing an env default -a
-        * (which will erase all variables prior to calling this),
-        * we want the baudrate to actually change - for real.
-        */
-       if (oldval != NULL ||                   /* variable exists */
-               (flag & H_NOCLEAR) == 0) {      /* or env is clear */
-               /*
-                * Switch to new baudrate if new baudrate is supported
-                */
-               if (strcmp(name, "baudrate") == 0) {
-                       int baudrate = simple_strtoul(newval, NULL, 10);
-                       int i;
-                       for (i = 0; i < N_BAUDRATES; ++i) {
-                               if (baudrate == baudrate_table[i])
-                                       break;
-                       }
-                       if (i == N_BAUDRATES) {
-                               if ((flag & H_FORCE) == 0)
-                                       printf("## Baudrate %d bps not "
-                                               "supported\n", baudrate);
-                               return 1;
-                       }
-                       if (gd->baudrate == baudrate) {
-                               /* If unchanged, we just say it's OK */
-                               return 0;
-                       }
-                       printf("## Switch baudrate to %d bps and"
-                               "press ENTER ...\n", baudrate);
-                       udelay(50000);
-                       gd->baudrate = baudrate;
-#if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2)
-                       gd->bd->bi_baudrate = baudrate;
-#endif
-
-                       serial_setbrg();
-                       udelay(50000);
-                       while (getc() != '\r')
-                               ;
-               }
-       }
-
-       /*
-        * Some variables should be updated when the corresponding
-        * entry in the environment is changed
-        */
-       if (strcmp(name, "loadaddr") == 0) {
-               load_addr = simple_strtoul(newval, NULL, 16);
-               return 0;
-       }
-#if defined(CONFIG_CMD_NET)
-       else if (strcmp(name, "bootfile") == 0) {
-               copy_filename(BootFile, newval, sizeof(BootFile));
-               return 0;
-       }
-#endif
-       return 0;
-}
-
 /*
  * Set a new environment variable,
  * or replace or delete an existing one.
-*/
+ */
 static int _do_env_set(int flag, int argc, char * const argv[])
 {
        int   i, len;
        char  *name, *value, *s;
        ENTRY e, *ep;
+       int env_flag = H_INTERACTIVE;
+
+       debug("Initial value for argc=%d\n", argc);
+       while (argc > 1 && **(argv + 1) == '-') {
+               char *arg = *++argv;
 
+               --argc;
+               while (*++arg) {
+                       switch (*arg) {
+                       case 'f':               /* force */
+                               env_flag |= H_FORCE;
+                               break;
+                       default:
+                               return CMD_RET_USAGE;
+                       }
+               }
+       }
+       debug("Final value for argc=%d\n", argc);
        name = argv[1];
        value = argv[2];
 
@@ -339,25 +228,10 @@ static int _do_env_set(int flag, int argc, char * const argv[])
        }
 
        env_id++;
-       /*
-        * search if variable with this name already exists
-        */
-       e.key = name;
-       e.data = NULL;
-       hsearch_r(e, FIND, &ep, &env_htab);
-
-       /*
-        * Perform requested checks. Notice how since we are overwriting
-        * a single variable, we need to set H_NOCLEAR
-        */
-       if (env_check_apply(name, ep ? ep->data : NULL, value, H_NOCLEAR)) {
-               debug("check function did not approve, refusing\n");
-               return 1;
-       }
 
        /* Delete only ? */
        if (argc < 3 || argv[2] == NULL) {
-               int rc = hdelete_r(name, &env_htab, 0);
+               int rc = hdelete_r(name, &env_htab, env_flag);
                return !rc;
        }
 
@@ -384,7 +258,7 @@ static int _do_env_set(int flag, int argc, char * const argv[])
 
        e.key   = name;
        e.data  = value;
-       hsearch_r(e, ENTER, &ep, &env_htab);
+       hsearch_r(e, ENTER, &ep, &env_htab, env_flag);
        free(value);
        if (!ep) {
                printf("## Error inserting \"%s\" variable, errno=%d\n",
@@ -511,6 +385,153 @@ int do_env_ask(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 }
 #endif
 
+#if defined(CONFIG_CMD_ENV_CALLBACK)
+static int print_static_binding(const char *var_name, const char *callback_name)
+{
+       printf("\t%-20s %-20s\n", var_name, callback_name);
+
+       return 0;
+}
+
+static int print_active_callback(ENTRY *entry)
+{
+       struct env_clbk_tbl *clbkp;
+       int i;
+       int num_callbacks;
+
+       if (entry->callback == NULL)
+               return 0;
+
+       /* look up the callback in the linker-list */
+       num_callbacks = ll_entry_count(struct env_clbk_tbl, env_clbk);
+       for (i = 0, clbkp = ll_entry_start(struct env_clbk_tbl, env_clbk);
+            i < num_callbacks;
+            i++, clbkp++) {
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+               if (entry->callback == clbkp->callback + gd->reloc_off)
+#else
+               if (entry->callback == clbkp->callback)
+#endif
+                       break;
+       }
+
+       if (i == num_callbacks)
+               /* this should probably never happen, but just in case... */
+               printf("\t%-20s %p\n", entry->key, entry->callback);
+       else
+               printf("\t%-20s %-20s\n", entry->key, clbkp->name);
+
+       return 0;
+}
+
+/*
+ * Print the callbacks available and what they are bound to
+ */
+int do_env_callback(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       struct env_clbk_tbl *clbkp;
+       int i;
+       int num_callbacks;
+
+       /* Print the available callbacks */
+       puts("Available callbacks:\n");
+       puts("\tCallback Name\n");
+       puts("\t-------------\n");
+       num_callbacks = ll_entry_count(struct env_clbk_tbl, env_clbk);
+       for (i = 0, clbkp = ll_entry_start(struct env_clbk_tbl, env_clbk);
+            i < num_callbacks;
+            i++, clbkp++)
+               printf("\t%s\n", clbkp->name);
+       puts("\n");
+
+       /* Print the static bindings that may exist */
+       puts("Static callback bindings:\n");
+       printf("\t%-20s %-20s\n", "Variable Name", "Callback Name");
+       printf("\t%-20s %-20s\n", "-------------", "-------------");
+       env_attr_walk(ENV_CALLBACK_LIST_STATIC, print_static_binding);
+       puts("\n");
+
+       /* walk through each variable and print the callback if it has one */
+       puts("Active callback bindings:\n");
+       printf("\t%-20s %-20s\n", "Variable Name", "Callback Name");
+       printf("\t%-20s %-20s\n", "-------------", "-------------");
+       hwalk_r(&env_htab, print_active_callback);
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_ENV_FLAGS)
+static int print_static_flags(const char *var_name, const char *flags)
+{
+       enum env_flags_vartype type = env_flags_parse_vartype(flags);
+       enum env_flags_varaccess access = env_flags_parse_varaccess(flags);
+
+       printf("\t%-20s %-20s %-20s\n", var_name,
+               env_flags_get_vartype_name(type),
+               env_flags_get_varaccess_name(access));
+
+       return 0;
+}
+
+static int print_active_flags(ENTRY *entry)
+{
+       enum env_flags_vartype type;
+       enum env_flags_varaccess access;
+
+       if (entry->flags == 0)
+               return 0;
+
+       type = (enum env_flags_vartype)
+               (entry->flags & ENV_FLAGS_VARTYPE_BIN_MASK);
+       access = env_flags_parse_varaccess_from_binflags(entry->flags);
+       printf("\t%-20s %-20s %-20s\n", entry->key,
+               env_flags_get_vartype_name(type),
+               env_flags_get_varaccess_name(access));
+
+       return 0;
+}
+
+/*
+ * Print the flags available and what variables have flags
+ */
+int do_env_flags(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       /* Print the available variable types */
+       printf("Available variable type flags (position %d):\n",
+               ENV_FLAGS_VARTYPE_LOC);
+       puts("\tFlag\tVariable Type Name\n");
+       puts("\t----\t------------------\n");
+       env_flags_print_vartypes();
+       puts("\n");
+
+       /* Print the available variable access types */
+       printf("Available variable access flags (position %d):\n",
+               ENV_FLAGS_VARACCESS_LOC);
+       puts("\tFlag\tVariable Access Name\n");
+       puts("\t----\t--------------------\n");
+       env_flags_print_varaccess();
+       puts("\n");
+
+       /* Print the static flags that may exist */
+       puts("Static flags:\n");
+       printf("\t%-20s %-20s %-20s\n", "Variable Name", "Variable Type",
+               "Variable Access");
+       printf("\t%-20s %-20s %-20s\n", "-------------", "-------------",
+               "---------------");
+       env_attr_walk(ENV_FLAGS_LIST_STATIC, print_static_flags);
+       puts("\n");
+
+       /* walk through each variable and print the flags if non-default */
+       puts("Active flags:\n");
+       printf("\t%-20s %-20s %-20s\n", "Variable Name", "Variable Type",
+               "Variable Access");
+       printf("\t%-20s %-20s %-20s\n", "-------------", "-------------",
+               "---------------");
+       hwalk_r(&env_htab, print_active_flags);
+       return 0;
+}
+#endif
+
 /*
  * Interactively edit an environment variable
  */
@@ -552,7 +573,7 @@ char *getenv(const char *name)
 
                e.key   = name;
                e.data  = NULL;
-               hsearch_r(e, FIND, &ep, &env_htab);
+               hsearch_r(e, FIND, &ep, &env_htab, 0);
 
                return ep ? ep->data : NULL;
        }
@@ -704,8 +725,36 @@ static int do_env_default(cmd_tbl_t *cmdtp, int __flag,
 static int do_env_delete(cmd_tbl_t *cmdtp, int flag,
                         int argc, char * const argv[])
 {
-       printf("Not implemented yet\n");
-       return 0;
+       int env_flag = H_INTERACTIVE;
+       int ret = 0;
+
+       debug("Initial value for argc=%d\n", argc);
+       while (argc > 1 && **(argv + 1) == '-') {
+               char *arg = *++argv;
+
+               --argc;
+               while (*++arg) {
+                       switch (*arg) {
+                       case 'f':               /* force */
+                               env_flag |= H_FORCE;
+                               break;
+                       default:
+                               return CMD_RET_USAGE;
+                       }
+               }
+       }
+       debug("Final value for argc=%d\n", argc);
+
+       env_id++;
+
+       while (--argc > 0) {
+               char *name = *++argv;
+
+               if (!hdelete_r(name, &env_htab, env_flag))
+                       ret = 1;
+       }
+
+       return ret;
 }
 
 #ifdef CONFIG_CMD_EXPORTENV
@@ -812,7 +861,7 @@ NXTARG:             ;
        argv++;
 
        if (sep) {              /* export as text file */
-               len = hexport_r(&env_htab, sep, &addr, size, argc, argv);
+               len = hexport_r(&env_htab, sep, 0, &addr, size, argc, argv);
                if (len < 0) {
                        error("Cannot export environment: errno = %d\n", errno);
                        return 1;
@@ -830,7 +879,7 @@ NXTARG:             ;
        else                    /* export as raw binary data */
                res = addr;
 
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, argc, argv);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, argc, argv);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
@@ -951,7 +1000,7 @@ static int do_env_import(cmd_tbl_t *cmdtp, int flag,
        }
 
        if (himport_r(&env_htab, addr, size, sep, del ? 0 : H_NOCLEAR,
-                       0, NULL, 0 /* do_apply */) == 0) {
+                       0, NULL) == 0) {
                error("Environment import failed: errno = %d\n", errno);
                return 1;
        }
@@ -974,10 +1023,16 @@ static cmd_tbl_t cmd_env_sub[] = {
        U_BOOT_CMD_MKENT(ask, CONFIG_SYS_MAXARGS, 1, do_env_ask, "", ""),
 #endif
        U_BOOT_CMD_MKENT(default, 1, 0, do_env_default, "", ""),
-       U_BOOT_CMD_MKENT(delete, 2, 0, do_env_delete, "", ""),
+       U_BOOT_CMD_MKENT(delete, CONFIG_SYS_MAXARGS, 0, do_env_delete, "", ""),
 #if defined(CONFIG_CMD_EDITENV)
        U_BOOT_CMD_MKENT(edit, 2, 0, do_env_edit, "", ""),
 #endif
+#if defined(CONFIG_CMD_ENV_CALLBACK)
+       U_BOOT_CMD_MKENT(callbacks, 1, 0, do_env_callback, "", ""),
+#endif
+#if defined(CONFIG_CMD_ENV_FLAGS)
+       U_BOOT_CMD_MKENT(flags, 1, 0, do_env_flags, "", ""),
+#endif
 #if defined(CONFIG_CMD_EXPORTENV)
        U_BOOT_CMD_MKENT(export, 4, 0, do_env_export, "", ""),
 #endif
@@ -1027,22 +1082,29 @@ static int do_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 static char env_help_text[] =
 #if defined(CONFIG_CMD_ASKENV)
        "ask name [message] [size] - ask for environment variable\nenv "
+#endif
+#if defined(CONFIG_CMD_ENV_CALLBACK)
+       "callbacks - print callbacks and their associated variables\nenv "
 #endif
        "default [-f] -a - [forcibly] reset default environment\n"
        "env default [-f] var [...] - [forcibly] reset variable(s) to their default values\n"
+       "env delete [-f] var [...] - [forcibly] delete variable(s)\n"
 #if defined(CONFIG_CMD_EDITENV)
        "env edit name - edit environment variable\n"
 #endif
 #if defined(CONFIG_CMD_EXPORTENV)
        "env export [-t | -b | -c] [-s size] addr [var ...] - export environment\n"
 #endif
+#if defined(CONFIG_CMD_ENV_FLAGS)
+       "env flags - print variables that have non-default flags\n"
+#endif
 #if defined(CONFIG_CMD_GREPENV)
        "env grep string [...] - search environment\n"
 #endif
 #if defined(CONFIG_CMD_IMPORTENV)
        "env import [-d] [-t | -b | -c] addr [size] - import environment\n"
 #endif
-       "env print [name ...] - print environment\n"
+       "env print [-a | name ...] - print environment\n"
 #if defined(CONFIG_CMD_RUN)
        "env run var [...] - run commands in an environment variable\n"
 #endif
@@ -1074,7 +1136,7 @@ U_BOOT_CMD_COMPLETE(
 U_BOOT_CMD_COMPLETE(
        printenv, CONFIG_SYS_MAXARGS, 1,        do_env_print,
        "print environment variables",
-       "\n    - print values of all environment variables\n"
+       "[-a]\n    - print [all] values of all environment variables\n"
        "printenv name ...\n"
        "    - print value of environment variable 'name'",
        var_complete
@@ -1093,10 +1155,10 @@ U_BOOT_CMD_COMPLETE(
 U_BOOT_CMD_COMPLETE(
        setenv, CONFIG_SYS_MAXARGS, 0,  do_env_set,
        "set environment variables",
-       "name value ...\n"
-       "    - set environment variable 'name' to 'value ...'\n"
-       "setenv name\n"
-       "    - delete environment variable 'name'",
+       "[-f] name value ...\n"
+       "    - [forcibly] set environment variable 'name' to 'value ...'\n"
+       "setenv [-f] name\n"
+       "    - [forcibly] delete environment variable 'name'",
        var_complete
 );
 
diff --git a/common/cmd_read.c b/common/cmd_read.c
new file mode 100644 (file)
index 0000000..f0fc9bf
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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>
+#include <command.h>
+#include <part.h>
+
+int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       char *ep;
+       block_dev_desc_t *dev_desc = NULL;
+       int dev;
+       int part = 0;
+       disk_partition_t part_info;
+       ulong offset = 0u;
+       ulong limit = 0u;
+       void *addr;
+       uint blk;
+       uint cnt;
+
+       if (argc != 6) {
+               cmd_usage(cmdtp);
+               return 1;
+       }
+
+       dev = (int)simple_strtoul(argv[2], &ep, 16);
+       if (*ep) {
+               if (*ep != ':') {
+                       printf("Invalid block device %s\n", argv[2]);
+                       return 1;
+               }
+               part = (int)simple_strtoul(++ep, NULL, 16);
+       }
+
+       dev_desc = get_dev(argv[1], dev);
+       if (dev_desc == NULL) {
+               printf("Block device %s %d not supported\n", argv[1], dev);
+               return 1;
+       }
+
+       addr = (void *)simple_strtoul(argv[3], NULL, 16);
+       blk = simple_strtoul(argv[4], NULL, 16);
+       cnt = simple_strtoul(argv[5], NULL, 16);
+
+       if (part != 0) {
+               if (get_partition_info(dev_desc, part, &part_info)) {
+                       printf("Cannot find partition %d\n", part);
+                       return 1;
+               }
+               offset = part_info.start;
+               limit = part_info.size;
+       } else {
+               /* Largest address not available in block_dev_desc_t. */
+               limit = ~0;
+       }
+
+       if (cnt + blk > limit) {
+               printf("Read out of range\n");
+               return 1;
+       }
+
+       if (dev_desc->block_read(dev, offset + blk, cnt, addr) < 0) {
+               printf("Error reading blocks\n");
+               return 1;
+       }
+
+       return 0;
+}
+
+U_BOOT_CMD(
+       read,   6,      0,      do_read,
+       "Load binary data from a partition",
+       "<interface> <dev[:part]> addr blk# cnt"
+);
index 8db5456c9583ec8cf6b927f9760a748d72f4f1ed..fe927ab248f3fa3aafdc0dbbc1b974f78cef798c 100644 (file)
 
 #include <common.h>
 #include <command.h>
+#include <hash.h>
 #include <sha1.h>
 
-/*
- * Store the resulting sum to an address or variable
- */
-static void store_result(const u8 *sum, const char *dest)
-{
-       unsigned int i;
-
-       if (*dest == '*') {
-               u8 *ptr;
-
-               ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16);
-               for (i = 0; i < 20; i++)
-                       *ptr++ = sum[i];
-       } else {
-               char str_output[41];
-               char *str_ptr = str_output;
-
-               for (i = 0; i < 20; i++) {
-                       sprintf(str_ptr, "%02x", sum[i]);
-                       str_ptr += 2;
-               }
-               str_ptr = '\0';
-               setenv(dest, str_output);
-       }
-}
-
-#ifdef CONFIG_SHA1SUM_VERIFY
-static int parse_verify_sum(char *verify_str, u8 *vsum)
-{
-       if (*verify_str == '*') {
-               u8 *ptr;
-
-               ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16);
-               memcpy(vsum, ptr, 20);
-       } else {
-               unsigned int i;
-               char *vsum_str;
-
-               if (strlen(verify_str) == 40)
-                       vsum_str = verify_str;
-               else {
-                       vsum_str = getenv(verify_str);
-                       if (vsum_str == NULL || strlen(vsum_str) != 40)
-                               return 1;
-               }
-
-               for (i = 0; i < 20; i++) {
-                       char *nullp = vsum_str + (i + 1) * 2;
-                       char end = *nullp;
-
-                       *nullp = '\0';
-                       *(u8 *)(vsum + i) =
-                               simple_strtoul(vsum_str + (i * 2), NULL, 16);
-                       *nullp = end;
-               }
-       }
-       return 0;
-}
-
 int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       ulong addr, len;
-       unsigned int i;
-       u8 output[20];
-       u8 vsum[20];
        int verify = 0;
        int ac;
        char * const *av;
@@ -102,75 +40,16 @@ int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        av = argv + 1;
        ac = argc - 1;
+#ifdef CONFIG_SHA1SUM_VERIFY
        if (strcmp(*av, "-v") == 0) {
                verify = 1;
                av++;
                ac--;
-               if (ac < 3)
-                       return CMD_RET_USAGE;
        }
+#endif
 
-       addr = simple_strtoul(*av++, NULL, 16);
-       len = simple_strtoul(*av++, NULL, 16);
-
-       sha1_csum_wd((unsigned char *) addr, len, output, CHUNKSZ_SHA1);
-
-       if (!verify) {
-               printf("SHA1 for %08lx ... %08lx ==> ", addr, addr + len - 1);
-               for (i = 0; i < 20; i++)
-                       printf("%02x", output[i]);
-               printf("\n");
-
-               if (ac > 2)
-                       store_result(output, *av);
-       } else {
-               char *verify_str = *av++;
-
-               if (parse_verify_sum(verify_str, vsum)) {
-                       printf("ERROR: %s does not contain a valid SHA1 sum\n",
-                               verify_str);
-                       return 1;
-               }
-               if (memcmp(output, vsum, 20) != 0) {
-                       printf("SHA1 for %08lx ... %08lx ==> ", addr,
-                               addr + len - 1);
-                       for (i = 0; i < 20; i++)
-                               printf("%02x", output[i]);
-                       printf(" != ");
-                       for (i = 0; i < 20; i++)
-                               printf("%02x", vsum[i]);
-                       printf(" ** ERROR **\n");
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-#else
-static int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       unsigned long addr, len;
-       unsigned int i;
-       u8 output[20];
-
-       if (argc < 3)
-               return CMD_RET_USAGE;
-
-       addr = simple_strtoul(argv[1], NULL, 16);
-       len = simple_strtoul(argv[2], NULL, 16);
-
-       sha1_csum_wd((unsigned char *) addr, len, output, CHUNKSZ_SHA1);
-       printf("SHA1 for %08lx ... %08lx ==> ", addr, addr + len - 1);
-       for (i = 0; i < 20; i++)
-               printf("%02x", output[i]);
-       printf("\n");
-
-       if (argc > 3)
-               store_result(output, argv[3]);
-
-       return 0;
+       return hash_command("sha1", verify, cmdtp, flag, ac, av);
 }
-#endif
 
 #ifdef CONFIG_SHA1SUM_VERIFY
 U_BOOT_CMD(
index 9ec054af3b359b6048df6d5f503307cec156697c..e3c543b46a54724eade6cb92f99dbc3381a5e1ed 100644 (file)
@@ -130,10 +130,12 @@ static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                if (call_bootm(argc, argv, subcmd_list[(int)c->cmd]))
                        return -1;
                switch ((int)c->cmd) {
+#ifdef CONFIG_OF_LIBFDT
                case SPL_EXPORT_FDT:
                        printf("Argument image is now in RAM: 0x%p\n",
                                (void *)images.ft_addr);
                        break;
+#endif
                case SPL_EXPORT_ATAGS:
                        printf("Argument image is now in RAM at: 0x%p\n",
                                (void *)gd->bd->bi_boot_params);
index 6f5cd4895d8cedea527612471d2eeaee5bcc9b30..0970a6fc191cab170cef254551b6a29b67dec0e6 100644 (file)
@@ -63,19 +63,68 @@ static int tpm_process(int argc, char * const argv[], cmd_tbl_t *cmdtp)
        return rv;
 }
 
-static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+#define CHECK(exp) do {                                                        \
+               int _rv = exp;                                          \
+               if (_rv) {                                              \
+                       printf("CHECK: %s %d %x\n", #exp, __LINE__, _rv);\
+               }                                                       \
+       } while (0)
+
+static int tpm_process_stress(int repeat_count)
 {
+       int i;
        int rv = 0;
+       u8 request[] = {0x0, 0xc1,
+                       0x0, 0x0, 0x0, 0x16,
+                       0x0, 0x0, 0x0, 0x65,
+                       0x0, 0x0, 0x0, 0x4,
+                       0x0, 0x0, 0x0, 0x4,
+                       0x0, 0x0, 0x1, 0x9};
+       u8 response[MAX_TRANSACTION_SIZE];
+       u32 rlength = MAX_TRANSACTION_SIZE;
+
+       CHECK(tis_init());
+
+       for (i = 0; i < repeat_count; i++) {
+               CHECK(tis_open());
+               rv = tis_sendrecv(request, sizeof(request), response, &rlength);
+               if (rv) {
+                       printf("tpm test failed at step %d with 0x%x\n", i, rv);
+                       CHECK(tis_close());
+                       break;
+               }
+               CHECK(tis_close());
+               if ((response[6] || response[7] || response[8] || response[9])
+                   && response[9] != 0x26) {
+                       /* Ignore postinit errors */
+                       printf("tpm command failed at step %d\n"
+                              "tpm error code: %02x%02x%02x%02x\n", i,
+                              response[6], response[7],
+                              response[8], response[9]);
+                       rv = -1;
+                       break;
+               }
+       }
+       return rv;
+}
 
-       /*
-        * Verify that in case it is present, the first argument, it is
-        * exactly one character in size.
-        */
-       if (argc < 7) {
+
+static int do_tpm_many(cmd_tbl_t *cmdtp, int flag,
+                      int argc, char * const argv[], int repeat_count)
+
+{
+       int rv = 0;
+
+       if (argc < 7 && repeat_count == 0) {
                puts("command should be at least six bytes in size\n");
                return -1;
        }
 
+       if (repeat_count > 0) {
+               rv = tpm_process_stress(repeat_count);
+               return rv;
+       }
+
        if (tis_init()) {
                puts("tis_init() failed!\n");
                return -1;
@@ -96,8 +145,40 @@ static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        return rv;
 }
 
+
+static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       return do_tpm_many(cmdtp, flag, argc, argv, 0);
+}
+
+
 U_BOOT_CMD(tpm, MAX_TRANSACTION_SIZE, 1, do_tpm,
           "<byte> [<byte> ...]   - write data and read response",
           "send arbitrary data (at least 6 bytes) to the TPM "
           "device and read the response"
 );
+
+static int do_tpm_stress(cmd_tbl_t *cmdtp, int flag,
+                        int argc, char * const argv[])
+{
+       long unsigned int n;
+       int rv;
+
+       if (argc != 2) {
+               puts("usage: tpm_stress <count>\n");
+               return -1;
+       }
+
+       rv = strict_strtoul(argv[1], 10, &n);
+       if (rv) {
+               puts("tpm_stress: bad count");
+               return -1;
+       }
+
+       return do_tpm_many(cmdtp, flag, argc, argv, n);
+}
+
+U_BOOT_CMD(tpm_stress, 2, 1, do_tpm_stress,
+          "<n>   - stress-test communication with TPM",
+          "Repeat a TPM transaction (request-response) N times"
+);
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 1177f7d396b889effbb9973b77966a013f15ee96..bf7317869097a8bf84bf9929bacdf90ff8f693a3 100644 (file)
 #include <common.h>
 #include <stdarg.h>
 #include <malloc.h>
+#include <serial.h>
 #include <stdio_dev.h>
 #include <exports.h>
+#include <environment.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static int on_console(const char *name, const char *value, enum env_op op,
+       int flags)
+{
+       int console = -1;
+
+       /* Check for console redirection */
+       if (strcmp(name, "stdin") == 0)
+               console = stdin;
+       else if (strcmp(name, "stdout") == 0)
+               console = stdout;
+       else if (strcmp(name, "stderr") == 0)
+               console = stderr;
+
+       /* if not actually setting a console variable, we don't care */
+       if (console == -1 || (gd->flags & GD_FLG_DEVINIT) == 0)
+               return 0;
+
+       switch (op) {
+       case env_op_create:
+       case env_op_overwrite:
+
+#ifdef CONFIG_CONSOLE_MUX
+               if (iomux_doenv(console, value))
+                       return 1;
+#else
+               /* Try assigning specified device */
+               if (console_assign(console, value) < 0)
+                       return 1;
+#endif /* CONFIG_CONSOLE_MUX */
+               return 0;
+
+       case env_op_delete:
+               if ((flags & H_FORCE) == 0)
+                       printf("Can't delete \"%s\"\n", name);
+               return 1;
+
+       default:
+               return 0;
+       }
+}
+U_BOOT_ENV_CALLBACK(console, on_console);
+
+#ifdef CONFIG_SILENT_CONSOLE
+static int on_silent(const char *name, const char *value, enum env_op op,
+       int flags)
+{
+#ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_SET
+       if (flags & H_INTERACTIVE)
+               return 0;
+#endif
+#ifndef CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC
+       if ((flags & H_INTERACTIVE) == 0)
+               return 0;
+#endif
+
+       if (value != NULL)
+               gd->flags |= GD_FLG_SILENT;
+       else
+               gd->flags &= ~GD_FLG_SILENT;
+
+       return 0;
+}
+U_BOOT_ENV_CALLBACK(silent, on_silent);
+#endif
+
 #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
 /*
  * if overwrite_console returns 1, the stdin, stderr and stdout
@@ -591,7 +658,6 @@ int console_init_f(void)
 
 void stdio_print_current_devices(void)
 {
-#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
        /* Print information */
        puts("In:    ");
        if (stdio_devices[stdin] == NULL) {
@@ -613,7 +679,6 @@ void stdio_print_current_devices(void)
        } else {
                printf ("%s\n", stdio_devices[stderr]->name);
        }
-#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
 }
 
 #ifdef CONFIG_SYS_CONSOLE_IS_IN_ENV
@@ -683,9 +748,9 @@ int console_init_r(void)
 done:
 #endif
 
-       gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
-
+#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
        stdio_print_current_devices();
+#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
 
 #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
        /* set the environment variables (will overwrite previous env settings) */
@@ -694,6 +759,8 @@ done:
        }
 #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */
 
+       gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
+
 #if 0
        /* If nothing usable installed, use only the initial console */
        if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
@@ -758,15 +825,17 @@ int console_init_r(void)
 #endif
        }
 
-       gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
-
+#ifndef CONFIG_SYS_CONSOLE_INFO_QUIET
        stdio_print_current_devices();
+#endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */
 
        /* Setting environment variables */
        for (i = 0; i < 3; i++) {
                setenv(stdio_names[i], stdio_devices[i]->name);
        }
 
+       gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
+
 #if 0
        /* If nothing usable installed, use only the initial console */
        if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
diff --git a/common/edid.c b/common/edid.c
new file mode 100644 (file)
index 0000000..c82c298
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * (C) Copyright 2010
+ * Petr Stetiar <ynezz@true.cz>
+ *
+ * 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
+ *
+ * Contains stolen code from ddcprobe project which is:
+ * Copyright (C) Nalin Dahyabhai <bigfun@pobox.com>
+ *
+ */
+
+#include <common.h>
+#include <edid.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+
+int edid_check_info(struct edid1_info *edid_info)
+{
+       if ((edid_info == NULL) || (edid_info->version == 0))
+               return -1;
+
+       if (memcmp(edid_info->header, "\x0\xff\xff\xff\xff\xff\xff\x0", 8))
+               return -1;
+
+       if (edid_info->version == 0xff && edid_info->revision == 0xff)
+               return -1;
+
+       return 0;
+}
+
+int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin,
+                   unsigned int *hmax, unsigned int *vmin,
+                   unsigned int *vmax)
+{
+       int i;
+       struct edid_monitor_descriptor *monitor;
+
+       *hmin = *hmax = *vmin = *vmax = 0;
+       if (edid_check_info(edid))
+               return -1;
+
+       for (i = 0; i < ARRAY_SIZE(edid->monitor_details.descriptor); i++) {
+               monitor = &edid->monitor_details.descriptor[i];
+               if (monitor->type == EDID_MONITOR_DESCRIPTOR_RANGE) {
+                       *hmin = monitor->data.range_data.horizontal_min;
+                       *hmax = monitor->data.range_data.horizontal_max;
+                       *vmin = monitor->data.range_data.vertical_min;
+                       *vmax = monitor->data.range_data.vertical_max;
+                       return 0;
+               }
+       }
+       return -1;
+}
+
+/**
+ * Snip the tailing whitespace/return of a string.
+ *
+ * @param string       The string to be snipped
+ * @return the snipped string
+ */
+static char *snip(char *string)
+{
+       char *s;
+
+       /*
+        * This is always a 13 character buffer
+        * and it's not always terminated.
+        */
+       string[12] = '\0';
+       s = &string[strlen(string) - 1];
+
+       while (s >= string && (isspace(*s) || *s == '\n' || *s == '\r' ||
+                       *s == '\0'))
+               *(s--) = '\0';
+
+       return string;
+}
+
+/**
+ * Print an EDID monitor descriptor block
+ *
+ * @param monitor      The EDID monitor descriptor block
+ * @have_timing                Modifies to 1 if the desciptor contains timing info
+ */
+static void edid_print_dtd(struct edid_monitor_descriptor *monitor,
+                          unsigned int *have_timing)
+{
+       unsigned char *bytes = (unsigned char *)monitor;
+       struct edid_detailed_timing *timing =
+                       (struct edid_detailed_timing *)monitor;
+
+       if (bytes[0] == 0 && bytes[1] == 0) {
+               if (monitor->type == EDID_MONITOR_DESCRIPTOR_SERIAL)
+                       printf("Monitor serial number: %s\n",
+                              snip(monitor->data.string));
+               else if (monitor->type == EDID_MONITOR_DESCRIPTOR_ASCII)
+                       printf("Monitor ID: %s\n",
+                              snip(monitor->data.string));
+               else if (monitor->type == EDID_MONITOR_DESCRIPTOR_NAME)
+                       printf("Monitor name: %s\n",
+                              snip(monitor->data.string));
+               else if (monitor->type == EDID_MONITOR_DESCRIPTOR_RANGE)
+                       printf("Monitor range limits, horizontal sync: "
+                              "%d-%d kHz, vertical refresh: "
+                              "%d-%d Hz, max pixel clock: "
+                              "%d MHz\n",
+                              monitor->data.range_data.horizontal_min,
+                              monitor->data.range_data.horizontal_max,
+                              monitor->data.range_data.vertical_min,
+                              monitor->data.range_data.vertical_max,
+                              monitor->data.range_data.pixel_clock_max * 10);
+       } else {
+               uint32_t pixclock, h_active, h_blanking, v_active, v_blanking;
+               uint32_t h_total, v_total, vfreq;
+
+               pixclock = EDID_DETAILED_TIMING_PIXEL_CLOCK(*timing);
+               h_active = EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(*timing);
+               h_blanking = EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(*timing);
+               v_active = EDID_DETAILED_TIMING_VERTICAL_ACTIVE(*timing);
+               v_blanking = EDID_DETAILED_TIMING_VERTICAL_BLANKING(*timing);
+
+               h_total = h_active + h_blanking;
+               v_total = v_active + v_blanking;
+               if (v_total * h_total)
+                       vfreq = pixclock / (v_total * h_total);
+               else
+                       vfreq = 1; /* Error case */
+               printf("\t%dx%d\%c\t%d Hz (detailed)\n", h_active,
+                      v_active, h_active > 1000 ? ' ' : '\t', vfreq);
+               *have_timing = 1;
+       }
+}
+
+/**
+ * Get the manufacturer name from an EDID info.
+ *
+ * @param edid_info     The EDID info to be printed
+ * @param name         Returns the string of the manufacturer name
+ */
+static void edid_get_manufacturer_name(struct edid1_info *edid, char *name)
+{
+       name[0] = EDID1_INFO_MANUFACTURER_NAME_CHAR1(*edid) + 'A' - 1;
+       name[1] = EDID1_INFO_MANUFACTURER_NAME_CHAR2(*edid) + 'A' - 1;
+       name[2] = EDID1_INFO_MANUFACTURER_NAME_CHAR3(*edid) + 'A' - 1;
+       name[3] = '\0';
+}
+
+void edid_print_info(struct edid1_info *edid_info)
+{
+       int i;
+       char manufacturer[4];
+       unsigned int have_timing = 0;
+       uint32_t serial_number;
+
+       if (edid_check_info(edid_info)) {
+               printf("Not a valid EDID\n");
+               return;
+       }
+
+       printf("EDID version: %d.%d\n",
+              edid_info->version, edid_info->revision);
+
+       printf("Product ID code: %04x\n", EDID1_INFO_PRODUCT_CODE(*edid_info));
+
+       edid_get_manufacturer_name(edid_info, manufacturer);
+       printf("Manufacturer: %s\n", manufacturer);
+
+       serial_number = EDID1_INFO_SERIAL_NUMBER(*edid_info);
+       if (serial_number != 0xffffffff) {
+               if (strcmp(manufacturer, "MAG") == 0)
+                       serial_number -= 0x7000000;
+               if (strcmp(manufacturer, "OQI") == 0)
+                       serial_number -= 456150000;
+               if (strcmp(manufacturer, "VSC") == 0)
+                       serial_number -= 640000000;
+       }
+       printf("Serial number: %08x\n", serial_number);
+       printf("Manufactured in week: %d year: %d\n",
+              edid_info->week, edid_info->year + 1990);
+
+       printf("Video input definition: %svoltage level %d%s%s%s%s%s\n",
+              EDID1_INFO_VIDEO_INPUT_DIGITAL(*edid_info) ?
+              "digital signal, " : "analog signal, ",
+              EDID1_INFO_VIDEO_INPUT_VOLTAGE_LEVEL(*edid_info),
+              EDID1_INFO_VIDEO_INPUT_BLANK_TO_BLACK(*edid_info) ?
+              ", blank to black" : "",
+              EDID1_INFO_VIDEO_INPUT_SEPARATE_SYNC(*edid_info) ?
+              ", separate sync" : "",
+              EDID1_INFO_VIDEO_INPUT_COMPOSITE_SYNC(*edid_info) ?
+              ", composite sync" : "",
+              EDID1_INFO_VIDEO_INPUT_SYNC_ON_GREEN(*edid_info) ?
+              ", sync on green" : "",
+              EDID1_INFO_VIDEO_INPUT_SERRATION_V(*edid_info) ?
+              ", serration v" : "");
+
+       printf("Monitor is %s\n",
+              EDID1_INFO_FEATURE_RGB(*edid_info) ? "RGB" : "non-RGB");
+
+       printf("Maximum visible display size: %d cm x %d cm\n",
+              edid_info->max_size_horizontal,
+              edid_info->max_size_vertical);
+
+       printf("Power management features: %s%s, %s%s, %s%s\n",
+              EDID1_INFO_FEATURE_ACTIVE_OFF(*edid_info) ?
+              "" : "no ", "active off",
+              EDID1_INFO_FEATURE_SUSPEND(*edid_info) ? "" : "no ", "suspend",
+              EDID1_INFO_FEATURE_STANDBY(*edid_info) ? "" : "no ", "standby");
+
+       printf("Estabilished timings:\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_720X400_70(*edid_info))
+               printf("\t720x400\t\t70 Hz (VGA 640x400, IBM)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_720X400_88(*edid_info))
+               printf("\t720x400\t\t88 Hz (XGA2)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_640X480_60(*edid_info))
+               printf("\t640x480\t\t60 Hz (VGA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_640X480_67(*edid_info))
+               printf("\t640x480\t\t67 Hz (Mac II, Apple)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_640X480_72(*edid_info))
+               printf("\t640x480\t\t72 Hz (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_640X480_75(*edid_info))
+               printf("\t640x480\t\t75 Hz (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_800X600_56(*edid_info))
+               printf("\t800x600\t\t56 Hz (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_800X600_60(*edid_info))
+               printf("\t800x600\t\t60 Hz (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_800X600_72(*edid_info))
+               printf("\t800x600\t\t72 Hz (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_800X600_75(*edid_info))
+               printf("\t800x600\t\t75 Hz (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_832X624_75(*edid_info))
+               printf("\t832x624\t\t75 Hz (Mac II)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_1024X768_87I(*edid_info))
+               printf("\t1024x768\t87 Hz Interlaced (8514A)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_1024X768_60(*edid_info))
+               printf("\t1024x768\t60 Hz (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_1024X768_70(*edid_info))
+               printf("\t1024x768\t70 Hz (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_1024X768_75(*edid_info))
+               printf("\t1024x768\t75 Hz (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_1280X1024_75(*edid_info))
+               printf("\t1280x1024\t75 (VESA)\n");
+       if (EDID1_INFO_ESTABLISHED_TIMING_1152X870_75(*edid_info))
+               printf("\t1152x870\t75 (Mac II)\n");
+
+       /* Standard timings. */
+       printf("Standard timings:\n");
+       for (i = 0; i < ARRAY_SIZE(edid_info->standard_timings); i++) {
+               unsigned int aspect = 10000;
+               unsigned int x, y;
+               unsigned char xres, vfreq;
+
+               xres = EDID1_INFO_STANDARD_TIMING_XRESOLUTION(*edid_info, i);
+               vfreq = EDID1_INFO_STANDARD_TIMING_VFREQ(*edid_info, i);
+               if ((xres != vfreq) ||
+                   ((xres != 0) && (xres != 1)) ||
+                   ((vfreq != 0) && (vfreq != 1))) {
+                       switch (EDID1_INFO_STANDARD_TIMING_ASPECT(*edid_info,
+                                       i)) {
+                       case ASPECT_625:
+                               aspect = 6250;
+                               break;
+                       case ASPECT_75:
+                               aspect = 7500;
+                               break;
+                       case ASPECT_8:
+                               aspect = 8000;
+                               break;
+                       case ASPECT_5625:
+                               aspect = 5625;
+                               break;
+                       }
+                       x = (xres + 31) * 8;
+                       y = x * aspect / 10000;
+                       printf("\t%dx%d%c\t%d Hz\n", x, y,
+                              x > 1000 ? ' ' : '\t', (vfreq & 0x3f) + 60);
+                       have_timing = 1;
+               }
+       }
+
+       /* Detailed timing information. */
+       for (i = 0; i < ARRAY_SIZE(edid_info->monitor_details.descriptor);
+                       i++) {
+               edid_print_dtd(&edid_info->monitor_details.descriptor[i],
+                              &have_timing);
+       }
+
+       if (!have_timing)
+               printf("\tNone\n");
+}
diff --git a/common/env_attr.c b/common/env_attr.c
new file mode 100644 (file)
index 0000000..210c98d
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * (C) Copyright 2012
+ * Joe Hershberger, National Instruments, joe.hershberger@ni.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
+ */
+
+#ifdef USE_HOSTCC /* Eliminate "ANSI does not permit..." warnings */
+#include <stdint.h>
+#include <stdio.h>
+#include <linux/linux_string.h>
+#else
+#include <common.h>
+#endif
+
+#include <env_attr.h>
+#include <errno.h>
+#include <linux/string.h>
+#include <malloc.h>
+
+/*
+ * Iterate through the whole list calling the callback for each found element.
+ * "attr_list" takes the form:
+ *     attributes = [^,:\s]*
+ *     entry = name[:attributes]
+ *     list = entry[,list]
+ */
+int env_attr_walk(const char *attr_list,
+       int (*callback)(const char *name, const char *attributes))
+{
+       const char *entry, *entry_end;
+       char *name, *attributes;
+
+       if (!attr_list)
+               /* list not found */
+               return 1;
+
+       entry = attr_list;
+       do {
+               char *entry_cpy = NULL;
+
+               entry_end = strchr(entry, ENV_ATTR_LIST_DELIM);
+               /* check if this is the last entry in the list */
+               if (entry_end == NULL) {
+                       int entry_len = strlen(entry);
+
+                       if (entry_len) {
+                               /*
+                                * allocate memory to copy the entry into since
+                                * we will need to inject '\0' chars and squash
+                                * white-space before calling the callback
+                                */
+                               entry_cpy = malloc(entry_len + 1);
+                               if (entry_cpy)
+                                       /* copy the rest of the list */
+                                       strcpy(entry_cpy, entry);
+                               else
+                                       return -ENOMEM;
+                       }
+               } else {
+                       int entry_len = entry_end - entry;
+
+                       if (entry_len) {
+                               /*
+                                * allocate memory to copy the entry into since
+                                * we will need to inject '\0' chars and squash
+                                * white-space before calling the callback
+                                */
+                               entry_cpy = malloc(entry_len + 1);
+                               if (entry_cpy) {
+                                       /* copy just this entry and null term */
+                                       strncpy(entry_cpy, entry, entry_len);
+                                       entry_cpy[entry_len] = '\0';
+                               } else
+                                       return -ENOMEM;
+                       }
+               }
+
+               /* check if there is anything to process (e.g. not ",,,") */
+               if (entry_cpy != NULL) {
+                       attributes = strchr(entry_cpy, ENV_ATTR_SEP);
+                       /* check if there is a ':' */
+                       if (attributes != NULL) {
+                               /* replace the ':' with '\0' to term name */
+                               *attributes++ = '\0';
+                               /* remove white-space from attributes */
+                               attributes = strim(attributes);
+                       }
+                       /* remove white-space from name */
+                       name = strim(entry_cpy);
+
+                       /* only call the callback if there is a name */
+                       if (strlen(name) != 0) {
+                               int retval = 0;
+
+                               retval = callback(name, attributes);
+                               if (retval) {
+                                       free(entry_cpy);
+                                       return retval;
+                               }
+                       }
+               }
+
+               free(entry_cpy);
+               entry = entry_end + 1;
+       } while (entry_end != NULL);
+
+       return 0;
+}
+
+/*
+ * Search for the last matching string in another string with the option to
+ * start looking at a certain point (i.e. ignore anything beyond that point).
+ */
+static char *reverse_strstr(const char *searched, const char *search_for,
+       const char *searched_start)
+{
+       char *result = NULL;
+
+       if (*search_for == '\0')
+               return (char *)searched;
+
+       for (;;) {
+               char *match = strstr(searched, search_for);
+
+               /*
+                * Stop looking if no new match is found or looking past the
+                * searched_start pointer
+                */
+               if (match == NULL || (searched_start != NULL &&
+                   match + strlen(search_for) > searched_start))
+                       break;
+
+               result = match;
+               searched = match + 1;
+       }
+
+       return result;
+}
+
+/*
+ * Retrieve the attributes string associated with a single name in the list
+ * There is no protection on attributes being too small for the value
+ */
+int env_attr_lookup(const char *attr_list, const char *name, char *attributes)
+{
+       const char *entry = NULL;
+
+       if (!attributes)
+               /* bad parameter */
+               return -1;
+       if (!attr_list)
+               /* list not found */
+               return 1;
+
+       entry = reverse_strstr(attr_list, name, NULL);
+       while (entry != NULL) {
+               const char *prevch = entry - 1;
+               const char *nextch = entry + strlen(name);
+
+               /* Skip spaces */
+               while (*prevch == ' ')
+                       prevch--;
+               while (*nextch == ' ')
+                       nextch++;
+
+               /* check for an exact match */
+               if ((entry == attr_list ||
+                    *prevch == ENV_ATTR_LIST_DELIM) &&
+                   (*nextch == ENV_ATTR_SEP ||
+                    *nextch == ENV_ATTR_LIST_DELIM ||
+                    *nextch == '\0'))
+                       break;
+
+               entry = reverse_strstr(attr_list, name, entry);
+       }
+       if (entry != NULL) {
+               int len;
+
+               /* skip the name */
+               entry += strlen(name);
+               /* skip spaces */
+               while (*entry == ' ')
+                       entry++;
+               if (*entry != ENV_ATTR_SEP)
+                       len = 0;
+               else {
+                       const char *delim;
+                       static const char delims[] = {
+                               ENV_ATTR_LIST_DELIM, ' ', '\0'};
+
+                       /* skip the attr sep */
+                       entry += 1;
+                       /* skip spaces */
+                       while (*entry == ' ')
+                               entry++;
+
+                       delim = strpbrk(entry, delims);
+                       if (delim == NULL)
+                               len = strlen(entry);
+                       else
+                               len = delim - entry;
+                       memcpy(attributes, entry, len);
+               }
+               attributes[len] = '\0';
+
+               /* success */
+               return 0;
+       }
+
+       /* not found in list */
+       return 2;
+}
diff --git a/common/env_callback.c b/common/env_callback.c
new file mode 100644 (file)
index 0000000..78ca367
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * (C) Copyright 2012
+ * Joe Hershberger, National Instruments, joe.hershberger@ni.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 <environment.h>
+
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+/*
+ * Look up a callback function pointer by name
+ */
+struct env_clbk_tbl *find_env_callback(const char *name)
+{
+       struct env_clbk_tbl *clbkp;
+       int i;
+       int num_callbacks = ll_entry_count(struct env_clbk_tbl, env_clbk);
+
+       if (name == NULL)
+               return NULL;
+
+       /* look up the callback in the linker-list */
+       for (i = 0, clbkp = ll_entry_start(struct env_clbk_tbl, env_clbk);
+            i < num_callbacks;
+            i++, clbkp++) {
+               if (strcmp(name, clbkp->name) == 0)
+                       return clbkp;
+       }
+
+       return NULL;
+}
+
+/*
+ * Look for a possible callback for a newly added variable
+ * This is called specifically when the variable did not exist in the hash
+ * previously, so the blanket update did not find this variable.
+ */
+void env_callback_init(ENTRY *var_entry)
+{
+       const char *var_name = var_entry->key;
+       const char *callback_list = getenv(ENV_CALLBACK_VAR);
+       char callback_name[256] = "";
+       struct env_clbk_tbl *clbkp;
+       int ret = 1;
+
+       /* look in the ".callbacks" var for a reference to this variable */
+       if (callback_list != NULL)
+               ret = env_attr_lookup(callback_list, var_name, callback_name);
+
+       /* only if not found there, look in the static list */
+       if (ret)
+               ret = env_attr_lookup(ENV_CALLBACK_LIST_STATIC, var_name,
+                       callback_name);
+
+       /* if an association was found, set the callback pointer */
+       if (!ret && strlen(callback_name)) {
+               clbkp = find_env_callback(callback_name);
+               if (clbkp != NULL)
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+                       var_entry->callback = clbkp->callback + gd->reloc_off;
+#else
+                       var_entry->callback = clbkp->callback;
+#endif
+       }
+}
+
+/*
+ * Called on each existing env var prior to the blanket update since removing
+ * a callback association should remove its callback.
+ */
+static int clear_callback(ENTRY *entry)
+{
+       entry->callback = NULL;
+
+       return 0;
+}
+
+/*
+ * Call for each element in the list that associates variables to callbacks
+ */
+static int set_callback(const char *name, const char *value)
+{
+       ENTRY e, *ep;
+       struct env_clbk_tbl *clbkp;
+
+       e.key   = name;
+       e.data  = NULL;
+       hsearch_r(e, FIND, &ep, &env_htab, 0);
+
+       /* does the env variable actually exist? */
+       if (ep != NULL) {
+               /* the assocaition delares no callback, so remove the pointer */
+               if (value == NULL || strlen(value) == 0)
+                       ep->callback = NULL;
+               else {
+                       /* assign the requested callback */
+                       clbkp = find_env_callback(value);
+                       if (clbkp != NULL)
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+                               ep->callback = clbkp->callback + gd->reloc_off;
+#else
+                               ep->callback = clbkp->callback;
+#endif
+               }
+       }
+
+       return 0;
+}
+
+static int on_callbacks(const char *name, const char *value, enum env_op op,
+       int flags)
+{
+       /* remove all callbacks */
+       hwalk_r(&env_htab, clear_callback);
+
+       /* configure any static callback bindings */
+       env_attr_walk(ENV_CALLBACK_LIST_STATIC, set_callback);
+       /* configure any dynamic callback bindings */
+       env_attr_walk(value, set_callback);
+
+       return 0;
+}
+U_BOOT_ENV_CALLBACK(callbacks, on_callbacks);
index 3d3cb70a6d60a21de660a20b260a20c447270ed9..906b41fccada86dc41d58d23ad42f74e7d5476b2 100644 (file)
@@ -40,7 +40,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #include <env_default.h>
 
 struct hsearch_data env_htab = {
-       .apply = env_check_apply,
+       .change_ok = env_flags_validate,
 };
 
 static uchar __env_get_char_spec(int index)
@@ -81,13 +81,42 @@ const uchar *env_get_addr(int index)
                return &default_environment[index];
 }
 
+/*
+ * Read an environment variable as a boolean
+ * Return -1 if variable does not exist (default to true)
+ */
+int getenv_yesno(const char *var)
+{
+       char *s = getenv(var);
+
+       if (s == NULL)
+               return -1;
+       return (*s == '1' || *s == 'y' || *s == 'Y' || *s == 't' || *s == 'T') ?
+               1 : 0;
+}
+
+/*
+ * Look up the variable from the default environment
+ */
+char *getenv_default(const char *name)
+{
+       char *ret_val;
+       unsigned long really_valid = gd->env_valid;
+       unsigned long real_gd_flags = gd->flags;
+
+       /* Pretend that the image is bad. */
+       gd->flags &= ~GD_FLG_ENV_READY;
+       gd->env_valid = 0;
+       ret_val = getenv(name);
+       gd->env_valid = really_valid;
+       gd->flags = real_gd_flags;
+       return ret_val;
+}
+
 void set_default_env(const char *s)
 {
-       /*
-        * By default, do not apply changes as they will eventually
-        * be applied by someone else
-        */
-       int do_apply = 0;
+       int flags = 0;
+
        if (sizeof(default_environment) > ENV_SIZE) {
                puts("*** Error - default environment is too large\n\n");
                return;
@@ -99,14 +128,7 @@ void set_default_env(const char *s)
                                "using default environment\n\n",
                                s + 1);
                } else {
-                       /*
-                        * This set_to_default was explicitly asked for
-                        * by the user, as opposed to being a recovery
-                        * mechanism.  Therefore we check every single
-                        * variable and apply changes to the system
-                        * right away (e.g. baudrate, console).
-                        */
-                       do_apply = 1;
+                       flags = H_INTERACTIVE;
                        puts(s);
                }
        } else {
@@ -114,8 +136,8 @@ void set_default_env(const char *s)
        }
 
        if (himport_r(&env_htab, (char *)default_environment,
-                       sizeof(default_environment), '\0', 0,
-                       0, NULL, do_apply) == 0)
+                       sizeof(default_environment), '\0', flags,
+                       0, NULL) == 0)
                error("Environment import failed: errno = %d\n", errno);
 
        gd->flags |= GD_FLG_ENV_READY;
@@ -130,8 +152,8 @@ int set_default_vars(int nvars, char * const vars[])
         * (and use \0 as a separator)
         */
        return himport_r(&env_htab, (const char *)default_environment,
-                               sizeof(default_environment), '\0', H_NOCLEAR,
-                               nvars, vars, 1 /* do_apply */);
+                               sizeof(default_environment), '\0',
+                               H_NOCLEAR | H_INTERACTIVE, nvars, vars);
 }
 
 #ifndef CONFIG_SPL_BUILD
@@ -155,7 +177,7 @@ int env_import(const char *buf, int check)
        }
 
        if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0,
-                       0, NULL, 0 /* do_apply */)) {
+                       0, NULL)) {
                gd->flags |= GD_FLG_ENV_READY;
                return 1;
        }
@@ -172,6 +194,7 @@ void env_relocate(void)
 {
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
        env_reloc();
+       env_htab.change_ok += gd->reloc_off;
 #endif
        if (gd->env_valid == 0) {
 #if defined(CONFIG_ENV_IS_NOWHERE) || defined(CONFIG_SPL_BUILD)
index 3c5af37bf50c290afb33f111b945d539926bf0dd..38c96157b9fa66a41c53c6722cbab2127565c84e 100644 (file)
@@ -60,7 +60,7 @@ int saveenv(void)
        char    *res;
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
index b66bba29f53fd53251abab1dc724e88c26ff15b5..45c935b6df7895844ae9914e01b69ffe6fa2333e 100644 (file)
@@ -139,7 +139,7 @@ int saveenv(void)
        BUG_ON(env_ptr != NULL);
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
index 6ef531821e015788a605836fe608077c70d17d9c..c0f18ab97dfde66b32a8a8cb7fe7437fcdfa3410 100644 (file)
@@ -61,7 +61,7 @@ int saveenv(void)
        int err;
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
diff --git a/common/env_flags.c b/common/env_flags.c
new file mode 100644 (file)
index 0000000..336cae4
--- /dev/null
@@ -0,0 +1,560 @@
+/*
+ * (C) Copyright 2012
+ * Joe Hershberger, National Instruments, joe.hershberger@ni.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 <linux/string.h>
+#include <linux/ctype.h>
+
+#ifdef USE_HOSTCC /* Eliminate "ANSI does not permit..." warnings */
+#include <stdint.h>
+#include <stdio.h>
+#include "fw_env.h"
+#include <env_attr.h>
+#include <env_flags.h>
+#define getenv fw_getenv
+#else
+#include <common.h>
+#include <environment.h>
+#endif
+
+#ifdef CONFIG_CMD_NET
+#define ENV_FLAGS_NET_VARTYPE_REPS "im"
+#else
+#define ENV_FLAGS_NET_VARTYPE_REPS ""
+#endif
+
+static const char env_flags_vartype_rep[] = "sdxb" ENV_FLAGS_NET_VARTYPE_REPS;
+static const char env_flags_varaccess_rep[] = "aroc";
+static const int env_flags_varaccess_mask[] = {
+       0,
+       ENV_FLAGS_VARACCESS_PREVENT_DELETE |
+               ENV_FLAGS_VARACCESS_PREVENT_CREATE |
+               ENV_FLAGS_VARACCESS_PREVENT_OVERWR,
+       ENV_FLAGS_VARACCESS_PREVENT_DELETE |
+               ENV_FLAGS_VARACCESS_PREVENT_OVERWR,
+       ENV_FLAGS_VARACCESS_PREVENT_DELETE |
+               ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR};
+
+#ifdef CONFIG_CMD_ENV_FLAGS
+static const char * const env_flags_vartype_names[] = {
+       "string",
+       "decimal",
+       "hexadecimal",
+       "boolean",
+#ifdef CONFIG_CMD_NET
+       "IP address",
+       "MAC address",
+#endif
+};
+static const char * const env_flags_varaccess_names[] = {
+       "any",
+       "read-only",
+       "write-once",
+       "change-default",
+};
+
+/*
+ * Print the whole list of available type flags.
+ */
+void env_flags_print_vartypes(void)
+{
+       enum env_flags_vartype curtype = (enum env_flags_vartype)0;
+
+       while (curtype != env_flags_vartype_end) {
+               printf("\t%c   -\t%s\n", env_flags_vartype_rep[curtype],
+                       env_flags_vartype_names[curtype]);
+               curtype++;
+       }
+}
+
+/*
+ * Print the whole list of available access flags.
+ */
+void env_flags_print_varaccess(void)
+{
+       enum env_flags_varaccess curaccess = (enum env_flags_varaccess)0;
+
+       while (curaccess != env_flags_varaccess_end) {
+               printf("\t%c   -\t%s\n", env_flags_varaccess_rep[curaccess],
+                       env_flags_varaccess_names[curaccess]);
+               curaccess++;
+       }
+}
+
+/*
+ * Return the name of the type.
+ */
+const char *env_flags_get_vartype_name(enum env_flags_vartype type)
+{
+       return env_flags_vartype_names[type];
+}
+
+/*
+ * Return the name of the access.
+ */
+const char *env_flags_get_varaccess_name(enum env_flags_varaccess access)
+{
+       return env_flags_varaccess_names[access];
+}
+#endif /* CONFIG_CMD_ENV_FLAGS */
+
+/*
+ * Parse the flags string from a .flags attribute list into the vartype enum.
+ */
+enum env_flags_vartype env_flags_parse_vartype(const char *flags)
+{
+       char *type;
+
+       if (strlen(flags) <= ENV_FLAGS_VARTYPE_LOC)
+               return env_flags_vartype_string;
+
+       type = strchr(env_flags_vartype_rep,
+               flags[ENV_FLAGS_VARTYPE_LOC]);
+
+       if (type != NULL)
+               return (enum env_flags_vartype)
+                       (type - &env_flags_vartype_rep[0]);
+
+       printf("## Warning: Unknown environment variable type '%c'\n",
+               flags[ENV_FLAGS_VARTYPE_LOC]);
+       return env_flags_vartype_string;
+}
+
+/*
+ * Parse the flags string from a .flags attribute list into the varaccess enum.
+ */
+enum env_flags_varaccess env_flags_parse_varaccess(const char *flags)
+{
+       char *access;
+
+       if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
+               return env_flags_varaccess_any;
+
+       access = strchr(env_flags_varaccess_rep,
+               flags[ENV_FLAGS_VARACCESS_LOC]);
+
+       if (access != NULL)
+               return (enum env_flags_varaccess)
+                       (access - &env_flags_varaccess_rep[0]);
+
+       printf("## Warning: Unknown environment variable access method '%c'\n",
+               flags[ENV_FLAGS_VARACCESS_LOC]);
+       return env_flags_varaccess_any;
+}
+
+/*
+ * Parse the binary flags from a hash table entry into the varaccess enum.
+ */
+enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags)
+{
+       int i;
+
+       for (i = 0; i < sizeof(env_flags_varaccess_mask); i++)
+               if (env_flags_varaccess_mask[i] ==
+                   (binflags & ENV_FLAGS_VARACCESS_BIN_MASK))
+                       return (enum env_flags_varaccess)i;
+
+       printf("Warning: Non-standard access flags. (0x%x)\n",
+               binflags & ENV_FLAGS_VARACCESS_BIN_MASK);
+
+       return env_flags_varaccess_any;
+}
+
+static inline int is_hex_prefix(const char *value)
+{
+       return value[0] == '0' && (value[1] == 'x' || value[1] == 'X');
+}
+
+static void skip_num(int hex, const char *value, const char **end,
+       int max_digits)
+{
+       int i;
+
+       if (hex && is_hex_prefix(value))
+               value += 2;
+
+       for (i = max_digits; i != 0; i--) {
+               if (hex && !isxdigit(*value))
+                       break;
+               if (!hex && !isdigit(*value))
+                       break;
+               value++;
+       }
+       if (end != NULL)
+               *end = value;
+}
+
+/*
+ * Based on the declared type enum, validate that the value string complies
+ * with that format
+ */
+static int _env_flags_validate_type(const char *value,
+       enum env_flags_vartype type)
+{
+       const char *end;
+#ifdef CONFIG_CMD_NET
+       const char *cur;
+       int i;
+#endif
+
+       switch (type) {
+       case env_flags_vartype_string:
+               break;
+       case env_flags_vartype_decimal:
+               skip_num(0, value, &end, -1);
+               if (*end != '\0')
+                       return -1;
+               break;
+       case env_flags_vartype_hex:
+               skip_num(1, value, &end, -1);
+               if (*end != '\0')
+                       return -1;
+               if (value + 2 == end && is_hex_prefix(value))
+                       return -1;
+               break;
+       case env_flags_vartype_bool:
+               if (value[0] != '1' && value[0] != 'y' && value[0] != 't' &&
+                   value[0] != 'Y' && value[0] != 'T' &&
+                   value[0] != '0' && value[0] != 'n' && value[0] != 'f' &&
+                   value[0] != 'N' && value[0] != 'F')
+                       return -1;
+               if (value[1] != '\0')
+                       return -1;
+               break;
+#ifdef CONFIG_CMD_NET
+       case env_flags_vartype_ipaddr:
+               cur = value;
+               for (i = 0; i < 4; i++) {
+                       skip_num(0, cur, &end, 3);
+                       if (cur == end)
+                               return -1;
+                       if (i != 3 && *end != '.')
+                               return -1;
+                       if (i == 3 && *end != '\0')
+                               return -1;
+                       cur = end + 1;
+               }
+               break;
+       case env_flags_vartype_macaddr:
+               cur = value;
+               for (i = 0; i < 6; i++) {
+                       skip_num(1, cur, &end, 2);
+                       if (cur == end)
+                               return -1;
+                       if (cur + 2 == end && is_hex_prefix(cur))
+                               return -1;
+                       if (i != 5 && *end != ':')
+                               return -1;
+                       if (i == 5 && *end != '\0')
+                               return -1;
+                       cur = end + 1;
+               }
+               break;
+#endif
+       case env_flags_vartype_end:
+               return -1;
+       }
+
+       /* OK */
+       return 0;
+}
+
+/*
+ * Look for flags in a provided list and failing that the static list
+ */
+static inline int env_flags_lookup(const char *flags_list, const char *name,
+       char *flags)
+{
+       int ret = 1;
+
+       if (!flags)
+               /* bad parameter */
+               return -1;
+
+       /* try the env first */
+       if (flags_list)
+               ret = env_attr_lookup(flags_list, name, flags);
+
+       if (ret != 0)
+               /* if not found in the env, look in the static list */
+               ret = env_attr_lookup(ENV_FLAGS_LIST_STATIC, name, flags);
+
+       return ret;
+}
+
+#ifdef USE_HOSTCC /* Functions only used from tools/env */
+/*
+ * Look up any flags directly from the .flags variable and the static list
+ * and convert them to the vartype enum.
+ */
+enum env_flags_vartype env_flags_get_type(const char *name)
+{
+       const char *flags_list = getenv(ENV_FLAGS_VAR);
+       char flags[ENV_FLAGS_ATTR_MAX_LEN + 1];
+
+       if (env_flags_lookup(flags_list, name, flags))
+               return env_flags_vartype_string;
+
+       if (strlen(flags) <= ENV_FLAGS_VARTYPE_LOC)
+               return env_flags_vartype_string;
+
+       return env_flags_parse_vartype(flags);
+}
+
+/*
+ * Look up the access of a variable directly from the .flags var.
+ */
+enum env_flags_varaccess env_flags_get_varaccess(const char *name)
+{
+       const char *flags_list = getenv(ENV_FLAGS_VAR);
+       char flags[ENV_FLAGS_ATTR_MAX_LEN + 1];
+
+       if (env_flags_lookup(flags_list, name, flags))
+               return env_flags_varaccess_any;
+
+       if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
+               return env_flags_varaccess_any;
+
+       return env_flags_parse_varaccess(flags);
+}
+
+/*
+ * Validate that the proposed new value for "name" is valid according to the
+ * defined flags for that variable, if any.
+ */
+int env_flags_validate_type(const char *name, const char *value)
+{
+       enum env_flags_vartype type;
+
+       if (value == NULL)
+               return 0;
+       type = env_flags_get_type(name);
+       if (_env_flags_validate_type(value, type) < 0) {
+               printf("## Error: flags type check failure for "
+                       "\"%s\" <= \"%s\" (type: %c)\n",
+                       name, value, env_flags_vartype_rep[type]);
+               return -1;
+       }
+       return 0;
+}
+
+/*
+ * Validate that the proposed access to variable "name" is valid according to
+ * the defined flags for that variable, if any.
+ */
+int env_flags_validate_varaccess(const char *name, int check_mask)
+{
+       enum env_flags_varaccess access;
+       int access_mask;
+
+       access = env_flags_get_varaccess(name);
+       access_mask = env_flags_varaccess_mask[access];
+
+       return (check_mask & access_mask) != 0;
+}
+
+/*
+ * Validate the parameters to "env set" directly
+ */
+int env_flags_validate_env_set_params(int argc, char * const argv[])
+{
+       if ((argc >= 3) && argv[2] != NULL) {
+               enum env_flags_vartype type = env_flags_get_type(argv[1]);
+
+               /*
+                * we don't currently check types that need more than
+                * one argument
+                */
+               if (type != env_flags_vartype_string && argc > 3) {
+                       printf("## Error: too many parameters for setting "
+                               "\"%s\"\n", argv[1]);
+                       return -1;
+               }
+               return env_flags_validate_type(argv[1], argv[2]);
+       }
+       /* ok */
+       return 0;
+}
+
+#else /* !USE_HOSTCC - Functions only used from lib/hashtable.c */
+
+/*
+ * Parse the flag charachters from the .flags attribute list into the binary
+ * form to be stored in the environment entry->flags field.
+ */
+static int env_parse_flags_to_bin(const char *flags)
+{
+       int binflags;
+
+       binflags = env_flags_parse_vartype(flags) & ENV_FLAGS_VARTYPE_BIN_MASK;
+       binflags |= env_flags_varaccess_mask[env_flags_parse_varaccess(flags)];
+
+       return binflags;
+}
+
+/*
+ * Look for possible flags for a newly added variable
+ * This is called specifically when the variable did not exist in the hash
+ * previously, so the blanket update did not find this variable.
+ */
+void env_flags_init(ENTRY *var_entry)
+{
+       const char *var_name = var_entry->key;
+       const char *flags_list = getenv(ENV_FLAGS_VAR);
+       char flags[ENV_FLAGS_ATTR_MAX_LEN + 1] = "";
+       int ret = 1;
+
+       /* look in the ".flags" and static for a reference to this variable */
+       ret = env_flags_lookup(flags_list, var_name, flags);
+
+       /* if any flags were found, set the binary form to the entry */
+       if (!ret && strlen(flags))
+               var_entry->flags = env_parse_flags_to_bin(flags);
+}
+
+/*
+ * Called on each existing env var prior to the blanket update since removing
+ * a flag in the flag list should remove its flags.
+ */
+static int clear_flags(ENTRY *entry)
+{
+       entry->flags = 0;
+
+       return 0;
+}
+
+/*
+ * Call for each element in the list that defines flags for a variable
+ */
+static int set_flags(const char *name, const char *value)
+{
+       ENTRY e, *ep;
+
+       e.key   = name;
+       e.data  = NULL;
+       hsearch_r(e, FIND, &ep, &env_htab, 0);
+
+       /* does the env variable actually exist? */
+       if (ep != NULL) {
+               /* the flag list is empty, so clear the flags */
+               if (value == NULL || strlen(value) == 0)
+                       ep->flags = 0;
+               else
+                       /* assign the requested flags */
+                       ep->flags = env_parse_flags_to_bin(value);
+       }
+
+       return 0;
+}
+
+static int on_flags(const char *name, const char *value, enum env_op op,
+       int flags)
+{
+       /* remove all flags */
+       hwalk_r(&env_htab, clear_flags);
+
+       /* configure any static flags */
+       env_attr_walk(ENV_FLAGS_LIST_STATIC, set_flags);
+       /* configure any dynamic flags */
+       env_attr_walk(value, set_flags);
+
+       return 0;
+}
+U_BOOT_ENV_CALLBACK(flags, on_flags);
+
+/*
+ * Perform consistency checking before creating, overwriting, or deleting an
+ * environment variable. Called as a callback function by hsearch_r() and
+ * hdelete_r(). Returns 0 in case of success, 1 in case of failure.
+ * When (flag & H_FORCE) is set, do not print out any error message and force
+ * overwriting of write-once variables.
+ */
+
+int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op,
+       int flag)
+{
+       const char *name;
+       const char *oldval = NULL;
+
+       if (op != env_op_create)
+               oldval = item->data;
+
+       name = item->key;
+
+       /* Default value for NULL to protect string-manipulating functions */
+       newval = newval ? : "";
+
+       /* validate the value to match the variable type */
+       if (op != env_op_delete) {
+               enum env_flags_vartype type = (enum env_flags_vartype)
+                       (ENV_FLAGS_VARTYPE_BIN_MASK & item->flags);
+
+               if (_env_flags_validate_type(newval, type) < 0) {
+                       printf("## Error: flags type check failure for "
+                               "\"%s\" <= \"%s\" (type: %c)\n",
+                               name, newval, env_flags_vartype_rep[type]);
+                       return -1;
+               }
+       }
+
+       /* check for access permission */
+#ifndef CONFIG_ENV_ACCESS_IGNORE_FORCE
+       if (flag & H_FORCE)
+               return 0;
+#endif
+       switch (op) {
+       case env_op_delete:
+               if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_DELETE) {
+                       printf("## Error: Can't delete \"%s\"\n", name);
+                       return 1;
+               }
+               break;
+       case env_op_overwrite:
+               if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_OVERWR) {
+                       printf("## Error: Can't overwrite \"%s\"\n", name);
+                       return 1;
+               } else if (item->flags &
+                   ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR) {
+                       const char *defval = getenv_default(name);
+
+                       if (defval == NULL)
+                               defval = "";
+                       printf("oldval: %s  defval: %s\n", oldval, defval);
+                       if (strcmp(oldval, defval) != 0) {
+                               printf("## Error: Can't overwrite \"%s\"\n",
+                                       name);
+                               return 1;
+                       }
+               }
+               break;
+       case env_op_create:
+               if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_CREATE) {
+                       printf("## Error: Can't create \"%s\"\n", name);
+                       return 1;
+               }
+               break;
+       }
+
+       return 0;
+}
+
+#endif
index aa970d44007a18d2fd8d1a4a26acd3d362bcb626..e07d336a48b9940bc0987255554f68ff27fd52cd 100644 (file)
@@ -142,7 +142,7 @@ int saveenv(void)
                goto done;
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                goto done;
@@ -275,7 +275,7 @@ int saveenv(void)
                goto done;
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                goto done;
index a2ff90bf485eeb4d47b02a8e22865b7fec381ad3..ce2167121004303ac4972f64cd31db37d16c6ccd 100644 (file)
@@ -130,7 +130,7 @@ int saveenv(void)
        }
 
        res = (char *)&env_new->data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                ret = 1;
index 79e803370505dd8e996621d56757e44690817662..22e72a20b07b74ce8552a31e2d02b4b619d9fe6e 100644 (file)
@@ -186,7 +186,7 @@ int saveenv(void)
                return 1;
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
@@ -239,7 +239,7 @@ int saveenv(void)
                return 1;
 
        res = (char *)&env_new->data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
index 6483db39d3388fc672985d0fde867ade43b55b5a..eab0e7be0ecb90bc11f842dbe521e3df3c60f9dc 100644 (file)
@@ -90,7 +90,7 @@ int saveenv(void)
        int     rcode = 0;
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
index da35071251f8941861392afdd0963e9a097b6243..faa903d2f0251cd2459daef22d6d6514124dc86c 100644 (file)
@@ -95,7 +95,7 @@ int saveenv(void)
        };
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
index bbd472fcf281eb2340ab3fe65b8c73c4506556ba..d9e9085461bb6759b0b0ee0cc2f717d6653ede99 100644 (file)
@@ -79,7 +79,7 @@ int saveenv(void)
        }
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                return 1;
@@ -277,7 +277,7 @@ int saveenv(void)
        }
 
        res = (char *)&env_new.data;
-       len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+       len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
        if (len < 0) {
                error("Cannot export environment: errno = %d\n", errno);
                goto done;
index 963ea90234699c29ad19eb0d8f855513a70539b0..6b9fa0550f18e5694cd9f1e83911c52c089920d8 100644 (file)
@@ -1315,7 +1315,7 @@ int fdt_set_status_by_alias(void *fdt, const char* alias,
        return fdt_set_node_status(fdt, offset, status, error_code);
 }
 
-#if defined(CONFIG_VIDEO)
+#if defined(CONFIG_VIDEO) || defined(CONFIG_LCD)
 int fdt_add_edid(void *blob, const char *compat, unsigned char *edid_buf)
 {
        int noff;
diff --git a/common/hash.c b/common/hash.c
new file mode 100644 (file)
index 0000000..e3a6e43
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * (C) Copyright 2011
+ * Joe Hershberger, National Instruments, joe.hershberger@ni.com
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <hash.h>
+#include <sha1.h>
+#include <sha256.h>
+
+/*
+ * These are the hash algorithms we support. Chips which support accelerated
+ * crypto could perhaps add named version of these algorithms here.
+ */
+static struct hash_algo hash_algo[] = {
+#ifdef CONFIG_SHA1
+       {
+               "SHA1",
+               SHA1_SUM_LEN,
+               sha1_csum_wd,
+               CHUNKSZ_SHA1,
+       },
+#endif
+#ifdef CONFIG_SHA256
+       {
+               "SHA256",
+               SHA256_SUM_LEN,
+               sha256_csum_wd,
+               CHUNKSZ_SHA256,
+       },
+#endif
+};
+
+/**
+ * store_result: Store the resulting sum to an address or variable
+ *
+ * @algo:              Hash algorithm being used
+ * @sum:               Hash digest (algo->digest_size bytes)
+ * @dest:              Destination, interpreted as a hex address if it starts
+ *                     with * or otherwise as an environment variable.
+ */
+static void store_result(struct hash_algo *algo, const u8 *sum,
+                        const char *dest)
+{
+       unsigned int i;
+
+       if (*dest == '*') {
+               u8 *ptr;
+
+               ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16);
+               memcpy(ptr, sum, algo->digest_size);
+       } else {
+               char str_output[HASH_MAX_DIGEST_SIZE * 2 + 1];
+               char *str_ptr = str_output;
+
+               for (i = 0; i < algo->digest_size; i++) {
+                       sprintf(str_ptr, "%02x", sum[i]);
+                       str_ptr += 2;
+               }
+               str_ptr = '\0';
+               setenv(dest, str_output);
+       }
+}
+
+/**
+ * parse_verify_sum: Parse a hash verification parameter
+ *
+ * @algo:              Hash algorithm being used
+ * @verify_str:                Argument to parse. If it starts with * then it is
+ *                     interpreted as a hex address containing the hash.
+ *                     If the length is exactly the right number of hex digits
+ *                     for the digest size, then we assume it is a hex digest.
+ *                     Otherwise we assume it is an environment variable, and
+ *                     look up its value (it must contain a hex digest).
+ * @vsum:              Returns binary digest value (algo->digest_size bytes)
+ * @return 0 if ok, non-zero on error
+ */
+static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum)
+{
+       if (*verify_str == '*') {
+               u8 *ptr;
+
+               ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16);
+               memcpy(vsum, ptr, algo->digest_size);
+       } else {
+               unsigned int i;
+               char *vsum_str;
+               int digits = algo->digest_size * 2;
+
+               /*
+                * As with the original code from sha1sum.c, we assume that a
+                * string which matches the digest size exactly is a hex
+                * string and not an environment variable.
+                */
+               if (strlen(verify_str) == digits)
+                       vsum_str = verify_str;
+               else {
+                       vsum_str = getenv(verify_str);
+                       if (vsum_str == NULL || strlen(vsum_str) != digits) {
+                               printf("Expected %d hex digits in env var\n",
+                                      digits);
+                               return 1;
+                       }
+               }
+
+               for (i = 0; i < algo->digest_size; i++) {
+                       char *nullp = vsum_str + (i + 1) * 2;
+                       char end = *nullp;
+
+                       *nullp = '\0';
+                       vsum[i] = simple_strtoul(vsum_str + (i * 2), NULL, 16);
+                       *nullp = end;
+               }
+       }
+       return 0;
+}
+
+static struct hash_algo *find_hash_algo(const char *name)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
+               if (!strcasecmp(name, hash_algo[i].name))
+                       return &hash_algo[i];
+       }
+
+       return NULL;
+}
+
+static void show_hash(struct hash_algo *algo, ulong addr, ulong len,
+                     u8 *output)
+{
+       int i;
+
+       printf("%s for %08lx ... %08lx ==> ", algo->name, addr, addr + len - 1);
+       for (i = 0; i < algo->digest_size; i++)
+               printf("%02x", output[i]);
+}
+
+int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag,
+                int argc, char * const argv[])
+{
+       struct hash_algo *algo;
+       ulong addr, len;
+       u8 output[HASH_MAX_DIGEST_SIZE];
+       u8 vsum[HASH_MAX_DIGEST_SIZE];
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       algo = find_hash_algo(algo_name);
+       if (!algo) {
+               printf("Unknown hash algorithm '%s'\n", algo_name);
+               return CMD_RET_USAGE;
+       }
+       addr = simple_strtoul(*argv++, NULL, 16);
+       len = simple_strtoul(*argv++, NULL, 16);
+       argc -= 2;
+
+       if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
+               puts("HASH_MAX_DIGEST_SIZE exceeded\n");
+               return 1;
+       }
+
+       algo->hash_func_ws((const unsigned char *)addr, len, output,
+                          algo->chunk_size);
+
+       /* Try to avoid code bloat when verify is not needed */
+#ifdef CONFIG_HASH_VERIFY
+       if (verify) {
+#else
+       if (0) {
+#endif
+               if (!argc)
+                       return CMD_RET_USAGE;
+               if (parse_verify_sum(algo, *argv, vsum)) {
+                       printf("ERROR: %s does not contain a valid %s sum\n",
+                               *argv, algo->name);
+                       return 1;
+               }
+               if (memcmp(output, vsum, algo->digest_size) != 0) {
+                       int i;
+
+                       show_hash(algo, addr, len, output);
+                       printf(" != ");
+                       for (i = 0; i < algo->digest_size; i++)
+                               printf("%02x", vsum[i]);
+                       puts(" ** ERROR **\n");
+                       return 1;
+               }
+       } else {
+               show_hash(algo, addr, len, output);
+               printf("\n");
+
+               if (argc)
+                       store_result(algo, output, *argv);
+       }
+
+       return 0;
+}
index df642e656ca23271ff1fa05b0afd3b8c1e50090a..95498e6186e2290cc79a6cb1c9ac84b446b3a6fb 100644 (file)
@@ -43,6 +43,7 @@
 #include <rtc.h>
 #endif
 
+#include <environment.h>
 #include <image.h>
 
 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
@@ -416,11 +417,25 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
 /* Shared dual-format routines */
 /*****************************************************************************/
 #ifndef USE_HOSTCC
-int getenv_yesno(char *var)
+ulong load_addr = CONFIG_SYS_LOAD_ADDR;        /* Default Load Address */
+ulong save_addr;                       /* Default Save Address */
+ulong save_size;                       /* Default Save Size (in bytes) */
+
+static int on_loadaddr(const char *name, const char *value, enum env_op op,
+       int flags)
 {
-       char *s = getenv(var);
-       return (s && (*s == 'n')) ? 0 : 1;
+       switch (op) {
+       case env_op_create:
+       case env_op_overwrite:
+               load_addr = simple_strtoul(value, NULL, 16);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
 }
+U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr);
 
 ulong getenv_bootm_low(void)
 {
@@ -3049,6 +3064,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 3017604734bb27ce9d5057bafd3f0ee8033584be..4778655a26ae1982223be91014d957eee22164d6 100644 (file)
@@ -696,6 +696,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
@@ -729,7 +861,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;
@@ -816,7 +948,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);
@@ -835,6 +967,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
@@ -850,7 +994,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;
@@ -862,7 +1006,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;
@@ -940,5 +1084,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 5fdfff2e28587eeb37adccda828d542d737e985d..5d8454ea0e5a6407882e4b0e06a27426270036f2 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;
@@ -299,6 +376,8 @@ void main_loop (void)
        char bcs_set[16];
 #endif /* CONFIG_BOOTCOUNT_LIMIT */
 
+       bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
+
 #ifdef CONFIG_BOOTCOUNT_LIMIT
        bootcount = bootcount_load();
        bootcount++;
@@ -380,6 +459,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 +500,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..97ff9cf4a6a49f533f90240e9469bd4063986a11 100644 (file)
@@ -135,7 +135,6 @@ struct stdio_dev* stdio_clone(struct stdio_dev *dev)
                return NULL;
 
        memcpy(_dev, dev, sizeof(struct stdio_dev));
-       strncpy(_dev->name, dev->name, 16);
 
        return _dev;
 }
@@ -237,6 +236,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 a3873cebb33712d2ad016eb522eff8d6427b2096..76650173309624ed21eaa98a2b7a0dd3b7ef2fe3 100644 (file)
 #include <command.h>
 #include <ide.h>
 #include <malloc.h>
-#include "part_efi.h"
+#include <part_efi.h>
 #include <linux/ctype.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #if defined(CONFIG_CMD_IDE) || \
     defined(CONFIG_CMD_SATA) || \
     defined(CONFIG_CMD_SCSI) || \
     defined(CONFIG_MMC) || \
     defined(CONFIG_SYSTEMACE)
 
-/* Convert char[2] in little endian format to the host format integer
- */
-static inline unsigned short le16_to_int(unsigned char *le16)
-{
-       return ((le16[1] << 8) + le16[0]);
-}
-
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned long le32_to_int(unsigned char *le32)
-{
-       return ((le32[3] << 24) + (le32[2] << 16) + (le32[1] << 8) + le32[0]);
-}
-
-/* Convert char[8] in little endian format to the host format integer
- */
-static inline unsigned long long le64_to_int(unsigned char *le64)
-{
-       return (((unsigned long long)le64[7] << 56) +
-               ((unsigned long long)le64[6] << 48) +
-               ((unsigned long long)le64[5] << 40) +
-               ((unsigned long long)le64[4] << 32) +
-               ((unsigned long long)le64[3] << 24) +
-               ((unsigned long long)le64[2] << 16) +
-               ((unsigned long long)le64[1] << 8) +
-               (unsigned long long)le64[0]);
-}
-
 /**
  * efi_crc32() - EFI version of crc32 function
  * @buf: buffer to calculate crc32 of
@@ -79,7 +53,7 @@ static inline unsigned long long le64_to_int(unsigned char *le64)
  *
  * Description: Returns EFI-style CRC32 value for @buf
  */
-static inline unsigned long efi_crc32(const void *buf, unsigned long len)
+static inline u32 efi_crc32(const void *buf, u32 len)
 {
        return crc32(0, buf, len);
 }
@@ -90,13 +64,10 @@ static inline unsigned long efi_crc32(const void *buf, unsigned long len)
 
 static int pmbr_part_valid(struct partition *part);
 static int is_pmbr_valid(legacy_mbr * mbr);
-
 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
                                gpt_header * pgpt_head, gpt_entry ** pgpt_pte);
-
 static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
                                gpt_header * pgpt_head);
-
 static int is_pte_valid(gpt_entry * pte);
 
 static char *print_efiname(gpt_entry *pte)
@@ -142,6 +113,7 @@ static inline int is_bootable(gpt_entry *p)
                        sizeof(efi_guid_t));
 }
 
+#ifdef CONFIG_EFI_PARTITION
 /*
  * Public Functions (include/part.h)
  */
@@ -171,14 +143,14 @@ void print_part_efi(block_dev_desc_t * dev_desc)
        printf("\tType UUID\n");
        printf("\tPartition UUID\n");
 
-       for (i = 0; i < le32_to_int(gpt_head->num_partition_entries); i++) {
+       for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
                /* Stop at the first non valid PTE */
                if (!is_pte_valid(&gpt_pte[i]))
                        break;
 
                printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1),
-                       le64_to_int(gpt_pte[i].starting_lba),
-                       le64_to_int(gpt_pte[i].ending_lba),
+                       le64_to_cpu(gpt_pte[i].starting_lba),
+                       le64_to_cpu(gpt_pte[i].ending_lba),
                        print_efiname(&gpt_pte[i]));
                printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw);
                uuid_string(gpt_pte[i].partition_type_guid.b, uuid);
@@ -211,7 +183,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
                return -1;
        }
 
-       if (part > le32_to_int(gpt_head->num_partition_entries) ||
+       if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
            !is_pte_valid(&gpt_pte[part - 1])) {
                printf("%s: *** ERROR: Invalid partition number %d ***\n",
                        __func__, part);
@@ -219,9 +191,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
        }
 
        /* The ulong casting limits the maximum disk size to 2 TB */
-       info->start = (ulong) le64_to_int(gpt_pte[part - 1].starting_lba);
+       info->start = (u64)le64_to_cpu(gpt_pte[part - 1].starting_lba);
        /* The ending LBA is inclusive, to calculate size, add 1 to it */
-       info->size = ((ulong)le64_to_int(gpt_pte[part - 1].ending_lba) + 1)
+       info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
                     - info->start;
        info->blksz = GPT_BLOCK_SIZE;
 
@@ -253,6 +225,281 @@ int test_part_efi(block_dev_desc_t * dev_desc)
        return 0;
 }
 
+/**
+ * set_protective_mbr(): Set the EFI protective MBR
+ * @param dev_desc - block device descriptor
+ *
+ * @return - zero on success, otherwise error
+ */
+static int set_protective_mbr(block_dev_desc_t *dev_desc)
+{
+       legacy_mbr *p_mbr;
+
+       /* Setup the Protective MBR */
+       p_mbr = calloc(1, sizeof(p_mbr));
+       if (p_mbr == NULL) {
+               printf("%s: calloc failed!\n", __func__);
+               return -1;
+       }
+       /* Append signature */
+       p_mbr->signature = MSDOS_MBR_SIGNATURE;
+       p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
+       p_mbr->partition_record[0].start_sect = 1;
+       p_mbr->partition_record[0].nr_sects = (u32) dev_desc->lba;
+
+       /* Write MBR sector to the MMC device */
+       if (dev_desc->block_write(dev_desc->dev, 0, 1, p_mbr) != 1) {
+               printf("** Can't write to device %d **\n",
+                       dev_desc->dev);
+               free(p_mbr);
+               return -1;
+       }
+
+       free(p_mbr);
+       return 0;
+}
+
+/**
+ * string_uuid(); Convert UUID stored as string to bytes
+ *
+ * @param uuid - UUID represented as string
+ * @param dst - GUID buffer
+ *
+ * @return return 0 on successful conversion
+ */
+static int string_uuid(char *uuid, u8 *dst)
+{
+       efi_guid_t guid;
+       u16 b, c, d;
+       u64 e;
+       u32 a;
+       u8 *p;
+       u8 i;
+
+       const u8 uuid_str_len = 36;
+
+       /* The UUID is written in text: */
+       /* 1        9    14   19   24 */
+       /* xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx */
+
+       debug("%s: uuid: %s\n", __func__, uuid);
+
+       if (strlen(uuid) != uuid_str_len)
+               return -1;
+
+       for (i = 0; i < uuid_str_len; i++) {
+               if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) {
+                       if (uuid[i] != '-')
+                               return -1;
+               } else {
+                       if (!isxdigit(uuid[i]))
+                               return -1;
+               }
+       }
+
+       a = (u32)simple_strtoul(uuid, NULL, 16);
+       b = (u16)simple_strtoul(uuid + 9, NULL, 16);
+       c = (u16)simple_strtoul(uuid + 14, NULL, 16);
+       d = (u16)simple_strtoul(uuid + 19, NULL, 16);
+       e = (u64)simple_strtoull(uuid + 24, NULL, 16);
+
+       p = (u8 *) &e;
+       guid = EFI_GUID(a, b, c, d >> 8, d & 0xFF,
+                       *(p + 5), *(p + 4), *(p + 3),
+                       *(p + 2), *(p + 1) , *p);
+
+       memcpy(dst, guid.b, sizeof(efi_guid_t));
+
+       return 0;
+}
+
+int write_gpt_table(block_dev_desc_t *dev_desc,
+               gpt_header *gpt_h, gpt_entry *gpt_e)
+{
+       const int pte_blk_num = (gpt_h->num_partition_entries
+               * sizeof(gpt_entry)) / dev_desc->blksz;
+
+       u32 calc_crc32;
+       u64 val;
+
+       debug("max lba: %x\n", (u32) dev_desc->lba);
+       /* Setup the Protective MBR */
+       if (set_protective_mbr(dev_desc) < 0)
+               goto err;
+
+       /* Generate CRC for the Primary GPT Header */
+       calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
+                             le32_to_cpu(gpt_h->num_partition_entries) *
+                             le32_to_cpu(gpt_h->sizeof_partition_entry));
+       gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32);
+
+       calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
+                             le32_to_cpu(gpt_h->header_size));
+       gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
+
+       /* Write the First GPT to the block right after the Legacy MBR */
+       if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)
+               goto err;
+
+       if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
+           != pte_blk_num)
+               goto err;
+
+       /* recalculate the values for the Second GPT Header */
+       val = le64_to_cpu(gpt_h->my_lba);
+       gpt_h->my_lba = gpt_h->alternate_lba;
+       gpt_h->alternate_lba = cpu_to_le64(val);
+       gpt_h->header_crc32 = 0;
+
+       calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
+                             le32_to_cpu(gpt_h->header_size));
+       gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
+
+       if (dev_desc->block_write(dev_desc->dev,
+                                 le32_to_cpu(gpt_h->last_usable_lba + 1),
+                                 pte_blk_num, gpt_e) != pte_blk_num)
+               goto err;
+
+       if (dev_desc->block_write(dev_desc->dev,
+                                 le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1)
+               goto err;
+
+       debug("GPT successfully written to block device!\n");
+       return 0;
+
+ err:
+       printf("** Can't write to device %d **\n", dev_desc->dev);
+       return -1;
+}
+
+int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
+               disk_partition_t *partitions, int parts)
+{
+       u32 offset = (u32)le32_to_cpu(gpt_h->first_usable_lba);
+       ulong start;
+       int i, k;
+       size_t name_len;
+#ifdef CONFIG_PARTITION_UUIDS
+       char *str_uuid;
+#endif
+
+       for (i = 0; i < parts; i++) {
+               /* partition starting lba */
+               start = partitions[i].start;
+               if (start && (start < offset)) {
+                       printf("Partition overlap\n");
+                       return -1;
+               }
+               if (start) {
+                       gpt_e[i].starting_lba = cpu_to_le64(start);
+                       offset = start + partitions[i].size;
+               } else {
+                       gpt_e[i].starting_lba = cpu_to_le64(offset);
+                       offset += partitions[i].size;
+               }
+               if (offset >= gpt_h->last_usable_lba) {
+                       printf("Partitions layout exceds disk size\n");
+                       return -1;
+               }
+               /* partition ending lba */
+               if ((i == parts - 1) && (partitions[i].size == 0))
+                       /* extend the last partition to maximuim */
+                       gpt_e[i].ending_lba = gpt_h->last_usable_lba;
+               else
+                       gpt_e[i].ending_lba = cpu_to_le64(offset - 1);
+
+               /* partition type GUID */
+               memcpy(gpt_e[i].partition_type_guid.b,
+                       &PARTITION_BASIC_DATA_GUID, 16);
+
+#ifdef CONFIG_PARTITION_UUIDS
+               str_uuid = partitions[i].uuid;
+               if (string_uuid(str_uuid, gpt_e[i].unique_partition_guid.b)) {
+                       printf("Partition no. %d: invalid guid: %s\n",
+                               i, str_uuid);
+                       return -1;
+               }
+#endif
+
+               /* partition attributes */
+               memset(&gpt_e[i].attributes, 0,
+                      sizeof(gpt_entry_attributes));
+
+               /* partition name */
+               name_len = sizeof(gpt_e[i].partition_name)
+                       / sizeof(efi_char16_t);
+               for (k = 0; k < name_len; k++)
+                       gpt_e[i].partition_name[k] =
+                               (efi_char16_t)(partitions[i].name[k]);
+
+               debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%lx\n",
+                     __func__, partitions[i].name, i,
+                     offset, i, partitions[i].size);
+       }
+
+       return 0;
+}
+
+int gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h,
+               char *str_guid, int parts_count)
+{
+       gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
+       gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
+       gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
+       gpt_h->my_lba = cpu_to_le64(1);
+       gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1);
+       gpt_h->first_usable_lba = cpu_to_le64(34);
+       gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
+       gpt_h->partition_entry_lba = cpu_to_le64(2);
+       gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
+       gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry));
+       gpt_h->header_crc32 = 0;
+       gpt_h->partition_entry_array_crc32 = 0;
+
+       if (string_uuid(str_guid, gpt_h->disk_guid.b))
+               return -1;
+
+       return 0;
+}
+
+int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,
+               disk_partition_t *partitions, int parts_count)
+{
+       int ret;
+
+       gpt_header *gpt_h = calloc(1, sizeof(gpt_header));
+       if (gpt_h == NULL) {
+               printf("%s: calloc failed!\n", __func__);
+               return -1;
+       }
+
+       gpt_entry *gpt_e = calloc(GPT_ENTRY_NUMBERS, sizeof(gpt_entry));
+       if (gpt_e == NULL) {
+               printf("%s: calloc failed!\n", __func__);
+               free(gpt_h);
+               return -1;
+       }
+
+       /* Generate Primary GPT header (LBA1) */
+       ret = gpt_fill_header(dev_desc, gpt_h, str_disk_guid, parts_count);
+       if (ret)
+               goto err;
+
+       /* Generate partition entries */
+       ret = gpt_fill_pte(gpt_h, gpt_e, partitions, parts_count);
+       if (ret)
+               goto err;
+
+       /* Write GPT partition table */
+       ret = write_gpt_table(dev_desc, gpt_h, gpt_e);
+
+err:
+       free(gpt_e);
+       free(gpt_h);
+       return ret;
+}
+#endif
+
 /*
  * Private functions
  */
@@ -264,7 +511,7 @@ int test_part_efi(block_dev_desc_t * dev_desc)
 static int pmbr_part_valid(struct partition *part)
 {
        if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
-               le32_to_int(part->start_sect) == 1UL) {
+               le32_to_cpu(part->start_sect) == 1UL) {
                return 1;
        }
 
@@ -283,9 +530,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 {
        int i = 0;
 
-       if (!mbr || le16_to_int(mbr->signature) != MSDOS_MBR_SIGNATURE) {
+       if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
                return 0;
-       }
 
        for (i = 0; i < 4; i++) {
                if (pmbr_part_valid(&mbr->partition_record[i])) {
@@ -308,8 +554,8 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
                        gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
 {
-       unsigned char crc32_backup[4] = { 0 };
-       unsigned long calc_crc32;
+       u32 crc32_backup = 0;
+       u32 calc_crc32;
        unsigned long long lastlba;
 
        if (!dev_desc || !pgpt_head) {
@@ -324,54 +570,54 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
        }
 
        /* Check the GPT header signature */
-       if (le64_to_int(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
+       if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
                printf("GUID Partition Table Header signature is wrong:"
                        "0x%llX != 0x%llX\n",
-                       (unsigned long long)le64_to_int(pgpt_head->signature),
-                       (unsigned long long)GPT_HEADER_SIGNATURE);
+                       le64_to_cpu(pgpt_head->signature),
+                       GPT_HEADER_SIGNATURE);
                return 0;
        }
 
        /* Check the GUID Partition Table CRC */
-       memcpy(crc32_backup, pgpt_head->header_crc32, sizeof(crc32_backup));
-       memset(pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
+       memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup));
+       memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
 
        calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
-               le32_to_int(pgpt_head->header_size));
+               le32_to_cpu(pgpt_head->header_size));
 
-       memcpy(pgpt_head->header_crc32, crc32_backup, sizeof(crc32_backup));
+       memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup));
 
-       if (calc_crc32 != le32_to_int(crc32_backup)) {
+       if (calc_crc32 != le32_to_cpu(crc32_backup)) {
                printf("GUID Partition Table Header CRC is wrong:"
-                       "0x%08lX != 0x%08lX\n",
-                       le32_to_int(crc32_backup), calc_crc32);
+                       "0x%x != 0x%x\n",
+                      le32_to_cpu(crc32_backup), calc_crc32);
                return 0;
        }
 
        /* Check that the my_lba entry points to the LBA that contains the GPT */
-       if (le64_to_int(pgpt_head->my_lba) != lba) {
+       if (le64_to_cpu(pgpt_head->my_lba) != lba) {
                printf("GPT: my_lba incorrect: %llX != %llX\n",
-                       (unsigned long long)le64_to_int(pgpt_head->my_lba),
-                       (unsigned long long)lba);
+                       le64_to_cpu(pgpt_head->my_lba),
+                       lba);
                return 0;
        }
 
        /* Check the first_usable_lba and last_usable_lba are within the disk. */
        lastlba = (unsigned long long)dev_desc->lba;
-       if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
+       if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {
                printf("GPT: first_usable_lba incorrect: %llX > %llX\n",
-                       le64_to_int(pgpt_head->first_usable_lba), lastlba);
+                       le64_to_cpu(pgpt_head->first_usable_lba), lastlba);
                return 0;
        }
-       if (le64_to_int(pgpt_head->last_usable_lba) > lastlba) {
+       if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) {
                printf("GPT: last_usable_lba incorrect: %llX > %llX\n",
-                       le64_to_int(pgpt_head->last_usable_lba), lastlba);
+                       (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
                return 0;
        }
 
        debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
-               le64_to_int(pgpt_head->first_usable_lba),
-               le64_to_int(pgpt_head->last_usable_lba), lastlba);
+               le64_to_cpu(pgpt_head->first_usable_lba),
+               le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
 
        /* Read and allocate Partition Table Entries */
        *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
@@ -382,13 +628,13 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 
        /* Check the GUID Partition Table Entry Array CRC */
        calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
-               le32_to_int(pgpt_head->num_partition_entries) *
-               le32_to_int(pgpt_head->sizeof_partition_entry));
+               le32_to_cpu(pgpt_head->num_partition_entries) *
+               le32_to_cpu(pgpt_head->sizeof_partition_entry));
 
-       if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
+       if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) {
                printf("GUID Partition Table Entry Array CRC is wrong:"
-                       "0x%08lX != 0x%08lX\n",
-                       le32_to_int(pgpt_head->partition_entry_array_crc32),
+                       "0x%x != 0x%x\n",
+                       le32_to_cpu(pgpt_head->partition_entry_array_crc32),
                        calc_crc32);
 
                free(*pgpt_pte);
@@ -419,12 +665,12 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
                return NULL;
        }
 
-       count = le32_to_int(pgpt_head->num_partition_entries) *
-               le32_to_int(pgpt_head->sizeof_partition_entry);
+       count = le32_to_cpu(pgpt_head->num_partition_entries) *
+               le32_to_cpu(pgpt_head->sizeof_partition_entry);
 
-       debug("%s: count = %lu * %lu = %zu\n", __func__,
-               le32_to_int(pgpt_head->num_partition_entries),
-               le32_to_int(pgpt_head->sizeof_partition_entry), count);
+       debug("%s: count = %u * %u = %zu\n", __func__,
+             (u32) le32_to_cpu(pgpt_head->num_partition_entries),
+             (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count);
 
        /* Allocate memory for PTE, remember to FREE */
        if (count != 0) {
@@ -440,7 +686,7 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 
        /* Read GPT Entries from device */
        if (dev_desc->block_read (dev_desc->dev,
-               (unsigned long)le64_to_int(pgpt_head->partition_entry_lba),
+               le64_to_cpu(pgpt_head->partition_entry_lba),
                (lbaint_t) (count / GPT_BLOCK_SIZE), pte)
                != (count / GPT_BLOCK_SIZE)) {
 
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):
diff --git a/doc/README.gpt b/doc/README.gpt
new file mode 100644 (file)
index 0000000..a9c58b4
--- /dev/null
@@ -0,0 +1,201 @@
+#
+#  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
+
+
+Glossary:
+========
+- UUID -(Universally Unique Identifier)
+- GUID - (Globally Unique ID)
+- EFI - (Extensible Firmware Interface)
+- UEFI - (Unified EFI) - EFI evolution
+- GPT (GUID Partition Table) - it is the EFI standard part
+- partitions - lists of available partitions (defined at u-boot):
+  ./include/configs/{target}.h
+
+Introduction:
+=============
+This document describes the GPT partition table format and usage of
+the gpt command in u-boot.
+
+
+UUID introduction:
+====================
+
+GPT for marking disks/partitions is using the UUID. It is supposed to be a
+globally unique value. A UUID is a 16-byte (128-bit) number. The number of
+theoretically possible UUIDs is therefore about 3 x 10^38.
+More often UUID is displayed as 32 hexadecimal digits, in 5 groups,
+separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
+(32 digits and 4 hyphens)
+
+For instance, GUID of Linux data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
+
+Historically there are 5 methods to generate this number. The oldest one is
+combining machine's MAC address and timer (epoch) value.
+
+Successive versions are using MD5 hash, random numbers and SHA-1 hash. All major
+OSes and programming languages are providing libraries to compute UUID (e.g.
+uuid command line tool).
+
+GPT brief explanation:
+======================
+
+       Layout:
+       -------
+
+       --------------------------------------------------
+       LBA 0          |Protective MBR                   |
+       ----------------------------------------------------------
+       LBA 1          |Primary GPT Header               | Primary
+       -------------------------------------------------- GPT
+       LBA 2          |Entry 1|Entry 2| Entry 3| Entry 4|
+       --------------------------------------------------
+       LBA 3          |Entries 5 - 128                  |
+                      |                                 |
+                      |                                 |
+       ----------------------------------------------------------
+       LBA 34         |Partition 1                      |
+                      |                                 |
+                      -----------------------------------
+                      |Partition 2                      |
+                      |                                 |
+                      -----------------------------------
+                      |Partition n                      |
+                      |                                 |
+       ----------------------------------------------------------
+       LBA -34        |Entry 1|Entry 2| Entry 3| Entry 4| Secondary
+       -------------------------------------------------- (bkp)
+       LBA -33        |Entries 5 - 128                  | GPT
+                      |                                 |
+                      |                                 |
+       LBA -2         |                                 |
+       --------------------------------------------------
+       LBA -1         |Secondary GPT Header             |
+       ----------------------------------------------------------
+
+
+For a legacy reasons, GPT's LBA 0 sector has a MBR structure. It is called
+"protective MBR".
+Its first partition entry ID has 0xEE value, and disk software, which is not
+handling the GPT sees it as a storage device without free space.
+
+It is possible to define 128 linearly placed partition entries.
+
+"LBA -1" means the last addressable block (in the mmc subsystem:
+"dev_desc->lba - 1")
+
+Primary/Secondary GPT header:
+----------------------------
+Offset  Size    Description
+
+0       8 B     Signature ("EFI PART", 45 46 49 20 50 41 52 54)
+8       4 B     Revision (For version 1.0, the value is 00 00 01 00)
+12      4 B     Header size (in bytes, usually 5C 00 00 00 meaning 92 bytes)
+16      4 B     CRC32 of header (0 to header size), with this field zeroed
+               during calculation
+20      4 B     Reserved (ZERO);
+24      8 B     Current LBA (location of this header copy)
+32      8 B     Backup LBA (location of the other header copy)
+40      8 B     First usable LBA for partitions (primary partition table last
+               LBA + 1)
+48      8 B     Last usable LBA (secondary partition table first LBA - 1)
+56      16 B    Disk GUID (also referred as UUID on UNIXes)
+72      8 B     Partition entries starting LBA (always 2 in primary copy)
+80      4 B     Number of partition entries
+84      4 B     Size of a partition entry (usually 128)
+88      4 B     CRC32 of partition array
+92      *       Reserved; must be ZERO (420 bytes for a 512-byte LBA)
+
+TOTAL: 512 B
+
+
+
+IMPORTANT:
+
+GPT headers and partition entries are protected by CRC32 (the POSIX CRC32).
+
+Primary GPT header and Secondary GPT header have swapped values of "Current LBA"
+and "Backup LBA" and therefore different CRC32 check-sum.
+
+CRC32 for GPT headers (field "CRC of header") are calculated up till
+"Header size" (92), NOT 512 bytes.
+
+CRC32 for partition entries (field "CRC32 of partition array") is calculated for
+the whole array entry ( Number_of_partition_entries *
+sizeof(partition_entry_size (usually 128)))
+
+Observe, how Secondary GPT is placed in the memory. It is NOT a mirror reflect
+of the Primary.
+
+
+          Partition Entry Format:
+          ----------------------
+          Offset  Size    Description
+
+          0       16 B    Partition type GUID
+          16      16 B    Unique partition GUID
+          32      8  B    First LBA (Little Endian)
+          40      8  B    Last LBA (inclusive)
+          48      8  B    Attribute flags [+]
+          56      72 B    Partition name (text)
+
+          Attribute flags:
+          Bit 0  - System partition
+          Bit 60 - Read-only
+          Bit 62 - Hidden
+          Bit 63 - Not mount
+
+
+Creating GPT partitions in U-Boot:
+==============
+
+To restore GUID partition table one needs to:
+1. Define partition layout in the environment.
+   Format of partitions layout:
+     "partitions=uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
+       name=kernel,size=60MiB,uuid=...;"
+     or
+     "partitions=uuid_disk=${uuid_gpt_disk};name=${uboot_name},
+       size=${uboot_size},uuid=${uboot_uuid};"
+
+   Fields 'name', 'size' and 'uuid' are mandatory for every partition.
+   The field 'start' is optional.
+
+2. Define 'CONFIG_EFI_PARTITION' and 'CONFIG_CMD_GPT'
+
+2. From u-boot prompt type:
+   gpt write mmc 0 $partitions
+
+
+Useful info:
+============
+
+Two programs, namely: 'fdisk' and 'parted' are recommended to work with GPT
+recovery. Parted is able to handle GUID partitions. Unfortunately the 'fdisk'
+hasn't got such ability.
+Please, pay attention at -l switch for parted.
+
+"uuid" program is recommended to generate UUID string. Moreover it can decode
+(-d switch) passed in UUID string. It can be used to generate partitions UUID
+passed to u-boot environment variables.
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 a26e3df0da606af9c278f70a4e90d87417ef5c57..70202cece97fe8a53b49251ca8f64a9cef26ee1e 100644 (file)
@@ -1,9 +1,15 @@
 The config option CONFIG_SILENT_CONSOLE can be used to quiet messages
 on the console.  If the option has been enabled, the output can be
-silenced by setting the environment variable "silent".  The variable
-is latched into the global data at an early stage in the boot process
-so deleting it with "setenv" will not take effect until the system is
-restarted.
+silenced by setting the environment variable "silent".
+
+- CONFIG_SILENT_CONSOLE_UPDATE_ON_SET
+       When the "silent" variable is changed with env set, the change
+       will take effect immediately.
+
+- CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC
+       Some environments are not available until relocation (e.g. NAND)
+       so this will make the value in the flash env take effect at
+       relocation.
 
 The following actions are taken if "silent" is set at boot time:
 
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 bf64a2a643ab2871c053188d7f3f8dd061aaeb58..665387091ae351f4e2701be96a0b23ae7f339f95 100644 (file)
 #include <asm/arch/hardware.h>
 #include "designware_i2c.h"
 
-static struct i2c_regs *const i2c_regs_p =
+#ifdef CONFIG_I2C_MULTI_BUS
+static unsigned int bus_initialized[CONFIG_SYS_I2C_BUS_MAX];
+static unsigned int current_bus = 0;
+#endif
+
+static struct i2c_regs *i2c_regs_p =
     (struct i2c_regs *)CONFIG_SYS_I2C_BASE;
 
 /*
@@ -39,7 +44,6 @@ static void set_speed(int i2c_spd)
 {
        unsigned int cntl;
        unsigned int hcnt, lcnt;
-       unsigned int high, low;
        unsigned int enbl;
 
        /* to set speed cltr must be disabled */
@@ -47,39 +51,38 @@ static void set_speed(int i2c_spd)
        enbl &= ~IC_ENABLE_0B;
        writel(enbl, &i2c_regs_p->ic_enable);
 
-
        cntl = (readl(&i2c_regs_p->ic_con) & (~IC_CON_SPD_MSK));
 
        switch (i2c_spd) {
        case IC_SPEED_MODE_MAX:
                cntl |= IC_CON_SPD_HS;
-               high = MIN_HS_SCL_HIGHTIME;
-               low = MIN_HS_SCL_LOWTIME;
+               hcnt = (IC_CLK * MIN_HS_SCL_HIGHTIME) / NANO_TO_MICRO;
+               writel(hcnt, &i2c_regs_p->ic_hs_scl_hcnt);
+               lcnt = (IC_CLK * MIN_HS_SCL_LOWTIME) / NANO_TO_MICRO;
+               writel(lcnt, &i2c_regs_p->ic_hs_scl_lcnt);
                break;
 
        case IC_SPEED_MODE_STANDARD:
                cntl |= IC_CON_SPD_SS;
-               high = MIN_SS_SCL_HIGHTIME;
-               low = MIN_SS_SCL_LOWTIME;
+               hcnt = (IC_CLK * MIN_SS_SCL_HIGHTIME) / NANO_TO_MICRO;
+               writel(hcnt, &i2c_regs_p->ic_ss_scl_hcnt);
+               lcnt = (IC_CLK * MIN_SS_SCL_LOWTIME) / NANO_TO_MICRO;
+               writel(lcnt, &i2c_regs_p->ic_ss_scl_lcnt);
                break;
 
        case IC_SPEED_MODE_FAST:
        default:
                cntl |= IC_CON_SPD_FS;
-               high = MIN_FS_SCL_HIGHTIME;
-               low = MIN_FS_SCL_LOWTIME;
+               hcnt = (IC_CLK * MIN_FS_SCL_HIGHTIME) / NANO_TO_MICRO;
+               writel(hcnt, &i2c_regs_p->ic_fs_scl_hcnt);
+               lcnt = (IC_CLK * MIN_FS_SCL_LOWTIME) / NANO_TO_MICRO;
+               writel(lcnt, &i2c_regs_p->ic_fs_scl_lcnt);
                break;
        }
 
        writel(cntl, &i2c_regs_p->ic_con);
 
-       hcnt = (IC_CLK * high) / NANO_TO_MICRO;
-       writel(hcnt, &i2c_regs_p->ic_fs_scl_hcnt);
-
-       lcnt = (IC_CLK * low) / NANO_TO_MICRO;
-       writel(lcnt, &i2c_regs_p->ic_fs_scl_lcnt);
-
-       /* re-enable i2c ctrl back now that speed is set */
+       /* Enable back i2c now speed set */
        enbl |= IC_ENABLE_0B;
        writel(enbl, &i2c_regs_p->ic_enable);
 }
@@ -150,6 +153,10 @@ void i2c_init(int speed, int slaveadd)
        enbl = readl(&i2c_regs_p->ic_enable);
        enbl |= IC_ENABLE_0B;
        writel(enbl, &i2c_regs_p->ic_enable);
+
+#ifdef CONFIG_I2C_MULTI_BUS
+       bus_initialized[current_bus] = 1;
+#endif
 }
 
 /*
@@ -274,7 +281,10 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 
        start_time_rx = get_timer(0);
        while (len) {
-               writel(IC_CMD, &i2c_regs_p->ic_cmd_data);
+               if (len == 1)
+                       writel(IC_CMD | IC_STOP, &i2c_regs_p->ic_cmd_data);
+               else
+                       writel(IC_CMD, &i2c_regs_p->ic_cmd_data);
 
                if (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) {
                        *buffer++ = (uchar)readl(&i2c_regs_p->ic_cmd_data);
@@ -313,9 +323,11 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
        start_time_tx = get_timer(0);
        while (len) {
                if (readl(&i2c_regs_p->ic_status) & IC_STATUS_TFNF) {
-                       writel(*buffer, &i2c_regs_p->ic_cmd_data);
+                       if (--len == 0)
+                               writel(*buffer | IC_STOP, &i2c_regs_p->ic_cmd_data);
+                       else
+                               writel(*buffer, &i2c_regs_p->ic_cmd_data);
                        buffer++;
-                       len--;
                        start_time_tx = get_timer(0);
 
                } else if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO)) {
@@ -344,3 +356,74 @@ int i2c_probe(uchar chip)
 
        return ret;
 }
+
+#ifdef CONFIG_I2C_MULTI_BUS
+int i2c_set_bus_num(unsigned int bus)
+{
+       switch (bus) {
+       case 0:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE;
+               break;
+#ifdef CONFIG_SYS_I2C_BASE1
+       case 1:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE1;
+               break;
+#endif
+#ifdef CONFIG_SYS_I2C_BASE2
+       case 2:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE2;
+               break;
+#endif
+#ifdef CONFIG_SYS_I2C_BASE3
+       case 3:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE3;
+               break;
+#endif
+#ifdef CONFIG_SYS_I2C_BASE4
+       case 4:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE4;
+               break;
+#endif
+#ifdef CONFIG_SYS_I2C_BASE5
+       case 5:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE5;
+               break;
+#endif
+#ifdef CONFIG_SYS_I2C_BASE6
+       case 6:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE6;
+               break;
+#endif
+#ifdef CONFIG_SYS_I2C_BASE7
+       case 7:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE7;
+               break;
+#endif
+#ifdef CONFIG_SYS_I2C_BASE8
+       case 8:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE8;
+               break;
+#endif
+#ifdef CONFIG_SYS_I2C_BASE9
+       case 9:
+               i2c_regs_p = (void *)CONFIG_SYS_I2C_BASE9;
+               break;
+#endif
+       default:
+               printf("Bad bus: %d\n", bus);
+               return -1;
+       }
+
+       current_bus = bus;
+
+       if (!bus_initialized[current_bus])
+               i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+       return 0;
+}
+
+int i2c_get_bus_num(void)
+{
+       return current_bus;
+}
+#endif
index 03b520ed43a0a48def984d0a98db0e89c1c71c29..2faf4a8717a31f1868dfa70cebb0f12b1b7d5694 100644 (file)
@@ -60,14 +60,16 @@ struct i2c_regs {
        u32 ic_tx_abrt_source;
 };
 
+#if !defined(IC_CLK)
 #define IC_CLK                 166
+#endif
 #define NANO_TO_MICRO          1000
 
 /* High and low times in different speed modes (in ns) */
 #define MIN_SS_SCL_HIGHTIME    4000
-#define MIN_SS_SCL_LOWTIME     5000
-#define MIN_FS_SCL_HIGHTIME    800
-#define MIN_FS_SCL_LOWTIME     1700
+#define MIN_SS_SCL_LOWTIME     4700
+#define MIN_FS_SCL_HIGHTIME    600
+#define MIN_FS_SCL_LOWTIME     1300
 #define MIN_HS_SCL_HIGHTIME    60
 #define MIN_HS_SCL_LOWTIME     160
 
@@ -95,6 +97,7 @@ struct i2c_regs {
 
 /* i2c data buffer and command register definitions */
 #define IC_CMD                 0x0100
+#define IC_STOP                        0x0200
 
 /* i2c interrupt status register definitions */
 #define IC_GEN_CALL            0x0800
index 18270b9de64f065dd583dadd8bf8b44acaafaeaa..a73b10b9c49f662c167276f3d97abcc7517e75dd 100644 (file)
@@ -115,7 +115,7 @@ static uint8_t i2c_imx_get_clk(unsigned int rate)
 /*
  * Set I2C Bus speed
  */
-int bus_i2c_set_bus_speed(void *base, int speed)
+static int bus_i2c_set_bus_speed(void *base, int speed)
 {
        struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
        u8 clk_idx = i2c_imx_get_clk(speed);
@@ -133,7 +133,7 @@ int bus_i2c_set_bus_speed(void *base, int speed)
 /*
  * Get I2C Speed
  */
-unsigned int bus_i2c_get_bus_speed(void *base)
+static unsigned int bus_i2c_get_bus_speed(void *base)
 {
        struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
        u8 clk_idx = readb(&i2c_regs->ifdr);
index 2a193c220d7b41252dd35b5870dfee8c07b59706..b907f7b379bb6c6bb02aabffdff363f4560bc23c 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <common.h>
 #include <malloc.h>
+#include <i2c.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
@@ -40,6 +41,7 @@ void mxs_i2c_reset(void)
 {
        struct mxs_i2c_regs *i2c_regs = (struct mxs_i2c_regs *)MXS_I2C0_BASE;
        int ret;
+       int speed = i2c_get_bus_speed();
 
        ret = mxs_reset_block(&i2c_regs->hw_i2c_ctrl0_reg);
        if (ret) {
@@ -53,6 +55,8 @@ void mxs_i2c_reset(void)
                &i2c_regs->hw_i2c_ctrl1_clr);
 
        writel(I2C_QUEUECTRL_PIO_QUEUE_MODE, &i2c_regs->hw_i2c_queuectrl_set);
+
+       i2c_set_bus_speed(speed);
 }
 
 void mxs_i2c_setup_read(uint8_t chip, int len)
@@ -210,37 +214,65 @@ int i2c_probe(uchar chip)
        return ret;
 }
 
-void i2c_init(int speed, int slaveadd)
+int i2c_set_bus_speed(unsigned int speed)
 {
        struct mxs_i2c_regs *i2c_regs = (struct mxs_i2c_regs *)MXS_I2C0_BASE;
+       /*
+        * The timing derivation algorithm. There is no documentation for this
+        * algorithm available, it was derived by using the scope and fiddling
+        * with constants until the result observed on the scope was good enough
+        * for 20kHz, 50kHz, 100kHz, 200kHz, 300kHz and 400kHz. It should be
+        * possible to assume the algorithm works for other frequencies as well.
+        *
+        * Note it was necessary to cap the frequency on both ends as it's not
+        * possible to configure completely arbitrary frequency for the I2C bus
+        * clock.
+        */
+       uint32_t clk = mxc_get_clock(MXC_XTAL_CLK);
+       uint32_t base = ((clk / speed) - 38) / 2;
+       uint16_t high_count = base + 3;
+       uint16_t low_count = base - 3;
+       uint16_t rcv_count = (high_count * 3) / 4;
+       uint16_t xmit_count = low_count / 4;
+
+       if (speed > 540000) {
+               printf("MXS I2C: Speed too high (%d Hz)\n", speed);
+               return -EINVAL;
+       }
 
-       mxs_i2c_reset();
-
-       switch (speed) {
-       case 100000:
-               writel((0x0078 << I2C_TIMING0_HIGH_COUNT_OFFSET) |
-                       (0x0030 << I2C_TIMING0_RCV_COUNT_OFFSET),
-                       &i2c_regs->hw_i2c_timing0);
-               writel((0x0080 << I2C_TIMING1_LOW_COUNT_OFFSET) |
-                       (0x0030 << I2C_TIMING1_XMIT_COUNT_OFFSET),
-                       &i2c_regs->hw_i2c_timing1);
-               break;
-       case 400000:
-               writel((0x000f << I2C_TIMING0_HIGH_COUNT_OFFSET) |
-                       (0x0007 << I2C_TIMING0_RCV_COUNT_OFFSET),
-                       &i2c_regs->hw_i2c_timing0);
-               writel((0x001f << I2C_TIMING1_LOW_COUNT_OFFSET) |
-                       (0x000f << I2C_TIMING1_XMIT_COUNT_OFFSET),
-                       &i2c_regs->hw_i2c_timing1);
-               break;
-       default:
-               printf("MXS I2C: Invalid speed selected (%d Hz)\n", speed);
-               return;
+       if (speed < 12000) {
+               printf("MXS I2C: Speed too low (%d Hz)\n", speed);
+               return -EINVAL;
        }
 
-       writel((0x0015 << I2C_TIMING2_BUS_FREE_OFFSET) |
-               (0x000d << I2C_TIMING2_LEADIN_COUNT_OFFSET),
+       writel((high_count << 16) | rcv_count, &i2c_regs->hw_i2c_timing0);
+       writel((low_count << 16) | xmit_count, &i2c_regs->hw_i2c_timing1);
+
+       writel((0x0030 << I2C_TIMING2_BUS_FREE_OFFSET) |
+               (0x0030 << I2C_TIMING2_LEADIN_COUNT_OFFSET),
                &i2c_regs->hw_i2c_timing2);
 
+       return 0;
+}
+
+unsigned int i2c_get_bus_speed(void)
+{
+       struct mxs_i2c_regs *i2c_regs = (struct mxs_i2c_regs *)MXS_I2C0_BASE;
+       uint32_t clk = mxc_get_clock(MXC_XTAL_CLK);
+       uint32_t timing0;
+
+       timing0 = readl(&i2c_regs->hw_i2c_timing0);
+       /*
+        * This is a reverse version of the algorithm presented in
+        * i2c_set_bus_speed(). Please refer there for details.
+        */
+       return clk / ((((timing0 >> 16) - 3) * 2) + 38);
+}
+
+void i2c_init(int speed, int slaveadd)
+{
+       mxs_i2c_reset();
+       i2c_set_bus_speed(speed);
+
        return;
 }
index 1bbb2ca54c1f7a0606567f94f01c25e64065a8b6..54e9b1586fb8ad17baec72d1910bb6ceca511a48 100644 (file)
@@ -180,7 +180,8 @@ static int i2c_read_byte(u8 devaddr, u16 regoffset, u8 alen, u8 *value)
                if (status & I2C_STAT_XRDY) {
                        w = tmpbuf[i++];
 #if !(defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
-       defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX))
+       defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
+       defined(CONFIG_OMAP54XX))
                        w |= tmpbuf[i++] << 8;
 #endif
                        writew(w, &i2c_base->data);
@@ -210,7 +211,8 @@ static int i2c_read_byte(u8 devaddr, u16 regoffset, u8 alen, u8 *value)
                }
                if (status & I2C_STAT_RRDY) {
 #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
-       defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX)
+       defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
+       defined(CONFIG_OMAP54XX)
                        *value = readb(&i2c_base->data);
 #else
                        *value = readw(&i2c_base->data);
@@ -240,7 +242,8 @@ static void flush_fifo(void)
                stat = readw(&i2c_base->stat);
                if (stat == I2C_STAT_RRDY) {
 #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
-       defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX)
+       defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
+       defined(CONFIG_OMAP54XX)
                        readb(&i2c_base->data);
 #else
                        readw(&i2c_base->data);
@@ -294,7 +297,8 @@ int i2c_probe(uchar chip)
                if (status & I2C_STAT_RRDY) {
                        res = 0;
 #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
-    defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX)
+       defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
+       defined(CONFIG_OMAP54XX)
                        readb(&i2c_base->data);
 #else
                        readw(&i2c_base->data);
@@ -382,7 +386,8 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
                if (status & I2C_STAT_XRDY) {
                        w = (i < 0) ? tmpbuf[2+i] : buffer[i];
 #if !(defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
-       defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX))
+       defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
+       defined(CONFIG_OMAP54XX))
                        w |= ((++i < 0) ? tmpbuf[2+i] : buffer[i]) << 8;
 #endif
                        writew(w, &i2c_base->data);
index 9bc4c7f1d1c714a06d1a482631065feee0a928ee..90d297a28422ac9a4c7e568bfe1bd2edc2f26dff 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include <common.h>
-#ifdef CONFIG_EXYNOS5
+#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
 #include <asm/arch/clk.h>
 #include <asm/arch/cpu.h>
 #else
@@ -62,7 +62,7 @@
 
 static unsigned int g_current_bus;     /* Stores Current I2C Bus */
 
-#ifndef CONFIG_EXYNOS5
+#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
 static int GetI2CSDA(void)
 {
        struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
@@ -121,7 +121,12 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c)
 
 static struct s3c24x0_i2c *get_base_i2c(void)
 {
-#ifdef CONFIG_EXYNOS5
+#ifdef CONFIG_EXYNOS4
+       struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()
+                                                       + (EXYNOS4_I2C_SPACING
+                                                       * g_current_bus));
+       return i2c;
+#elif defined CONFIG_EXYNOS5
        struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()
                                                        + (EXYNOS5_I2C_SPACING
                                                        * g_current_bus));
@@ -134,7 +139,7 @@ static struct s3c24x0_i2c *get_base_i2c(void)
 static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
 {
        ulong freq, pres = 16, div;
-#ifdef CONFIG_EXYNOS5
+#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
        freq = get_i2c_clk();
 #else
        freq = get_PCLK();
@@ -188,7 +193,7 @@ unsigned int i2c_get_bus_num(void)
 void i2c_init(int speed, int slaveadd)
 {
        struct s3c24x0_i2c *i2c;
-#ifndef CONFIG_EXYNOS5
+#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
        struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
 #endif
        int i;
@@ -204,7 +209,7 @@ void i2c_init(int speed, int slaveadd)
                i--;
        }
 
-#ifndef CONFIG_EXYNOS5
+#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
        if ((readl(&i2c->iicstat) & I2CSTAT_BSY) || GetI2CSDA() == 0) {
 #ifdef CONFIG_S3C2410
                ulong old_gpecon = readl(&gpio->gpecon);
@@ -248,7 +253,7 @@ void i2c_init(int speed, int slaveadd)
                writel(old_gpecon, &gpio->pgcon);
 #endif
        }
-#endif /* #ifndef CONFIG_EXYNOS5 */
+#endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */
        i2c_ch_init(i2c, speed, slaveadd);
 }
 
index 1595c0714a825efaca42f8210de6b41bc6b5ee6f..ae3c57392b8d011bcd36d862e3c062b751920b0f 100644 (file)
@@ -30,6 +30,9 @@
 #include <ioports.h>
 #include <asm/io.h>
 #endif
+#if defined(CONFIG_AVR32)
+#include <asm/arch/portmux.h>
+#endif
 #if defined(CONFIG_AT91FAMILY)
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
index 9fac190a6a846dcc51c75422f32a34e5b0f1c38c..8cdc3b649ca34a963efe314da8731642914a684b 100644 (file)
@@ -27,21 +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_MAX77686) += pmic_max77686.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 1fd5592f2de76bf5dbad93cb3b1b63e8a3972d8b..d749ab095e3eecfe1d4070f5b37eacf5a9d3933b 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 5322f3a953c694dc350da9c2be43068a6e08b3d2..2c3812c3bab20d3ea762c9f2a61d3ea2107ef984 100644 (file)
@@ -26,22 +26,34 @@ 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
+
+ifdef CONFIG_SPL_NAND_DRIVERS
+NORMAL_DRIVERS=y
 endif
+
 COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
-ifdef CONFIG_SPL_NAND_LOAD
-COBJS-y        += nand_spl_load.o
-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
@@ -66,7 +78,9 @@ 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
+
+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 4701be846c6f2005d4358cb1e4e6b9c6fd051d3f..e38e15125407bb0f2361ac04e96edae893294c7d 100644 (file)
@@ -1058,6 +1058,8 @@ int mxs_nand_init(struct mxs_nand_info *info)
 {
        struct mxs_gpmi_regs *gpmi_regs =
                (struct mxs_gpmi_regs *)MXS_GPMI_BASE;
+       struct mxs_bch_regs *bch_regs =
+               (struct mxs_bch_regs *)MXS_BCH_BASE;
        int i = 0, j;
 
        info->desc = malloc(sizeof(struct mxs_dma_desc *) *
@@ -1081,6 +1083,7 @@ int mxs_nand_init(struct mxs_nand_info *info)
 
        /* Reset the GPMI block. */
        mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
+       mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
 
        /*
         * Choose NAND mode, set IRQ polarity, disable write protection and
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 2d4da4b386dd98caa822a3ecfa8417e396a0fc96..8ba98b27d52283be000f0896f838ca5e13eba591 100644 (file)
@@ -1688,6 +1688,16 @@ e1000_init_hw(struct eth_device *nic)
                E1000_WRITE_REG(hw, TXDCTL, ctrl);
        }
 
+       /* Set the receive descriptor write back policy */
+
+       if (hw->mac_type >= e1000_82571) {
+               ctrl = E1000_READ_REG(hw, RXDCTL);
+               ctrl =
+                   (ctrl & ~E1000_RXDCTL_WTHRESH) |
+                   E1000_RXDCTL_FULL_RX_DESC_WB;
+               E1000_WRITE_REG(hw, RXDCTL, ctrl);
+       }
+
        switch (hw->mac_type) {
        default:
                break;
index fd1d8f8717f2c90dc5b45cd869b52edfe6a224f9..1bbae5085ac9dac0fbf431c1c4bb8f231e50e9c1 100644 (file)
@@ -1551,6 +1551,7 @@ struct e1000_hw {
 #define E1000_RXDCTL_HTHRESH 0x00003F00        /* RXDCTL Host Threshold */
 #define E1000_RXDCTL_WTHRESH 0x003F0000        /* RXDCTL Writeback Threshold */
 #define E1000_RXDCTL_GRAN    0x01000000        /* RXDCTL Granularity */
+#define E1000_RXDCTL_FULL_RX_DESC_WB 0x01010000        /* GRAN=1, WTHRESH=1 */
 
 /* Transmit Descriptor Control */
 #define E1000_TXDCTL_PTHRESH 0x0000003F        /* TXDCTL Prefetch Threshold */
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 e51e799e2933803ddc73401e6400b9db8a2d0b78..4b271989acbbaf5dbc8c4333e705f29ab0f9d642 100644 (file)
@@ -425,6 +425,16 @@ static struct phy_driver M88E1118_driver = {
        .shutdown = &genphy_shutdown,
 };
 
+static struct phy_driver M88E1118R_driver = {
+       .name = "Marvell 88E1118R",
+       .uid = 0x1410e40,
+       .mask = 0xffffff0,
+       .features = PHY_GBIT_FEATURES,
+       .config = &m88e1118_config,
+       .startup = &m88e1118_startup,
+       .shutdown = &genphy_shutdown,
+};
+
 static struct phy_driver M88E1121R_driver = {
        .name = "Marvell 88E1121R",
        .uid = 0x1410cb0,
@@ -461,6 +471,7 @@ int phy_marvell_init(void)
        phy_register(&M88E1145_driver);
        phy_register(&M88E1121R_driver);
        phy_register(&M88E1118_driver);
+       phy_register(&M88E1118R_driver);
        phy_register(&M88E1111S_driver);
        phy_register(&M88E1011S_driver);
 
index 2d9cc328b5919683481f6621533731a32afa5bd2..e6fc8c8bf6e44f5cb2e7cebf6b9866681aaac8ef 100644 (file)
@@ -417,7 +417,7 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)
                printf(SHETHER_NAME ": 100Base/");
 #if defined(SH_ETH_TYPE_GETHER)
                sh_eth_write(eth, GECMR_100B, GECMR);
-#elif defined(CONFIG_CPU_SH7757)
+#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752)
                sh_eth_write(eth, 1, RTRATE);
 #elif defined(CONFIG_CPU_SH7724)
                val = ECMR_RTM;
@@ -426,7 +426,7 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)
                printf(SHETHER_NAME ": 10Base/");
 #if defined(SH_ETH_TYPE_GETHER)
                sh_eth_write(eth, GECMR_10B, GECMR);
-#elif defined(CONFIG_CPU_SH7757)
+#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752)
                sh_eth_write(eth, 0, RTRATE);
 #endif
        }
index 61d2df9063f5b00e727b1b8594477020b6717483..568fafe5f51fc4318ce1a3c3976e3a72e54c34fe 100644 (file)
@@ -288,7 +288,7 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
 #if defined(CONFIG_CPU_SH7763) || defined(CONFIG_CPU_SH7734)
 #define SH_ETH_TYPE_GETHER
 #define BASE_IO_ADDR   0xfee00000
-#elif defined(CONFIG_CPU_SH7757)
+#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752)
 #if defined(CONFIG_SH_ETHER_USE_GETHER)
 #define SH_ETH_TYPE_GETHER
 #define BASE_IO_ADDR   0xfee00000
@@ -346,7 +346,7 @@ enum DMAC_T_BIT {
 
 /* GECMR */
 enum GECMR_BIT {
-#if defined(CONFIG_CPU_SH7757)
+#if defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752)
        GECMR_1000B = 0x20, GECMR_100B = 0x01, GECMR_10B = 0x00,
 #else
        GECMR_1000B = 0x01, GECMR_100B = 0x04, GECMR_10B = 0x00,
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..14d426f
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# 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-$(CONFIG_POWER_MAX77686) += pmic_max77686.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;
+}
similarity index 82%
rename from drivers/misc/pmic_max77686.c
rename to drivers/power/pmic/pmic_max77686.c
index 36f7f4dde7ac16c958c997db4c6409cbd4a4cc32..fce0183afd6d82e6d174afb09e82850304844edb 100644 (file)
  */
 
 #include <common.h>
-#include <pmic.h>
-#include <max77686_pmic.h>
+#include <power/pmic.h>
+#include <power/max77686_pmic.h>
+#include <errno.h>
 
-int pmic_init(void)
+int pmic_init(unsigned char bus)
 {
-       struct pmic *p = get_pmic();
        static const char name[] = "MAX77686_PMIC";
+       struct pmic *p = pmic_alloc();
+
+       if (!p) {
+               printf("%s: POWER allocation error!\n", __func__);
+               return -ENOMEM;
+       }
 
        puts("Board PMIC init\n");
        p->name = name;
@@ -36,7 +42,7 @@ int pmic_init(void)
        p->number_of_regs = PMIC_NUM_OF_REGS;
        p->hw.i2c.addr = MAX77686_I2C_ADDR;
        p->hw.i2c.tx_num = 1;
-       p->bus = I2C_PMIC;
+       p->bus = bus;
 
        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 f5f43a6ddc05e6c463843a497c4b53a768464a1f..1f8955a0fdb586c9cae12783d3e440641a8e8266 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <serial.h>
 #include <stdio_dev.h>
 #include <post.h>
@@ -32,6 +33,11 @@ DECLARE_GLOBAL_DATA_PTR;
 
 static struct serial_device *serial_devices;
 static struct serial_device *serial_current;
+/*
+ * Table with supported baudrates (defined in config_xyz.h)
+ */
+static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
+#define        N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0]))
 
 /**
  * serial_null() - Void registration routine of a serial driver
@@ -45,6 +51,70 @@ static void serial_null(void)
 {
 }
 
+/**
+ * on_baudrate() - Update the actual baudrate when the env var changes
+ *
+ * This will check for a valid baudrate and only apply it if valid.
+ */
+static int on_baudrate(const char *name, const char *value, enum env_op op,
+       int flags)
+{
+       int i;
+       int baudrate;
+
+       switch (op) {
+       case env_op_create:
+       case env_op_overwrite:
+               /*
+                * Switch to new baudrate if new baudrate is supported
+                */
+               baudrate = simple_strtoul(value, NULL, 10);
+
+               /* Not actually changing */
+               if (gd->baudrate == baudrate)
+                       return 0;
+
+               for (i = 0; i < N_BAUDRATES; ++i) {
+                       if (baudrate == baudrate_table[i])
+                               break;
+               }
+               if (i == N_BAUDRATES) {
+                       if ((flags & H_FORCE) == 0)
+                               printf("## Baudrate %d bps not supported\n",
+                                       baudrate);
+                       return 1;
+               }
+               if ((flags & H_INTERACTIVE) != 0) {
+                       printf("## Switch baudrate to %d"
+                               " bps and press ENTER ...\n", baudrate);
+                       udelay(50000);
+               }
+
+               gd->baudrate = baudrate;
+#if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2)
+               gd->bd->bi_baudrate = baudrate;
+#endif
+
+               serial_setbrg();
+
+               udelay(50000);
+
+               if ((flags & H_INTERACTIVE) != 0)
+                       while (1) {
+                               if (getc() == '\r')
+                                       break;
+                       }
+
+               return 0;
+       case env_op_delete:
+               printf("## Baudrate may not be deleted\n");
+               return 1;
+       default:
+               return 0;
+       }
+}
+U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
+
 /**
  * serial_initfunc() - Forward declare of driver registration routine
  * @name:      Name of the real driver registration routine.
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 b3207c83c3cfc3089c4cbe8fa359f864b29e797c..170a358b5283849207827f21d7eb49dc419d9acf 100644 (file)
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_S6E63D6) += s6e63d6.o
 COBJS-$(CONFIG_LD9040) += ld9040.o
 COBJS-$(CONFIG_SED156X) += sed156x.o
 COBJS-$(CONFIG_VIDEO_AMBA) += amba.o
+COBJS-$(CONFIG_VIDEO_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 23c964940312efc36f4dffac82292a141c1050b6..bfedbe44596aa31fb2266f7e052a63401f06d181 100644 (file)
  */
 
 /**
- * Request ownership of a GPIO.
+ * Request a gpio. This should be called before any of the other functions
+ * are used on this gpio.
  *
- * @param gpio GPIO number
- * @param label        Name given to the GPIO
+ * @param gp   GPIO number
+ * @param label        User label for this GPIO
  * @return 0 if ok, -1 on error
  */
 int gpio_request(unsigned gpio, const char *label);
@@ -93,14 +94,4 @@ int gpio_get_value(unsigned gpio);
  * @return 0 if ok, -1 on error
  */
 int gpio_set_value(unsigned gpio, int value);
-
-/**
- * Request a gpio. This should be called before any of the other functions
- * are used on this gpio.
- *
- * @param gp   GPIO number
- * @param label        User label for this GPIO
- * @return 0 if ok, -1 on error
- */
-int gpio_request(unsigned gpio, const char *label);
 #endif /* _ASM_GENERIC_GPIO_H_ */
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 10bc2606c717f600de2af73e9857c4926ccd510e..476e7cffc2856523df090a54d73b03926e1b73ba 100644 (file)
@@ -89,10 +89,10 @@ extern int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *
  */
 
 #if defined(CONFIG_CMD_MEMORY)         \
-    || defined(CONFIG_CMD_I2C)         \
-    || defined(CONFIG_CMD_ITEST)       \
-    || defined(CONFIG_CMD_PCI)         \
-    || defined(CONFIG_CMD_PORTIO)
+       || defined(CONFIG_CMD_I2C)      \
+       || defined(CONFIG_CMD_ITEST)    \
+       || defined(CONFIG_CMD_PCI)      \
+       || defined(CONFIG_CMD_PORTIO)
 #define CMD_DATA_SIZE
 extern int cmd_get_data_size(char* arg, int default_size);
 #endif
index 5e3c5eeee14313f02f0ff90a410497b4f25ec595..d0bf1e8ab234b8c66e017a6eef944c1dc3637ec2 100644 (file)
@@ -340,6 +340,11 @@ int        envmatch     (uchar *, int);
 char   *getenv      (const char *);
 int    getenv_f     (const char *name, char *buf, unsigned len);
 ulong getenv_ulong(const char *name, int base, ulong default_val);
+/*
+ * Read an environment variable as a boolean
+ * Return -1 if variable does not exist (default to true)
+ */
+int getenv_yesno(const char *var);
 int    saveenv      (void);
 int    setenv       (const char *, const char *);
 int setenv_ulong(const char *varname, ulong value);
index f434cd08910e5f71ffaaa07ae512681b6117788b..e82f6421c0af6e2cd91eaf0c88e9fae371f620cf 100644 (file)
 #define CONFIG_CMD_FDOS                /* Floppy DOS support           */
 #define CONFIG_CMD_FLASH       /* flinfo, erase, protect       */
 #define CONFIG_CMD_FPGA                /* FPGA configuration Support   */
+#define CONFIG_CMD_GETTIME     /* Get time since boot         */
+#define CONFIG_CMD_HASH                /* calculate hash / digest      */
 #define CONFIG_CMD_HWFLOW      /* RTS/CTS hw flow control      */
 #define CONFIG_CMD_I2C         /* I2C serial bus support       */
 #define CONFIG_CMD_IDE         /* IDE harddisk support         */
 #define CONFIG_CMD_IMI         /* iminfo                       */
 #define CONFIG_CMD_IMLS                /* List all found images        */
 #define CONFIG_CMD_IMMAP       /* IMMR dump support            */
+#define CONFIG_CMD_IO          /* Access to X86 IO space       */
 #define CONFIG_CMD_IRQ         /* irqinfo                      */
 #define CONFIG_CMD_ITEST       /* Integer (and string) test    */
 #define CONFIG_CMD_JFFS2       /* JFFS2 Support                */
@@ -70,6 +73,7 @@
 #define CONFIG_CMD_REGINFO     /* Register dump                */
 #define CONFIG_CMD_REISER      /* Reiserfs support             */
 #define CONFIG_CMD_RARP                /* rarpboot support             */
+#define CONFIG_CMD_READ                /* Read data from partition     */
 #define CONFIG_CMD_RUN         /* run command in env variable  */
 #define CONFIG_CMD_SAVEENV     /* saveenv                      */
 #define CONFIG_CMD_SAVES       /* save S record dump           */
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 1daec6967780ce4863b583b8cef832eb23603df3..6bceccbc14b355b009fc276181753e506fcaf298 100644 (file)
 
 
 #define CONFIG_SYS_LOAD_ADDR           0x100000        /* where to load what we get from TFTP */
-#define CONFIG_SYS_TFTP_LOADADDR       CONFIG_SYS_LOAD_ADDR
 #define CONFIG_SYS_EXTBDINFO           1               /* To use extended board_into (bd_t) */
 #define CONFIG_SYS_DRAM_TEST           1
 
index b98caccb817f22b65dad63b0cc06f97751d71ce5..9a649ca125fec2ca3682c93aa18ab1d35075ce00 100644 (file)
 #undef CONFIG_LOADS_ECHO
 #define        CONFIG_SYS_LOADS_BAUD_CHANGE
 
-/*
- * Set default load address for tftp network downloads
- */
-#define        CONFIG_SYS_TFTP_LOADADDR                                0x01000000
-
 /*
  * Turn off the watchdog timer
  */
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             */
index 36921ca8b9ce05980153a215aecceea4835de839..4849f94c99184e1b1c200baf220f3f9796950403 100644 (file)
 #define CONFIG_IPADDR                                  10.0.4.111
 
 #define CONFIG_SYS_LOAD_ADDR           0x00100000      /* default load address */
-#define        CONFIG_SYS_TFTP_LOADADDR        0x00100000
 
 /*
  * For booting Linux, the board info and command line data
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 aed40c8927ad5491a43c683ba99b7aa5cbafbc31..72459d859d18e5e1c8a7ecc7a9d71113e54607f0 100644 (file)
 #define CONFIG_SPL_BOARD_INIT
 #define CONFIG_SPL_NAND_AM33XX_BCH
 #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     (CONFIG_SYS_NAND_BLOCK_SIZE / \
                                         CONFIG_SYS_NAND_PAGE_SIZE)
 #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 ccfe032ca731fe7e79a57bddd9f14ae0cd2b52f7..5a87cc5d3d6c627f26d9f8518122e125fa08531b 100644 (file)
 #define        CONFIG_CLOCKS_IN_MHZ    1      /* clocks passsed to Linux in MHz */
 
 #define CONFIG_SYS_LOAD_ADDR     0x00100000   /* default load address */
-#define CONFIG_SYS_TFTP_LOADADDR 0x00100000   /* default load address for network file downloads */
 
 #define CONFIG_SYS_HZ            1000         /* decrementer freq: 1 ms ticks */
 
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 85eed8e17c1b2e457657d8ddc85a71a6f8c16f5d..43dd06e2467d59e36822283dabad29c0b4bf3d04 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 b49ec8c7dd61fd4139a145bb62f2f730b23c025f..3f37e8430c516b3367904ab62c14c9daa12143b4 100644 (file)
                "if tftp ${update_nand_full_filename} ; then "          \
                "run update_nand_get_fcb_size ; "                       \
                "nand scrub -y 0x0 ${filesize} ; "                      \
-               "nand write.raw ${loadaddr} 0x0 ${update_nand_fcb} ; "  \
+               "nand write.raw ${loadaddr} 0x0 ${fcb_sz} ; "   \
                "setexpr update_off ${loadaddr} + ${update_nand_fcb} ; " \
                "setexpr update_sz ${filesize} - ${update_nand_fcb} ; " \
                "nand write ${update_off} ${update_nand_fcb} ${update_sz} ; " \
index a436149a5735e1177f3f0119b4fc0835e642ec3b..185faa7ef18c3d1bbb0711c71b48be211213bf64 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 b5338a0009030022e253deec6d808a0708eecd82..c10e78b634bd1abe6db46715ebf87585ff98a142 100644 (file)
@@ -87,6 +87,7 @@
 
 /* U-Boot commands */
 #include <config_cmd_default.h>
+#define CONFIG_OF_LIBFDT
 #define CONFIG_CMD_BOOTZ
 #define CONFIG_CMD_CACHE
 #define CONFIG_CMD_MMC
 #define CONFIG_SYS_FSL_ESDHC_NUM       1
 
 /* 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_MC34704
 #define CONFIG_SYS_FSL_PMIC_I2C_ADDR   0x54
 
index 8b89b25f74d73e9282d7cfb0927271efd53bbd6b..cdf3e1508e2471ce85a3a1e33d4097cefbf9b099 100644 (file)
                "if tftp ${update_nand_full_filename} ; then " \
                "run update_nand_get_fcb_size ; " \
                "nand scrub -y 0x0 ${filesize} ; " \
-               "nand write.raw ${loadaddr} 0x0 ${update_nand_fcb} ; " \
+               "nand write.raw ${loadaddr} 0x0 ${fcb_sz} ; " \
                "setexpr update_off ${loadaddr} + ${update_nand_fcb} ; " \
                "setexpr update_sz ${filesize} - ${update_nand_fcb} ; " \
                "nand write ${update_off} ${update_nand_fcb} ${update_sz} ; " \
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 741cbd9cef312383bde52324af622859ce449430..d0daa455e5243ccbf616c4352a12e414319fe2ca 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..fc6e78208c5ddcc23dee32190f3663651cc77b75 100644 (file)
 #define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME       "u-boot.img"
 
 /* Partition tables */
-/* Only need DOS partition support for SPL, currently */
-#ifndef CONFIG_SPL_BUILD
 #define CONFIG_EFI_PARTITION
-#endif
 #define CONFIG_DOS_PARTITION
 
 /* USB
 /* 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 035c27fe94797e8905a7fd66fddc365b5227c842..eb13bb3a671c0461419880ca291e95191d18b64c 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 c2d1c66215f3ffa3d563af6f5a740e143cbcc548..de0c777819b2b4a41d18dbd3188a611df2390306 100644 (file)
 #define CONFIG_TEGRA_KEYBOARD
 #define CONFIG_KEYBOARD
 
-#undef TEGRA_DEVICE_SETTINGS
-#define TEGRA_DEVICE_SETTINGS  "stdin=serial,tegra-kbc\0" \
-                               "stdout=serial,lcd\0" \
-                               "stderr=serial,lcd\0"
+/* USB keyboard */
+#define CONFIG_USB_KEYBOARD
 
 /* LCD support */
 #define CONFIG_LCD
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 e412da8c9d8f7e18a568a64f678850a6616f166f..75c25c00348fd87bef18728baa528a1ab69850a6 100644 (file)
@@ -65,7 +65,7 @@
 #define INFORM1_OFFSET                 0x804
 
 /* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + (1 << 20))
+#define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + (4 << 20))
 
 /* select serial console configuration */
 #define CONFIG_SERIAL3                 /* use SERIAL 3 */
 #define CONFIG_I2C_MULTI_BUS
 #define CONFIG_MAX_I2C_NUM     8
 #define CONFIG_SYS_I2C_SLAVE    0x0
+#define CONFIG_I2C_EDID
 
 /* PMIC */
 #define CONFIG_PMIC
 #define CONFIG_ENV_SPI_MAX_HZ  50000000
 #endif
 
+/* PMIC */
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_MAX77686
+
+/* SPI */
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_SPI_FLASH
+
+#ifdef CONFIG_SPI_FLASH
+#define CONFIG_EXYNOS_SPI
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_SF_DEFAULT_MODE         SPI_MODE_0
+#define CONFIG_SF_DEFAULT_SPEED                50000000
+#define EXYNOS5_SPI_NUM_CONTROLLERS    5
+#endif
+
+#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_SPI_MODE    SPI_MODE_0
+#define CONFIG_ENV_SECT_SIZE   CONFIG_ENV_SIZE
+#define CONFIG_ENV_SPI_BUS     1
+#define CONFIG_ENV_SPI_MAX_HZ  50000000
+#endif
+
 /* Ethernet Controllor Driver */
 #ifdef CONFIG_CMD_NET
 #define CONFIG_SMC911X
 /* Enable devicetree support */
 #define CONFIG_OF_LIBFDT
 
+/* SHA hashing */
+#define CONFIG_CMD_HASH
+#define CONFIG_HASH_VERIFY
+#define CONFIG_SHA1
+#define CONFIG_SHA256
+
 #endif /* __CONFIG_H */
index c377678929df173d2966e3a5f24410f92e647443..9f1fb9feef8f9df717d3d130b32d0e866b86d729 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 2d0d61dc9d4a91dc229f1d3f88983ae6d4dd7347..ee40cc2a3e0e26a38d3ddf58bf5f74c01db5c190 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,lcd\0" \
+       "stderr=serial,lcd\0" \
+
 #define CONFIG_EXTRA_ENV_SETTINGS \
        TEGRA_DEVICE_SETTINGS \
        MEM_LAYOUT_ENV_SETTINGS \
index 72b661a895e90e6e3367aa170470fb0ce50b72ff..fe07f72260de43ef37cd982fab60fa9ccb9ff0bc 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 a24e945313f474b4160c75697d6243a35652ecdd..6efee5c47707b4c1678ba06786df90e4deff4a8d 100644 (file)
@@ -98,6 +98,7 @@
 #undef CONFIG_CMD_MTDPARTS
 #define CONFIG_CMD_MMC
 #define CONFIG_CMD_DFU
+#define CONFIG_CMD_GPT
 
 /* FAT */
 #define CONFIG_CMD_FAT
 #define CONFIG_BOOTBLOCK               "10"
 #define CONFIG_ENV_COMMON_BOOT         "${console} ${meminfo}"
 
+/* Tizen - partitions definitions */
+#define PARTS_CSA              "csa-mmc"
+#define PARTS_BOOTLOADER       "u-boot"
+#define PARTS_BOOT             "boot"
+#define PARTS_ROOT             "platform"
+#define PARTS_DATA             "data"
+#define PARTS_CSC              "csc"
+#define PARTS_UMS              "ums"
+
+#define PARTS_DEFAULT \
+       "uuid_disk=${uuid_gpt_disk};" \
+       "name="PARTS_CSA",size=8MiB,uuid=${uuid_gpt_"PARTS_CSA"};" \
+       "name="PARTS_BOOTLOADER",size=60MiB," \
+               "uuid=${uuid_gpt_"PARTS_BOOTLOADER"};" \
+       "name="PARTS_BOOT",size=100MiB,uuid=${uuid_gpt_"PARTS_BOOT"};" \
+       "name="PARTS_ROOT",size=1GiB,uuid=${uuid_gpt_"PARTS_ROOT"};" \
+       "name="PARTS_DATA",size=3GiB,uuid=${uuid_gpt_"PARTS_DATA"};" \
+       "name="PARTS_CSC",size=150MiB,uuid=${uuid_gpt_"PARTS_CSC"};" \
+       "name="PARTS_UMS",size=-,uuid=${uuid_gpt_"PARTS_UMS"}\0" \
+
 #define CONFIG_DFU_ALT \
        "dfu_alt_info=" \
        "u-boot mmc 80 400;" \
        "mmcbootpart=2\0" \
        "mmcrootpart=3\0" \
        "opts=always_resume=1\0" \
-       CONFIG_DFU_ALT
+       "partitions=" PARTS_DEFAULT \
+       CONFIG_DFU_ALT \
 
 /* Miscellaneous configurable options */
 #define CONFIG_SYS_LONGHELP            /* undef to save memory */
 
 #define CONFIG_DOS_PARTITION
 
+/* GPT */
+#define CONFIG_EFI_PARTITION
+#define CONFIG_PARTITION_UUIDS
+
 #define CONFIG_SYS_INIT_SP_ADDR        (CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE)
 #define CONFIG_SYS_CACHELINE_SIZE       32
 
 #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 c5c058508b7b6b1d19da36364d2ee04e2cfd5684..bcb0350b8c740b747606c5d07ab800fc2b1e414e 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 d203bb4dd7fc3fa35eabeea467412534692c4da6..66568c8d004b63bc52d4df7dadae752184585238 100644 (file)
@@ -65,7 +65,6 @@
 #define CONFIG_BOOTARGS                "root=/dev/ram console=ttyS0,57600" /* RAMdisk */
 #define CONFIG_ETHADDR         00:AA:00:14:00:05       /* UTX5 */
 #define CONFIG_SERVERIP                10.8.17.105     /* Spree */
-#define CONFIG_SYS_TFTP_LOADADDR       10000
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
        "kernel_addr=FFA00000\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 8f455221c908e734e6b8131790ad0536f444f9d3..b55ebc9bfc00a890496dcac8a17d813f14b7a5f5 100644 (file)
@@ -78,6 +78,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
 
diff --git a/include/edid.h b/include/edid.h
new file mode 100644 (file)
index 0000000..4788de9
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * (C) Copyright 2010
+ * Petr Stetiar <ynezz@true.cz>
+ *
+ * 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
+ *
+ * Contains stolen code from ddcprobe project which is:
+ * Copyright (C) Nalin Dahyabhai <bigfun@pobox.com>
+ *
+ */
+
+#ifndef __EDID_H_
+#define __EDID_H_
+
+#include <linux/types.h>
+
+#define GET_BIT(_x, _pos) \
+       (((_x) >> (_pos)) & 1)
+#define GET_BITS(_x, _pos_msb, _pos_lsb) \
+       (((_x) >> (_pos_lsb)) & ((1 << ((_pos_msb) - (_pos_lsb) + 1)) - 1))
+
+/* Aspect ratios used in EDID info. */
+enum edid_aspect {
+       ASPECT_625 = 0,
+       ASPECT_75,
+       ASPECT_8,
+       ASPECT_5625,
+};
+
+/* Detailed timing information used in EDID v1.x */
+struct edid_detailed_timing {
+       unsigned char pixel_clock[2];
+#define EDID_DETAILED_TIMING_PIXEL_CLOCK(_x) \
+       (((((uint32_t)(_x).pixel_clock[1]) << 8) + \
+        (_x).pixel_clock[0]) * 10000)
+       unsigned char horizontal_active;
+       unsigned char horizontal_blanking;
+       unsigned char horizontal_active_blanking_hi;
+#define EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(_x) \
+       ((GET_BITS((_x).horizontal_active_blanking_hi, 7, 4) << 8) + \
+        (_x).horizontal_active)
+#define EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(_x) \
+       ((GET_BITS((_x).horizontal_active_blanking_hi, 3, 0) << 8) + \
+        (_x).horizontal_blanking)
+       unsigned char vertical_active;
+       unsigned char vertical_blanking;
+       unsigned char vertical_active_blanking_hi;
+#define EDID_DETAILED_TIMING_VERTICAL_ACTIVE(_x) \
+       ((GET_BITS((_x).vertical_active_blanking_hi, 7, 4) << 8) + \
+        (_x).vertical_active)
+#define EDID_DETAILED_TIMING_VERTICAL_BLANKING(_x) \
+       ((GET_BITS((_x).vertical_active_blanking_hi, 3, 0) << 8) + \
+        (_x).vertical_blanking)
+       unsigned char hsync_offset;
+       unsigned char hsync_pulse_width;
+       unsigned char sync_offset_pulse_width;
+       unsigned char hsync_vsync_offset_pulse_width_hi;
+#define EDID_DETAILED_TIMING_HSYNC_OFFSET(_x) \
+       ((GET_BITS((_x).hsync_vsync_offset_pulse_width_hi, 7, 6) << 8) + \
+        (_x).hsync_offset)
+#define EDID_DETAILED_TIMING_HSYNC_PULSE_WIDTH(_x) \
+       ((GET_BITS((_x).hsync_vsync_offset_pulse_width_hi, 5, 4) << 8) + \
+        (_x).hsync_pulse_width)
+#define EDID_DETAILED_TIMING_VSYNC_OFFSET(_x) \
+       ((GET_BITS((_x).hsync_vsync_offset_pulse_width_hi, 3, 2) << 4) + \
+        GET_BITS((_x).vsync_offset_pulse_width, 7, 4))
+#define EDID_DETAILED_TIMING_VSYNC_PULSE_WIDTH(_x) \
+       ((GET_BITS((_x).hsync_vsync_offset_pulse_width_hi, 1, 0) << 4) + \
+        GET_BITS((_x).vsync_offset_pulse_width, 3, 0))
+       unsigned char himage_size;
+       unsigned char vimage_size;
+       unsigned char himage_vimage_size_hi;
+#define EDID_DETAILED_TIMING_HIMAGE_SIZE(_x) \
+       ((GET_BITS((_x).himage_vimage_size_hi, 7, 4) << 8) + (_x).himage_size)
+#define EDID_DETAILED_TIMING_VIMAGE_SIZE(_x) \
+       ((GET_BITS((_x).himage_vimage_size_hi, 3, 0) << 8) + (_x).vimage_size)
+       unsigned char hborder;
+       unsigned char vborder;
+       unsigned char flags;
+#define EDID_DETAILED_TIMING_FLAG_INTERLACED(_x) \
+       GET_BIT((_x).flags, 7)
+#define EDID_DETAILED_TIMING_FLAG_STEREO(_x) \
+       GET_BITS((_x).flags, 6, 5)
+#define EDID_DETAILED_TIMING_FLAG_DIGITAL_COMPOSITE(_x) \
+       GET_BITS((_x).flags, 4, 3)
+#define EDID_DETAILED_TIMING_FLAG_POLARITY(_x) \
+       GET_BITS((_x).flags, 2, 1)
+#define EDID_DETAILED_TIMING_FLAG_INTERLEAVED(_x) \
+       GET_BIT((_x).flags, 0)
+} __attribute__ ((__packed__));
+
+enum edid_monitor_descriptor_types {
+       EDID_MONITOR_DESCRIPTOR_SERIAL = 0xff,
+       EDID_MONITOR_DESCRIPTOR_ASCII = 0xfe,
+       EDID_MONITOR_DESCRIPTOR_RANGE = 0xfd,
+       EDID_MONITOR_DESCRIPTOR_NAME = 0xfc,
+};
+
+struct edid_monitor_descriptor {
+       uint16_t zero_flag_1;
+       unsigned char zero_flag_2;
+       unsigned char type;
+       unsigned char zero_flag_3;
+       union {
+               char string[13];
+               struct {
+                       unsigned char vertical_min;
+                       unsigned char vertical_max;
+                       unsigned char horizontal_min;
+                       unsigned char horizontal_max;
+                       unsigned char pixel_clock_max;
+                       unsigned char gtf_data[8];
+               } range_data;
+       } data;
+} __attribute__ ((__packed__));
+
+struct edid1_info {
+       unsigned char header[8];
+       unsigned char manufacturer_name[2];
+#define EDID1_INFO_MANUFACTURER_NAME_ZERO(_x) \
+       GET_BIT(((_x).manufacturer_name[0]), 7)
+#define EDID1_INFO_MANUFACTURER_NAME_CHAR1(_x) \
+       GET_BITS(((_x).manufacturer_name[0]), 6, 2)
+#define EDID1_INFO_MANUFACTURER_NAME_CHAR2(_x) \
+       ((GET_BITS(((_x).manufacturer_name[0]), 1, 0) << 3) + \
+        GET_BITS(((_x).manufacturer_name[1]), 7, 5))
+#define EDID1_INFO_MANUFACTURER_NAME_CHAR3(_x) \
+       GET_BITS(((_x).manufacturer_name[1]), 4, 0)
+       unsigned char product_code[2];
+#define EDID1_INFO_PRODUCT_CODE(_x) \
+       (((uint16_t)(_x).product_code[1] << 8) + (_x).product_code[0])
+       unsigned char serial_number[4];
+#define EDID1_INFO_SERIAL_NUMBER(_x) \
+       (((uint32_t)(_x).serial_number[3] << 24) + \
+        ((_x).serial_number[2] << 16) + ((_x).serial_number[1] << 8) + \
+        (_x).serial_number[0])
+       unsigned char week;
+       unsigned char year;
+       unsigned char version;
+       unsigned char revision;
+       unsigned char video_input_definition;
+#define EDID1_INFO_VIDEO_INPUT_DIGITAL(_x) \
+       GET_BIT(((_x).video_input_definition), 7)
+#define EDID1_INFO_VIDEO_INPUT_VOLTAGE_LEVEL(_x) \
+       GET_BITS(((_x).video_input_definition), 6, 5)
+#define EDID1_INFO_VIDEO_INPUT_BLANK_TO_BLACK(_x) \
+       GET_BIT(((_x).video_input_definition), 4)
+#define EDID1_INFO_VIDEO_INPUT_SEPARATE_SYNC(_x) \
+       GET_BIT(((_x).video_input_definition), 3)
+#define EDID1_INFO_VIDEO_INPUT_COMPOSITE_SYNC(_x) \
+       GET_BIT(((_x).video_input_definition), 2)
+#define EDID1_INFO_VIDEO_INPUT_SYNC_ON_GREEN(_x) \
+       GET_BIT(((_x).video_input_definition), 1)
+#define EDID1_INFO_VIDEO_INPUT_SERRATION_V(_x) \
+       GET_BIT(((_x).video_input_definition), 0)
+       unsigned char max_size_horizontal;
+       unsigned char max_size_vertical;
+       unsigned char gamma;
+       unsigned char feature_support;
+#define EDID1_INFO_FEATURE_STANDBY(_x) \
+       GET_BIT(((_x).feature_support), 7)
+#define EDID1_INFO_FEATURE_SUSPEND(_x) \
+       GET_BIT(((_x).feature_support), 6)
+#define EDID1_INFO_FEATURE_ACTIVE_OFF(_x) \
+       GET_BIT(((_x).feature_support), 5)
+#define EDID1_INFO_FEATURE_DISPLAY_TYPE(_x) \
+       GET_BITS(((_x).feature_support), 4, 3)
+#define EDID1_INFO_FEATURE_RGB(_x) \
+       GET_BIT(((_x).feature_support), 2)
+#define EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(_x) \
+       GET_BIT(((_x).feature_support), 1)
+#define EDID1_INFO_FEATURE_DEFAULT_GTF_SUPPORT(_x) \
+       GET_BIT(((_x).feature_support), 0)
+       unsigned char color_characteristics[10];
+       unsigned char established_timings[3];
+#define EDID1_INFO_ESTABLISHED_TIMING_720X400_70(_x) \
+       GET_BIT(((_x).established_timings[0]), 7)
+#define EDID1_INFO_ESTABLISHED_TIMING_720X400_88(_x) \
+       GET_BIT(((_x).established_timings[0]), 6)
+#define EDID1_INFO_ESTABLISHED_TIMING_640X480_60(_x) \
+       GET_BIT(((_x).established_timings[0]), 5)
+#define EDID1_INFO_ESTABLISHED_TIMING_640X480_67(_x) \
+       GET_BIT(((_x).established_timings[0]), 4)
+#define EDID1_INFO_ESTABLISHED_TIMING_640X480_72(_x) \
+       GET_BIT(((_x).established_timings[0]), 3)
+#define EDID1_INFO_ESTABLISHED_TIMING_640X480_75(_x) \
+       GET_BIT(((_x).established_timings[0]), 2)
+#define EDID1_INFO_ESTABLISHED_TIMING_800X600_56(_x) \
+       GET_BIT(((_x).established_timings[0]), 1)
+#define EDID1_INFO_ESTABLISHED_TIMING_800X600_60(_x) \
+       GET_BIT(((_x).established_timings[0]), 0)
+#define EDID1_INFO_ESTABLISHED_TIMING_800X600_72(_x) \
+       GET_BIT(((_x).established_timings[1]), 7)
+#define EDID1_INFO_ESTABLISHED_TIMING_800X600_75(_x) \
+       GET_BIT(((_x).established_timings[1]), 6)
+#define EDID1_INFO_ESTABLISHED_TIMING_832X624_75(_x) \
+       GET_BIT(((_x).established_timings[1]), 5)
+#define EDID1_INFO_ESTABLISHED_TIMING_1024X768_87I(_x) \
+       GET_BIT(((_x).established_timings[1]), 4)
+#define EDID1_INFO_ESTABLISHED_TIMING_1024X768_60(_x) \
+       GET_BIT(((_x).established_timings[1]), 3)
+#define EDID1_INFO_ESTABLISHED_TIMING_1024X768_70(_x) \
+       GET_BIT(((_x).established_timings[1]), 2)
+#define EDID1_INFO_ESTABLISHED_TIMING_1024X768_75(_x) \
+       GET_BIT(((_x).established_timings[1]), 1)
+#define EDID1_INFO_ESTABLISHED_TIMING_1280X1024_75(_x) \
+       GET_BIT(((_x).established_timings[1]), 0)
+#define EDID1_INFO_ESTABLISHED_TIMING_1152X870_75(_x) \
+       GET_BIT(((_x).established_timings[2]), 7)
+       struct {
+               unsigned char xresolution;
+               unsigned char aspect_vfreq;
+       } __attribute__((__packed__)) standard_timings[8];
+#define EDID1_INFO_STANDARD_TIMING_XRESOLUTION(_x, _i) \
+       (((_x).standard_timings[_i]).xresolution)
+#define EDID1_INFO_STANDARD_TIMING_ASPECT(_x, _i) \
+       GET_BITS(((_x).standard_timings[_i].aspect_vfreq), 7, 6)
+#define EDID1_INFO_STANDARD_TIMING_VFREQ(_x, _i) \
+       GET_BITS(((_x).standard_timings[_i].aspect_vfreq), 5, 0)
+       union {
+               unsigned char timing[72];
+               struct edid_monitor_descriptor descriptor[4];
+       } monitor_details;
+       unsigned char extension_flag;
+       unsigned char checksum;
+} __attribute__ ((__packed__));
+
+/**
+ * Print the EDID info.
+ *
+ * @param edid_info    The EDID info to be printed
+ */
+void edid_print_info(struct edid1_info *edid_info);
+
+/**
+ * Check the EDID info.
+ *
+ * @param info  The EDID info to be checked
+ * @return 0 on valid, or -1 on invalid
+ */
+int edid_check_info(struct edid1_info *info);
+
+/**
+ * Get the horizontal and vertical rate ranges of the monitor.
+ *
+ * @param edid The EDID info
+ * @param hmin Returns the minimum horizontal rate
+ * @param hmax Returns the maxium horizontal rate
+ * @param vmin Returns the minimum vertical rate
+ * @param vmax Returns the maxium vertical rate
+ * @return 0 on success, or -1 on error
+ */
+int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin,
+                   unsigned int *hmax, unsigned int *vmin,
+                   unsigned int *vmax);
+
+#endif /* __EDID_H_ */
diff --git a/include/env_attr.h b/include/env_attr.h
new file mode 100644 (file)
index 0000000..6ef114f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2012
+ * Joe Hershberger, National Instruments, joe.hershberger@ni.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 __ENV_ATTR_H__
+#define __ENV_ATTR_H__
+
+#define ENV_ATTR_LIST_DELIM    ','
+#define ENV_ATTR_SEP           ':'
+
+/*
+ * env_attr_walk takes as input an "attr_list" that takes the form:
+ *     attributes = [^,:\s]*
+ *     entry = name[:attributes]
+ *     list = entry[,list]
+ * It will call the "callback" function with the "name" and attribute as "value"
+ * The callback may return a non-0 to abort the list walk.
+ * This return value will be passed through to the caller.
+ * 0 is returned on success.
+ */
+extern int env_attr_walk(const char *attr_list,
+       int (*callback)(const char *name, const char *value));
+
+/*
+ * env_attr_lookup takes as input an "attr_list" with the same form as above.
+ * It also takes as input a "name" to look for.
+ * If the name is found in the list, it's value is copied into "attributes".
+ * There is no protection on attributes being too small for the value.
+ * It returns -1 if attributes is NULL, 1 if "name" is not found, 2 if
+ * "attr_list" is NULL.
+ * Returns 0 on success.
+ */
+extern int env_attr_lookup(const char *attr_list, const char *name,
+       char *attributes);
+
+#endif /* __ENV_ATTR_H__ */
diff --git a/include/env_callback.h b/include/env_callback.h
new file mode 100644 (file)
index 0000000..47fdc6f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2012
+ * Joe Hershberger, National Instruments, joe.hershberger@ni.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 __ENV_CALLBACK_H__
+#define __ENV_CALLBACK_H__
+
+#include <env_flags.h>
+#include <linker_lists.h>
+#include <search.h>
+
+#define ENV_CALLBACK_VAR ".callbacks"
+
+/* Board configs can define additional static callback bindings */
+#ifndef CONFIG_ENV_CALLBACK_LIST_STATIC
+#define CONFIG_ENV_CALLBACK_LIST_STATIC
+#endif
+
+#ifdef CONFIG_SILENT_CONSOLE
+#define SILENT_CALLBACK "silent:silent,"
+#else
+#define SILENT_CALLBACK
+#endif
+
+/*
+ * This list of callback bindings is static, but may be overridden by defining
+ * a new association in the ".callbacks" environment variable.
+ */
+#define ENV_CALLBACK_LIST_STATIC ENV_CALLBACK_VAR ":callbacks," \
+       ENV_FLAGS_VAR ":flags," \
+       "baudrate:baudrate," \
+       "bootfile:bootfile," \
+       "loadaddr:loadaddr," \
+       SILENT_CALLBACK \
+       "stdin:console,stdout:console,stderr:console," \
+       CONFIG_ENV_CALLBACK_LIST_STATIC
+
+struct env_clbk_tbl {
+       const char *name;               /* Callback name */
+       int (*callback)(const char *name, const char *value, enum env_op op,
+               int flags);
+};
+
+struct env_clbk_tbl *find_env_callback(const char *);
+void env_callback_init(ENTRY *var_entry);
+
+/*
+ * Define a callback that can be associated with variables.
+ * when associated through the ".callbacks" environment variable, the callback
+ * will be executed any time the variable is inserted, overwritten, or deleted.
+ */
+#define U_BOOT_ENV_CALLBACK(name, callback) \
+       ll_entry_declare(struct env_clbk_tbl, name, env_clbk, env_clbk) = \
+       {#name, callback}
+
+#endif /* __ENV_CALLBACK_H__ */
index a1db73a2c559324c2360bded35188335a7da51ee..39c5b7c6aa3b0e09c006d91bf6ec57567f4d3b22 100644 (file)
@@ -24,6 +24,8 @@
  * MA 02111-1307 USA
  */
 
+#include <env_callback.h>
+
 #ifdef DEFAULT_ENV_INSTANCE_EMBEDDED
 env_t environment __PPCENV__ = {
        ENV_CRC,        /* CRC Sum */
@@ -36,6 +38,12 @@ static char default_environment[] = {
 #else
 const uchar default_environment[] = {
 #endif
+#ifdef CONFIG_ENV_CALLBACK_LIST_DEFAULT
+       ENV_CALLBACK_VAR "=" CONFIG_ENV_CALLBACK_LIST_DEFAULT "\0"
+#endif
+#ifdef CONFIG_ENV_FLAGS_LIST_DEFAULT
+       ENV_FLAGS_VAR "=" CONFIG_ENV_FLAGS_LIST_DEFAULT "\0"
+#endif
 #ifdef CONFIG_BOOTARGS
        "bootargs="     CONFIG_BOOTARGS                 "\0"
 #endif
diff --git a/include/env_flags.h b/include/env_flags.h
new file mode 100644 (file)
index 0000000..d1aa144
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * (C) Copyright 2012
+ * Joe Hershberger, National Instruments, joe.hershberger@ni.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 __ENV_FLAGS_H__
+#define __ENV_FLAGS_H__
+
+enum env_flags_vartype {
+       env_flags_vartype_string,
+       env_flags_vartype_decimal,
+       env_flags_vartype_hex,
+       env_flags_vartype_bool,
+#ifdef CONFIG_CMD_NET
+       env_flags_vartype_ipaddr,
+       env_flags_vartype_macaddr,
+#endif
+       env_flags_vartype_end
+};
+
+enum env_flags_varaccess {
+       env_flags_varaccess_any,
+       env_flags_varaccess_readonly,
+       env_flags_varaccess_writeonce,
+       env_flags_varaccess_changedefault,
+       env_flags_varaccess_end
+};
+
+#define ENV_FLAGS_VAR ".flags"
+#define ENV_FLAGS_ATTR_MAX_LEN 2
+#define ENV_FLAGS_VARTYPE_LOC 0
+#define ENV_FLAGS_VARACCESS_LOC 1
+
+#ifndef CONFIG_ENV_FLAGS_LIST_STATIC
+#define CONFIG_ENV_FLAGS_LIST_STATIC ""
+#endif
+
+#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_ENV_OVERWRITE
+#define ETHADDR_FLAGS "ethaddr:ma,"
+#else
+#ifdef CONFIG_OVERWRITE_ETHADDR_ONCE
+#define ETHADDR_FLAGS "ethaddr:mc,"
+#else
+#define ETHADDR_FLAGS "ethaddr:mo,"
+#endif
+#endif
+#else
+#define ETHADDR_FLAGS ""
+#endif
+
+#ifndef CONFIG_ENV_OVERWRITE
+#define SERIAL_FLAGS "serial#:so,"
+#else
+#define SERIAL_FLAGS ""
+#endif
+
+#define ENV_FLAGS_LIST_STATIC \
+       ETHADDR_FLAGS \
+       SERIAL_FLAGS \
+       CONFIG_ENV_FLAGS_LIST_STATIC
+
+#ifdef CONFIG_CMD_ENV_FLAGS
+/*
+ * Print the whole list of available type flags.
+ */
+void env_flags_print_vartypes(void);
+/*
+ * Print the whole list of available access flags.
+ */
+void env_flags_print_varaccess(void);
+/*
+ * Return the name of the type.
+ */
+const char *env_flags_get_vartype_name(enum env_flags_vartype type);
+/*
+ * Return the name of the access.
+ */
+const char *env_flags_get_varaccess_name(enum env_flags_varaccess access);
+#endif
+
+/*
+ * Parse the flags string from a .flags attribute list into the vartype enum.
+ */
+enum env_flags_vartype env_flags_parse_vartype(const char *flags);
+/*
+ * Parse the flags string from a .flags attribute list into the varaccess enum.
+ */
+enum env_flags_varaccess env_flags_parse_varaccess(const char *flags);
+/*
+ * Parse the binary flags from a hash table entry into the varaccess enum.
+ */
+enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags);
+
+#ifdef USE_HOSTCC
+/*
+ * Look up the type of a variable directly from the .flags var.
+ */
+enum env_flags_vartype env_flags_get_type(const char *name);
+/*
+ * Look up the access of a variable directly from the .flags var.
+ */
+enum env_flags_varaccess env_flags_get_access(const char *name);
+/*
+ * Validate the newval for its type to conform with the requirements defined by
+ * its flags (directly looked at the .flags var).
+ */
+int env_flags_validate_type(const char *name, const char *newval);
+/*
+ * Validate the newval for its access to conform with the requirements defined
+ * by its flags (directly looked at the .flags var).
+ */
+int env_flags_validate_access(const char *name, int check_mask);
+/*
+ * Validate that the proposed access to variable "name" is valid according to
+ * the defined flags for that variable, if any.
+ */
+int env_flags_validate_varaccess(const char *name, int check_mask);
+/*
+ * Validate the parameters passed to "env set" for type compliance
+ */
+int env_flags_validate_env_set_params(int argc, char * const argv[]);
+
+#else /* !USE_HOSTCC */
+
+#include <search.h>
+
+/*
+ * When adding a variable to the environment, initialize the flags for that
+ * variable.
+ */
+void env_flags_init(ENTRY *var_entry);
+
+/*
+ * Validate the newval for to conform with the requirements defined by its flags
+ */
+int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op,
+       int flag);
+
+#endif /* USE_HOSTCC */
+
+/*
+ * These are the binary flags used in the environment entry->flags variable to
+ * decribe properties of veriables in the table
+ */
+#define ENV_FLAGS_VARTYPE_BIN_MASK                     0x00000007
+/* The actual variable type values use the enum value (within the mask) */
+#define ENV_FLAGS_VARACCESS_PREVENT_DELETE             0x00000008
+#define ENV_FLAGS_VARACCESS_PREVENT_CREATE             0x00000010
+#define ENV_FLAGS_VARACCESS_PREVENT_OVERWR             0x00000020
+#define ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR      0x00000040
+#define ENV_FLAGS_VARACCESS_BIN_MASK                   0x00000078
+
+#endif /* __ENV_FLAGS_H__ */
index e8ab7033bf7e75166d2e008985215da45146471d..e64b43d2d94834760553dc9a0cd06f632022394b 100644 (file)
@@ -164,6 +164,9 @@ extern void env_reloc(void);
 
 #ifndef DO_DEPS_ONLY
 
+#include <env_attr.h>
+#include <env_callback.h>
+#include <env_flags.h>
 #include <search.h>
 
 extern struct hsearch_data env_htab;
@@ -178,6 +181,9 @@ unsigned char env_get_char_memory(int index);
 /* Function that updates CRC of the enironment */
 void env_crc_update(void);
 
+/* Look up the variable from the default environment */
+char *getenv_default(const char *name);
+
 /* [re]set to the default environment */
 void set_default_env(const char *s);
 
@@ -187,15 +193,6 @@ int set_default_vars(int nvars, char * const vars[]);
 /* Import from binary representation into hash table */
 int env_import(const char *buf, int check);
 
-/*
- * Check if variable "name" can be changed from oldval to newval,
- * and if so, apply the changes (e.g. baudrate).
- * When (flag & H_FORCE) is set, it does not print out any error
- * message and forces overwriting of write-once variables.
- */
-int env_check_apply(const char *name, const char *oldval,
-                       const char *newval, int flag);
-
 #endif /* DO_DEPS_ONLY */
 
 #endif /* _ENVIRONMENT_H_ */
index 63aa4b264a17e70687c5e2aab8851d374f2a9b45..6cf31aa5e794c0c6fb186bb6ee3705136cc40a2b 100644 (file)
@@ -23,7 +23,7 @@ char *getenv (const char *name);
 int setenv (const char *varname, const char *varvalue);
 long simple_strtol(const char *cp,char **endp,unsigned int base);
 int strcmp(const char * cs,const char * ct);
-int ustrtoul(const char *cp, char **endp, unsigned int base);
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
 #if defined(CONFIG_CMD_I2C)
 int i2c_write (uchar, uint, int , uchar* , int);
 int i2c_read (uchar, uint, int , uchar* , int);
index 64e5cffe80382d38a2323c2d5e3a1641fc9b5398..70d0e979d127b38f9358218d214a3e7b69d55c38 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 */
@@ -89,6 +91,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.
@@ -109,6 +127,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.
  *
@@ -168,6 +199,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
@@ -344,6 +390,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.
@@ -356,6 +418,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
@@ -387,4 +482,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);
diff --git a/include/hash.h b/include/hash.h
new file mode 100644 (file)
index 0000000..34ba558
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _HASH_H
+#define _HASH_H
+
+#ifdef CONFIG_SHA1SUM_VERIFY
+#define CONFIG_HASH_VERIFY
+#endif
+
+struct hash_algo {
+       const char *name;                       /* Name of algorithm */
+       int digest_size;                        /* Length of digest */
+       /**
+        * hash_func_ws: Generic hashing function
+        *
+        * This is the generic prototype for a hashing function. We only
+        * have the watchdog version at present.
+        *
+        * @input:      Input buffer
+        * @ilen:       Input buffer length
+        * @output:     Checksum result (length depends on algorithm)
+        * @chunk_sz:   Trigger watchdog after processing this many bytes
+        */
+       void (*hash_func_ws)(const unsigned char *input, unsigned int ilen,
+               unsigned char *output, unsigned int chunk_sz);
+       int chunk_size;                         /* Watchdog chunk size */
+};
+
+/*
+ * Maximum digest size for all algorithms we support. Having this value
+ * avoids a malloc() or C99 local declaration in common/cmd_hash.c.
+ */
+#define HASH_MAX_DIGEST_SIZE   32
+
+/**
+ * hash_command: Process a hash command for a particular algorithm
+ *
+ * This common function is used to implement specific hash commands.
+ *
+ * @algo_name:         Hash algorithm being used
+ * @verify:            Non-zero to enable verify mode
+ * @cmdtp:             Pointer to command table entry
+ * @flag:              Some flags normally 0 (see CMD_FLAG_.. above)
+ * @argc:              Number of arguments (arg 0 must be the command text)
+ * @argv:              Arguments
+ */
+int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag,
+                int argc, char * const argv[]);
+
+#endif
index 0a895f2044c21a4b81245caae79ef95af6a6b999..b958b18a4de2fd8fc6e8638c90149f74ced088ad 100644 (file)
@@ -460,7 +460,6 @@ static inline void image_set_name(image_header_t *hdr, const char *name)
 int image_check_hcrc(const image_header_t *hdr);
 int image_check_dcrc(const image_header_t *hdr);
 #ifndef USE_HOSTCC
-int getenv_yesno(char *var);
 ulong getenv_bootm_low(void);
 phys_size_t getenv_bootm_size(void);
 phys_size_t getenv_bootm_mapsize(void);
@@ -615,6 +614,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 8f847419612e33e60c8088ea2a87238977c4dfa1..c24164a9de0c74cf4cfb910ed695b1c6aa71f42d 100644 (file)
@@ -302,6 +302,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
diff --git a/include/linux/linux_string.h b/include/linux/linux_string.h
new file mode 100644 (file)
index 0000000..192b4c9
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _LINUX_LINUX_STRING_H_
+#define _LINUX_LINUX_STRING_H_
+
+extern char * skip_spaces(const char *);
+
+extern char *strim(char *);
+
+#endif
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 9a8cbc24cdceeef5612dcdeca82fe788b3d33f56..e9b134d1428f43786bce85d8f7dc4a6fc72d1907 100644 (file)
@@ -38,8 +38,11 @@ extern int strcmp(const char *,const char *);
 #ifndef __HAVE_ARCH_STRNCMP
 extern int strncmp(const char *,const char *,__kernel_size_t);
 #endif
-#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */
-extern int strnicmp(const char *, const char *, __kernel_size_t);
+#ifndef __HAVE_ARCH_STRCASECMP
+int strcasecmp(const char *s1, const char *s2);
+#endif
+#ifndef __HAVE_ARCH_STRNCASECMP
+extern int strncasecmp(const char *s1, const char *s2, __kernel_size_t len);
 #endif
 #ifndef __HAVE_ARCH_STRCHR
 extern char * strchr(const char *,int);
@@ -47,10 +50,7 @@ extern char * strchr(const char *,int);
 #ifndef __HAVE_ARCH_STRRCHR
 extern char * strrchr(const char *,int);
 #endif
-extern char * skip_spaces(const char *);
-
-extern char *strim(char *);
-
+#include <linux/linux_string.h>
 #ifndef __HAVE_ARCH_STRSTR
 extern char * strstr(const char *,const char *);
 #endif
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 27ea283f1edc4e583c7d329f441f190f02e4b6f0..c58a734ada0196fce6c75af2a195f660c98f10b6 100644 (file)
@@ -176,10 +176,62 @@ int   test_part_amiga (block_dev_desc_t *dev_desc);
 #endif
 
 #ifdef CONFIG_EFI_PARTITION
+#include <part_efi.h>
 /* disk/part_efi.c */
 int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 void print_part_efi (block_dev_desc_t *dev_desc);
 int   test_part_efi (block_dev_desc_t *dev_desc);
+
+/**
+ * write_gpt_table() - Write the GUID Partition Table to disk
+ *
+ * @param dev_desc - block device descriptor
+ * @param gpt_h - pointer to GPT header representation
+ * @param gpt_e - pointer to GPT partition table entries
+ *
+ * @return - zero on success, otherwise error
+ */
+int write_gpt_table(block_dev_desc_t *dev_desc,
+                 gpt_header *gpt_h, gpt_entry *gpt_e);
+
+/**
+ * gpt_fill_pte(): Fill the GPT partition table entry
+ *
+ * @param gpt_h - GPT header representation
+ * @param gpt_e - GPT partition table entries
+ * @param partitions - list of partitions
+ * @param parts - number of partitions
+ *
+ * @return zero on success
+ */
+int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
+               disk_partition_t *partitions, int parts);
+
+/**
+ * gpt_fill_header(): Fill the GPT header
+ *
+ * @param dev_desc - block device descriptor
+ * @param gpt_h - GPT header representation
+ * @param str_guid - disk guid string representation
+ * @param parts_count - number of partitions
+ *
+ * @return - error on str_guid conversion error
+ */
+int gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h,
+               char *str_guid, int parts_count);
+
+/**
+ * gpt_restore(): Restore GPT partition table
+ *
+ * @param dev_desc - block device descriptor
+ * @param str_disk_guid - disk GUID
+ * @param partitions - list of partitions
+ * @param parts - number of partitions
+ *
+ * @return zero on success
+ */
+int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,
+               disk_partition_t *partitions, const int parts_count);
 #endif
 
 #endif /* _PART_H */
similarity index 66%
rename from disk/part_efi.h
rename to include/part_efi.h
index 4e28d1dcb66c1e15d8b9b8f40b2ba9b61ca7c896..6de0a3258aa0e2257d452d429ec7cc9b4b9ee310 100644 (file)
@@ -29,6 +29,8 @@
  * http://developer.intel.com/technology/efi/efi.htm
 */
 
+#include <linux/compiler.h>
+
 #ifndef _DISK_PART_EFI_H
 #define _DISK_PART_EFI_H
 
@@ -41,6 +43,8 @@
 #define GPT_HEADER_REVISION_V1 0x00010000
 #define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
 #define GPT_ENTRY_NAME "gpt"
+#define GPT_ENTRY_NUMBERS              128
+#define GPT_ENTRY_SIZE                 128
 
 #define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
        ((efi_guid_t) \
                0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
 
 /* linux/include/efi.h */
-typedef unsigned short efi_char16_t;
+typedef u16 efi_char16_t;
 
 typedef struct {
-       unsigned char b[16];
+       u8 b[16];
 } efi_guid_t;
 
 /* based on linux/include/genhd.h */
 struct partition {
-       unsigned char boot_ind;         /* 0x80 - active */
-       unsigned char head;             /* starting head */
-       unsigned char sector;           /* starting sector */
-       unsigned char cyl;              /* starting cylinder */
-       unsigned char sys_ind;          /* What partition type */
-       unsigned char end_head;         /* end head */
-       unsigned char end_sector;       /* end sector */
-       unsigned char end_cyl;          /* end cylinder */
-       unsigned char start_sect[4];    /* starting sector counting from 0 */
-       unsigned char nr_sects[4];      /* nr of sectors in partition */
-} __attribute__ ((packed));
+       u8 boot_ind;            /* 0x80 - active */
+       u8 head;                /* starting head */
+       u8 sector;              /* starting sector */
+       u8 cyl;                 /* starting cylinder */
+       u8 sys_ind;             /* What partition type */
+       u8 end_head;            /* end head */
+       u8 end_sector;          /* end sector */
+       u8 end_cyl;             /* end cylinder */
+       __le32 start_sect;      /* starting sector counting from 0 */
+       __le32 nr_sects;        /* nr of sectors in partition */
+} __packed;
 
 /* based on linux/fs/partitions/efi.h */
 typedef struct _gpt_header {
-       unsigned char signature[8];
-       unsigned char revision[4];
-       unsigned char header_size[4];
-       unsigned char header_crc32[4];
-       unsigned char reserved1[4];
-       unsigned char my_lba[8];
-       unsigned char alternate_lba[8];
-       unsigned char first_usable_lba[8];
-       unsigned char last_usable_lba[8];
+       __le64 signature;
+       __le32 revision;
+       __le32 header_size;
+       __le32 header_crc32;
+       __le32 reserved1;
+       __le64 my_lba;
+       __le64 alternate_lba;
+       __le64 first_usable_lba;
+       __le64 last_usable_lba;
        efi_guid_t disk_guid;
-       unsigned char partition_entry_lba[8];
-       unsigned char num_partition_entries[4];
-       unsigned char sizeof_partition_entry[4];
-       unsigned char partition_entry_array_crc32[4];
-       unsigned char reserved2[GPT_BLOCK_SIZE - 92];
-} __attribute__ ((packed)) gpt_header;
+       __le64 partition_entry_lba;
+       __le32 num_partition_entries;
+       __le32 sizeof_partition_entry;
+       __le32 partition_entry_array_crc32;
+       u8 reserved2[GPT_BLOCK_SIZE - 92];
+} __packed gpt_header;
 
 typedef union _gpt_entry_attributes {
        struct {
-               unsigned long long required_to_function:1;
-               unsigned long long no_block_io_protocol:1;
-               unsigned long long legacy_bios_bootable:1;
-               unsigned long long reserved:45;
-               unsigned long long type_guid_specific:16;
+               u64 required_to_function:1;
+               u64 no_block_io_protocol:1;
+               u64 legacy_bios_bootable:1;
+               u64 reserved:45;
+               u64 type_guid_specific:16;
        } fields;
        unsigned long long raw;
-} __attribute__ ((packed)) gpt_entry_attributes;
+} __packed gpt_entry_attributes;
 
 #define PARTNAME_SZ    (72 / sizeof(efi_char16_t))
 typedef struct _gpt_entry {
        efi_guid_t partition_type_guid;
        efi_guid_t unique_partition_guid;
-       unsigned char starting_lba[8];
-       unsigned char ending_lba[8];
+       __le64 starting_lba;
+       __le64 ending_lba;
        gpt_entry_attributes attributes;
        efi_char16_t partition_name[PARTNAME_SZ];
-}
-__attribute__ ((packed)) gpt_entry;
+} __packed gpt_entry;
 
 typedef struct _legacy_mbr {
-       unsigned char boot_code[440];
-       unsigned char unique_mbr_signature[4];
-       unsigned char unknown[2];
+       u8 boot_code[440];
+       __le32 unique_mbr_signature;
+       __le16 unknown;
        struct partition partition_record[4];
-       unsigned char signature[2];
-} __attribute__ ((packed)) legacy_mbr;
+       __le16 signature;
+} __packed legacy_mbr;
 
 #endif /* _DISK_PART_EFI_H */
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 93e1cbc6d0bd6be5bcc6cecc36ddcee20d1e0e17..13d3be6291701a3170dbd3a15e873b6cc7378c82 100644 (file)
 
 #define __set_errno(val) do { errno = val; } while (0)
 
+enum env_op {
+       env_op_create,
+       env_op_delete,
+       env_op_overwrite,
+};
+
 /* Action which shall be performed in the call the hsearch.  */
 typedef enum {
        FIND,
@@ -41,6 +47,9 @@ typedef enum {
 typedef struct entry {
        const char *key;
        char *data;
+       int (*callback)(const char *name, const char *value, enum env_op op,
+               int flags);
+       int flags;
 } ENTRY;
 
 /* Opaque type for internal use.  */
@@ -59,21 +68,20 @@ struct hsearch_data {
        unsigned int filled;
 /*
  * Callback function which will check whether the given change for variable
- * "name" from "oldval" to "newval" may be applied or not, and possibly apply
- * such change.
+ * "item" to "newval" may be applied or not, and possibly apply such change.
  * When (flag & H_FORCE) is set, it shall not print out any error message and
  * shall force overwriting of write-once variables.
 .* Must return 0 for approval, 1 for denial.
  */
-       int (*apply)(const char *name, const char *oldval,
-                       const char *newval, int flag);
+       int (*change_ok)(const ENTRY *__item, const char *newval, enum env_op,
+               int flag);
 };
 
 /* Create a new hashing table which will at most contain NEL elements.  */
 extern int hcreate_r(size_t __nel, struct hsearch_data *__htab);
 
 /* Destroy current internal hashing table.  */
-extern void hdestroy_r(struct hsearch_data *__htab, int do_apply);
+extern void hdestroy_r(struct hsearch_data *__htab);
 
 /*
  * Search for entry matching ITEM.key in internal hash table.  If
@@ -82,7 +90,7 @@ extern void hdestroy_r(struct hsearch_data *__htab, int do_apply);
  * ITEM.data.
  * */
 extern int hsearch_r(ENTRY __item, ACTION __action, ENTRY ** __retval,
-                    struct hsearch_data *__htab);
+                    struct hsearch_data *__htab, int __flag);
 
 /*
  * Search for an entry matching `MATCH'.  Otherwise, Same semantics
@@ -99,10 +107,10 @@ extern int hstrstr_r(const char *__match, int __last_idx, ENTRY ** __retval,
 
 /* Search and delete entry matching ITEM.key in internal hash table. */
 extern int hdelete_r(const char *__key, struct hsearch_data *__htab,
-                       int do_apply);
+                    int __flag);
 
 extern ssize_t hexport_r(struct hsearch_data *__htab,
-                    const char __sep, char **__resp, size_t __size,
+                    const char __sep, int __flag, char **__resp, size_t __size,
                     int argc, char * const argv[]);
 
 /*
@@ -113,10 +121,15 @@ extern ssize_t hexport_r(struct hsearch_data *__htab,
  */
 extern int himport_r(struct hsearch_data *__htab,
                     const char *__env, size_t __size, const char __sep,
-                    int __flag, int nvars, char * const vars[], int do_apply);
+                    int __flag, int nvars, char * const vars[]);
+
+/* Walk the whole table calling the callback on each element */
+extern int hwalk_r(struct hsearch_data *__htab, int (*callback)(ENTRY *));
 
-/* Flags for himport_r() */
-#define        H_NOCLEAR       (1 << 0) /* do not clear hash table before importing */
-#define        H_FORCE         (1 << 1) /* overwrite read-only/write-once variables */
+/* Flags for himport_r(), hexport_r(), hdelete_r(), and hsearch_r() */
+#define H_NOCLEAR      (1 << 0) /* do not clear hash table before importing */
+#define H_FORCE                (1 << 1) /* overwrite read-only/write-once variables */
+#define H_INTERACTIVE  (1 << 2) /* indicate that an import is user directed */
+#define H_HIDE_DOT     (1 << 3) /* don't print env vars that begin with '.' */
 
 #endif /* search.h */
index 734d1fb153dc7d448e7f08e9e54f44e033b184bc..da09dab9769af05a80c7f42c42e1f489fe32cb66 100644 (file)
@@ -59,7 +59,8 @@ void sha1_starts( sha1_context *ctx );
  * \param input    buffer holding the  data
  * \param ilen    length of the input data
  */
-void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
+void sha1_update(sha1_context *ctx, const unsigned char *input,
+                unsigned int ilen);
 
 /**
  * \brief         SHA-1 final digest
@@ -76,8 +77,8 @@ void sha1_finish( sha1_context *ctx, unsigned char output[20] );
  * \param ilen    length of the input data
  * \param output   SHA-1 checksum result
  */
-void sha1_csum( unsigned char *input, int ilen,
-               unsigned char output[20] );
+void sha1_csum(const unsigned char *input, unsigned int ilen,
+               unsigned char *output);
 
 /**
  * \brief         Output = SHA-1( input buffer ), with watchdog triggering
@@ -87,17 +88,8 @@ void sha1_csum( unsigned char *input, int ilen,
  * \param output   SHA-1 checksum result
  * \param chunk_sz watchdog triggering period (in bytes of input processed)
  */
-void sha1_csum_wd (unsigned char *input, int ilen,
-               unsigned char output[20], unsigned int chunk_sz);
-
-/**
- * \brief         Output = SHA-1( file contents )
- *
- * \param path    input file name
- * \param output   SHA-1 checksum result
- * \return        0 if successful, or 1 if fopen failed
- */
-int sha1_file( char *path, unsigned char output[20] );
+void sha1_csum_wd(const unsigned char *input, unsigned int ilen,
+               unsigned char *output, unsigned int chunk_sz);
 
 /**
  * \brief         Output = HMAC-SHA-1( input buffer, hmac key )
@@ -108,9 +100,9 @@ int sha1_file( char *path, unsigned char output[20] );
  * \param ilen    length of the input data
  * \param output   HMAC-SHA-1 result
  */
-void sha1_hmac( unsigned char *key, int keylen,
-               unsigned char *input, int ilen,
-               unsigned char output[20] );
+void sha1_hmac(const unsigned char *key, int keylen,
+               const unsigned char *input, unsigned int ilen,
+               unsigned char *output);
 
 /**
  * \brief         Checkup routine
index e38ea898c3e825c7c72c683a78bf328f764ff946..beadab35ffc445a6b7d19b41cc9dc85f095facdd 100644 (file)
@@ -3,6 +3,9 @@
 
 #define SHA256_SUM_LEN 32
 
+/* Reset watchdog each time we process this many bytes */
+#define CHUNKSZ_SHA256 (64 * 1024)
+
 typedef struct {
        uint32_t total[2];
        uint32_t state[8];
@@ -10,7 +13,10 @@ typedef struct {
 } sha256_context;
 
 void sha256_starts(sha256_context * ctx);
-void sha256_update(sha256_context * ctx, uint8_t * input, uint32_t length);
+void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length);
 void sha256_finish(sha256_context * ctx, uint8_t digest[SHA256_SUM_LEN]);
 
+void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
+               unsigned char *output, unsigned int chunk_sz);
+
 #endif /* _SHA256_H */
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..86ca1a6ec1db0b16e2c3a036ddf3ba977ed034e2 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
@@ -68,6 +69,7 @@ endif
 COBJS-y += crc32.o
 COBJS-y += ctype.o
 COBJS-y += div64.o
+COBJS-y += linux_string.o
 COBJS-y += string.o
 COBJS-y += time.o
 COBJS-$(CONFIG_BOOTP_PXE) += uuid.o
index 23e020572122cbd1203b821ec02002c24d6918af..6dba4389f23c231c9b9b34a330b7afeb753689b1 100644 (file)
@@ -54,28 +54,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)
 {
@@ -113,6 +91,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;
@@ -130,7 +121,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;
 
@@ -173,7 +164,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]);
@@ -428,9 +419,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;
@@ -477,6 +467,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)
 {
        /*
@@ -514,3 +524,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 94a7b61717a8b9f0ecc6312c9dfda2130a6e6767..07ebfb218f8a6f152d915e448a2c2304a53b9f02 100644 (file)
@@ -54,7 +54,9 @@
 #define        CONFIG_ENV_MAX_ENTRIES 512
 #endif
 
-#include "search.h"
+#include <env_callback.h>
+#include <env_flags.h>
+#include <search.h>
 
 /*
  * [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
  * Instead the interface of all functions is extended to take an argument
  * which describes the current status.
  */
+
 typedef struct _ENTRY {
        int used;
        ENTRY entry;
 } _ENTRY;
 
 
+static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep,
+       int idx);
+
 /*
  * hcreate()
  */
@@ -142,7 +148,7 @@ int hcreate_r(size_t nel, struct hsearch_data *htab)
  * be freed and the local static variable can be marked as not used.
  */
 
-void hdestroy_r(struct hsearch_data *htab, int do_apply)
+void hdestroy_r(struct hsearch_data *htab)
 {
        int i;
 
@@ -156,10 +162,7 @@ void hdestroy_r(struct hsearch_data *htab, int do_apply)
        for (i = 1; i <= htab->size; ++i) {
                if (htab->table[i].used > 0) {
                        ENTRY *ep = &htab->table[i].entry;
-                       if (do_apply && htab->apply != NULL) {
-                               /* deletion is always forced */
-                               htab->apply(ep->key, ep->data, NULL, H_FORCE);
-                       }
+
                        free((void *)ep->key);
                        free(ep->data);
                }
@@ -250,14 +253,65 @@ int hmatch_r(const char *match, int last_idx, ENTRY ** retval,
        return 0;
 }
 
+/*
+ * Compare an existing entry with the desired key, and overwrite if the action
+ * is ENTER.  This is simply a helper function for hsearch_r().
+ */
+static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action,
+       ENTRY **retval, struct hsearch_data *htab, int flag,
+       unsigned int hval, unsigned int idx)
+{
+       if (htab->table[idx].used == hval
+           && strcmp(item.key, htab->table[idx].entry.key) == 0) {
+               /* Overwrite existing value? */
+               if ((action == ENTER) && (item.data != NULL)) {
+                       /* check for permission */
+                       if (htab->change_ok != NULL && htab->change_ok(
+                           &htab->table[idx].entry, item.data,
+                           env_op_overwrite, flag)) {
+                               debug("change_ok() rejected setting variable "
+                                       "%s, skipping it!\n", item.key);
+                               __set_errno(EPERM);
+                               *retval = NULL;
+                               return 0;
+                       }
+
+                       /* If there is a callback, call it */
+                       if (htab->table[idx].entry.callback &&
+                           htab->table[idx].entry.callback(item.key,
+                           item.data, env_op_overwrite, flag)) {
+                               debug("callback() rejected setting variable "
+                                       "%s, skipping it!\n", item.key);
+                               __set_errno(EINVAL);
+                               *retval = NULL;
+                               return 0;
+                       }
+
+                       free(htab->table[idx].entry.data);
+                       htab->table[idx].entry.data = strdup(item.data);
+                       if (!htab->table[idx].entry.data) {
+                               __set_errno(ENOMEM);
+                               *retval = NULL;
+                               return 0;
+                       }
+               }
+               /* return found entry */
+               *retval = &htab->table[idx].entry;
+               return idx;
+       }
+       /* keep searching */
+       return -1;
+}
+
 int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
-             struct hsearch_data *htab)
+             struct hsearch_data *htab, int flag)
 {
        unsigned int hval;
        unsigned int count;
        unsigned int len = strlen(item.key);
        unsigned int idx;
        unsigned int first_deleted = 0;
+       int ret;
 
        /* Compute an value for the given string. Perhaps use a better method. */
        hval = len;
@@ -289,23 +343,10 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
                    && !first_deleted)
                        first_deleted = idx;
 
-               if (htab->table[idx].used == hval
-                   && strcmp(item.key, htab->table[idx].entry.key) == 0) {
-                       /* Overwrite existing value? */
-                       if ((action == ENTER) && (item.data != NULL)) {
-                               free(htab->table[idx].entry.data);
-                               htab->table[idx].entry.data =
-                                       strdup(item.data);
-                               if (!htab->table[idx].entry.data) {
-                                       __set_errno(ENOMEM);
-                                       *retval = NULL;
-                                       return 0;
-                               }
-                       }
-                       /* return found entry */
-                       *retval = &htab->table[idx].entry;
-                       return idx;
-               }
+               ret = _compare_and_overwrite_entry(item, action, retval, htab,
+                       flag, hval, idx);
+               if (ret != -1)
+                       return ret;
 
                /*
                 * Second hash function:
@@ -331,23 +372,10 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
                                break;
 
                        /* If entry is found use it. */
-                       if ((htab->table[idx].used == hval)
-                           && strcmp(item.key, htab->table[idx].entry.key) == 0) {
-                               /* Overwrite existing value? */
-                               if ((action == ENTER) && (item.data != NULL)) {
-                                       free(htab->table[idx].entry.data);
-                                       htab->table[idx].entry.data =
-                                               strdup(item.data);
-                                       if (!htab->table[idx].entry.data) {
-                                               __set_errno(ENOMEM);
-                                               *retval = NULL;
-                                               return 0;
-                                       }
-                               }
-                               /* return found entry */
-                               *retval = &htab->table[idx].entry;
-                               return idx;
-                       }
+                       ret = _compare_and_overwrite_entry(item, action, retval,
+                               htab, flag, hval, idx);
+                       if (ret != -1)
+                               return ret;
                }
                while (htab->table[idx].used);
        }
@@ -383,6 +411,34 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
 
                ++htab->filled;
 
+               /* This is a new entry, so look up a possible callback */
+               env_callback_init(&htab->table[idx].entry);
+               /* Also look for flags */
+               env_flags_init(&htab->table[idx].entry);
+
+               /* check for permission */
+               if (htab->change_ok != NULL && htab->change_ok(
+                   &htab->table[idx].entry, item.data, env_op_create, flag)) {
+                       debug("change_ok() rejected setting variable "
+                               "%s, skipping it!\n", item.key);
+                       _hdelete(item.key, htab, &htab->table[idx].entry, idx);
+                       __set_errno(EPERM);
+                       *retval = NULL;
+                       return 0;
+               }
+
+               /* If there is a callback, call it */
+               if (htab->table[idx].entry.callback &&
+                   htab->table[idx].entry.callback(item.key, item.data,
+                   env_op_create, flag)) {
+                       debug("callback() rejected setting variable "
+                               "%s, skipping it!\n", item.key);
+                       _hdelete(item.key, htab, &htab->table[idx].entry, idx);
+                       __set_errno(EINVAL);
+                       *retval = NULL;
+                       return 0;
+               }
+
                /* return new entry */
                *retval = &htab->table[idx].entry;
                return 1;
@@ -404,7 +460,21 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
  * do that.
  */
 
-int hdelete_r(const char *key, struct hsearch_data *htab, int do_apply)
+static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep,
+       int idx)
+{
+       /* free used ENTRY */
+       debug("hdelete: DELETING key \"%s\"\n", key);
+       free((void *)ep->key);
+       free(ep->data);
+       ep->callback = NULL;
+       ep->flags = 0;
+       htab->table[idx].used = -1;
+
+       --htab->filled;
+}
+
+int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
 {
        ENTRY e, *ep;
        int idx;
@@ -413,20 +483,31 @@ int hdelete_r(const char *key, struct hsearch_data *htab, int do_apply)
 
        e.key = (char *)key;
 
-       if ((idx = hsearch_r(e, FIND, &ep, htab)) == 0) {
+       idx = hsearch_r(e, FIND, &ep, htab, 0);
+       if (idx == 0) {
                __set_errno(ESRCH);
                return 0;       /* not found */
        }
 
-       /* free used ENTRY */
-       debug("hdelete: DELETING key \"%s\"\n", key);
-       if (do_apply && htab->apply != NULL)
-               htab->apply(ep->key, ep->data, NULL, H_FORCE);
-       free((void *)ep->key);
-       free(ep->data);
-       htab->table[idx].used = -1;
+       /* Check for permission */
+       if (htab->change_ok != NULL &&
+           htab->change_ok(ep, NULL, env_op_delete, flag)) {
+               debug("change_ok() rejected deleting variable "
+                       "%s, skipping it!\n", key);
+               __set_errno(EPERM);
+               return 0;
+       }
 
-       --htab->filled;
+       /* If there is a callback, call it */
+       if (htab->table[idx].entry.callback &&
+           htab->table[idx].entry.callback(key, NULL, env_op_delete, flag)) {
+               debug("callback() rejected deleting variable "
+                       "%s, skipping it!\n", key);
+               __set_errno(EINVAL);
+               return 0;
+       }
+
+       _hdelete(key, htab, ep, idx);
 
        return 1;
 }
@@ -482,7 +563,7 @@ static int cmpkey(const void *p1, const void *p2)
        return (strcmp(e1->key, e2->key));
 }
 
-ssize_t hexport_r(struct hsearch_data *htab, const char sep,
+ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
                 char **resp, size_t size,
                 int argc, char * const argv[])
 {
@@ -519,6 +600,9 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep,
                        if ((argc > 0) && (found == 0))
                                continue;
 
+                       if ((flag & H_HIDE_DOT) && ep->key[0] == '.')
+                               continue;
+
                        list[n++] = ep;
 
                        totlen += strlen(ep->key) + 2;
@@ -674,7 +758,7 @@ static int drop_var_from_set(const char *name, int nvars, char * vars[])
 
 int himport_r(struct hsearch_data *htab,
                const char *env, size_t size, const char sep, int flag,
-               int nvars, char * const vars[], int do_apply)
+               int nvars, char * const vars[])
 {
        char *data, *sp, *dp, *name, *value;
        char *localvars[nvars];
@@ -704,7 +788,7 @@ int himport_r(struct hsearch_data *htab,
                debug("Destroy Hash Table: %p table = %p\n", htab,
                       htab->table);
                if (htab->table)
-                       hdestroy_r(htab, do_apply);
+                       hdestroy_r(htab);
        }
 
        /*
@@ -770,7 +854,7 @@ int himport_r(struct hsearch_data *htab,
                        if (!drop_var_from_set(name, nvars, localvars))
                                continue;
 
-                       if (hdelete_r(name, htab, do_apply) == 0)
+                       if (hdelete_r(name, htab, flag) == 0)
                                debug("DELETE ERROR ##############################\n");
 
                        continue;
@@ -794,30 +878,10 @@ int himport_r(struct hsearch_data *htab,
                e.key = name;
                e.data = value;
 
-               /* if there is an apply function, check what it has to say */
-               if (do_apply && htab->apply != NULL) {
-                       debug("searching before calling cb function"
-                               " for  %s\n", name);
-                       /*
-                        * Search for variable in existing env, so to pass
-                        * its previous value to the apply callback
-                        */
-                       hsearch_r(e, FIND, &rv, htab);
-                       debug("previous value was %s\n", rv ? rv->data : "");
-                       if (htab->apply(name, rv ? rv->data : NULL,
-                               value, flag)) {
-                               debug("callback function refused to set"
-                                       " variable %s, skipping it!\n", name);
-                               continue;
-                       }
-               }
-
-               hsearch_r(e, ENTER, &rv, htab);
-               if (rv == NULL) {
+               hsearch_r(e, ENTER, &rv, htab, flag);
+               if (rv == NULL)
                        printf("himport_r: can't insert \"%s=%s\" into hash table\n",
                                name, value);
-                       return 0;
-               }
 
                debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n",
                        htab, htab->filled, htab->size,
@@ -839,7 +903,7 @@ int himport_r(struct hsearch_data *htab,
                 * b) if the variable was not present in current env, we notify
                 *    it might be a typo
                 */
-               if (hdelete_r(localvars[i], htab, do_apply) == 0)
+               if (hdelete_r(localvars[i], htab, flag) == 0)
                        printf("WARNING: '%s' neither in running nor in imported env!\n", localvars[i]);
                else
                        printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]);
@@ -848,3 +912,27 @@ int himport_r(struct hsearch_data *htab,
        debug("INSERT: done\n");
        return 1;               /* everything OK */
 }
+
+/*
+ * hwalk_r()
+ */
+
+/*
+ * Walk all of the entries in the hash, calling the callback for each one.
+ * this allows some generic operation to be performed on each element.
+ */
+int hwalk_r(struct hsearch_data *htab, int (*callback)(ENTRY *))
+{
+       int i;
+       int retval;
+
+       for (i = 1; i <= htab->size; ++i) {
+               if (htab->table[i].used > 0) {
+                       retval = callback(&htab->table[i].entry);
+                       if (retval)
+                               return retval;
+               }
+       }
+
+       return 0;
+}
diff --git a/lib/linux_string.c b/lib/linux_string.c
new file mode 100644 (file)
index 0000000..d5a5e08
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  linux/lib/string.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifdef USE_HOSTCC
+#include <stdio.h>
+#endif
+
+#include <linux/ctype.h>
+#include <linux/string.h>
+
+/**
+ * skip_spaces - Removes leading whitespace from @str.
+ * @str: The string to be stripped.
+ *
+ * Returns a pointer to the first non-whitespace character in @str.
+ */
+char *skip_spaces(const char *str)
+{
+       while (isspace(*str))
+               ++str;
+       return (char *)str;
+}
+
+/**
+ * strim - Removes leading and trailing whitespace from @s.
+ * @s: The string to be stripped.
+ *
+ * Note that the first trailing whitespace is replaced with a %NUL-terminator
+ * in the given string @s. Returns a pointer to the first non-whitespace
+ * character in @s.
+ */
+char *strim(char *s)
+{
+       size_t size;
+       char *end;
+
+       s = skip_spaces(s);
+       size = strlen(s);
+       if (!size)
+               return s;
+
+       end = s + size - 1;
+       while (end >= s && isspace(*end))
+               end--;
+       *(end + 1) = '\0';
+
+       return s;
+}
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 da5bc16f3c65def17421c4042431ad500aa5111c..a121224855f4786f9ca92de5396bd1262301c6bc 100644 (file)
@@ -73,7 +73,7 @@ void sha1_starts (sha1_context * ctx)
        ctx->state[4] = 0xC3D2E1F0;
 }
 
-static void sha1_process (sha1_context * ctx, unsigned char data[64])
+static void sha1_process(sha1_context *ctx, const unsigned char data[64])
 {
        unsigned long temp, W[16], A, B, C, D, E;
 
@@ -230,7 +230,8 @@ static void sha1_process (sha1_context * ctx, unsigned char data[64])
 /*
  * SHA-1 process buffer
  */
-void sha1_update (sha1_context * ctx, unsigned char *input, int ilen)
+void sha1_update(sha1_context *ctx, const unsigned char *input,
+                unsigned int ilen)
 {
        int fill;
        unsigned long left;
@@ -305,7 +306,8 @@ void sha1_finish (sha1_context * ctx, unsigned char output[20])
 /*
  * Output = SHA-1( input buffer )
  */
-void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
+void sha1_csum(const unsigned char *input, unsigned int ilen,
+              unsigned char *output)
 {
        sha1_context ctx;
 
@@ -318,12 +320,12 @@ void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
  * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
  * bytes of input processed.
  */
-void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20],
-                       unsigned int chunk_sz)
+void sha1_csum_wd(const unsigned char *input, unsigned int ilen,
+                 unsigned char *output, unsigned int chunk_sz)
 {
        sha1_context ctx;
 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-       unsigned char *end, *curr;
+       const unsigned char *end, *curr;
        int chunk;
 #endif
 
@@ -350,8 +352,9 @@ void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20],
 /*
  * Output = HMAC-SHA-1( input buffer, hmac key )
  */
-void sha1_hmac (unsigned char *key, int keylen,
-               unsigned char *input, int ilen, unsigned char output[20])
+void sha1_hmac(const unsigned char *key, int keylen,
+              const unsigned char *input, unsigned int ilen,
+              unsigned char *output)
 {
        int i;
        sha1_context ctx;
index deb63a40b6d7218145e807850ff51cce488a7e4b..ab2db4890ae7eb4bc432320bb2a044a0d56aa518 100644 (file)
@@ -60,7 +60,7 @@ void sha256_starts(sha256_context * ctx)
        ctx->state[7] = 0x5BE0CD19;
 }
 
-void sha256_process(sha256_context * ctx, uint8_t data[64])
+static void sha256_process(sha256_context *ctx, const uint8_t data[64])
 {
        uint32_t temp1, temp2;
        uint32_t W[64];
@@ -191,7 +191,7 @@ void sha256_process(sha256_context * ctx, uint8_t data[64])
        ctx->state[7] += H;
 }
 
-void sha256_update(sha256_context * ctx, uint8_t * input, uint32_t length)
+void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
 {
        uint32_t left, fill;
 
@@ -260,3 +260,36 @@ void sha256_finish(sha256_context * ctx, uint8_t digest[32])
        PUT_UINT32_BE(ctx->state[6], digest, 24);
        PUT_UINT32_BE(ctx->state[7], digest, 28);
 }
+
+/*
+ * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz'
+ * bytes of input processed.
+ */
+void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
+               unsigned char *output, unsigned int chunk_sz)
+{
+       sha256_context ctx;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+       unsigned char *end, *curr;
+       int chunk;
+#endif
+
+       sha256_starts(&ctx);
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+       curr = input;
+       end = input + ilen;
+       while (curr < end) {
+               chunk = end - curr;
+               if (chunk > chunk_sz)
+                       chunk = chunk_sz;
+               sha256_update(&ctx, curr, chunk);
+               curr += chunk;
+               WATCHDOG_RESET();
+       }
+#else
+       sha256_update(&ctx, input, ilen);
+#endif
+
+       sha256_finish(&ctx, output);
+}
index c3ad055e2caeca752ba4238f65578edb0abfb814..09dfae03c247554deb48c29ce98693ffd9c25f9d 100644 (file)
 #include <malloc.h>
 
 
-#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */
 /**
- * strnicmp - Case insensitive, length-limited string comparison
+ * strncasecmp - Case insensitive, length-limited string comparison
  * @s1: One string
  * @s2: The other string
  * @len: the maximum number of characters to compare
  */
-int strnicmp(const char *s1, const char *s2, size_t len)
+int strncasecmp(const char *s1, const char *s2, size_t len)
 {
        /* Yes, Virginia, it had better be unsigned */
        unsigned char c1, c2;
@@ -52,7 +51,16 @@ int strnicmp(const char *s1, const char *s2, size_t len)
        }
        return (int)c1 - (int)c2;
 }
-#endif
+
+/**
+ * strcasecmp - Case insensitive string comparison
+ * @s1: One string
+ * @s2: The other string
+ */
+int strcasecmp(const char *s1, const char *s2)
+{
+       return strncasecmp(s1, s2, -1U);
+}
 
 char * ___strtok;
 
@@ -214,45 +222,6 @@ char * strrchr(const char * s, int c)
 }
 #endif
 
-
-/**
- * skip_spaces - Removes leading whitespace from @str.
- * @str: The string to be stripped.
- *
- * Returns a pointer to the first non-whitespace character in @str.
- */
-char *skip_spaces(const char *str)
-{
-       while (isspace(*str))
-               ++str;
-       return (char *)str;
-}
-
-/**
- * strim - Removes leading and trailing whitespace from @s.
- * @s: The string to be stripped.
- *
- * Note that the first trailing whitespace is replaced with a %NUL-terminator
- * in the given string @s. Returns a pointer to the first non-whitespace
- * character in @s.
- */
-char *strim(char *s)
-{
-       size_t size;
-       char *end;
-
-       s = skip_spaces(s);
-       size = strlen(s);
-       if (!size)
-               return s;
-
-       end = s + size - 1;
-       while (end >= s && isspace(*end))
-               end--;
-       *(end + 1) = '\0';
-
-       return s;
-}
 #ifndef __HAVE_ARCH_STRLEN
 /**
  * strlen - Find the length of a string
index b7a79c0e0c90ea6a5bd275a4bdf0fd3853c5d610..3c432f8764fb7cf679e4e7260247eee6d9938853 100644 (file)
@@ -103,7 +103,7 @@ long simple_strtol(const char *cp, char **endp, unsigned int base)
        return simple_strtoul(cp, endp, base);
 }
 
-int ustrtoul(const char *cp, char **endp, unsigned int base)
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
 {
        unsigned long result = simple_strtoul(cp, endp, base);
        switch (**endp) {
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 d52f13adb45deca75d52cabaaecc592963b2ca5f..1ba796ebdf949999f8663ff30049c1c085d43f56 100644 (file)
@@ -103,7 +103,7 @@ static void configure_wait(void)
 void link_local_start(void)
 {
        ip = getenv_IPaddr("llipaddr");
-       if (ip != 0 && (ip & IN_CLASSB_NET) != LINKLOCAL_ADDR) {
+       if (ip != 0 && (ntohl(ip) & IN_CLASSB_NET) != LINKLOCAL_ADDR) {
                puts("invalid link address");
                net_set_state(NETLOOP_FAIL);
                return;
index 82c4cc91179a547f14887c8d1f5e1cf13f84a5af..a40cde1e94e46367d727e30d40187b2630f60f15 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -82,6 +82,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <environment.h>
 #include <net.h>
 #if defined(CONFIG_STATUS_LED)
 #include <miiphy.h>
@@ -208,32 +209,46 @@ static int NetTryCount;
 
 /**********************************************************************/
 
+static int on_bootfile(const char *name, const char *value, enum env_op op,
+       int flags)
+{
+       switch (op) {
+       case env_op_create:
+       case env_op_overwrite:
+               copy_filename(BootFile, value, sizeof(BootFile));
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+U_BOOT_ENV_CALLBACK(bootfile, on_bootfile);
+
 /*
  * Check if autoload is enabled. If so, use either NFS or TFTP to download
  * the boot file.
  */
 void net_auto_load(void)
 {
+#if defined(CONFIG_CMD_NFS)
        const char *s = getenv("autoload");
 
-       if (s != NULL) {
-               if (*s == 'n') {
-                       /*
-                        * Just use BOOTP/RARP to configure system;
-                        * Do not use TFTP to load the bootfile.
-                        */
-                       net_set_state(NETLOOP_SUCCESS);
-                       return;
-               }
-#if defined(CONFIG_CMD_NFS)
-               if (strcmp(s, "NFS") == 0) {
-                       /*
-                        * Use NFS to load the bootfile.
-                        */
-                       NfsStart();
-                       return;
-               }
+       if (s != NULL && strcmp(s, "NFS") == 0) {
+               /*
+                * Use NFS to load the bootfile.
+                */
+               NfsStart();
+               return;
+       }
 #endif
+       if (getenv_yesno("autoload") == 0) {
+               /*
+                * Just use BOOTP/RARP to configure system;
+                * Do not use TFTP to load the bootfile.
+                */
+               net_set_state(NETLOOP_SUCCESS);
+               return;
        }
        TftpStart(TFTPGET);
 }
index 59a8ebb3cf339b3c40ff24846c13406e5dc0b9a4..09790eb7cf8202c051d594b5243aa3f843746691 100644 (file)
@@ -40,6 +40,7 @@
 
 static ulong TftpTimeoutMSecs = TIMEOUT;
 static int TftpTimeoutCountMax = TIMEOUT_COUNT;
+static ulong time_start;   /* Record time we started tftp */
 
 /*
  * These globals govern the timeout behavior when attempting a connection to a
@@ -299,6 +300,12 @@ static void tftp_complete(void)
                TftpNumchars++;
        }
 #endif
+       time_start = get_timer(time_start);
+       if (time_start > 0) {
+               puts("\n\t ");  /* Line up with "Loading: " */
+               print_size(NetBootFileXferSize /
+                       time_start * 1000, "/s");
+       }
        puts("\ndone\n");
        net_set_state(NETLOOP_SUCCESS);
 }
@@ -775,6 +782,7 @@ void TftpStart(enum proto_t protocol)
                TftpState = STATE_SEND_RRQ;
        }
 
+       time_start = get_timer(0);
        TftpTimeoutCountMax = TftpRRQTimeoutCountMax;
 
        NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
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 ab73c8c744b6401c4eb88b1e5083fbfc8794ce35..0e798e09403168d67abc327432f39fcecd5c7b26 100644 (file)
 include $(TOPDIR)/config.mk
 
 HOSTSRCS := $(SRCTREE)/lib/crc32.c  fw_env.c  fw_env_main.c
+HOSTSRCS += $(SRCTREE)/lib/ctype.c $(SRCTREE)/lib/linux_string.c
+HOSTSRCS += $(SRCTREE)/common/env_attr.c $(SRCTREE)/common/env_flags.c
 HEADERS        := fw_env.h $(OBJTREE)/include/config.h
 
 # Compile for a hosted environment on the target
 HOSTCPPFLAGS  = -idirafter $(SRCTREE)/include \
                -idirafter $(OBJTREE)/include2 \
                -idirafter $(OBJTREE)/include \
+               -idirafter $(SRCTREE)/tools/env \
                -DUSE_HOSTCC \
                -DTEXT_BASE=$(TEXT_BASE)
 
index 9b023e807bc446bebf10caf2864d92dbed8469b3..90c7a5d3f39fa37f76005f354976e8f9c8c1270e 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <errno.h>
+#include <env_flags.h>
 #include <fcntl.h>
 #include <linux/stringify.h>
 #include <stdio.h>
@@ -180,6 +181,32 @@ char *fw_getenv (char *name)
        return NULL;
 }
 
+/*
+ * Search the default environment for a variable.
+ * Return the value, if found, or NULL, if not found.
+ */
+char *fw_getdefenv(char *name)
+{
+       char *env, *nxt;
+
+       for (env = default_environment; *env; env = nxt + 1) {
+               char *val;
+
+               for (nxt = env; *nxt; ++nxt) {
+                       if (nxt >= &default_environment[ENV_SIZE]) {
+                               fprintf(stderr, "## Error: "
+                                       "default environment not terminated\n");
+                               return NULL;
+                       }
+               }
+               val = envmatch(name, env);
+               if (!val)
+                       continue;
+               return val;
+       }
+       return NULL;
+}
+
 /*
  * Print the current definition of one, or more, or all
  * environment variables
@@ -281,6 +308,7 @@ int fw_env_write(char *name, char *value)
        int len;
        char *env, *nxt;
        char *oldval = NULL;
+       int deleting, creating, overwriting;
 
        /*
         * search if variable with this name already exists
@@ -298,27 +326,49 @@ int fw_env_write(char *name, char *value)
                        break;
        }
 
-       /*
-        * Delete any existing definition
-        */
-       if (oldval) {
-#ifndef CONFIG_ENV_OVERWRITE
-               /*
-                * Ethernet Address and serial# can be set only once
-                */
-               if (
-                   (strcmp(name, "serial#") == 0) ||
-                   ((strcmp(name, "ethaddr") == 0)
-#if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
-                   && (strcmp(oldval, __stringify(CONFIG_ETHADDR)) != 0)
-#endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */
-                  ) ) {
-                       fprintf (stderr, "Can't overwrite \"%s\"\n", name);
+       deleting = (oldval && !(value && strlen(value)));
+       creating = (!oldval && (value && strlen(value)));
+       overwriting = (oldval && (value && strlen(value)));
+
+       /* check for permission */
+       if (deleting) {
+               if (env_flags_validate_varaccess(name,
+                   ENV_FLAGS_VARACCESS_PREVENT_DELETE)) {
+                       printf("Can't delete \"%s\"\n", name);
+                       errno = EROFS;
+                       return -1;
+               }
+       } else if (overwriting) {
+               if (env_flags_validate_varaccess(name,
+                   ENV_FLAGS_VARACCESS_PREVENT_OVERWR)) {
+                       printf("Can't overwrite \"%s\"\n", name);
+                       errno = EROFS;
+                       return -1;
+               } else if (env_flags_validate_varaccess(name,
+                   ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR)) {
+                       const char *defval = fw_getdefenv(name);
+
+                       if (defval == NULL)
+                               defval = "";
+                       if (strcmp(oldval, defval)
+                           != 0) {
+                               printf("Can't overwrite \"%s\"\n", name);
+                               errno = EROFS;
+                               return -1;
+                       }
+               }
+       } else if (creating) {
+               if (env_flags_validate_varaccess(name,
+                   ENV_FLAGS_VARACCESS_PREVENT_CREATE)) {
+                       printf("Can't create \"%s\"\n", name);
                        errno = EROFS;
                        return -1;
                }
-#endif /* CONFIG_ENV_OVERWRITE */
+       } else
+               /* Nothing to do */
+               return 0;
 
+       if (deleting || overwriting) {
                if (*++nxt == '\0') {
                        *env = '\0';
                } else {
@@ -395,6 +445,9 @@ int fw_setenv(int argc, char *argv[])
 
        name = argv[1];
 
+       if (env_flags_validate_env_set_params(argc, argv) < 0)
+               return 1;
+
        len = 0;
        for (i = 2; i < argc; ++i) {
                char *val = argv[i];
@@ -516,6 +569,11 @@ int fw_parse_script(char *fname)
                        name, val ? val : " removed");
 #endif
 
+               if (env_flags_validate_type(name, val) < 0) {
+                       ret = -1;
+                       break;
+               }
+
                /*
                 * If there is an error setting a variable,
                 * try to save the environment and returns an error
index ef9ffeeec599a9e04cb5d73c02f18d07825a94bb..76bbba125a84f03421502f4159e5e99673671a31 100644 (file)
@@ -80,7 +80,7 @@ static int fit_handle_file (struct mkimage_params *params)
        }
        sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX);
 
-       /* dtc -I dts -O -p 200 datafile > tmpfile */
+       /* dtc -I dts -O dtb -p 500 datafile > tmpfile */
        sprintf (cmd, "%s %s %s > %s",
                MKIMAGE_DTC, params->dtc, params->datafile, tmpfile);
        debug ("Trying to execute \"%s\"\n", cmd);
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