summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMinkyu Kang <mk7.kang@samsung.com>2012-12-10 13:44:41 +0900
committerMinkyu Kang <mk7.kang@samsung.com>2012-12-10 14:13:27 +0900
commit2c601c7208713ba9b2158c57adcf515f4bdbc212 (patch)
tree9f6e70f33565beceb956b98c261bee19731d50d2
parentb8a7c467960ffb4d5a5e1eef5f7783fb6f594542 (diff)
parentfd4d564b3c80b111f18c93adb14233a6a7ddb0e9 (diff)
downloadtalos-obmc-uboot-2c601c7208713ba9b2158c57adcf515f4bdbc212.tar.gz
talos-obmc-uboot-2c601c7208713ba9b2158c57adcf515f4bdbc212.zip
Merge branch 'master' of git://git.denx.de/u-boot into resolve
Conflicts: README board/samsung/universal_c210/universal.c drivers/misc/Makefile drivers/power/power_fsl.c include/configs/mx35pdk.h include/configs/mx53loco.h include/configs/seaboard.h
-rw-r--r--.gitignore2
-rw-r--r--MAINTAINERS8
-rwxr-xr-xMAKEALL69
-rw-r--r--Makefile60
-rw-r--r--README101
-rw-r--r--arch/arm/cpu/armv7/am33xx/board.c85
-rw-r--r--arch/arm/cpu/armv7/am33xx/clock.c8
-rw-r--r--arch/arm/cpu/armv7/omap3/Makefile1
-rw-r--r--arch/arm/cpu/armv7/omap3/am35x_musb.c75
-rw-r--r--arch/arm/include/asm/arch-am33xx/cpu.h11
-rw-r--r--arch/arm/include/asm/arch-am33xx/hardware.h4
-rw-r--r--arch/arm/include/asm/arch-exynos/dwmmc.h36
-rw-r--r--arch/arm/include/asm/arch-omap3/am35x_def.h27
-rw-r--r--arch/arm/include/asm/arch-omap3/musb.h (renamed from board/chromebook-x86/coreboot/coreboot_start16.S)36
-rw-r--r--arch/arm/include/asm/imx-common/mx5_video.h21
-rw-r--r--arch/arm/include/asm/omap_musb.h32
-rw-r--r--arch/arm/lib/board.c8
-rw-r--r--arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c2
-rw-r--r--arch/mips/cpu/mips32/time.c1
-rw-r--r--arch/mips/cpu/mips64/time.c1
-rw-r--r--arch/powerpc/config.mk5
-rw-r--r--arch/powerpc/cpu/mpc5xxx/Makefile4
-rw-r--r--arch/powerpc/cpu/mpc5xxx/spl_boot.c79
-rw-r--r--arch/powerpc/cpu/mpc5xxx/start.S22
-rw-r--r--arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds (renamed from nand_spl/board/freescale/common.c)51
-rw-r--r--arch/powerpc/cpu/mpc5xxx/usb_ohci.c2
-rw-r--r--arch/powerpc/cpu/mpc85xx/Makefile38
-rw-r--r--arch/powerpc/cpu/mpc85xx/cmd_errata.c114
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu.c17
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu_init.c14
-rw-r--r--arch/powerpc/cpu/mpc85xx/ddr-gen1.c4
-rw-r--r--arch/powerpc/cpu/mpc85xx/ddr-gen2.c9
-rw-r--r--arch/powerpc/cpu/mpc85xx/ddr-gen3.c14
-rw-r--r--arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c20
-rw-r--r--arch/powerpc/cpu/mpc85xx/release.S36
-rw-r--r--arch/powerpc/cpu/mpc85xx/spl_minimal.c (renamed from arch/powerpc/cpu/mpc85xx/cpu_init_nand.c)19
-rw-r--r--arch/powerpc/cpu/mpc85xx/start.S123
-rw-r--r--arch/powerpc/cpu/mpc85xx/tlb.c4
-rw-r--r--arch/powerpc/cpu/mpc85xx/u-boot-spl.lds87
-rw-r--r--arch/powerpc/cpu/mpc86xx/ddr-8641.c4
-rw-r--r--arch/powerpc/cpu/mpc8xxx/Makefile17
-rw-r--r--arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c10
-rw-r--r--arch/powerpc/cpu/mpc8xxx/ddr/util.c14
-rw-r--r--arch/powerpc/cpu/mpc8xxx/fdt.c6
-rw-r--r--arch/powerpc/cpu/mpc8xxx/law.c (renamed from drivers/misc/fsl_law.c)11
-rw-r--r--arch/powerpc/cpu/ppc4xx/usb_ohci.c2
-rw-r--r--arch/powerpc/include/asm/config_mpc85xx.h20
-rw-r--r--arch/powerpc/include/asm/immap_83xx.h6
-rw-r--r--arch/powerpc/include/asm/immap_85xx.h27
-rw-r--r--arch/powerpc/include/asm/immap_86xx.h8
-rw-r--r--arch/powerpc/include/asm/processor.h6
-rw-r--r--arch/powerpc/include/asm/spl.h (renamed from board/chromebook-x86/coreboot/coreboot_pci.c)21
-rw-r--r--arch/powerpc/lib/Makefile35
-rw-r--r--arch/powerpc/lib/bootm.c6
-rw-r--r--arch/powerpc/lib/spl.c42
-rw-r--r--arch/sh/include/asm/system.h2
-rw-r--r--arch/x86/cpu/Makefile7
-rw-r--r--arch/x86/cpu/coreboot/Makefile7
-rw-r--r--arch/x86/cpu/coreboot/car.S (renamed from arch/x86/cpu/coreboot/coreboot_car.S)0
-rw-r--r--arch/x86/cpu/coreboot/config.mk (renamed from board/BuS/eb_cpu5282/config.mk)8
-rw-r--r--arch/x86/cpu/coreboot/coreboot.c (renamed from board/chromebook-x86/coreboot/coreboot.c)61
-rw-r--r--arch/x86/cpu/coreboot/pci.c65
-rw-r--r--arch/x86/cpu/coreboot/sdram.c72
-rw-r--r--arch/x86/cpu/coreboot/sysinfo.c39
-rw-r--r--arch/x86/cpu/coreboot/tables.c117
-rw-r--r--arch/x86/cpu/coreboot/timestamp.c61
-rw-r--r--arch/x86/cpu/cpu.c49
-rw-r--r--arch/x86/cpu/interrupts.c99
-rw-r--r--arch/x86/cpu/start.S77
-rw-r--r--arch/x86/cpu/start16.S3
-rw-r--r--arch/x86/cpu/timer.c17
-rw-r--r--arch/x86/cpu/u-boot.lds3
-rw-r--r--arch/x86/dts/coreboot.dtsi16
-rw-r--r--arch/x86/dts/skeleton.dtsi13
-rw-r--r--arch/x86/include/asm/arch-coreboot/sysinfo.h34
-rw-r--r--arch/x86/include/asm/arch-coreboot/tables.h74
-rw-r--r--arch/x86/include/asm/arch-coreboot/timestamp.h52
-rw-r--r--arch/x86/include/asm/bitops.h5
-rw-r--r--arch/x86/include/asm/cache.h16
-rw-r--r--arch/x86/include/asm/control_regs.h105
-rw-r--r--arch/x86/include/asm/global_data.h18
-rw-r--r--arch/x86/include/asm/gpio.h (renamed from arch/nios2/include/asm/status_led.h)16
-rw-r--r--arch/x86/include/asm/init_helpers.h2
-rw-r--r--arch/x86/include/asm/io.h18
-rw-r--r--arch/x86/include/asm/msr-index.h469
-rw-r--r--arch/x86/include/asm/msr.h238
-rw-r--r--arch/x86/include/asm/mtrr.h206
-rw-r--r--arch/x86/include/asm/pci.h2
-rw-r--r--arch/x86/include/asm/processor.h1
-rw-r--r--arch/x86/include/asm/types.h4
-rw-r--r--arch/x86/include/asm/u-boot-x86.h14
-rw-r--r--arch/x86/include/asm/u-boot.h3
-rw-r--r--arch/x86/lib/Makefile12
-rw-r--r--arch/x86/lib/board.c15
-rw-r--r--arch/x86/lib/init_helpers.c83
-rw-r--r--arch/x86/lib/init_wrappers.c28
-rw-r--r--arch/x86/lib/pcat_timer.c2
-rw-r--r--arch/x86/lib/physmem.c228
-rw-r--r--arch/x86/lib/relocate.c4
-rw-r--r--arch/x86/lib/timer.c17
-rw-r--r--arch/x86/lib/video.c2
-rw-r--r--arch/x86/lib/zimage.c27
-rw-r--r--board/BuS/eb_cpu5282/Makefile2
-rw-r--r--board/BuS/eb_cpu5282/cfm_flash.c212
-rw-r--r--board/BuS/eb_cpu5282/cfm_flash.h40
-rw-r--r--board/BuS/eb_cpu5282/eb_cpu5282.c110
-rw-r--r--board/BuS/eb_cpu5282/flash.c415
-rw-r--r--board/a3m071/Makefile36
-rw-r--r--board/a3m071/README80
-rw-r--r--board/a3m071/a3m071.c335
-rw-r--r--board/a3m071/mt46v16m16-75.h32
-rw-r--r--board/chromebook-x86/coreboot/Makefile3
-rw-r--r--board/chromebook-x86/coreboot/config.mk37
-rw-r--r--board/chromebook-x86/dts/alex.dts24
-rw-r--r--board/chromebook-x86/dts/link.dts24
-rw-r--r--board/davedenx/qong/qong.c12
-rw-r--r--board/exmeritus/hww1u1a/hww1u1a.c2
-rw-r--r--board/freescale/common/Makefile2
-rw-r--r--board/freescale/common/ngpixis.h2
-rw-r--r--board/freescale/corenet_ds/Makefile2
-rw-r--r--board/freescale/corenet_ds/corenet_ds.c22
-rw-r--r--board/freescale/corenet_ds/ddr.c4
-rw-r--r--board/freescale/corenet_ds/eth_superhydra.c722
-rw-r--r--board/freescale/corenet_ds/p5040ds_ddr.c18
-rw-r--r--board/freescale/mpc8540ads/mpc8540ads.c2
-rw-r--r--board/freescale/mpc8560ads/mpc8560ads.c2
-rw-r--r--board/freescale/mpc8569mds/mpc8569mds.c2
-rw-r--r--board/freescale/mx31pdk/mx31pdk.c12
-rw-r--r--board/freescale/mx35pdk/mx35pdk.c14
-rw-r--r--board/freescale/mx51evk/Makefile4
-rw-r--r--board/freescale/mx51evk/mx51evk.c69
-rw-r--r--board/freescale/mx51evk/mx51evk_video.c81
-rw-r--r--board/freescale/mx53evk/mx53evk.c12
-rw-r--r--board/freescale/mx53loco/Makefile4
-rw-r--r--board/freescale/mx53loco/mx53loco.c87
-rw-r--r--board/freescale/mx53loco/mx53loco_video.c94
-rw-r--r--board/freescale/p1023rds/p1023rds.c2
-rw-r--r--board/freescale/p1_p2_rdb_pc/Makefile16
-rw-r--r--board/freescale/p1_p2_rdb_pc/ddr.c2
-rw-r--r--board/freescale/p1_p2_rdb_pc/law.c2
-rw-r--r--board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c2
-rw-r--r--board/freescale/p1_p2_rdb_pc/spl_minimal.c (renamed from nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c)12
-rw-r--r--board/freescale/p1_p2_rdb_pc/tlb.c22
-rw-r--r--board/freescale/p2020ds/p2020ds.c2
-rw-r--r--board/genesi/mx51_efikamx/efikamx.c12
-rw-r--r--board/hale/tt01/tt01.c14
-rw-r--r--board/iomega/iconnect/iconnect.c2
-rw-r--r--board/iomega/iconnect/iconnect.h2
-rw-r--r--board/iomega/iconnect/kwbimage.cfg2
-rw-r--r--board/logicpd/am3517evm/am3517evm.c74
-rw-r--r--board/raidsonic/ib62x0/ib62x0.c2
-rw-r--r--board/raidsonic/ib62x0/ib62x0.h2
-rw-r--r--board/raidsonic/ib62x0/kwbimage.cfg2
-rw-r--r--board/samsung/goni/goni.c22
-rw-r--r--board/samsung/trats/trats.c292
-rw-r--r--board/samsung/universal_c210/universal.c31
-rw-r--r--board/sbc8548/ddr.c2
-rw-r--r--board/socrates/sdram.c2
-rw-r--r--board/ti/am335x/board.c23
-rw-r--r--board/ti/beagle/beagle.c43
-rw-r--r--board/ttcontrol/vision2/vision2.c12
-rw-r--r--boards.cfg7
-rw-r--r--common/Makefile3
-rw-r--r--common/bouncebuf.c75
-rw-r--r--common/cmd_bmp.c5
-rw-r--r--common/cmd_bootm.c11
-rw-r--r--common/cmd_led.c6
-rw-r--r--common/cmd_mmc.c11
-rw-r--r--common/cmd_nand.c22
-rw-r--r--common/cmd_usb.c2
-rw-r--r--common/image.c127
-rw-r--r--common/lcd.c178
-rw-r--r--common/main.c104
-rw-r--r--common/spl/spl.c16
-rw-r--r--common/stdio.c4
-rw-r--r--common/usb.c4
-rw-r--r--common/usb_kbd.c18
-rw-r--r--disk/part.c2
-rw-r--r--doc/DocBook/Makefile2
-rw-r--r--doc/README.mpc85xx2
-rw-r--r--doc/README.nand21
-rw-r--r--doc/kwboot.12
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/intel_ich6_gpio.c290
-rw-r--r--drivers/misc/Makefile10
-rw-r--r--drivers/misc/cbmem_console.c67
-rw-r--r--drivers/misc/pmic_core.c147
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/exynos_dw_mmc.c57
-rw-r--r--drivers/mmc/mmc.c63
-rw-r--r--drivers/mmc/mxsmmc.c30
-rw-r--r--drivers/mmc/sdhci.c3
-rw-r--r--drivers/mmc/tegra_mmc.c64
-rw-r--r--drivers/mtd/nand/Makefile34
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c2
-rw-r--r--drivers/mtd/nand/fsl_elbc_spl.c168
-rw-r--r--drivers/mtd/nand/fsl_ifc_nand.c64
-rw-r--r--drivers/mtd/nand/nand_base.c9
-rw-r--r--drivers/mtd/nand/nand_util.c188
-rw-r--r--drivers/net/fm/Makefile1
-rw-r--r--drivers/net/fm/p5040.c113
-rw-r--r--drivers/pci/fsl_pci_init.c22
-rw-r--r--drivers/power/Makefile12
-rw-r--r--drivers/power/battery/Makefile47
-rw-r--r--drivers/power/battery/bat_trats.c100
-rw-r--r--drivers/power/fuel_gauge/Makefile47
-rw-r--r--drivers/power/fuel_gauge/fg_max17042.c250
-rw-r--r--drivers/power/pmic/Makefile49
-rw-r--r--drivers/power/pmic/muic_max8997.c90
-rw-r--r--drivers/power/pmic/pmic_max8997.c123
-rw-r--r--drivers/power/pmic/pmic_max8998.c (renamed from drivers/misc/pmic_max8998.c)16
-rw-r--r--drivers/power/power_core.c232
-rw-r--r--drivers/power/power_dialog.c (renamed from drivers/misc/pmic_dialog.c)14
-rw-r--r--drivers/power/power_fsl.c (renamed from drivers/misc/pmic_fsl.c)22
-rw-r--r--drivers/power/power_i2c.c (renamed from drivers/misc/pmic_i2c.c)47
-rw-r--r--drivers/power/power_spi.c (renamed from drivers/misc/pmic_spi.c)4
-rw-r--r--drivers/rtc/mc13xxx-rtc.c10
-rw-r--r--drivers/serial/ns16550.c3
-rw-r--r--drivers/serial/serial_ns16550.c4
-rw-r--r--drivers/serial/serial_pl01x.c4
-rw-r--r--drivers/serial/serial_sh.c20
-rw-r--r--drivers/usb/gadget/config.c1
-rw-r--r--drivers/usb/gadget/epautoconf.c1
-rw-r--r--drivers/usb/gadget/ether.c1
-rw-r--r--drivers/usb/gadget/f_dfu.c1
-rw-r--r--drivers/usb/gadget/gadget_chips.h4
-rw-r--r--drivers/usb/gadget/s3c_udc_otg.c1
-rw-r--r--drivers/usb/gadget/usbstring.c1
-rw-r--r--drivers/usb/host/ehci-hcd.c16
-rw-r--r--drivers/usb/host/isp116x-hcd.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c2
-rw-r--r--drivers/usb/host/ohci-s3c24xx.c2
-rw-r--r--drivers/usb/host/r8a66597-hcd.c17
-rw-r--r--drivers/usb/host/sl811-hcd.c2
-rw-r--r--drivers/usb/musb-new/Makefile39
-rw-r--r--drivers/usb/musb-new/am35x.c709
-rw-r--r--drivers/usb/musb-new/linux-compat.h116
-rw-r--r--drivers/usb/musb-new/musb_core.c2497
-rw-r--r--drivers/usb/musb-new/musb_core.h623
-rw-r--r--drivers/usb/musb-new/musb_debug.h58
-rw-r--r--drivers/usb/musb-new/musb_dma.h186
-rw-r--r--drivers/usb/musb-new/musb_dsps.c771
-rw-r--r--drivers/usb/musb-new/musb_gadget.c2333
-rw-r--r--drivers/usb/musb-new/musb_gadget.h130
-rw-r--r--drivers/usb/musb-new/musb_gadget_ep0.c1089
-rw-r--r--drivers/usb/musb-new/musb_host.c2400
-rw-r--r--drivers/usb/musb-new/musb_host.h114
-rw-r--r--drivers/usb/musb-new/musb_io.h146
-rw-r--r--drivers/usb/musb-new/musb_regs.h645
-rw-r--r--drivers/usb/musb-new/musb_uboot.c237
-rw-r--r--drivers/usb/musb-new/omap2430.c626
-rw-r--r--drivers/usb/musb-new/omap2430.h56
-rw-r--r--drivers/usb/musb-new/usb-compat.h88
-rw-r--r--drivers/usb/musb/musb_core.h3
-rw-r--r--drivers/usb/musb/musb_hcd.c5
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/atmel_hlcdfb.c12
-rw-r--r--drivers/video/bus_vcxk.c2
-rw-r--r--drivers/video/cfb_console.c51
-rw-r--r--drivers/video/coreboot_fb.c101
-rw-r--r--drivers/video/ipu_common.c10
-rw-r--r--fs/cbfs/Makefile4
-rw-r--r--fs/cbfs/cbfs.c3
-rw-r--r--fs/ext4/dev.c1
-rw-r--r--fs/ext4/ext4_common.c14
-rw-r--r--fs/ext4/ext4_journal.c3
-rw-r--r--fs/ext4/ext4fs.c13
-rw-r--r--fs/fs.c11
-rw-r--r--fs/zfs/zfs.c4
-rw-r--r--include/atmel_hlcdc.h7
-rw-r--r--include/bouncebuf.h47
-rw-r--r--include/cbfs.h72
-rw-r--r--include/configs/CPCI405.h2
-rw-r--r--include/configs/CPCI4052.h2
-rw-r--r--include/configs/CPCI405AB.h2
-rw-r--r--include/configs/CPCI405DT.h2
-rw-r--r--include/configs/P1010RDB.h1
-rw-r--r--include/configs/P1022DS.h1
-rw-r--r--include/configs/P1023RDS.h2
-rw-r--r--include/configs/P2041RDB.h20
-rw-r--r--include/configs/P3041DS.h1
-rw-r--r--include/configs/P5020DS.h1
-rw-r--r--include/configs/P5040DS.h40
-rw-r--r--include/configs/PK1C20.h1
-rw-r--r--include/configs/a3m071.h380
-rw-r--r--include/configs/am335x_evm.h27
-rw-r--r--include/configs/am3517_crane.h3
-rw-r--r--include/configs/am3517_evm.h36
-rw-r--r--include/configs/at91sam9x5ek.h19
-rw-r--r--include/configs/cam_enc_4xx.h3
-rw-r--r--include/configs/coreboot.h68
-rw-r--r--include/configs/corenet_ds.h2
-rw-r--r--include/configs/da850evm.h3
-rw-r--r--include/configs/devkit8000.h3
-rw-r--r--include/configs/eNET.h6
-rw-r--r--include/configs/eb_cpu5282.h102
-rw-r--r--include/configs/hawkboard.h3
-rw-r--r--include/configs/ib62x0.h2
-rw-r--r--include/configs/iconnect.h2
-rw-r--r--include/configs/igep00x0.h3
-rw-r--r--include/configs/imx31_litekit.h6
-rw-r--r--include/configs/lwmon5.h1
-rw-r--r--include/configs/mcx.h4
-rw-r--r--include/configs/mx31ads.h6
-rw-r--r--include/configs/mx31pdk.h6
-rw-r--r--include/configs/mx35pdk.h6
-rw-r--r--include/configs/mx51_efikamx.h6
-rw-r--r--include/configs/mx51evk.h6
-rw-r--r--include/configs/mx53evk.h6
-rw-r--r--include/configs/mx53loco.h8
-rw-r--r--include/configs/mx6qarm2.h2
-rw-r--r--include/configs/mx6qsabre_common.h2
-rw-r--r--include/configs/mx6qsabrelite.h2
-rw-r--r--include/configs/nios2-generic.h1
-rw-r--r--include/configs/omap3_beagle.h17
-rw-r--r--include/configs/omap3_evm.h3
-rw-r--r--include/configs/omap3_evm_quick_nand.h3
-rw-r--r--include/configs/omap3_overo.h3
-rw-r--r--include/configs/p1_p2_rdb_pc.h137
-rw-r--r--include/configs/qong.h6
-rw-r--r--include/configs/s5p_goni.h6
-rw-r--r--include/configs/s5pc210_universal.h6
-rw-r--r--include/configs/sc_sps_1.h2
-rw-r--r--include/configs/seaboard.h3
-rw-r--r--include/configs/sequoia.h3
-rw-r--r--include/configs/tam3517-common.h5
-rw-r--r--include/configs/tegra-common-post.h19
-rw-r--r--include/configs/tegra20-common.h8
-rw-r--r--include/configs/trats.h14
-rw-r--r--include/configs/tricorder.h3
-rw-r--r--include/configs/tt01.h6
-rw-r--r--include/configs/vct.h1
-rw-r--r--include/configs/ventana.h3
-rw-r--r--include/configs/vision2.h6
-rw-r--r--include/fdtdec.h112
-rw-r--r--include/g_dnl.h1
-rw-r--r--include/image.h1
-rw-r--r--include/lcd.h36
-rw-r--r--include/linux/byteorder/swab.h2
-rw-r--r--include/linux/mtd/nand.h7
-rw-r--r--include/linux/usb/ch9.h514
-rw-r--r--include/linux/usb/musb.h162
-rw-r--r--include/nand.h1
-rw-r--r--include/nios2.h12
-rw-r--r--include/pci.h123
-rw-r--r--include/physmem.h21
-rw-r--r--include/power/battery.h (renamed from drivers/misc/pmic_max8997.c)29
-rw-r--r--include/power/fg_battery_cell_params.h90
-rw-r--r--include/power/max17042_fg.h74
-rw-r--r--include/power/max8997_muic.h61
-rw-r--r--include/power/max8997_pmic.h (renamed from include/max8997_pmic.h)26
-rw-r--r--include/power/max8998_pmic.h (renamed from include/max8998_pmic.h)0
-rw-r--r--include/power/pmic.h (renamed from include/pmic.h)51
-rw-r--r--include/power/power_chrg.h43
-rw-r--r--include/sdhci.h1
-rw-r--r--include/status_led.h3
-rw-r--r--include/stdio_dev.h3
-rw-r--r--include/usb.h19
-rw-r--r--include/usb/s3c_udc.h1
-rw-r--r--include/usb_defs.h6
-rw-r--r--include/video.h48
-rw-r--r--lib/Makefile1
-rw-r--r--lib/fdtdec.c125
-rw-r--r--lib/lzma/LzmaDec.c14
-rw-r--r--lib/lzma/LzmaDec.h6
-rw-r--r--lib/lzma/Types.h36
-rw-r--r--lib/lzma/history.txt35
-rw-r--r--lib/lzma/lzma.txt34
-rw-r--r--lib/physmem.c24
-rw-r--r--nand_spl/board/freescale/mpc8536ds/Makefile13
-rw-r--r--nand_spl/board/freescale/mpc8569mds/Makefile13
-rw-r--r--nand_spl/board/freescale/mpc8572ds/Makefile13
-rw-r--r--nand_spl/board/freescale/mx31pdk/Makefile3
-rw-r--r--nand_spl/board/freescale/p1010rdb/Makefile19
-rw-r--r--nand_spl/board/freescale/p1010rdb/nand_boot.c2
-rw-r--r--nand_spl/board/freescale/p1023rds/Makefile19
-rw-r--r--nand_spl/board/freescale/p1023rds/nand_boot.c2
-rw-r--r--nand_spl/board/freescale/p1_p2_rdb/Makefile13
-rw-r--r--nand_spl/board/freescale/p1_p2_rdb_pc/Makefile146
-rw-r--r--nand_spl/board/karo/tx25/Makefile3
-rw-r--r--spl/Makefile21
-rw-r--r--tools/patman/series.py21
382 files changed, 23889 insertions, 2516 deletions
diff --git a/.gitignore b/.gitignore
index 1ac43f2825..a163728832 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,12 +38,12 @@
/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
diff --git a/MAINTAINERS b/MAINTAINERS
index e34d9f3ec3..36b47b741a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -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 84a5c92cf3..5b06c5477d 100755
--- 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
@@ -381,6 +394,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
diff --git a/Makefile b/Makefile
index 8a04727f62..44db8891f3 100644
--- a/Makefile
+++ b/Makefile
@@ -231,8 +231,8 @@ endif
OBJS = $(CPUDIR)/start.o
ifeq ($(CPU),x86)
-OBJS += $(CPUDIR)/start16.o
-OBJS += $(CPUDIR)/resetvec.o
+RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/start16.o
+RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/resetvec.o
endif
ifeq ($(CPU),ppc4xx)
OBJS += $(CPUDIR)/resetvec.o
@@ -241,7 +241,7 @@ ifeq ($(CPU),mpc85xx)
OBJS += $(CPUDIR)/resetvec.o
endif
-OBJS := $(addprefix $(obj),$(OBJS))
+OBJS := $(addprefix $(obj),$(OBJS) $(RESET_OBJS-))
HAVE_VENDOR_COMMON_LIB = $(if $(wildcard board/$(VENDOR)/common/Makefile),y,n)
@@ -293,7 +293,10 @@ LIBS-y += drivers/net/libnet.o
LIBS-y += drivers/net/phy/libphy.o
LIBS-y += drivers/pci/libpci.o
LIBS-y += drivers/pcmcia/libpcmcia.o
-LIBS-y += drivers/power/libpower.o
+LIBS-y += drivers/power/libpower.o \
+ drivers/power/fuel_gauge/libfuel_gauge.o \
+ drivers/power/pmic/libpmic.o \
+ drivers/power/battery/libbattery.o
LIBS-y += drivers/spi/libspi.o
LIBS-y += drivers/dfu/libdfu.o
ifeq ($(CPU),mpc83xx)
@@ -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 \
@@ -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 037513a134..5a86ae9c5f 100644
--- a/README
+++ b/README
@@ -54,6 +54,11 @@ In case of problems see the CHANGELOG and CREDITS files to find out
who contributed the specific port. The MAINTAINERS file lists board
maintainers.
+Note: There is no CHANGELOG file in the actual U-Boot source tree;
+it can be created dynamically from the Git log using:
+
+ make CHANGELOG
+
Where to get help:
==================
@@ -1409,6 +1414,13 @@ CBFS (Coreboot Filesystem) support
boot. See the documentation file README.video for a
description of this variable.
+ CONFIG_VIDEO_VGA
+
+ Enable the VGA video / BIOS for x86. The alternative if you
+ are using coreboot is to use the coreboot frame buffer
+ driver.
+
+
- Keyboard Support:
CONFIG_KEYBOARD
@@ -1469,21 +1481,10 @@ CBFS (Coreboot Filesystem) support
Normally display is black on white background; define
CONFIG_SYS_WHITE_ON_BLACK to get it inverted.
+ CONFIG_LCD_BMP_RLE8
- CONFIG_LCD_ALIGNMENT
-
- Normally the LCD is page-aligned (tyically 4KB). If this is
- defined then the LCD will be aligned to this value instead.
- For ARM it is sometimes useful to use MMU_SECTION_SIZE
- here, since it is cheaper to change data cache settings on
- a per-section basis.
+ Support drawing of RLE8-compressed bitmaps on the LCD.
- CONFIG_CONSOLE_SCROLL_LINES
-
- When the console need to be scrolled, this is the number of
- lines to scroll by. It defaults to 1. Increasing this makes
- the console jump but can help speed up operation when scrolling
- is slow.
- Splash Screen Support: CONFIG_SPLASH_SCREEN
@@ -2211,6 +2212,14 @@ CBFS (Coreboot Filesystem) support
HERMES, IP860, RPXlite, LWMON,
FLAGADM, TQM8260
+- Access to physical memory region (> 4GB)
+ Some basic support is provided for operations on memory not
+ normally accessible to U-Boot - e.g. some architectures
+ support access to more than 4GB of memory on 32-bit
+ machines using physical address extension or similar.
+ Define CONFIG_PHYSMEM to access this basic support, which
+ currently only supports clearing the memory.
+
- Error Recovery:
CONFIG_PANIC_HANG
@@ -2613,6 +2622,17 @@ FIT uImage format:
-150 common/cmd_nand.c Incorrect FIT image format
151 common/cmd_nand.c FIT image format OK
+- FIT image support:
+ CONFIG_FIT
+ Enable support for the FIT uImage format.
+
+ CONFIG_FIT_BEST_MATCH
+ When no configuration is explicitly selected, default to the
+ one whose fdt's compatibility field best matches that of
+ U-Boot itself. A match is considered "best" if it matches the
+ most specific compatibility entry of U-Boot's fdt's root node.
+ The order of entries in the configuration's fdt is ignored.
+
- Standalone program support:
CONFIG_STANDALONE_LOAD_ADDR
@@ -2664,6 +2684,10 @@ FIT uImage format:
CONFIG_SPL_TEXT_BASE
TEXT_BASE for linking the SPL binary.
+ CONFIG_SPL_RELOC_TEXT_BASE
+ Address to relocate to. If unspecified, this is equal to
+ CONFIG_SPL_TEXT_BASE (i.e. no relocation is done).
+
CONFIG_SPL_BSS_START_ADDR
Link address for the BSS within the SPL binary.
@@ -2673,6 +2697,11 @@ FIT uImage format:
CONFIG_SPL_STACK
Adress of the start of the stack SPL will use
+ CONFIG_SPL_RELOC_STACK
+ Adress of the start of the stack SPL will use after
+ relocation. If unspecified, this is equal to
+ CONFIG_SPL_STACK.
+
CONFIG_SYS_SPL_MALLOC_START
Starting address of the malloc pool used in SPL.
@@ -2688,6 +2717,9 @@ FIT uImage format:
For ARM, enable an optional function to print more information
about the running system.
+ CONFIG_SPL_INIT_MINIMAL
+ Arch init code should be built for a very small image
+
CONFIG_SPL_LIBCOMMON_SUPPORT
Support for common/libcommon.o in SPL binary
@@ -2715,8 +2747,19 @@ FIT uImage format:
CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
Filename to read to load U-Boot when reading from FAT
+ CONFIG_SPL_NAND_BASE
+ Include nand_base.c in the SPL. Requires
+ CONFIG_SPL_NAND_DRIVERS.
+
+ CONFIG_SPL_NAND_DRIVERS
+ SPL uses normal NAND drivers, not minimal drivers.
+
+ CONFIG_SPL_NAND_ECC
+ Include standard software ECC in the SPL
+
CONFIG_SPL_NAND_SIMPLE
- Support for drivers/mtd/nand/libnand.o in SPL binary
+ Support for NAND boot using simple NAND drivers that
+ expose the cmd_ctrl() interface.
CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_COUNT,
CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE,
@@ -2724,15 +2767,19 @@ FIT uImage format:
CONFIG_SYS_NAND_ECCPOS, CONFIG_SYS_NAND_ECCSIZE,
CONFIG_SYS_NAND_ECCBYTES
Defines the size and behavior of the NAND that SPL uses
- to read U-Boot with CONFIG_SPL_NAND_SIMPLE
+ to read U-Boot
CONFIG_SYS_NAND_U_BOOT_OFFS
- Location in NAND for CONFIG_SPL_NAND_SIMPLE to read U-Boot
- from.
+ Location in NAND to read U-Boot from
+
+ CONFIG_SYS_NAND_U_BOOT_DST
+ Location in memory to load U-Boot to
+
+ CONFIG_SYS_NAND_U_BOOT_SIZE
+ Size of image to load
CONFIG_SYS_NAND_U_BOOT_START
- Location in memory for CONFIG_SPL_NAND_SIMPLE to load U-Boot
- to.
+ Entry point in loaded image to jump to
CONFIG_SYS_NAND_HW_ECC_OOBFIRST
Define this if you need to first read the OOB and then the
@@ -2757,6 +2804,11 @@ FIT uImage format:
CONFIG_SPL_LIBGENERIC_SUPPORT
Support for lib/libgeneric.o in SPL binary
+ CONFIG_SPL_TARGET
+ Final target image containing SPL and payload. Some SPLs
+ use an arch-specific makefile fragment instead, for
+ example if more than one image needs to be produced.
+
Modem Support:
--------------
@@ -3632,6 +3684,16 @@ Low Level (hardware related) configuration options:
be used if available. These functions may be faster under some
conditions but may increase the binary size.
+- CONFIG_X86_NO_RESET_VECTOR
+ If defined, the x86 reset vector code is excluded. You will need
+ to do this when U-Boot is running from Coreboot.
+
+- CONFIG_X86_NO_REAL_MODE
+ If defined, x86 real mode code is omitted. This assumes a
+ 32-bit environment where such code is not needed. You will
+ need to do this when U-Boot is running from Coreboot.
+
+
Freescale QE/FMAN Firmware Support:
-----------------------------------
@@ -3859,6 +3921,7 @@ saveenv - save environment variables to persistent storage
protect - enable or disable FLASH write protection
erase - erase FLASH memory
flinfo - print FLASH memory information
+nand - NAND memory operations (see doc/README.nand)
bdinfo - print Board Info structure
iminfo - print header information for application image
coninfo - print console devices and informations
diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
index e4c123cd21..da5bc73185 100644
--- a/arch/arm/cpu/armv7/am33xx/board.c
+++ b/arch/arm/cpu/armv7/am33xx/board.c
@@ -33,6 +33,11 @@
#include <i2c.h>
#include <miiphy.h>
#include <cpsw.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
+#include <asm/omap_musb.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,3 +68,83 @@ void setup_clocks_for_console(void)
/* Not yet implemented */
return;
}
+
+/* AM33XX has two MUSB controllers which can be host or gadget */
+#if (defined(CONFIG_MUSB_GADGET) || defined(CONFIG_MUSB_HOST)) && \
+ (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1))
+static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
+/* USB 2.0 PHY Control */
+#define CM_PHY_PWRDN (1 << 0)
+#define CM_PHY_OTG_PWRDN (1 << 1)
+#define OTGVDET_EN (1 << 19)
+#define OTGSESSENDEN (1 << 20)
+
+static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr)
+{
+ if (on) {
+ clrsetbits_le32(reg_addr, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN,
+ OTGVDET_EN | OTGSESSENDEN);
+ } else {
+ clrsetbits_le32(reg_addr, 0, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN);
+ }
+}
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+ .dyn_fifo = 1,
+ .num_eps = 16,
+ .ram_bits = 12,
+};
+
+#ifdef CONFIG_AM335X_USB0
+static void am33xx_otg0_set_phy_power(u8 on)
+{
+ am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0);
+}
+
+struct omap_musb_board_data otg0_board_data = {
+ .set_phy_power = am33xx_otg0_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg0_plat = {
+ .mode = CONFIG_AM335X_USB0_MODE,
+ .config = &musb_config,
+ .power = 50,
+ .platform_ops = &musb_dsps_ops,
+ .board_data = &otg0_board_data,
+};
+#endif
+
+#ifdef CONFIG_AM335X_USB1
+static void am33xx_otg1_set_phy_power(u8 on)
+{
+ am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1);
+}
+
+struct omap_musb_board_data otg1_board_data = {
+ .set_phy_power = am33xx_otg1_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg1_plat = {
+ .mode = CONFIG_AM335X_USB1_MODE,
+ .config = &musb_config,
+ .power = 50,
+ .platform_ops = &musb_dsps_ops,
+ .board_data = &otg1_board_data,
+};
+#endif
+#endif
+
+int arch_misc_init(void)
+{
+#ifdef CONFIG_AM335X_USB0
+ musb_register(&otg0_plat, &otg0_board_data,
+ (void *)AM335X_USB0_OTG_BASE);
+#endif
+#ifdef CONFIG_AM335X_USB1
+ musb_register(&otg1_plat, &otg1_board_data,
+ (void *)AM335X_USB1_OTG_BASE);
+#endif
+ return 0;
+}
diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c
index bc2abb657c..0b4cb4e529 100644
--- a/arch/arm/cpu/armv7/am33xx/clock.c
+++ b/arch/arm/cpu/armv7/am33xx/clock.c
@@ -40,6 +40,7 @@
#define CLK_MODE_MASK 0xfffffff8
#define CLK_DIV_SEL 0xFFFFFFE0
#define CPGMAC0_IDLE 0x30000
+#define DPLL_CLKDCOLDO_GATE_CTRL 0x300
const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
@@ -194,6 +195,11 @@ static void enable_per_clocks(void)
writel(PRCM_MOD_EN, &cmrtc->rtcclkctrl);
while (readl(&cmrtc->rtcclkctrl) != PRCM_MOD_EN)
;
+
+ /* MUSB */
+ writel(PRCM_MOD_EN, &cmper->usb0clkctrl);
+ while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN)
+ ;
}
static void mpu_pll_config(void)
@@ -290,6 +296,8 @@ static void per_pll_config(void)
while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
;
+
+ writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper);
}
void ddr_pll_config(unsigned int ddrpll_m)
diff --git a/arch/arm/cpu/armv7/omap3/Makefile b/arch/arm/cpu/armv7/omap3/Makefile
index ac597be25a..de167eea56 100644
--- a/arch/arm/cpu/armv7/omap3/Makefile
+++ b/arch/arm/cpu/armv7/omap3/Makefile
@@ -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
index 0000000000..7183c4f248
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap3/am35x_musb.c
@@ -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);
+}
+
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h
index 819fd2f026..d6c038e3ae 100644
--- a/arch/arm/include/asm/arch-am33xx/cpu.h
+++ b/arch/arm/include/asm/arch-am33xx/cpu.h
@@ -82,7 +82,8 @@ struct cm_wkuppll {
unsigned int clkseldpllcore; /* offset 0x68 */
unsigned int resv9[1];
unsigned int idlestdpllper; /* offset 0x70 */
- unsigned int resv10[3];
+ unsigned int resv10[2];
+ unsigned int clkdcoldodpllper; /* offset 0x7c */
unsigned int divm4dpllcore; /* offset 0x80 */
unsigned int divm5dpllcore; /* offset 0x84 */
unsigned int clkmoddpllmpu; /* offset 0x88 */
@@ -275,12 +276,16 @@ struct ctrl_stat {
/* Control Device Register */
struct ctrl_dev {
unsigned int deviceid; /* offset 0x00 */
- unsigned int resv1[11];
+ unsigned int resv1[7];
+ unsigned int usb_ctrl0; /* offset 0x20 */
+ unsigned int resv2;
+ unsigned int usb_ctrl1; /* offset 0x28 */
+ unsigned int resv3;
unsigned int macid0l; /* offset 0x30 */
unsigned int macid0h; /* offset 0x34 */
unsigned int macid1l; /* offset 0x38 */
unsigned int macid1h; /* offset 0x3c */
- unsigned int resv2[4];
+ unsigned int resv4[4];
unsigned int miisel; /* offset 0x50 */
};
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware.h b/arch/arm/include/asm/arch-am33xx/hardware.h
index 5bd4bc8722..24ab365ea3 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware.h
@@ -87,4 +87,8 @@
/* RTC base address */
#define AM335X_RTC_BASE 0x44E3E000
+/* OTG */
+#define AM335X_USB0_OTG_BASE 0x47401000
+#define AM335X_USB1_OTG_BASE 0x47401800
+
#endif /* __AM33XX_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h
new file mode 100644
index 0000000000..8acdf9b725
--- /dev/null
+++ b/arch/arm/include/asm/arch-exynos/dwmmc.h
@@ -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);
+}
diff --git a/arch/arm/include/asm/arch-omap3/am35x_def.h b/arch/arm/include/asm/arch-omap3/am35x_def.h
index bbaf1bc97b..67698bc7ef 100644
--- a/arch/arm/include/asm/arch-omap3/am35x_def.h
+++ b/arch/arm/include/asm/arch-omap3/am35x_def.h
@@ -32,9 +32,34 @@
#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 */
diff --git a/board/chromebook-x86/coreboot/coreboot_start16.S b/arch/arm/include/asm/arch-omap3/musb.h
index 9ad06df8bc..423ac500f4 100644
--- a/board/chromebook-x86/coreboot/coreboot_start16.S
+++ b/arch/arm/include/asm/arch-omap3/musb.h
@@ -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.
@@ -18,29 +17,12 @@
*
* 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
index 0000000000..e54c25a560
--- /dev/null
+++ b/arch/arm/include/asm/imx-common/mx5_video.h
@@ -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
index 0000000000..b04d8650ef
--- /dev/null
+++ b/arch/arm/include/asm/omap_musb.h
@@ -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 */
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 92cad9a6eb..22a4d9cc0e 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -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: ");
diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
index c747767e1e..b9b0998d48 100644
--- a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
+++ b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
@@ -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;
diff --git a/arch/mips/cpu/mips32/time.c b/arch/mips/cpu/mips32/time.c
index 350896a2a5..09fc842b50 100644
--- a/arch/mips/cpu/mips32/time.c
+++ b/arch/mips/cpu/mips32/time.c
@@ -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;
diff --git a/arch/mips/cpu/mips64/time.c b/arch/mips/cpu/mips64/time.c
index 51542808dd..720f7b7f8c 100644
--- a/arch/mips/cpu/mips64/time.c
+++ b/arch/mips/cpu/mips64/time.c
@@ -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;
diff --git a/arch/powerpc/config.mk b/arch/powerpc/config.mk
index a30715459d..b7062818bb 100644
--- a/arch/powerpc/config.mk
+++ b/arch/powerpc/config.mk
@@ -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
diff --git a/arch/powerpc/cpu/mpc5xxx/Makefile b/arch/powerpc/cpu/mpc5xxx/Makefile
index 1a088b77bc..8de2c13598 100644
--- a/arch/powerpc/cpu/mpc5xxx/Makefile
+++ b/arch/powerpc/cpu/mpc5xxx/Makefile
@@ -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
index 0000000000..9f14127dca
--- /dev/null
+++ b/arch/powerpc/cpu/mpc5xxx/spl_boot.c
@@ -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!!! */
+}
diff --git a/arch/powerpc/cpu/mpc5xxx/start.S b/arch/powerpc/cpu/mpc5xxx/start.S
index 51cc4e2a10..ad5bc0a179 100644
--- a/arch/powerpc/cpu/mpc5xxx/start.S
+++ b/arch/powerpc/cpu/mpc5xxx/start.S
@@ -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/nand_spl/board/freescale/common.c b/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds
index 0e099bc7c6..cab9b9265c 100644
--- a/nand_spl/board/freescale/common.c
+++ b/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds
@@ -1,6 +1,5 @@
/*
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Author: Matthew McClintock <msm@freescale.com>
+ * 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
@@ -10,31 +9,49 @@
* 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>
+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
+}
-DECLARE_GLOBAL_DATA_PTR;
+OUTPUT_ARCH(powerpc)
+ENTRY(_start)
+SECTIONS
+{
+ .text :
+ {
+ __start = .;
+ arch/powerpc/cpu/mpc5xxx/start.o (.text)
+ *(.text*)
+ } > flash
-#ifndef CONFIG_SYS_FSL_TBCLK_DIV
-#define CONFIG_SYS_FSL_TBCLK_DIV 8
-#endif
+ . = ALIGN(4);
+ .data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash
-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);
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash
+
+ . = ALIGN(4);
+ .end_align : { *(.end_align*) } > flash
+ __spl_flash_end = .;
- while ((mfspr(SPRN_TBRL) - s) < ticks);
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > sdram
}
diff --git a/arch/powerpc/cpu/mpc5xxx/usb_ohci.c b/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
index 607034b7c6..de07343d93 100644
--- a/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
+++ b/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
@@ -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;
diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile
index 78c412d9f3..4c2b1040d4 100644
--- a/arch/powerpc/cpu/mpc85xx/Makefile
+++ b/arch/powerpc/cpu/mpc85xx/Makefile
@@ -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))
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
index 2be192d578..e5ecf5dae5 100644
--- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c
+++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
@@ -24,6 +24,109 @@
#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[])
{
@@ -137,6 +240,17 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#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;
}
diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c
index db232e64f8..9b9832cfc3 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu.c
@@ -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:
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index f01804bbb9..d1155e8126 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -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");
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen1.c b/arch/powerpc/cpu/mpc85xx/ddr-gen1.c
index 54437dd0cb..8a86819fb5 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen1.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen1.c
@@ -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);
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c
index 49000a19e8..a705862522 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c
@@ -19,15 +19,12 @@ 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) {
printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
index f118dd5daf..ef0dd1da64 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
@@ -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:
diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
index 7f466ac6a9..5495dc59ee 100644
--- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
@@ -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;
}
diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S
index 4ba44a9028..5c4b1e3b75 100644
--- a/arch/powerpc/cpu/mpc85xx/release.S
+++ b/arch/powerpc/cpu/mpc85xx/release.S
@@ -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)
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c b/arch/powerpc/cpu/mpc85xx/spl_minimal.c
index bf7a6f6be6..c6b9cd0acc 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c
+++ b/arch/powerpc/cpu/mpc85xx/spl_minimal.c
@@ -21,12 +21,16 @@
*/
#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);
+}
diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S
index ac17f9d3ca..bb0dc1a653 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -44,6 +44,15 @@
#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 */
diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c
index a548dec9a7..f44fadcffd 100644
--- a/arch/powerpc/cpu/mpc85xx/tlb.c
+++ b/arch/powerpc/cpu/mpc85xx/tlb.c
@@ -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
index 0000000000..1c408e29f5
--- /dev/null
+++ b/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds
@@ -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__ = .;
+}
diff --git a/arch/powerpc/cpu/mpc86xx/ddr-8641.c b/arch/powerpc/cpu/mpc86xx/ddr-8641.c
index b8f2c9387f..92ba26dc8e 100644
--- a/arch/powerpc/cpu/mpc86xx/ddr-8641.c
+++ b/arch/powerpc/cpu/mpc86xx/ddr-8641.c
@@ -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);
diff --git a/arch/powerpc/cpu/mpc8xxx/Makefile b/arch/powerpc/cpu/mpc8xxx/Makefile
index 4ae26e4210..3dc8e055b6 100644
--- a/arch/powerpc/cpu/mpc8xxx/Makefile
+++ b/arch/powerpc/cpu/mpc8xxx/Makefile
@@ -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))
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index 088cc0e855..8016bcdc22 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -18,15 +18,7 @@
#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)
{
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/util.c b/arch/powerpc/cpu/mpc8xxx/ddr/util.c
index 940ffff773..acfe1f095f 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/util.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/util.c
@@ -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
diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c
index 68db8e2448..1986fea030 100644
--- a/arch/powerpc/cpu/mpc8xxx/fdt.c
+++ b/arch/powerpc/cpu/mpc8xxx/fdt.c
@@ -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;
diff --git a/drivers/misc/fsl_law.c b/arch/powerpc/cpu/mpc8xxx/law.c
index 223cd5d65c..ce1d71e307 100644
--- a/drivers/misc/fsl_law.c
+++ b/arch/powerpc/cpu/mpc8xxx/law.c
@@ -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;
diff --git a/arch/powerpc/cpu/ppc4xx/usb_ohci.c b/arch/powerpc/cpu/ppc4xx/usb_ohci.c
index 4ce2726297..f820c37a8f 100644
--- a/arch/powerpc/cpu/ppc4xx/usb_ohci.c
+++ b/arch/powerpc/cpu/ppc4xx/usb_ohci.c
@@ -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;
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index 03baaee1b7..0b9638bcee 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -27,6 +27,12 @@
#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 */
@@ -131,7 +137,6 @@
#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
@@ -175,7 +180,6 @@
#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
@@ -188,7 +192,6 @@
#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
@@ -242,7 +245,6 @@
#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
@@ -318,7 +320,6 @@
#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
@@ -343,6 +344,7 @@
#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
@@ -350,7 +352,6 @@
#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
@@ -375,6 +376,7 @@
#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
@@ -417,6 +419,9 @@
#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 */
@@ -425,7 +430,6 @@
#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
@@ -449,6 +453,7 @@
#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
@@ -472,7 +477,6 @@
#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
diff --git a/arch/powerpc/include/asm/immap_83xx.h b/arch/powerpc/include/asm/immap_83xx.h
index 679832cd6c..8ac13fc05c 100644
--- a/arch/powerpc/include/asm/immap_83xx.h
+++ b/arch/powerpc/include/asm/immap_83xx.h
@@ -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)
diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h
index 969f726c36..296b549779 100644
--- a/arch/powerpc/include/asm/immap_85xx.h
+++ b/arch/powerpc/include/asm/immap_85xx.h
@@ -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 \
diff --git a/arch/powerpc/include/asm/immap_86xx.h b/arch/powerpc/include/asm/immap_86xx.h
index cc338e4739..2a704fe6b7 100644
--- a/arch/powerpc/include/asm/immap_86xx.h
+++ b/arch/powerpc/include/asm/immap_86xx.h
@@ -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
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 7aa3231ad4..19fe250305 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -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 */
diff --git a/board/chromebook-x86/coreboot/coreboot_pci.c b/arch/powerpc/include/asm/spl.h
index 732ca3ceaf..f43bc23c92 100644
--- a/board/chromebook-x86/coreboot/coreboot_pci.c
+++ b/arch/powerpc/include/asm/spl.h
@@ -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
@@ -24,7 +20,12 @@
* 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
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 808021c42e..844fe8636d 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -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)
diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index ac5bd6d4f1..7088293a36 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -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
index 0000000000..502c93bebe
--- /dev/null
+++ b/arch/powerpc/lib/spl.c
@@ -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 */
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index 56fd77acea..24b5ce8e30 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -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)
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 7f1fc188cb..57324b6174 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -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)
diff --git a/arch/x86/cpu/coreboot/Makefile b/arch/x86/cpu/coreboot/Makefile
index 13f5f8a2f0..b1d3e959f8 100644
--- a/arch/x86/cpu/coreboot/Makefile
+++ b/arch/x86/cpu/coreboot/Makefile
@@ -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))
diff --git a/arch/x86/cpu/coreboot/coreboot_car.S b/arch/x86/cpu/coreboot/car.S
index 3cc25755fd..3cc25755fd 100644
--- a/arch/x86/cpu/coreboot/coreboot_car.S
+++ b/arch/x86/cpu/coreboot/car.S
diff --git a/board/BuS/eb_cpu5282/config.mk b/arch/x86/cpu/coreboot/config.mk
index 18fb84eb3b..4858fc3728 100644
--- a/board/BuS/eb_cpu5282/config.mk
+++ b/arch/x86/cpu/coreboot/config.mk
@@ -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
diff --git a/board/chromebook-x86/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
index 22a643c9d6..9c9431e0d9 100644
--- a/board/chromebook-x86/coreboot/coreboot.c
+++ b/arch/x86/cpu/coreboot/coreboot.c
@@ -26,13 +26,15 @@
#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
index 0000000000..8f94167480
--- /dev/null
+++ b/arch/x86/cpu/coreboot/pci.c
@@ -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);
+}
diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c
index f8fdac6319..76274cb88e 100644
--- a/arch/x86/cpu/coreboot/sdram.c
+++ b/arch/x86/cpu/coreboot/sdram.c
@@ -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
index 9b3e660dde..0000000000
--- a/arch/x86/cpu/coreboot/sysinfo.c
+++ /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")));
diff --git a/arch/x86/cpu/coreboot/tables.c b/arch/x86/cpu/coreboot/tables.c
index 0e3451bb22..b116d59555 100644
--- a/arch/x86/cpu/coreboot/tables.c
+++ b/arch/x86/cpu/coreboot/tables.c
@@ -28,11 +28,20 @@
* 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
* we don't need. If in the future, we want to use coreboot on some other
@@ -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
index 0000000000..2ca7a57bce
--- /dev/null
+++ b/arch/x86/cpu/coreboot/timestamp.c
@@ -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());
+}
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index e9bb0d770a..315e87afeb 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -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)
+{
+}
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index 43ec3f8b08..dd30a05a9d 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -28,10 +28,14 @@
*/
#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" \
@@ -41,72 +45,6 @@
"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
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index ee0dabe4bc..e960e21f6e 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -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
diff --git a/arch/x86/cpu/start16.S b/arch/x86/cpu/start16.S
index cc393ff54f..603bf1d2d3 100644
--- a/arch/x86/cpu/start16.S
+++ b/arch/x86/cpu/start16.S
@@ -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
index 0000000000..149109d4f4
--- /dev/null
+++ b/arch/x86/cpu/timer.c
@@ -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;
+}
diff --git a/arch/x86/cpu/u-boot.lds b/arch/x86/cpu/u-boot.lds
index a1ecefafc6..0c6f0e31d8 100644
--- a/arch/x86/cpu/u-boot.lds
+++ b/arch/x86/cpu/u-boot.lds
@@ -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
index 0000000000..4862a59704
--- /dev/null
+++ b/arch/x86/dts/coreboot.dtsi
@@ -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
index 0000000000..b41d241de2
--- /dev/null
+++ b/arch/x86/dts/skeleton.dtsi
@@ -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>; };
+};
diff --git a/arch/x86/include/asm/arch-coreboot/sysinfo.h b/arch/x86/include/asm/arch-coreboot/sysinfo.h
index 5c44e1a47c..77ae304969 100644
--- a/arch/x86/include/asm/arch-coreboot/sysinfo.h
+++ b/arch/x86/include/asm/arch-coreboot/sysinfo.h
@@ -30,32 +30,52 @@
#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;
diff --git a/arch/x86/include/asm/arch-coreboot/tables.h b/arch/x86/include/asm/arch-coreboot/tables.h
index c28697375f..ad34a8b0f1 100644
--- a/arch/x86/include/asm/arch-coreboot/tables.h
+++ b/arch/x86/include/asm/arch-coreboot/tables.h
@@ -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
index 0000000000..d104912e06
--- /dev/null
+++ b/arch/x86/include/asm/arch-coreboot/timestamp.h
@@ -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
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index c7a38f237a..5a7e4cba2b 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -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
diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h
index 87c9e0be42..d4678d4916 100644
--- a/arch/x86/include/asm/cache.h
+++ b/arch/x86/include/asm/cache.h
@@ -32,4 +32,20 @@
#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
index 0000000000..aa8be30bac
--- /dev/null
+++ b/arch/x86/include/asm/control_regs.h
@@ -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
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index bce999f41c..dc6402b67d 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -33,9 +33,13 @@
#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 */
diff --git a/arch/nios2/include/asm/status_led.h b/arch/x86/include/asm/gpio.h
index 20f8d90195..0a37a85ad1 100644
--- a/arch/nios2/include/asm/status_led.h
+++ b/arch/x86/include/asm/gpio.h
@@ -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.
*
@@ -20,12 +18,10 @@
* 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_ */
diff --git a/arch/x86/include/asm/init_helpers.h b/arch/x86/include/asm/init_helpers.h
index 8afb443290..2f437e0343 100644
--- a/arch/x86/include/asm/init_helpers.h
+++ b/arch/x86/include/asm/init_helpers.h
@@ -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_ */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 9b757d489e..86bac90e8e 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -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
index 0000000000..50175994cf
--- /dev/null
+++ b/arch/x86/include/asm/msr-index.h
@@ -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
index 0000000000..6030633d10
--- /dev/null
+++ b/arch/x86/include/asm/msr.h
@@ -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
index 0000000000..6842da500a
--- /dev/null
+++ b/arch/x86/include/asm/mtrr.h
@@ -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 */
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 37cc7e3a0f..6d68ab6c92 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -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[]
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 6eb518063b..17f27cbb68 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -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)
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index 9a40e383eb..e9fde88f7d 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -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__ */
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index 878a1ee77b..99062e5955 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -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_ */
diff --git a/arch/x86/include/asm/u-boot.h b/arch/x86/include/asm/u-boot.h
index da667c50a4..2f45c7b3d7 100644
--- a/arch/x86/include/asm/u-boot.h
+++ b/arch/x86/include/asm/u-boot.h
@@ -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 */
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 51836dacca..0a52cc896c 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -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)
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c
index e5caf13561..22bc26dde9 100644
--- a/arch/x86/lib/board.c
+++ b/arch/x86/lib/board.c
@@ -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,
@@ -154,6 +161,9 @@ init_fnc_t *init_sequence_r[] = {
#ifndef CONFIG_SYS_NO_FLASH
flash_init_r,
#endif
+#ifdef CONFIG_SPI
+ init_func_spi;
+#endif
env_relocate_r,
#ifdef CONFIG_PCI
pci_init_r,
@@ -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
diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c
index 9ec34ff992..3eec9a61d6 100644
--- a/arch/x86/lib/init_helpers.c
+++ b/arch/x86/lib/init_helpers.c
@@ -28,9 +28,11 @@
#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
diff --git a/arch/x86/lib/init_wrappers.c b/arch/x86/lib/init_wrappers.c
index 71449fe6fa..cca018fa9b 100644
--- a/arch/x86/lib/init_wrappers.c
+++ b/arch/x86/lib/init_wrappers.c
@@ -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;
}
diff --git a/arch/x86/lib/pcat_timer.c b/arch/x86/lib/pcat_timer.c
index 6b3db69447..b0b6637f3a 100644
--- a/arch/x86/lib/pcat_timer.c
+++ b/arch/x86/lib/pcat_timer.c
@@ -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
index 0000000000..18f0e62acd
--- /dev/null
+++ b/arch/x86/lib/physmem.c
@@ -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;
+}
diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c
index 200baaba6a..23edca9526 100644
--- a/arch/x86/lib/relocate.c
+++ b/arch/x86/lib/relocate.c
@@ -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;
}
diff --git a/arch/x86/lib/timer.c b/arch/x86/lib/timer.c
index fd7032e92c..a13424b3e3 100644
--- a/arch/x86/lib/timer.c
+++ b/arch/x86/lib/timer.c
@@ -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;
+}
diff --git a/arch/x86/lib/video.c b/arch/x86/lib/video.c
index 3d6b24d620..20e2416ae1 100644
--- a/arch/x86/lib/video.c
+++ b/arch/x86/lib/video.c
@@ -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();
}
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 22142864c2..46af391f29 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -36,6 +36,10 @@
#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)
diff --git a/board/BuS/eb_cpu5282/Makefile b/board/BuS/eb_cpu5282/Makefile
index 0f14699c5e..ac860c1348 100644
--- a/board/BuS/eb_cpu5282/Makefile
+++ b/board/BuS/eb_cpu5282/Makefile
@@ -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
index fe03b17581..0000000000
--- a/board/BuS/eb_cpu5282/cfm_flash.c
+++ /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
index ed4e7943e7..0000000000
--- a/board/BuS/eb_cpu5282/cfm_flash.h
+++ /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
diff --git a/board/BuS/eb_cpu5282/eb_cpu5282.c b/board/BuS/eb_cpu5282/eb_cpu5282.c
index d64ad1b705..f73431eff5 100644
--- a/board/BuS/eb_cpu5282/eb_cpu5282.c
+++ b/board/BuS/eb_cpu5282/eb_cpu5282.c
@@ -35,18 +35,19 @@
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
index 8b7f9578fc..0000000000
--- a/board/BuS/eb_cpu5282/flash.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * (C) Copyright 2005
- * BuS Elektronik GmbH & Co.KG <esw@bus-elektonik.de>
- *
- * Based On
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include "cfm_flash.h"
-
-#define PHYS_FLASH_1 CONFIG_SYS_FLASH_BASE
-#define FLASH_BANK_SIZE 0x200000
-
-flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
-
-void flash_print_info (flash_info_t * info)
-{
- int i;
-
- switch (info->flash_id & FLASH_VENDMASK) {
- case (AMD_MANUFACT & FLASH_VENDMASK):
- printf ("AMD: ");
- switch (info->flash_id & FLASH_TYPEMASK) {
- case (AMD_ID_LV160B & FLASH_TYPEMASK):
- printf ("AM29LV160B (16Bit)\n");
- break;
- default:
- printf ("Unknown Chip Type\n");
- break;
- }
- break;
- case FREESCALE_MANUFACT & FLASH_VENDMASK:
- cfm_flash_print_info (info);
- break;
- default:
- printf ("Unknown Vendor ");
- break;
- }
-
- puts (" Size: ");
- if ((info->size >> 20) > 0)
- {
- printf ("%ld MiB",info->size >> 20);
- }
- else
- {
- printf ("%ld KiB",info->size >> 10);
- }
- printf (" in %d Sectors\n", info->sector_count);
-
- printf (" Sector Start Addresses:");
- for (i = 0; i < info->sector_count; i++) {
- if ((i % 4) == 0) {
- printf ("\n ");
- }
- printf ("%02d: %08lX%s ", i,info->start[i],
- info->protect[i] ? " P" : " ");
- }
- printf ("\n\n");
-}
-
-unsigned long flash_init (void)
-{
- int i, j;
- ulong size = 0;
-
- for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
- ulong flashbase = 0;
-
- switch (i)
- {
- case 1:
- flash_info[i].flash_id =
- (AMD_MANUFACT & FLASH_VENDMASK) |
- (AMD_ID_LV160B & FLASH_TYPEMASK);
- flash_info[i].size = FLASH_BANK_SIZE;
- flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
- memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
- flashbase = PHYS_FLASH_1;
- for (j = 0; j < flash_info[i].sector_count; j++) {
- if (j == 0) {
- /* 1st is 16 KiB */
- flash_info[i].start[j] = flashbase;
- }
- if ((j >= 1) && (j <= 2)) {
- /* 2nd and 3rd are 8 KiB */
- flash_info[i].start[j] =
- flashbase + 0x4000 + 0x2000 * (j - 1);
- }
- if (j == 3) {
- /* 4th is 32 KiB */
- flash_info[i].start[j] = flashbase + 0x8000;
- }
- if ((j >= 4) && (j <= 34)) {
- /* rest is 256 KiB */
- flash_info[i].start[j] =
- flashbase + 0x10000 + 0x10000 * (j - 4);
- }
- }
- break;
- case 0:
- cfm_flash_init (&flash_info[i]);
- break;
- default:
- panic ("configured to many flash banks!\n");
- }
-
- size += flash_info[i].size;
- }
-
- flash_protect (FLAG_PROTECT_SET,
- CONFIG_SYS_FLASH_BASE,
- CONFIG_SYS_FLASH_BASE + 0xffff, &flash_info[0]);
-
- return size;
-}
-
-#define CMD_READ_ARRAY 0x00F0
-#define CMD_UNLOCK1 0x00AA
-#define CMD_UNLOCK2 0x0055
-#define CMD_ERASE_SETUP 0x0080
-#define CMD_ERASE_CONFIRM 0x0030
-#define CMD_PROGRAM 0x00A0
-#define CMD_UNLOCK_BYPASS 0x0020
-
-#define MEM_FLASH_ADDR1 (*(volatile u16 *)(info->start[0] + (0x00000555<<1)))
-#define MEM_FLASH_ADDR2 (*(volatile u16 *)(info->start[0] + (0x000002AA<<1)))
-
-
-#define BIT_ERASE_DONE 0x0080
-#define BIT_RDY_MASK 0x0080
-#define BIT_PROGRAM_ERROR 0x0020
-#define BIT_TIMEOUT 0x80000000 /* our flag */
-
-#define ERR_READY -1
-
-int amd_flash_erase_sector(flash_info_t * info, int sector)
-{
- int state;
- ulong result;
- ulong start;
-
- volatile u16 *addr =
- (volatile u16 *) (info->start[sector]);
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- MEM_FLASH_ADDR2 = CMD_UNLOCK2;
- MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- MEM_FLASH_ADDR2 = CMD_UNLOCK2;
- *addr = CMD_ERASE_CONFIRM;
-
- /* wait until flash is ready */
- state = 0;
- start = get_timer(0);
-
- do {
- result = *addr;
-
- /* check timeout */
- if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
- MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
- state = ERR_TIMOUT;
- }
-
- if (!state && (result & 0xFFFF) & BIT_ERASE_DONE)
- state = ERR_READY;
- }
- while (!state);
- if (state == ERR_READY)
- state = ERR_OK;
-
- MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
-
- return state;
-}
-
-int flash_erase (flash_info_t * info, int s_first, int s_last)
-{
- int iflag, cflag;
- int sector;
- int rc;
-
- rc = ERR_OK;
-
- if (info->flash_id == FLASH_UNKNOWN)
- {
- rc = ERR_UNKNOWN_FLASH_TYPE;
- } /* (info->flash_id == FLASH_UNKNOWN) */
-
- if ((s_first < 0) || (s_first > s_last) || s_last >= info->sector_count)
- {
- rc = ERR_INVAL;
- }
-
- cflag = icache_status ();
- icache_disable ();
- iflag = disable_interrupts ();
-
- for (sector = s_first; (sector <= s_last) && (rc == ERR_OK); sector++) {
-
- if (info->protect[sector])
- {
- putc('P'); /* protected sector will not erase */
- }
- else
- {
- /* erase on unprotected sector */
- puts("E\b");
- switch (info->flash_id & FLASH_VENDMASK)
- {
- case (AMD_MANUFACT & FLASH_VENDMASK):
- rc = amd_flash_erase_sector(info,sector);
- break;
- case (FREESCALE_MANUFACT & FLASH_VENDMASK):
- rc = cfm_flash_erase_sector(info,sector);
- break;
- default:
- return ERR_UNKNOWN_FLASH_VENDOR;
- }
- putc('.');
- }
- }
- if (rc!=ERR_OK)
- {
- printf ("\n ");
- flash_perror (rc);
- }
- else
- {
- printf (" done\n");
- }
-
- udelay (10000); /* allow flash to settle - wait 10 ms */
-
- if (iflag)
- enable_interrupts ();
-
- if (cflag)
- icache_enable ();
-
- return rc;
-}
-
-volatile static int amd_write_word (flash_info_t * info, ulong dest, u16 data)
-{
- volatile u16 *addr;
- ulong result;
- int cflag, iflag;
- int state;
- ulong start;
-
- /*
- * Check if Flash is (sufficiently) erased
- */
- addr = (volatile u16 *) dest;
-
- result = *addr;
- if ((result & data) != data)
- return ERR_NOT_ERASED;
-
- /*
- * Disable interrupts which might cause a timeout
- * here. Remember that our exception vectors are
- * at address 0 in the flash, and we don't want a
- * (ticker) exception to happen while the flash
- * chip is in programming mode.
- */
-
- cflag = icache_status ();
- icache_disable ();
- iflag = disable_interrupts ();
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- MEM_FLASH_ADDR2 = CMD_UNLOCK2;
- MEM_FLASH_ADDR1 = CMD_PROGRAM;
- *addr = data;
-
- /* arm simple, non interrupt dependent timer */
- start = get_timer(0);
-
- /* wait until flash is ready */
- state = 0;
- do {
- result = *addr;
-
- /* check timeout */
- if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
- state = ERR_TIMOUT;
- }
- if (!state && ((result & BIT_RDY_MASK) == (data & BIT_RDY_MASK)))
- state = ERR_READY;
-
- } while (!state);
-
- *addr = CMD_READ_ARRAY;
-
- if (state == ERR_READY)
- state = ERR_OK;
- if ((*addr != data) && (state != ERR_TIMOUT))
- state = ERR_PROG_ERROR;
-
- if (iflag)
- enable_interrupts ();
-
- if (cflag)
- icache_enable ();
-
- return state;
-}
-
-int amd_flash_write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
-{
- int rc;
- ulong dest;
- u16 data;
-
- rc = ERR_OK;
- if (addr & 1)
- {
- debug ("Byte alignment not supported\n");
- rc = ERR_ALIGN;
- }
- if (cnt & 1)
- {
- debug ("Byte transfer not supported\n");
- rc = ERR_ALIGN;
- }
-
- dest = addr;
- while ((cnt>=2) && (rc == ERR_OK))
- {
- data = *((volatile u16 *) src);
- rc=amd_write_word (info,dest,data);
- src +=2;
- dest +=2;
- cnt -=2;
- }
- return rc;
-}
-
-int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
-{
- int rc;
-
- switch (info->flash_id & FLASH_VENDMASK)
- {
- case (AMD_MANUFACT & FLASH_VENDMASK):
- rc = amd_flash_write_buff(info,src,addr,cnt);
- break;
- case (FREESCALE_MANUFACT & FLASH_VENDMASK):
- rc = cfm_flash_write_buff(info,src,addr,cnt);
- break;
- default:
- rc = ERR_UNKNOWN_FLASH_VENDOR;
- }
- return rc;
-
-}
-int amd_flash_protect(flash_info_t * info,long sector,int prot)
-{
- int rc;
- rc= ERR_OK;
- if (prot)
- {
- info->protect[sector]=1;
- }
- else
- {
- info->protect[sector]=0;
- }
- return rc;
-}
-
-#ifdef CONFIG_SYS_FLASH_PROTECTION
-
-int flash_real_protect(flash_info_t * info,long sector,int prot)
-{
- int rc;
-
- switch (info->flash_id & FLASH_VENDMASK)
- {
- case (AMD_MANUFACT & FLASH_VENDMASK):
- rc = amd_flash_protect(info,sector,prot);
- break;
- case (FREESCALE_MANUFACT & FLASH_VENDMASK):
- rc = cfm_flash_protect(info,sector,prot);
- break;
- default:
- rc = ERR_UNKNOWN_FLASH_VENDOR;
- }
- return rc;
-}
-
-#endif
diff --git a/board/a3m071/Makefile b/board/a3m071/Makefile
new file mode 100644
index 0000000000..6f961fb6e3
--- /dev/null
+++ b/board/a3m071/Makefile
@@ -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
index 0000000000..7698614a62
--- /dev/null
+++ b/board/a3m071/README
@@ -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
index 0000000000..89ced824eb
--- /dev/null
+++ b/board/a3m071/a3m071.c
@@ -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
index 0000000000..e49e99618a
--- /dev/null
+++ b/board/a3m071/mt46v16m16-75.h
@@ -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
diff --git a/board/chromebook-x86/coreboot/Makefile b/board/chromebook-x86/coreboot/Makefile
index cfcc0dfbe5..886baf6c96 100644
--- a/board/chromebook-x86/coreboot/Makefile
+++ b/board/chromebook-x86/coreboot/Makefile
@@ -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
index 0000000000..f720851aac
--- /dev/null
+++ b/board/chromebook-x86/coreboot/config.mk
@@ -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
index 0000000000..cb6a9e41ee
--- /dev/null
+++ b/board/chromebook-x86/dts/alex.dts
@@ -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
index 0000000000..af60f59de7
--- /dev/null
+++ b/board/chromebook-x86/dts/link.dts
@@ -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>; };
+};
diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c
index c41f11d60c..a3079dbca3 100644
--- a/board/davedenx/qong/qong.c
+++ b/board/davedenx/qong/qong.c
@@ -28,11 +28,12 @@
#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);
diff --git a/board/exmeritus/hww1u1a/hww1u1a.c b/board/exmeritus/hww1u1a/hww1u1a.c
index 52c22faaa0..89cfaad91f 100644
--- a/board/exmeritus/hww1u1a/hww1u1a.c
+++ b/board/exmeritus/hww1u1a/hww1u1a.c
@@ -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");
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index 36f7c4f30f..75725b49ad 100644
--- a/board/freescale/common/Makefile
+++ b/board/freescale/common/Makefile
@@ -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))
diff --git a/board/freescale/common/ngpixis.h b/board/freescale/common/ngpixis.h
index 1d4483d8b9..a239ee31df 100644
--- a/board/freescale/common/ngpixis.h
+++ b/board/freescale/common/ngpixis.h
@@ -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 */
diff --git a/board/freescale/corenet_ds/Makefile b/board/freescale/corenet_ds/Makefile
index 1fdf8b706b..d79193af2a 100644
--- a/board/freescale/corenet_ds/Makefile
+++ b/board/freescale/corenet_ds/Makefile
@@ -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))
diff --git a/board/freescale/corenet_ds/corenet_ds.c b/board/freescale/corenet_ds/corenet_ds.c
index a33c936fa0..21428e3347 100644
--- a/board/freescale/corenet_ds/corenet_ds.c
+++ b/board/freescale/corenet_ds/corenet_ds.c
@@ -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;
diff --git a/board/freescale/corenet_ds/ddr.c b/board/freescale/corenet_ds/ddr.c
index 4a53b8d933..da284cde95 100644
--- a/board/freescale/corenet_ds/ddr.c
+++ b/board/freescale/corenet_ds/ddr.c
@@ -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
index 0000000000..ef9de25bd8
--- /dev/null
+++ b/board/freescale/corenet_ds/eth_superhydra.c
@@ -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
index 0000000000..e65de364d7
--- /dev/null
+++ b/board/freescale/corenet_ds/p5040ds_ddr.c
@@ -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}
+};
diff --git a/board/freescale/mpc8540ads/mpc8540ads.c b/board/freescale/mpc8540ads/mpc8540ads.c
index a275d3a074..418c06b655 100644
--- a/board/freescale/mpc8540ads/mpc8540ads.c
+++ b/board/freescale/mpc8540ads/mpc8540ads.c
@@ -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;
diff --git a/board/freescale/mpc8560ads/mpc8560ads.c b/board/freescale/mpc8560ads/mpc8560ads.c
index 285edbce6b..a4f48bb234 100644
--- a/board/freescale/mpc8560ads/mpc8560ads.c
+++ b/board/freescale/mpc8560ads/mpc8560ads.c
@@ -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;
diff --git a/board/freescale/mpc8569mds/mpc8569mds.c b/board/freescale/mpc8569mds/mpc8569mds.c
index d119c6517f..0d3b418625 100644
--- a/board/freescale/mpc8569mds/mpc8569mds.c
+++ b/board/freescale/mpc8569mds/mpc8569mds.c
@@ -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);
diff --git a/board/freescale/mx31pdk/mx31pdk.c b/board/freescale/mx31pdk/mx31pdk.c
index 9f8bc53e71..bc60632aa0 100644
--- a/board/freescale/mx31pdk/mx31pdk.c
+++ b/board/freescale/mx31pdk/mx31pdk.c
@@ -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);
diff --git a/board/freescale/mx35pdk/mx35pdk.c b/board/freescale/mx35pdk/mx35pdk.c
index 4d8f2f5eea..2aa000f238 100644
--- a/board/freescale/mx35pdk/mx35pdk.c
+++ b/board/freescale/mx35pdk/mx35pdk.c
@@ -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);
diff --git a/board/freescale/mx51evk/Makefile b/board/freescale/mx51evk/Makefile
index 224eaa3c73..2310fe137d 100644
--- a/board/freescale/mx51evk/Makefile
+++ b/board/freescale/mx51evk/Makefile
@@ -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))
diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c
index 421d8c2244..d1ef431895 100644
--- a/board/freescale/mx51evk/mx51evk.c
+++ b/board/freescale/mx51evk/mx51evk.c
@@ -30,19 +30,14 @@
#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
index 0000000000..f036cf73b2
--- /dev/null
+++ b/board/freescale/mx51evk/mx51evk_video.c
@@ -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);
+}
diff --git a/board/freescale/mx53evk/mx53evk.c b/board/freescale/mx53evk/mx53evk.c
index bb4621d62e..1273501476 100644
--- a/board/freescale/mx53evk/mx53evk.c
+++ b/board/freescale/mx53evk/mx53evk.c
@@ -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);
diff --git a/board/freescale/mx53loco/Makefile b/board/freescale/mx53loco/Makefile
index 8bc69a92c1..3be17c5917 100644
--- a/board/freescale/mx53loco/Makefile
+++ b/board/freescale/mx53loco/Makefile
@@ -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))
diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c
index a11e883186..81c511cdc1 100644
--- a/board/freescale/mx53loco/mx53loco.c
+++ b/board/freescale/mx53loco/mx53loco.c
@@ -31,12 +31,13 @@
#include <asm/arch/iomux.h>
#include <asm/arch/clock.h>
#include <asm/errno.h>
+#include <asm/imx-common/mx5_video.h>
#include <netdev.h>
#include <i2c.h>
#include <mmc.h>
#include <fsl_esdhc.h>
#include <asm/gpio.h>
-#include <pmic.h>
+#include <power/pmic.h>
#include <dialog_pmic.h>
#include <fsl_pmic.h>
#include <linux/fb.h>
@@ -344,10 +345,16 @@ static int power_init(void)
unsigned int val;
int ret = -1;
struct pmic *p;
+ int retval;
if (!i2c_probe(CONFIG_SYS_DIALOG_PMIC_I2C_ADDR)) {
- pmic_dialog_init();
- p = get_pmic();
+ retval = pmic_dialog_init(I2C_PMIC);
+ if (retval)
+ return retval;
+
+ p = pmic_get("DIALOG_PMIC");
+ if (!p)
+ return -ENODEV;
/* Set VDDA to 1.25V */
val = DA9052_BUCKCORE_BCOREEN | DA_BUCKCORE_VBCORE_1_250V;
@@ -363,8 +370,13 @@ static int power_init(void)
}
if (!i2c_probe(CONFIG_SYS_FSL_PMIC_I2C_ADDR)) {
- pmic_init();
- p = get_pmic();
+ retval = pmic_init(I2C_PMIC);
+ if (retval)
+ return retval;
+
+ p = pmic_get("DIALOG_PMIC");
+ if (!p)
+ return -ENODEV;
/* Set VDDGP to 1.25V for 1GHz on SW1 */
pmic_reg_read(p, REG_SW_0, &val);
@@ -412,74 +424,11 @@ static void clock_1GHz(void)
printf("CPU: Switch DDR clock to 400MHz failed\n");
}
-static struct fb_videomode const claa_wvga = {
- .name = "CLAA07LC0ACW",
- .refresh = 57,
- .xres = 800,
- .yres = 480,
- .pixclock = 37037,
- .left_margin = 40,
- .right_margin = 60,
- .upper_margin = 10,
- .lower_margin = 10,
- .hsync_len = 20,
- .vsync_len = 10,
- .sync = 0,
- .vmode = FB_VMODE_NONINTERLACED
-};
-
-void lcd_iomux(void)
-{
- mxc_request_iomux(MX53_PIN_DI0_DISP_CLK, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DI0_PIN15, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DI0_PIN2, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DI0_PIN3, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT0, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT1, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT2, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT3, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT4, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT5, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT6, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT7, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT8, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT9, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT10, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT11, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT12, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT13, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT14, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT15, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT16, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT17, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT18, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT19, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT20, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT21, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT22, IOMUX_CONFIG_ALT0);
- mxc_request_iomux(MX53_PIN_DISP0_DAT23, IOMUX_CONFIG_ALT0);
-
- /* Turn on GPIO backlight */
- mxc_request_iomux(MX53_PIN_EIM_D24, IOMUX_CONFIG_ALT1);
- gpio_direction_output(MX53LOCO_LCD_POWER, 1);
-
- /* Turn on display contrast */
- mxc_request_iomux(MX53_PIN_GPIO_1, IOMUX_CONFIG_ALT1);
- gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_1), 1);
-}
-
-void lcd_enable(void)
-{
- int ret = ipuv3_fb_init(&claa_wvga, 0, IPU_PIX_FMT_RGB565);
- if (ret)
- printf("LCD cannot be configured: %d\n", ret);
-}
-
int board_early_init_f(void)
{
setup_iomux_uart();
setup_iomux_fec();
- lcd_iomux();
+ setup_iomux_lcd();
return 0;
}
diff --git a/board/freescale/mx53loco/mx53loco_video.c b/board/freescale/mx53loco/mx53loco_video.c
new file mode 100644
index 0000000000..69991e8511
--- /dev/null
+++ b/board/freescale/mx53loco/mx53loco_video.c
@@ -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);
+}
diff --git a/board/freescale/p1023rds/p1023rds.c b/board/freescale/p1023rds/p1023rds.c
index eb11f3fe12..9110767a14 100644
--- a/board/freescale/p1023rds/p1023rds.c
+++ b/board/freescale/p1023rds/p1023rds.c
@@ -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);
diff --git a/board/freescale/p1_p2_rdb_pc/Makefile b/board/freescale/p1_p2_rdb_pc/Makefile
index 0dcf7d1ab1..5b45d72f51 100644
--- a/board/freescale/p1_p2_rdb_pc/Makefile
+++ b/board/freescale/p1_p2_rdb_pc/Makefile
@@ -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))
diff --git a/board/freescale/p1_p2_rdb_pc/ddr.c b/board/freescale/p1_p2_rdb_pc/ddr.c
index 88ba56f457..9355536b35 100644
--- a/board/freescale/p1_p2_rdb_pc/ddr.c
+++ b/board/freescale/p1_p2_rdb_pc/ddr.c
@@ -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,
diff --git a/board/freescale/p1_p2_rdb_pc/law.c b/board/freescale/p1_p2_rdb_pc/law.c
index 0da8300c6f..cb5e7b7c0c 100644
--- a/board/freescale/p1_p2_rdb_pc/law.c
+++ b/board/freescale/p1_p2_rdb_pc/law.c
@@ -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
};
diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
index aa39260ca7..5b5b86c822 100644
--- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
+++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
@@ -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);
diff --git a/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c b/board/freescale/p1_p2_rdb_pc/spl_minimal.c
index 4c140c1572..09019e98af 100644
--- a/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c
+++ b/board/freescale/p1_p2_rdb_pc/spl_minimal.c
@@ -23,18 +23,20 @@
#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)
diff --git a/board/freescale/p1_p2_rdb_pc/tlb.c b/board/freescale/p1_p2_rdb_pc/tlb.c
index 6d2246387a..3e4dffd237 100644
--- a/board/freescale/p1_p2_rdb_pc/tlb.c
+++ b/board/freescale/p1_p2_rdb_pc/tlb.c
@@ -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);
diff --git a/board/freescale/p2020ds/p2020ds.c b/board/freescale/p2020ds/p2020ds.c
index 3188f59e4b..d4a445108a 100644
--- a/board/freescale/p2020ds/p2020ds.c
+++ b/board/freescale/p2020ds/p2020ds.c
@@ -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;
diff --git a/board/genesi/mx51_efikamx/efikamx.c b/board/genesi/mx51_efikamx/efikamx.c
index c2b2823ef9..69d41db530 100644
--- a/board/genesi/mx51_efikamx/efikamx.c
+++ b/board/genesi/mx51_efikamx/efikamx.c
@@ -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);
diff --git a/board/hale/tt01/tt01.c b/board/hale/tt01/tt01.c
index 143fcefedf..0c2cb795dd 100644
--- a/board/hale/tt01/tt01.c
+++ b/board/hale/tt01/tt01.c
@@ -25,12 +25,13 @@
#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));
diff --git a/board/iomega/iconnect/iconnect.c b/board/iomega/iconnect/iconnect.c
index 6ee2128aab..8cfb4e6620 100644
--- a/board/iomega/iconnect/iconnect.c
+++ b/board/iomega/iconnect/iconnect.c
@@ -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.
diff --git a/board/iomega/iconnect/iconnect.h b/board/iomega/iconnect/iconnect.h
index 2fb3e5ed8f..8b6fe1bcad 100644
--- a/board/iomega/iconnect/iconnect.h
+++ b/board/iomega/iconnect/iconnect.h
@@ -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.
diff --git a/board/iomega/iconnect/kwbimage.cfg b/board/iomega/iconnect/kwbimage.cfg
index 6c9dfe3d31..4b64dab592 100644
--- a/board/iomega/iconnect/kwbimage.cfg
+++ b/board/iomega/iconnect/kwbimage.cfg
@@ -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.
diff --git a/board/logicpd/am3517evm/am3517evm.c b/board/logicpd/am3517evm/am3517evm.c
index d316f33cd1..0b3721ed85 100644
--- a/board/logicpd/am3517evm/am3517evm.c
+++ b/board/logicpd/am3517evm/am3517evm.c
@@ -25,12 +25,20 @@
#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
+
diff --git a/board/raidsonic/ib62x0/ib62x0.c b/board/raidsonic/ib62x0/ib62x0.c
index b7e6e4107c..5f0f3961d3 100644
--- a/board/raidsonic/ib62x0/ib62x0.c
+++ b/board/raidsonic/ib62x0/ib62x0.c
@@ -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
diff --git a/board/raidsonic/ib62x0/ib62x0.h b/board/raidsonic/ib62x0/ib62x0.h
index 0118c2b69a..3315696dda 100644
--- a/board/raidsonic/ib62x0/ib62x0.h
+++ b/board/raidsonic/ib62x0/ib62x0.h
@@ -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.
diff --git a/board/raidsonic/ib62x0/kwbimage.cfg b/board/raidsonic/ib62x0/kwbimage.cfg
index bd594ebd5d..bade627ccf 100644
--- a/board/raidsonic/ib62x0/kwbimage.cfg
+++ b/board/raidsonic/ib62x0/kwbimage.cfg
@@ -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.
diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c
index e8fb1ea413..ff76963925 100644
--- a/board/samsung/goni/goni.c
+++ b/board/samsung/goni/goni.c
@@ -25,10 +25,10 @@
#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;
diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c
index d5c681c05e..4724029424 100644
--- a/board/samsung/trats/trats.c
+++ b/board/samsung/trats/trats.c
@@ -35,10 +35,13 @@
#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;
diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c
index afe3bb0aeb..3d508bea23 100644
--- a/board/samsung/universal_c210/universal.c
+++ b/board/samsung/universal_c210/universal.c
@@ -31,13 +31,13 @@
#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,16 @@ static int get_hwrev(void)
return board_rev & 0xFF;
}
-static void check_hw_revision(void);
+int power_init_board(void)
+{
+ int ret;
+
+ ret = pmic_init(I2C_5);
+ if (ret)
+ return ret;
+
+ return 0;
+}
int dram_init(void)
{
@@ -101,7 +110,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 +235,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;
@@ -489,10 +502,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
diff --git a/board/sbc8548/ddr.c b/board/sbc8548/ddr.c
index 45ec485c50..9508561133 100644
--- a/board/sbc8548/ddr.c
+++ b/board/sbc8548/ddr.c
@@ -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);
diff --git a/board/socrates/sdram.c b/board/socrates/sdram.c
index c8235f4a9b..8a9ce790f1 100644
--- a/board/socrates/sdram.c
+++ b/board/socrates/sdram.c
@@ -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.
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index b56a801a4d..f0eca54c9e 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -379,9 +379,14 @@ static struct cpsw_platform_data cpsw_data = {
.host_port_num = 0,
.version = CPSW_CTRL_VERSION_2,
};
+#endif
+#if defined(CONFIG_DRIVER_TI_CPSW) || \
+ (defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
int board_eth_init(bd_t *bis)
{
+ int rv, n = 0;
+#ifdef CONFIG_DRIVER_TI_CPSW
uint8_t mac_addr[6];
uint32_t mac_hi, mac_lo;
@@ -400,7 +405,7 @@ int board_eth_init(bd_t *bis)
if (is_valid_ether_addr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
else
- return -1;
+ goto try_usbether;
}
if (board_is_bone() || board_is_bone_lt() || board_is_idk()) {
@@ -413,6 +418,20 @@ int board_eth_init(bd_t *bis)
PHY_INTERFACE_MODE_RGMII;
}
- return cpsw_register(&cpsw_data);
+ rv = cpsw_register(&cpsw_data);
+ if (rv < 0)
+ printf("Error %d registering CPSW switch\n", rv);
+ else
+ n += rv;
+#endif
+try_usbether:
+#if defined(CONFIG_USB_ETHER) && !defined(CONFIG_SPL_BUILD)
+ rv = usb_eth_initialize(bis);
+ if (rv < 0)
+ printf("Error %d registering USB_ETHER\n", rv);
+ else
+ n += rv;
+#endif
+ return n;
}
#endif
diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c
index 6175e1d1ac..f20ebed452 100644
--- a/board/ti/beagle/beagle.c
+++ b/board/ti/beagle/beagle.c
@@ -42,6 +42,11 @@
#include <asm/arch/sys_proto.h>
#include <asm/gpio.h>
#include <asm/mach-types.h>
+#include <asm/omap_musb.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
#include "beagle.h"
#include <command.h>
@@ -285,6 +290,33 @@ static void beagle_dvi_pup(void)
}
#endif
+#ifdef CONFIG_USB_MUSB_OMAP2PLUS
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+ .dyn_fifo = 1,
+ .num_eps = 16,
+ .ram_bits = 12,
+};
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#if defined(CONFIG_MUSB_HOST)
+ .mode = MUSB_HOST,
+#elif defined(CONFIG_MUSB_GADGET)
+ .mode = MUSB_PERIPHERAL,
+#else
+#error "Please define either CONFIG_MUSB_HOST or CONFIG_MUSB_GADGET"
+#endif
+ .config = &musb_config,
+ .power = 100,
+ .platform_ops = &omap2430_ops,
+ .board_data = &musb_board_data,
+};
+#endif
+
/*
* Routine: misc_init_r
* Description: Configure board specific parts
@@ -466,6 +498,10 @@ int misc_init_r(void)
omap3_dss_enable();
#endif
+#ifdef CONFIG_USB_MUSB_OMAP2PLUS
+ musb_register(&musb_plat, &musb_board_data, (void *)MUSB_BASE);
+#endif
+
return 0;
}
@@ -513,3 +549,10 @@ int ehci_hcd_stop(int index)
}
#endif /* CONFIG_USB_EHCI */
+
+#if defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)
+int board_eth_init(bd_t *bis)
+{
+ return usb_eth_initialize(bis);
+}
+#endif
diff --git a/board/ttcontrol/vision2/vision2.c b/board/ttcontrol/vision2/vision2.c
index abdd1aac2b..a471fec23d 100644
--- a/board/ttcontrol/vision2/vision2.c
+++ b/board/ttcontrol/vision2/vision2.c
@@ -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);
diff --git a/boards.cfg b/boards.cfg
index 6f21af0821..388e4a4461 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -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
diff --git a/common/Makefile b/common/Makefile
index ded6318dc6..132b3bd79c 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -196,6 +196,9 @@ COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
endif
ifdef CONFIG_SPL_BUILD
+COBJS-y += cmd_nvedit.o
+COBJS-y += env_common.o
+COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
COBJS-$(CONFIG_SPL_NET_SUPPORT) += cmd_nvedit.o
COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_common.o
diff --git a/common/bouncebuf.c b/common/bouncebuf.c
index 4f827f893d..1df12cdda0 100644
--- a/common/bouncebuf.c
+++ b/common/bouncebuf.c
@@ -27,21 +27,19 @@
#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;
}
diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index b8809e3bf5..5a52edde31 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -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
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index d256ddfaa6..4dbe952bb0 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -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_led.c b/common/cmd_led.c
index d83b3ba69b..7f5ab43c7f 100644
--- a/common/cmd_led.c
+++ b/common/cmd_led.c
@@ -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)"
);
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 62a1c224d3..7dacd5114c 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -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);
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 4b1606972b..1568594ca4 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -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"
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 8ad0b23058..dacdc2d5b1 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -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);
diff --git a/common/image.c b/common/image.c
index df642e656c..e93b6e89cf 100644
--- a/common/image.c
+++ b/common/image.c
@@ -3049,6 +3049,133 @@ int fit_check_format(const void *fit)
return 1;
}
+
+/**
+ * fit_conf_find_compat
+ * @fit: pointer to the FIT format image header
+ * @fdt: pointer to the device tree to compare against
+ *
+ * fit_conf_find_compat() attempts to find the configuration whose fdt is the
+ * most compatible with the passed in device tree.
+ *
+ * Example:
+ *
+ * / o image-tree
+ * |-o images
+ * | |-o fdt@1
+ * | |-o fdt@2
+ * |
+ * |-o configurations
+ * |-o config@1
+ * | |-fdt = fdt@1
+ * |
+ * |-o config@2
+ * |-fdt = fdt@2
+ *
+ * / o U-Boot fdt
+ * |-compatible = "foo,bar", "bim,bam"
+ *
+ * / o kernel fdt1
+ * |-compatible = "foo,bar",
+ *
+ * / o kernel fdt2
+ * |-compatible = "bim,bam", "baz,biz"
+ *
+ * Configuration 1 would be picked because the first string in U-Boot's
+ * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
+ * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
+ *
+ * returns:
+ * offset to the configuration to use if one was found
+ * -1 otherwise
+ */
+int fit_conf_find_compat(const void *fit, const void *fdt)
+{
+ int ndepth = 0;
+ int noffset, confs_noffset, images_noffset;
+ const void *fdt_compat;
+ int fdt_compat_len;
+ int best_match_offset = 0;
+ int best_match_pos = 0;
+
+ confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
+ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+ if (confs_noffset < 0 || images_noffset < 0) {
+ debug("Can't find configurations or images nodes.\n");
+ return -1;
+ }
+
+ fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
+ if (!fdt_compat) {
+ debug("Fdt for comparison has no \"compatible\" property.\n");
+ return -1;
+ }
+
+ /*
+ * Loop over the configurations in the FIT image.
+ */
+ for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
+ (noffset >= 0) && (ndepth > 0);
+ noffset = fdt_next_node(fit, noffset, &ndepth)) {
+ const void *kfdt;
+ const char *kfdt_name;
+ int kfdt_noffset;
+ const char *cur_fdt_compat;
+ int len;
+ size_t size;
+ int i;
+
+ if (ndepth > 1)
+ continue;
+
+ kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
+ if (!kfdt_name) {
+ debug("No fdt property found.\n");
+ continue;
+ }
+ kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
+ kfdt_name);
+ if (kfdt_noffset < 0) {
+ debug("No image node named \"%s\" found.\n",
+ kfdt_name);
+ continue;
+ }
+ /*
+ * Get a pointer to this configuration's fdt.
+ */
+ if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) {
+ debug("Failed to get fdt \"%s\".\n", kfdt_name);
+ continue;
+ }
+
+ len = fdt_compat_len;
+ cur_fdt_compat = fdt_compat;
+ /*
+ * Look for a match for each U-Boot compatibility string in
+ * turn in this configuration's fdt.
+ */
+ for (i = 0; len > 0 &&
+ (!best_match_offset || best_match_pos > i); i++) {
+ int cur_len = strlen(cur_fdt_compat) + 1;
+
+ if (!fdt_node_check_compatible(kfdt, 0,
+ cur_fdt_compat)) {
+ best_match_offset = noffset;
+ best_match_pos = i;
+ break;
+ }
+ len -= cur_len;
+ cur_fdt_compat += cur_len;
+ }
+ }
+ if (!best_match_offset) {
+ debug("No match found.\n");
+ return -1;
+ }
+
+ return best_match_offset;
+}
+
/**
* fit_conf_get_node - get node offset for configuration of a given unit name
* @fit: pointer to the FIT format image header
diff --git a/common/lcd.c b/common/lcd.c
index 3017604734..4778655a26 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -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;
+}
+
/************************************************************************/
/************************************************************************/
diff --git a/common/main.c b/common/main.c
index 5fdfff2e28..44fa20dd6a 100644
--- a/common/main.c
+++ b/common/main.c
@@ -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
@@ -40,13 +41,19 @@
#include <hush.h>
#endif
+#ifdef CONFIG_OF_CONTROL
+#include <fdtdec.h>
+#endif
+
+#ifdef CONFIG_OF_LIBFDT
+#include <fdt_support.h>
+#endif /* CONFIG_OF_LIBFDT */
+
#include <post.h>
#include <linux/ctype.h>
#include <menu.h>
-#if defined(CONFIG_SILENT_CONSOLE) || defined(CONFIG_POST) || defined(CONFIG_CMDLINE_EDITING)
DECLARE_GLOBAL_DATA_PTR;
-#endif
/*
* Board-specific Platform code can reimplement show_boot_progress () if needed
@@ -274,6 +281,73 @@ int abortboot(int bootdelay)
# endif /* CONFIG_AUTOBOOT_KEYED */
#endif /* CONFIG_BOOTDELAY >= 0 */
+/*
+ * Runs the given boot command securely. Specifically:
+ * - Doesn't run the command with the shell (run_command or parse_string_outer),
+ * since that's a lot of code surface that an attacker might exploit.
+ * Because of this, we don't do any argument parsing--the secure boot command
+ * has to be a full-fledged u-boot command.
+ * - Doesn't check for keypresses before booting, since that could be a
+ * security hole; also disables Ctrl-C.
+ * - Doesn't allow the command to return.
+ *
+ * Upon any failures, this function will drop into an infinite loop after
+ * printing the error message to console.
+ */
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \
+ defined(CONFIG_OF_CONTROL)
+static void secure_boot_cmd(char *cmd)
+{
+ cmd_tbl_t *cmdtp;
+ int rc;
+
+ if (!cmd) {
+ printf("## Error: Secure boot command not specified\n");
+ goto err;
+ }
+
+ /* Disable Ctrl-C just in case some command is used that checks it. */
+ disable_ctrlc(1);
+
+ /* Find the command directly. */
+ cmdtp = find_cmd(cmd);
+ if (!cmdtp) {
+ printf("## Error: \"%s\" not defined\n", cmd);
+ goto err;
+ }
+
+ /* Run the command, forcing no flags and faking argc and argv. */
+ rc = (cmdtp->cmd)(cmdtp, 0, 1, &cmd);
+
+ /* Shouldn't ever return from boot command. */
+ printf("## Error: \"%s\" returned (code %d)\n", cmd, rc);
+
+err:
+ /*
+ * Not a whole lot to do here. Rebooting won't help much, since we'll
+ * just end up right back here. Just loop.
+ */
+ hang();
+}
+
+static void process_fdt_options(const void *blob)
+{
+ ulong addr;
+
+ /* Add an env variable to point to a kernel payload, if available */
+ addr = fdtdec_get_config_int(gd->fdt_blob, "kernel-offset", 0);
+ if (addr)
+ setenv_addr("kernaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
+
+ /* Add an env variable to point to a root disk, if available */
+ addr = fdtdec_get_config_int(gd->fdt_blob, "rootdisk-offset", 0);
+ if (addr)
+ setenv_addr("rootaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
+}
+#endif /* CONFIG_OF_CONTROL */
+
+
/****************************************************************************/
void main_loop (void)
@@ -284,7 +358,10 @@ void main_loop (void)
int rc = 1;
int flag;
#endif
-
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) && \
+ defined(CONFIG_OF_CONTROL)
+ char *env;
+#endif
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
char *s;
int bootdelay;
@@ -380,6 +457,23 @@ void main_loop (void)
else
#endif /* CONFIG_BOOTCOUNT_LIMIT */
s = getenv ("bootcmd");
+#ifdef CONFIG_OF_CONTROL
+ /* Allow the fdt to override the boot command */
+ env = fdtdec_get_config_string(gd->fdt_blob, "bootcmd");
+ if (env)
+ s = env;
+
+ process_fdt_options(gd->fdt_blob);
+
+ /*
+ * If the bootsecure option was chosen, use secure_boot_cmd().
+ * Always use 'env' in this case, since bootsecure requres that the
+ * bootcmd was specified in the FDT too.
+ */
+ if (fdtdec_get_config_int(gd->fdt_blob, "bootsecure", 0))
+ secure_boot_cmd(env);
+
+#endif /* CONFIG_OF_CONTROL */
debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
@@ -404,6 +498,10 @@ void main_loop (void)
#endif /* CONFIG_MENUKEY */
#endif /* CONFIG_BOOTDELAY */
+#if defined CONFIG_OF_CONTROL
+ set_working_fdt_addr((void *)gd->fdt_blob);
+#endif /* CONFIG_OF_CONTROL */
+
/*
* Main Loop for Monitor Command Processing
*/
diff --git a/common/spl/spl.c b/common/spl/spl.c
index f068abd8f8..ff9ba7b0a5 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -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();
diff --git a/common/stdio.c b/common/stdio.c
index 605ff3fde3..9f48e5f503 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -237,6 +237,8 @@ int stdio_init (void)
#ifdef CONFIG_JTAG_CONSOLE
drv_jtag_console_init ();
#endif
-
+#ifdef CONFIG_CBMEM_CONSOLE
+ cbmemc_init();
+#endif
return (0);
}
diff --git a/common/usb.c b/common/usb.c
index 50b81752eb..ac9b4ca8d5 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -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)
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 19f01db1ca..4efbcfe90d 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -94,6 +94,15 @@ static const unsigned char usb_kbd_num_keypad[] = {
};
/*
+ * 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;
diff --git a/disk/part.c b/disk/part.c
index 4646f682d2..7bdc90eff7 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -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;
diff --git a/doc/DocBook/Makefile b/doc/DocBook/Makefile
index da88b32419..521e8bc0e9 100644
--- a/doc/DocBook/Makefile
+++ b/doc/DocBook/Makefile
@@ -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.mpc85xx b/doc/README.mpc85xx
index 5a4b591a89..f9b023f284 100644
--- a/doc/README.mpc85xx
+++ b/doc/README.mpc85xx
@@ -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)
diff --git a/doc/README.nand b/doc/README.nand
index c130189587..a1a511c533 100644
--- a/doc/README.nand
+++ b/doc/README.nand
@@ -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)
diff --git a/doc/kwboot.1 b/doc/kwboot.1
index ed0839836e..25fe69aa5c 100644
--- a/doc/kwboot.1
+++ b/doc/kwboot.1
@@ -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>
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d50ac3bfef..2d97b4f1e4 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -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
index 0000000000..6fed01f71a
--- /dev/null
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -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;
+}
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9fac190a6a..8cdc3b649c 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -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
index 0000000000..80a84fdf8f
--- /dev/null
+++ b/drivers/misc/cbmem_console.c
@@ -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
index 5d62a56d34..0000000000
--- a/drivers/misc/pmic_core.c
+++ /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"
-);
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index a1dd7302bf..65791aa218 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -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
index 0000000000..72a31b73fd
--- /dev/null
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -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;
+}
+
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 5ffd8c59e6..72e8ce6da4 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -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
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index 109acbf623..024df592f2 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -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;
}
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 7845f873ac..b9cbe34f1f 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -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);
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 1fd5592f2d..d749ab095e 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -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;
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index beb99cacb6..28e52bd08e 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -26,21 +26,33 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libnand.o
ifdef CONFIG_CMD_NAND
+
ifdef CONFIG_SPL_BUILD
-ifdef CONFIG_SPL_NAND_SIMPLE
-COBJS-y += nand_spl_simple.o
-endif
-ifdef CONFIG_SPL_NAND_LOAD
-COBJS-y += nand_spl_load.o
+
+ifdef CONFIG_SPL_NAND_DRIVERS
+NORMAL_DRIVERS=y
endif
-else
+
+COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
+COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
+COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
+COBJS-$(CONFIG_SPL_NAND_BASE) += nand_base.o
+
+else # not spl
+
+NORMAL_DRIVERS=y
+
COBJS-y += nand.o
COBJS-y += nand_bbt.o
COBJS-y += nand_ids.o
COBJS-y += nand_util.o
-endif
COBJS-y += nand_ecc.o
COBJS-y += nand_base.o
+
+endif # not spl
+
+ifdef NORMAL_DRIVERS
+
COBJS-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
COBJS-$(CONFIG_NAND_ATMEL) += atmel_nand.o
@@ -65,7 +77,13 @@ COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o
COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
-endif
+
+else # minimal SPL drivers
+
+COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
+
+endif # drivers
+endif # nand
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 9076ad4cdc..834a8a6498 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -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
index 0000000000..50ff4fe93e
--- /dev/null
+++ b/drivers/mtd/nand/fsl_elbc_spl.c
@@ -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)();
+}
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index b3b7c705e1..0878bece67 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -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;
}
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index d3b71a50ad..a2d06be99f 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -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 :
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index c4752a7cbf..2ba0c5ef95 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -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
diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile
index 7a1fcdd81f..7fbb50a562 100644
--- a/drivers/net/fm/Makefile
+++ b/drivers/net/fm/Makefile
@@ -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
index 0000000000..bc6b4ba0bb
--- /dev/null
+++ b/drivers/net/fm/p5040.c
@@ -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;
+}
diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
index 48ae16374d..77ac1f7c7b 100644
--- a/drivers/pci/fsl_pci_init.c
+++ b/drivers/pci/fsl_pci_init.c
@@ -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);
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 6bf388cb7d..8c7190156c 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -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
index 0000000000..b176701234
--- /dev/null
+++ b/drivers/power/battery/Makefile
@@ -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
index 0000000000..ca0d214659
--- /dev/null
+++ b/drivers/power/battery/bat_trats.c
@@ -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
index 0000000000..da1541412b
--- /dev/null
+++ b/drivers/power/fuel_gauge/Makefile
@@ -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
index 0000000000..9b7c184cb0
--- /dev/null
+++ b/drivers/power/fuel_gauge/fg_max17042.c
@@ -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
index 0000000000..e19a9a8195
--- /dev/null
+++ b/drivers/power/pmic/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2012 Samsung Electronics
+# Lukasz Majewski <l.majewski@samsung.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB := $(obj)libpmic.o
+
+COBJS-$(CONFIG_POWER_MAX8998) += pmic_max8998.o
+COBJS-$(CONFIG_POWER_MAX8997) += pmic_max8997.o
+COBJS-$(CONFIG_POWER_MUIC_MAX8997) += muic_max8997.o
+
+COBJS := $(COBJS-y)
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+########################################################################
diff --git a/drivers/power/pmic/muic_max8997.c b/drivers/power/pmic/muic_max8997.c
new file mode 100644
index 0000000000..d5095c899e
--- /dev/null
+++ b/drivers/power/pmic/muic_max8997.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <power/pmic.h>
+#include <power/power_chrg.h>
+#include <power/max8997_muic.h>
+#include <i2c.h>
+#include <errno.h>
+
+static int power_chrg_get_type(struct pmic *p)
+{
+ unsigned int val;
+ unsigned char charge_type, charger;
+
+ if (pmic_probe(p))
+ return CHARGER_NO;
+
+ pmic_reg_read(p, MAX8997_MUIC_STATUS2, &val);
+ charge_type = val & MAX8997_MUIC_CHG_MASK;
+
+ switch (charge_type) {
+ case MAX8997_MUIC_CHG_NO:
+ charger = CHARGER_NO;
+ break;
+ case MAX8997_MUIC_CHG_USB:
+ case MAX8997_MUIC_CHG_USB_D:
+ charger = CHARGER_USB;
+ break;
+ case MAX8997_MUIC_CHG_TA:
+ case MAX8997_MUIC_CHG_TA_1A:
+ charger = CHARGER_TA;
+ break;
+ case MAX8997_MUIC_CHG_TA_500:
+ charger = CHARGER_TA_500;
+ break;
+ default:
+ charger = CHARGER_UNKNOWN;
+ break;
+ }
+
+ return charger;
+}
+
+static struct power_chrg power_chrg_muic_ops = {
+ .chrg_type = power_chrg_get_type,
+};
+
+int power_muic_init(unsigned int bus)
+{
+ static const char name[] = "MAX8997_MUIC";
+ struct pmic *p = pmic_alloc();
+
+ if (!p) {
+ printf("%s: POWER allocation error!\n", __func__);
+ return -ENOMEM;
+ }
+
+ debug("Board Micro USB Interface Controller init\n");
+
+ p->name = name;
+ p->interface = PMIC_I2C;
+ p->number_of_regs = MUIC_NUM_OF_REGS;
+ p->hw.i2c.addr = MAX8997_MUIC_I2C_ADDR;
+ p->hw.i2c.tx_num = 1;
+ p->bus = bus;
+
+ p->chrg = &power_chrg_muic_ops;
+ return 0;
+}
diff --git a/drivers/power/pmic/pmic_max8997.c b/drivers/power/pmic/pmic_max8997.c
new file mode 100644
index 0000000000..4e5c6d647f
--- /dev/null
+++ b/drivers/power/pmic/pmic_max8997.c
@@ -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;
+}
diff --git a/drivers/misc/pmic_max8998.c b/drivers/power/pmic/pmic_max8998.c
index cc69fd7080..452e1c8d86 100644
--- a/drivers/misc/pmic_max8998.c
+++ b/drivers/power/pmic/pmic_max8998.c
@@ -22,13 +22,19 @@
*/
#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
index 0000000000..90df2c58c4
--- /dev/null
+++ b/drivers/power/power_core.c
@@ -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"
+);
diff --git a/drivers/misc/pmic_dialog.c b/drivers/power/power_dialog.c
index e97af1d1d0..d7ebd1583e 100644
--- a/drivers/misc/pmic_dialog.c
+++ b/drivers/power/power_dialog.c
@@ -17,13 +17,19 @@
*/
#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;
}
diff --git a/drivers/misc/pmic_fsl.c b/drivers/power/power_fsl.c
index c8d4c8d9ec..a663831589 100644
--- a/drivers/misc/pmic_fsl.c
+++ b/drivers/power/power_fsl.c
@@ -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
@@ -32,22 +33,27 @@
#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;
diff --git a/drivers/misc/pmic_i2c.c b/drivers/power/power_i2c.c
index 95a3365b9f..3e5a784cf5 100644
--- a/drivers/misc/pmic_i2c.c
+++ b/drivers/power/power_i2c.c
@@ -28,24 +28,40 @@
#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;
diff --git a/drivers/misc/pmic_spi.c b/drivers/power/power_spi.c
index 5a0dd22e29..27488ea5d9 100644
--- a/drivers/misc/pmic_spi.c
+++ b/drivers/power/power_spi.c
@@ -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))
diff --git a/drivers/rtc/mc13xxx-rtc.c b/drivers/rtc/mc13xxx-rtc.c
index 70ea8a1589..e79f4621d3 100644
--- a/drivers/rtc/mc13xxx-rtc.c
+++ b/drivers/rtc/mc13xxx-rtc.c
@@ -23,16 +23,18 @@
#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);
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 9027781445..bbd91ca247 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -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)
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index c1c0134bcb..fc01a3c516 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -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 */
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index b331be794b..dfdba9f64e 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -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;
}
diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c
index 3c931d0212..ee1f2d768a 100644
--- a/drivers/serial/serial_sh.c
+++ b/drivers/serial/serial_sh.c
@@ -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)
{
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index f88d0c190c..f9163a80ed 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -27,7 +27,6 @@
#include <linux/string.h>
#include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
#include <linux/usb/gadget.h>
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index b656c8b9f4..5b8776e0b7 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -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>
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 8b24e00e27..de880ffeb8 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -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>
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
index 3ec4c65e74..10547e3279 100644
--- a/drivers/usb/gadget/f_dfu.c
+++ b/drivers/usb/gadget/f_dfu.c
@@ -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>
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 02cae0fc75..e5701422fa 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -125,8 +125,8 @@
#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
diff --git a/drivers/usb/gadget/s3c_udc_otg.c b/drivers/usb/gadget/s3c_udc_otg.c
index 3fdfdf7af0..f9d24e3dfd 100644
--- a/drivers/usb/gadget/s3c_udc_otg.c
+++ b/drivers/usb/gadget/s3c_udc_otg.c
@@ -37,7 +37,6 @@
#include <malloc.h>
#include <linux/usb/ch9.h>
-#include <usbdescriptors.h>
#include <linux/usb/gadget.h>
#include <asm/byteorder.h>
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c
index 4dbe060d6f..95555cf96b 100644
--- a/drivers/usb/gadget/usbstring.c
+++ b/drivers/usb/gadget/usbstring.c
@@ -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>
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d90e94d810..7f98a6354a 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -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);
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 19e16a4a80..289018c4f6 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -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 */
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index c2106adbd3..bdbe250b01 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -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) {
diff --git a/drivers/usb/host/ohci-s3c24xx.c b/drivers/usb/host/ohci-s3c24xx.c
index 03cd4c3d2a..dde0764034 100644
--- a/drivers/usb/host/ohci-s3c24xx.c
+++ b/drivers/usb/host/ohci-s3c24xx.c
@@ -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;
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 2a4e7ff4b3..b503b356ce 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -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;
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 2830616046..417f1a8aba 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -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
index 0000000000..c23bef1cc2
--- /dev/null
+++ b/drivers/usb/musb-new/Makefile
@@ -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
index 0000000000..57c9bd393b
--- /dev/null
+++ b/drivers/usb/musb-new/am35x.c
@@ -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
index 0000000000..5c126ef9cf
--- /dev/null
+++ b/drivers/usb/musb-new/linux-compat.h
@@ -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
index 0000000000..040a5c0f0f
--- /dev/null
+++ b/drivers/usb/musb-new/musb_core.c
@@ -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: