]> git.sur5r.net Git - u-boot/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot
authorStefano Babic <sbabic@denx.de>
Tue, 24 May 2016 12:55:06 +0000 (14:55 +0200)
committerStefano Babic <sbabic@denx.de>
Tue, 24 May 2016 12:55:06 +0000 (14:55 +0200)
288 files changed:
README
api/api.c
api/api_storage.c
arch/arm/cpu/armv8/start.S
arch/arm/dts/exynos4210-universal_c210.dts
arch/arm/dts/tegra20-seaboard.dts
arch/arm/include/asm/arch-ls102xa/config.h
arch/m68k/cpu/mcf5227x/start.S
arch/m68k/cpu/mcf523x/start.S
arch/m68k/cpu/mcf52x2/start.S
arch/m68k/cpu/mcf530x/cpu_init.c
arch/m68k/cpu/mcf530x/start.S
arch/m68k/cpu/mcf532x/start.S
arch/m68k/cpu/mcf5445x/start.S
arch/m68k/cpu/mcf547x_8x/start.S
arch/m68k/include/asm/config.h
arch/m68k/include/asm/fsl_i2c.h
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/cpu/cpu.c
arch/mips/cpu/start.S
arch/mips/dts/Makefile
arch/mips/dts/ap121.dts [new file with mode: 0644]
arch/mips/dts/ap143.dts [new file with mode: 0644]
arch/mips/dts/ar933x.dtsi [new file with mode: 0644]
arch/mips/dts/ar934x.dtsi [new file with mode: 0644]
arch/mips/dts/qca953x.dtsi [new file with mode: 0644]
arch/mips/dts/tplink_wdr4300.dts [new file with mode: 0644]
arch/mips/include/asm/global_data.h
arch/mips/lib/cache_init.S
arch/mips/mach-ath79/Kconfig [new file with mode: 0644]
arch/mips/mach-ath79/Makefile [new file with mode: 0644]
arch/mips/mach-ath79/ar933x/Makefile [new file with mode: 0644]
arch/mips/mach-ath79/ar933x/clk.c [new file with mode: 0644]
arch/mips/mach-ath79/ar933x/ddr.c [new file with mode: 0644]
arch/mips/mach-ath79/ar933x/lowlevel_init.S [new file with mode: 0644]
arch/mips/mach-ath79/ar934x/Makefile [new file with mode: 0644]
arch/mips/mach-ath79/ar934x/clk.c [new file with mode: 0644]
arch/mips/mach-ath79/ar934x/cpu.c [new file with mode: 0644]
arch/mips/mach-ath79/ar934x/ddr.c [new file with mode: 0644]
arch/mips/mach-ath79/cpu.c [new file with mode: 0644]
arch/mips/mach-ath79/dram.c [new file with mode: 0644]
arch/mips/mach-ath79/include/mach/ar71xx_regs.h [new file with mode: 0644]
arch/mips/mach-ath79/include/mach/ath79.h [new file with mode: 0644]
arch/mips/mach-ath79/include/mach/ddr.h [new file with mode: 0644]
arch/mips/mach-ath79/include/mach/reset.h [new file with mode: 0644]
arch/mips/mach-ath79/qca953x/Makefile [new file with mode: 0644]
arch/mips/mach-ath79/qca953x/clk.c [new file with mode: 0644]
arch/mips/mach-ath79/qca953x/ddr.c [new file with mode: 0644]
arch/mips/mach-ath79/qca953x/lowlevel_init.S [new file with mode: 0644]
arch/mips/mach-ath79/reset.c [new file with mode: 0644]
arch/powerpc/include/asm/fsl_i2c.h
arch/powerpc/include/asm/immap_85xx.h
arch/powerpc/include/asm/immap_86xx.h
arch/sandbox/include/asm/io.h
arch/x86/Kconfig
arch/x86/cpu/broadwell/sata.c
arch/x86/cpu/intel_common/cpu.c
arch/x86/cpu/ivybridge/bd82x6x.c
arch/x86/cpu/ivybridge/sata.c
board/cm5200/fwupdate.c
board/compulab/common/eeprom.c
board/imgtec/malta/lowlevel_init.S
board/keymile/km83xx/km83xx_i2c.c
board/mpl/pip405/README
board/qca/ap121/Kconfig [new file with mode: 0644]
board/qca/ap121/MAINTAINERS [new file with mode: 0644]
board/qca/ap121/Makefile [new file with mode: 0644]
board/qca/ap121/ap121.c [new file with mode: 0644]
board/qca/ap143/Kconfig [new file with mode: 0644]
board/qca/ap143/MAINTAINERS [new file with mode: 0644]
board/qca/ap143/Makefile [new file with mode: 0644]
board/qca/ap143/ap143.c [new file with mode: 0644]
board/sandbox/MAINTAINERS
board/tplink/wdr4300/Kconfig [new file with mode: 0644]
board/tplink/wdr4300/MAINTAINERS [new file with mode: 0644]
board/tplink/wdr4300/Makefile [new file with mode: 0644]
board/tplink/wdr4300/wdr4300.c [new file with mode: 0644]
cmd/Makefile
cmd/bdinfo.c
cmd/disk.c
cmd/eeprom.c
cmd/ide.c
cmd/mmc.c
cmd/sata.c
cmd/scsi.c
cmd/usb.c
common/Makefile
common/board_r.c
common/dlmalloc.c
common/eeprom/eeprom_field.c [new file with mode: 0644]
common/eeprom/eeprom_layout.c [new file with mode: 0644]
common/env_mmc.c
common/ide.c [new file with mode: 0644]
common/image-fit.c
common/sata.c [new file with mode: 0644]
common/scsi.c [new file with mode: 0644]
common/spl/spl_fat.c
common/spl/spl_fit.c
common/spl/spl_mmc.c
common/spl/spl_sata.c
common/spl/spl_usb.c
common/usb_storage.c
configs/ap121_defconfig [new file with mode: 0644]
configs/ap143_defconfig [new file with mode: 0644]
configs/axs101_defconfig
configs/axs103_defconfig
configs/pico-imx6ul_defconfig
configs/sandbox_defconfig
configs/sandbox_noblk_defconfig [new file with mode: 0644]
configs/socfpga_arria5_defconfig
configs/socfpga_cyclone5_defconfig
configs/socfpga_de0_nano_soc_defconfig
configs/socfpga_mcvevk_defconfig
configs/socfpga_sockit_defconfig
configs/socfpga_socrates_defconfig
configs/socfpga_sr1500_defconfig
configs/spear300_defconfig
configs/spear300_nand_defconfig
configs/spear300_usbtty_defconfig
configs/spear300_usbtty_nand_defconfig
configs/spear310_defconfig
configs/spear310_nand_defconfig
configs/spear310_pnor_defconfig
configs/spear310_usbtty_defconfig
configs/spear310_usbtty_nand_defconfig
configs/spear310_usbtty_pnor_defconfig
configs/spear320_defconfig
configs/spear320_nand_defconfig
configs/spear320_pnor_defconfig
configs/spear320_usbtty_defconfig
configs/spear320_usbtty_nand_defconfig
configs/spear320_usbtty_pnor_defconfig
configs/spear600_defconfig
configs/spear600_nand_defconfig
configs/spear600_usbtty_defconfig
configs/spear600_usbtty_nand_defconfig
configs/tplink_wdr4300_defconfig [new file with mode: 0644]
configs/x600_defconfig
disk/part.c
doc/device-tree-bindings/serial/qca,ar9330-uart.txt [new file with mode: 0644]
doc/device-tree-bindings/spi/spi-ath79.txt [new file with mode: 0644]
drivers/Makefile
drivers/block/Kconfig
drivers/block/Makefile
drivers/block/ahci-uclass.c [new file with mode: 0644]
drivers/block/blk-uclass.c
drivers/block/blk_legacy.c [new file with mode: 0644]
drivers/block/disk-uclass.c [deleted file]
drivers/block/sandbox.c
drivers/block/sandbox_scsi.c [new file with mode: 0644]
drivers/block/sata_sandbox.c [new file with mode: 0644]
drivers/block/sym53c8xx.c
drivers/block/systemace.c
drivers/core/device-remove.c
drivers/core/device.c
drivers/core/lists.c
drivers/ddr/marvell/a38x/ddr3_init.c
drivers/dfu/dfu_mmc.c
drivers/gpio/74x164_gpio.c [new file with mode: 0644]
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-uclass.c
drivers/gpio/intel_broadwell_gpio.c
drivers/gpio/omap_gpio.c
drivers/gpio/pca953x_gpio.c [new file with mode: 0644]
drivers/gpio/pic32_gpio.c
drivers/gpio/rk_gpio.c
drivers/gpio/s5p_gpio.c
drivers/i2c/Kconfig
drivers/i2c/designware_i2c.c
drivers/i2c/fsl_i2c.c
drivers/i2c/i2c-cdns.c
drivers/i2c/muxes/Kconfig
drivers/i2c/muxes/Makefile
drivers/i2c/muxes/pca954x.c [new file with mode: 0644]
drivers/i2c/mvtwsi.c
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/mmc-uclass.c
drivers/mmc/mmc.c
drivers/mmc/mmc_legacy.c [new file with mode: 0644]
drivers/mmc/mmc_private.h
drivers/mmc/mmc_write.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/pic32_sdhci.c
drivers/mmc/rockchip_dw_mmc.c
drivers/mmc/sandbox_mmc.c
drivers/mmc/socfpga_dw_mmc.c
drivers/mmc/uniphier-sd.c
drivers/mmc/zynq_sdhci.c
drivers/mtd/Kconfig
drivers/mtd/Makefile
drivers/mtd/pic32_flash.c [new file with mode: 0644]
drivers/pci/pci.c
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/ath79/Makefile [new file with mode: 0644]
drivers/pinctrl/ath79/pinctrl_ar933x.c [new file with mode: 0644]
drivers/pinctrl/ath79/pinctrl_qca953x.c [new file with mode: 0644]
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/mcfuart.c
drivers/serial/serial_ar933x.c [new file with mode: 0644]
drivers/spi/Kconfig
drivers/spi/Makefile
drivers/spi/ath79_spi.c [new file with mode: 0644]
drivers/spi/omap3_spi.c
drivers/spi/soft_spi.c
drivers/spi/spi-uclass.c
drivers/usb/common/Makefile
drivers/usb/common/common.c [new file with mode: 0644]
drivers/video/tegra.c
dts/Kconfig
examples/api/Makefile
examples/api/crt0.S
examples/api/glue.c
examples/standalone/stubs.c
fs/fat/fat.c
include/asm-generic/gpio.h
include/ata.h
include/blk.h
include/config_cmd_all.h
include/config_distro_bootcmd.h
include/config_fallbacks.h
include/configs/MPC8544DS.h
include/configs/MPC8572DS.h
include/configs/MPC8610HPCD.h
include/configs/MPC8641HPCN.h
include/configs/PIP405.h
include/configs/am57xx_evm.h
include/configs/ap121.h [new file with mode: 0644]
include/configs/ap143.h [new file with mode: 0644]
include/configs/axs101.h
include/configs/cm_fx6.h
include/configs/cm_t335.h
include/configs/cm_t35.h
include/configs/cm_t3517.h
include/configs/cm_t43.h
include/configs/cm_t54.h
include/configs/db-88f6820-gp.h
include/configs/dra7xx_evm.h
include/configs/efi-x86.h
include/configs/galileo.h
include/configs/highbank.h
include/configs/ls1043aqds.h
include/configs/ls2080aqds.h
include/configs/ls2080ardb.h
include/configs/omap5_uevm.h
include/configs/qemu-mips.h
include/configs/qemu-mips64.h
include/configs/qemu-x86.h
include/configs/sandbox.h
include/configs/sbc8641d.h
include/configs/socfpga_common.h
include/configs/spear-common.h
include/configs/sunxi-common.h
include/configs/theadorable.h
include/configs/tplink_wdr4300.h [new file with mode: 0644]
include/configs/x600.h
include/configs/x86-common.h
include/configs/xilinx_zynqmp.h
include/dm/device.h
include/dm/platform_data/serial_coldfire.h [new file with mode: 0644]
include/dm/uclass-id.h
include/eeprom_field.h [new file with mode: 0644]
include/eeprom_layout.h [new file with mode: 0644]
include/flash.h
include/ide.h
include/iotrace.h
include/linux/usb/otg.h
include/mmc.h
include/part.h
include/spi.h
include/systemace.h [deleted file]
include/usb.h
lib/efi_loader/efi_disk.c
scripts/basic/fixdep.c
test/dm/blk.c
test/dm/mmc.c
tools/buildman/README
tools/buildman/builder.py
tools/buildman/builderthread.py
tools/buildman/cmdline.py
tools/buildman/control.py
tools/imagetool.c
tools/imagetool.h
tools/mkimage.c

diff --git a/README b/README
index d881da2de288a26e623dd4e6412c167c93486f0b..6f4c09a3a1fc13b47a6510b01c5c96a260c503ff 100644 (file)
--- a/README
+++ b/README
@@ -1003,6 +1003,7 @@ The following options need to be configured:
                CONFIG_CMD_ECHO           echo arguments
                CONFIG_CMD_EDITENV        edit env variable
                CONFIG_CMD_EEPROM       * EEPROM read/write support
+               CONFIG_CMD_EEPROM_LAYOUT* EEPROM layout aware commands
                CONFIG_CMD_ELF          * bootelf, bootvx
                CONFIG_CMD_ENV_CALLBACK * display details about env callbacks
                CONFIG_CMD_ENV_FLAGS    * display details about env flags
@@ -1066,7 +1067,7 @@ The following options need to be configured:
                CONFIG_CMD_RUN            run command in env variable
                CONFIG_CMD_SANDBOX      * sb command to access sandbox features
                CONFIG_CMD_SAVES        * save S record dump
-               CONFIG_CMD_SCSI         * SCSI Support
+               CONFIG_SCSI             * SCSI Support
                CONFIG_CMD_SDRAM        * print SDRAM configuration information
                                          (requires CONFIG_CMD_I2C)
                CONFIG_CMD_SETGETDCR      Support for DCR Register access
@@ -1254,7 +1255,7 @@ The following options need to be configured:
                CONFIG_MTD_PARTITIONS  Memory Technology Device partition table.
 
                If IDE or SCSI support is enabled (CONFIG_CMD_IDE or
-               CONFIG_CMD_SCSI) you must configure support for at
+               CONFIG_SCSI) you must configure support for at
                least one non-MTD partition type as well.
 
 - IDE Reset method:
index 457dc36f6fc4e76a9ff5356414e9c0ba67fe7466..8a1433af78a98357f8e7ac58773c2b32a49aebad 100644 (file)
--- a/api/api.c
+++ b/api/api.c
@@ -52,7 +52,7 @@ static int API_getc(va_list ap)
 {
        int *c;
 
-       if ((c = (int *)va_arg(ap, u_int32_t)) == NULL)
+       if ((c = (int *)va_arg(ap, uintptr_t)) == NULL)
                return API_EINVAL;
 
        *c = getc();
@@ -68,7 +68,7 @@ static int API_tstc(va_list ap)
 {
        int *t;
 
-       if ((t = (int *)va_arg(ap, u_int32_t)) == NULL)
+       if ((t = (int *)va_arg(ap, uintptr_t)) == NULL)
                return API_EINVAL;
 
        *t = tstc();
@@ -84,7 +84,7 @@ static int API_putc(va_list ap)
 {
        char *c;
 
-       if ((c = (char *)va_arg(ap, u_int32_t)) == NULL)
+       if ((c = (char *)va_arg(ap, uintptr_t)) == NULL)
                return API_EINVAL;
 
        putc(*c);
@@ -100,7 +100,7 @@ static int API_puts(va_list ap)
 {
        char *s;
 
-       if ((s = (char *)va_arg(ap, u_int32_t)) == NULL)
+       if ((s = (char *)va_arg(ap, uintptr_t)) == NULL)
                return API_EINVAL;
 
        puts(s);
@@ -132,7 +132,7 @@ static int API_get_sys_info(va_list ap)
 {
        struct sys_info *si;
 
-       si = (struct sys_info *)va_arg(ap, u_int32_t);
+       si = (struct sys_info *)va_arg(ap, uintptr_t);
        if (si == NULL)
                return API_ENOMEM;
 
@@ -148,7 +148,7 @@ static int API_udelay(va_list ap)
 {
        unsigned long *d;
 
-       if ((d = (unsigned long *)va_arg(ap, u_int32_t)) == NULL)
+       if ((d = (unsigned long *)va_arg(ap, unsigned long)) == NULL)
                return API_EINVAL;
 
        udelay(*d);
@@ -164,11 +164,11 @@ static int API_get_timer(va_list ap)
 {
        unsigned long *base, *cur;
 
-       cur = (unsigned long *)va_arg(ap, u_int32_t);
+       cur = (unsigned long *)va_arg(ap, unsigned long);
        if (cur == NULL)
                return API_EINVAL;
 
-       base = (unsigned long *)va_arg(ap, u_int32_t);
+       base = (unsigned long *)va_arg(ap, unsigned long);
        if (base == NULL)
                return API_EINVAL;
 
@@ -199,7 +199,7 @@ static int API_dev_enum(va_list ap)
        struct device_info *di;
 
        /* arg is ptr to the device_info struct we are going to fill out */
-       di = (struct device_info *)va_arg(ap, u_int32_t);
+       di = (struct device_info *)va_arg(ap, uintptr_t);
        if (di == NULL)
                return API_EINVAL;
 
@@ -233,7 +233,7 @@ static int API_dev_open(va_list ap)
        int err = 0;
 
        /* arg is ptr to the device_info struct */
-       di = (struct device_info *)va_arg(ap, u_int32_t);
+       di = (struct device_info *)va_arg(ap, uintptr_t);
        if (di == NULL)
                return API_EINVAL;
 
@@ -265,7 +265,7 @@ static int API_dev_close(va_list ap)
        int err = 0;
 
        /* arg is ptr to the device_info struct */
-       di = (struct device_info *)va_arg(ap, u_int32_t);
+       di = (struct device_info *)va_arg(ap, uintptr_t);
        if (di == NULL)
                return API_EINVAL;
 
@@ -319,7 +319,7 @@ static int API_dev_write(va_list ap)
        int err = 0;
 
        /* 1. arg is ptr to the device_info struct */
-       di = (struct device_info *)va_arg(ap, u_int32_t);
+       di = (struct device_info *)va_arg(ap, uintptr_t);
        if (di == NULL)
                return API_EINVAL;
 
@@ -329,12 +329,12 @@ static int API_dev_write(va_list ap)
                return API_ENODEV;
 
        /* 2. arg is ptr to buffer from where to get data to write */
-       buf = (void *)va_arg(ap, u_int32_t);
+       buf = (void *)va_arg(ap, uintptr_t);
        if (buf == NULL)
                return API_EINVAL;
 
        /* 3. arg is length of buffer */
-       len = (int *)va_arg(ap, u_int32_t);
+       len = (int *)va_arg(ap, uintptr_t);
        if (len == NULL)
                return API_EINVAL;
        if (*len <= 0)
@@ -387,7 +387,7 @@ static int API_dev_read(va_list ap)
        int *len_net, *act_len_net;
 
        /* 1. arg is ptr to the device_info struct */
-       di = (struct device_info *)va_arg(ap, u_int32_t);
+       di = (struct device_info *)va_arg(ap, uintptr_t);
        if (di == NULL)
                return API_EINVAL;
 
@@ -397,23 +397,23 @@ static int API_dev_read(va_list ap)
                return API_ENODEV;
 
        /* 2. arg is ptr to buffer from where to put the read data */
-       buf = (void *)va_arg(ap, u_int32_t);
+       buf = (void *)va_arg(ap, uintptr_t);
        if (buf == NULL)
                return API_EINVAL;
 
        if (di->type & DEV_TYP_STOR) {
                /* 3. arg - ptr to var with # of blocks to read */
-               len_stor = (lbasize_t *)va_arg(ap, u_int32_t);
+               len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
                if (!len_stor)
                        return API_EINVAL;
                if (*len_stor <= 0)
                        return API_EINVAL;
 
                /* 4. arg - ptr to var with start block */
-               start = (lbastart_t *)va_arg(ap, u_int32_t);
+               start = (lbastart_t *)va_arg(ap, uintptr_t);
 
                /* 5. arg - ptr to var where to put the len actually read */
-               act_len_stor = (lbasize_t *)va_arg(ap, u_int32_t);
+               act_len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
                if (!act_len_stor)
                        return API_EINVAL;
 
@@ -422,14 +422,14 @@ static int API_dev_read(va_list ap)
        } else if (di->type & DEV_TYP_NET) {
 
                /* 3. arg points to the var with length of packet to read */
-               len_net = (int *)va_arg(ap, u_int32_t);
+               len_net = (int *)va_arg(ap, uintptr_t);
                if (!len_net)
                        return API_EINVAL;
                if (*len_net <= 0)
                        return API_EINVAL;
 
                /* 4. - ptr to var where to put the len actually read */
-               act_len_net = (int *)va_arg(ap, u_int32_t);
+               act_len_net = (int *)va_arg(ap, uintptr_t);
                if (!act_len_net)
                        return API_EINVAL;
 
@@ -453,9 +453,9 @@ static int API_env_get(va_list ap)
 {
        char *name, **value;
 
-       if ((name = (char *)va_arg(ap, u_int32_t)) == NULL)
+       if ((name = (char *)va_arg(ap, uintptr_t)) == NULL)
                return API_EINVAL;
-       if ((value = (char **)va_arg(ap, u_int32_t)) == NULL)
+       if ((value = (char **)va_arg(ap, uintptr_t)) == NULL)
                return API_EINVAL;
 
        *value = getenv(name);
@@ -476,9 +476,9 @@ static int API_env_set(va_list ap)
 {
        char *name, *value;
 
-       if ((name = (char *)va_arg(ap, u_int32_t)) == NULL)
+       if ((name = (char *)va_arg(ap, uintptr_t)) == NULL)
                return API_EINVAL;
-       if ((value = (char *)va_arg(ap, u_int32_t)) == NULL)
+       if ((value = (char *)va_arg(ap, uintptr_t)) == NULL)
                return API_EINVAL;
 
        setenv(name, value);
@@ -498,9 +498,9 @@ static int API_env_enum(va_list ap)
        int i, n;
        char *last, **next;
 
-       last = (char *)va_arg(ap, u_int32_t);
+       last = (char *)va_arg(ap, unsigned long);
 
-       if ((next = (char **)va_arg(ap, u_int32_t)) == NULL)
+       if ((next = (char **)va_arg(ap, uintptr_t)) == NULL)
                return API_EINVAL;
 
        if (last == NULL)
@@ -662,14 +662,14 @@ void api_init(void)
        }
 
        setenv_hex("api_address", (unsigned long)sig);
-       debugf("API sig @ 0x%08x\n", sig);
+       debugf("API sig @ 0x%lX\n", (unsigned long)sig);
        memcpy(sig->magic, API_SIG_MAGIC, 8);
        sig->version = API_SIG_VERSION;
        sig->syscall = &syscall;
        sig->checksum = 0;
        sig->checksum = crc32(0, (unsigned char *)sig,
                              sizeof(struct api_signature));
-       debugf("syscall entry: 0x%08x\n", sig->syscall);
+       debugf("syscall entry: 0x%lX\n", (unsigned long)sig->syscall);
 }
 
 void platform_set_mr(struct sys_info *si, unsigned long start, unsigned long size,
index 8c30c56e497a1ddf74c2510f7a5eec7c92cccd29..d425a9ad1dbd7fce338e3065b294561c732a4120 100644 (file)
@@ -67,7 +67,7 @@ void dev_stor_init(void)
        specs[ENUM_SATA].type = DEV_TYP_STOR | DT_STOR_SATA;
        specs[ENUM_SATA].name = "sata";
 #endif
-#if defined(CONFIG_CMD_SCSI)
+#if defined(CONFIG_SCSI)
        specs[ENUM_SCSI].max_dev = CONFIG_SYS_SCSI_MAX_DEVICE;
        specs[ENUM_SCSI].enum_started = 0;
        specs[ENUM_SCSI].enum_ended = 0;
index c3cc8199caf94f87f869c30d720ed09a6d6b7fb1..e933021a17ebe78de0a7a6150e248fe414d8bbdf 100644 (file)
@@ -216,7 +216,7 @@ WEAK(lowlevel_init)
 #endif
 #endif
 
-#ifndef CONFIG_ARMV8_MULTIENTRY
+#ifdef CONFIG_ARMV8_MULTIENTRY
        branch_if_master x0, x1, 2f
 
        /*
index 16948c93422725571ab05f2f7ed6e8977cb38571..ad3527ec6f118324e82e0168681c6d2e7774dec2 100644 (file)
        };
 
        soft-spi {
-               compatible = "u-boot,soft-spi";
-               cs-gpio = <&gpy4 3 0>;
-               sclk-gpio = <&gpy3 1 0>;
-               mosi-gpio = <&gpy3 3 0>;
-               miso-gpio = <&gpy3 0 0>;
+               compatible = "spi-gpio";
+               cs-gpios = <&gpy4 3 0>;
+               gpio-sck = <&gpy3 1 0>;
+               gpio-mosi = <&gpy3 3 0>;
+               gpio-miso = <&gpy3 0 0>;
                spi-delay-us = <1>;
                #address-cells = <1>;
                #size-cells = <0>;
index eada59073efcfd8d41f70e1010a30496ac04b5e0..5893d2a3f84e67ad68d21ab108e442873011710c 100644 (file)
                                nvidia,panel = <&lcd_panel>;
                        };
                };
-
-               dc@54240000 {
-                       status = "disabled";
-               };
        };
 
        /* This is not used in U-Boot, but is expected to be in kernel .dts */
index 267bd17727c619c1475f6f924c6fce916a594151..d77c04a86a3c1d9f6c9e3143d9ada67aaec1c092 100644 (file)
@@ -82,7 +82,7 @@
 /* SATA */
 #define AHCI_BASE_ADDR                         (CONFIG_SYS_IMMR + 0x02200000)
 #define CONFIG_BOARD_LATE_INIT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 23024f94c8586a6d4cff8f754f9b84e57fb57a56..13c036f746edd5d3750bb87515785b72f4472220 100644 (file)
@@ -372,14 +372,29 @@ _start:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for
-          the first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
+
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       bsr     board_init_f_alloc_reserve
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       bsr     board_init_f_init_reserve
 
        bsr cpu_init_f                  /* run low-level CPU init code (from flash) */
+       clr.l   %sp@-
        bsr board_init_f                /* run low-level board init code (from flash) */
 
        /* board_init_f() does not return */
index 1702f98ab1f11c97d7369a476da9722206e327c0..3aa4dd61faaa8b1894d6fc5ff83fd4e2ccca947d 100644 (file)
@@ -134,17 +134,34 @@ _start:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for the
-          first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       move.l  #board_init_f_alloc_reserve, %a1
+       jsr     (%a1)
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       move.l  #board_init_f_init_reserve, %a1
+       jsr     (%a1)
 
        /* run low-level CPU init code (from flash) */
        move.l #cpu_init_f, %a1
        jsr (%a1)
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        move.l #board_init_f, %a1
        jsr (%a1)
 
index 4af691f5aff7f4ff49845b48463746e2c627044a..a048884f6ce455c0129ff6bf6f08acb59e2989ba 100644 (file)
@@ -192,16 +192,34 @@ _after_flashbar_copy:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for the first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
 
-       move.l #__got_start, %a5                /* put relocation table address to a5 */
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       move.l  #board_init_f_alloc_reserve, %a1
+       jsr (%a1)
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       move.l  #board_init_f_init_reserve, %a1
+       jsr (%a1)
 
        /* run low-level CPU init code (from flash) */
        move.l #cpu_init_f, %a1
        jsr (%a1)
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        move.l #board_init_f, %a1
        jsr (%a1)
 
index 80dc23910e095cf50300b37fe61ec7cb29d425b0..b09eed80240341e810b3090a5fa911eda4cb15b2 100644 (file)
@@ -142,7 +142,7 @@ int cpu_init_r(void)
        return 0;
 }
 
-void uart_port_conf(void)
+void uart_port_conf(int port)
 {
 }
 
index 097958afda3eccfc6e9d94d5df4566a6cf869b57..ca8bb320630187713e6d991673ff5a387f795ab1 100644 (file)
@@ -126,21 +126,32 @@ _start:
        move.l  %d0, (%a1)
        move.l  %d0, (%a2)
 
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
+
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
        /*
-        * set stackpointer to internal sram end - 80
-        * (global data struct size + some bytes)
-        * get some stackspace for the first c-code,
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
         */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l   %sp@-
+       move.l  %sp, -(%sp)
+       bsr     board_init_f_alloc_reserve
 
-       /* put relocation table address to a5 */
-       move.l #__got_start, %a5
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       bsr     board_init_f_init_reserve
 
        /* run low-level CPU init code (from flash) */
        bsr cpu_init_f
 
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        bsr board_init_f
 
        /* board_init_f() does not return */
index 131ad6e392e9c48fabe730f46baf97222951528e..f25bc541be7cf6f1110b55d3c5d15669395ce15d 100644 (file)
@@ -148,17 +148,34 @@ _start:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for the
-          first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       move.l  #board_init_f_alloc_reserve, %a1
+       jsr     (%a1)
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       move.l  #board_init_f_init_reserve, %a1
+       jsr     (%a1)
 
        /* run low-level CPU init code (from flash) */
        move.l #cpu_init_f, %a1
        jsr (%a1)
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        move.l #board_init_f, %a1
        jsr (%a1)
 
index f50f147a4f3e6c4fb1722095998556519ff5e5a1..ba38678be3c1e79dc757df78f99ea960db513957 100644 (file)
@@ -657,17 +657,34 @@ _start:
        movec   %d0, %RAMBAR1
 #endif
 
-       /* set stackpointer to end of internal ram to get some stackspace for
-          the first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
+
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       move.l  #board_init_f_alloc_reserve, %a1
+       jsr     (%a1)
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       move.l  #board_init_f_init_reserve, %a1
+       jsr     (%a1)
 
        /* run low-level CPU init code (from flash) */
        move.l #cpu_init_f, %a1
        jsr (%a1)
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        move.l #board_init_f, %a1
        jsr (%a1)
 
index 75de22d37c8a71dbbf10ac19797a5a1d94bf6997..9a87a0da230af6beb465f7dfecbf4fa3eab4f455 100644 (file)
@@ -141,14 +141,29 @@ _start:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for the
-          first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       bsr     board_init_f_alloc_reserve
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       bsr     board_init_f_init_reserve
 
        jbsr cpu_init_f                 /* run low-level CPU init code (from flash) */
+       clr.l   %sp@-
        jbsr board_init_f               /* run low-level board init code (from flash) */
 
        /* board_init_f() does not return */
index e1458acd2c76091b5217f163e72e0654973236d0..9c4d3fb8fd7e905fe9ba2bf598d095fea86e8e43 100644 (file)
@@ -7,8 +7,6 @@
 #ifndef _ASM_CONFIG_H_
 #define _ASM_CONFIG_H_
 
-#define CONFIG_SYS_GENERIC_GLOBAL_DATA
-
 #define CONFIG_NEEDS_MANUAL_RELOC
 
 #define CONFIG_LMB
index 1b1c25ef8990da1fbcc797f4be04d512ec30cbf5..c7d2aa33e8597904208d6132390b1d716e06560f 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <asm/types.h>
 
-typedef struct fsl_i2c {
+typedef struct fsl_i2c_base {
 
        u8 adr;         /* I2C slave address */
        u8 res0[3];
index fe37d1fa2d7f14dc7cd20fe42c840fd16c577cef..dc34c18258cbf9aad441fd1b8145ecfd88f13a76 100644 (file)
@@ -5,8 +5,8 @@ config SYS_ARCH
        default "mips"
 
 config SYS_CPU
-       default "mips32" if CPU_MIPS32_R1 || CPU_MIPS32_R2
-       default "mips64" if CPU_MIPS64_R1 || CPU_MIPS64_R2
+       default "mips32" if CPU_MIPS32
+       default "mips64" if CPU_MIPS64
 
 choice
        prompt "Target select"
@@ -28,6 +28,7 @@ config TARGET_MALTA
        select SUPPORTS_LITTLE_ENDIAN
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
+       select SUPPORTS_CPU_MIPS32_R6
        select SWAP_IO_SPACE
        select MIPS_L1_CACHE_SHIFT_6
 
@@ -55,6 +56,11 @@ config TARGET_PB1X00
        select SYS_MIPS_CACHE_INIT_RAM_LOAD
        select MIPS_TUNE_4KC
 
+config ARCH_ATH79
+       bool "Support QCA/Atheros ath79"
+       select OF_CONTROL
+       select DM
+
 config MACH_PIC32
        bool "Support Microchip PIC32"
        select OF_CONTROL
@@ -67,6 +73,7 @@ source "board/imgtec/malta/Kconfig"
 source "board/micronas/vct/Kconfig"
 source "board/pb1x00/Kconfig"
 source "board/qemu-mips/Kconfig"
+source "arch/mips/mach-ath79/Kconfig"
 source "arch/mips/mach-pic32/Kconfig"
 
 if MIPS
@@ -98,7 +105,7 @@ config CPU_MIPS32_R1
        depends on SUPPORTS_CPU_MIPS32_R1
        select 32BIT
        help
-         Choose this option to build an U-Boot for release 1 or later of the
+         Choose this option to build an U-Boot for release 1 through 5 of the
          MIPS32 architecture.
 
 config CPU_MIPS32_R2
@@ -106,7 +113,15 @@ config CPU_MIPS32_R2
        depends on SUPPORTS_CPU_MIPS32_R2
        select 32BIT
        help
-         Choose this option to build an U-Boot for release 2 or later of the
+         Choose this option to build an U-Boot for release 2 through 5 of the
+         MIPS32 architecture.
+
+config CPU_MIPS32_R6
+       bool "MIPS32 Release 6"
+       depends on SUPPORTS_CPU_MIPS32_R6
+       select 32BIT
+       help
+         Choose this option to build an U-Boot for release 6 or later of the
          MIPS32 architecture.
 
 config CPU_MIPS64_R1
@@ -114,7 +129,7 @@ config CPU_MIPS64_R1
        depends on SUPPORTS_CPU_MIPS64_R1
        select 64BIT
        help
-         Choose this option to build a kernel for release 1 or later of the
+         Choose this option to build a kernel for release 1 through 5 of the
          MIPS64 architecture.
 
 config CPU_MIPS64_R2
@@ -122,7 +137,15 @@ config CPU_MIPS64_R2
        depends on SUPPORTS_CPU_MIPS64_R2
        select 64BIT
        help
-         Choose this option to build a kernel for release 2 or later of the
+         Choose this option to build a kernel for release 2 through 5 of the
+         MIPS64 architecture.
+
+config CPU_MIPS64_R6
+       bool "MIPS64 Release 6"
+       depends on SUPPORTS_CPU_MIPS64_R6
+       select 64BIT
+       help
+         Choose this option to build a kernel for release 6 or later of the
          MIPS64 architecture.
 
 endchoice
@@ -169,19 +192,25 @@ config SUPPORTS_CPU_MIPS32_R1
 config SUPPORTS_CPU_MIPS32_R2
        bool
 
+config SUPPORTS_CPU_MIPS32_R6
+       bool
+
 config SUPPORTS_CPU_MIPS64_R1
        bool
 
 config SUPPORTS_CPU_MIPS64_R2
        bool
 
+config SUPPORTS_CPU_MIPS64_R6
+       bool
+
 config CPU_MIPS32
        bool
-       default y if CPU_MIPS32_R1 || CPU_MIPS32_R2
+       default y if CPU_MIPS32_R1 || CPU_MIPS32_R2 || CPU_MIPS32_R6
 
 config CPU_MIPS64
        bool
-       default y if CPU_MIPS64_R1 || CPU_MIPS64_R2
+       default y if CPU_MIPS64_R1 || CPU_MIPS64_R2 || CPU_MIPS64_R6
 
 config MIPS_TUNE_4KC
        bool
@@ -192,6 +221,9 @@ config MIPS_TUNE_14KC
 config MIPS_TUNE_24KC
        bool
 
+config MIPS_TUNE_74KC
+       bool
+
 config 32BIT
        bool
 
index aec5a1517a7b1ef20d4e47ecd7e53783c079bbe7..655a49338201396559df33a13b9208271b105e01 100644 (file)
@@ -8,6 +8,7 @@ libs-y += arch/mips/cpu/
 libs-y += arch/mips/lib/
 
 machine-$(CONFIG_SOC_AU1X00) += au1x00
+machine-$(CONFIG_ARCH_ATH79) += ath79
 machine-$(CONFIG_MACH_PIC32) += pic32
 
 machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
@@ -18,13 +19,16 @@ PLATFORM_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs))
 # Optimize for MIPS architectures
 arch-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,-mips32
 arch-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,-mips32r2
+arch-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,-mips32r6
 arch-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,-mips64
 arch-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,-mips64r2
+arch-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,-mips64r6
 
 # Allow extra optimization for specific CPUs/SoCs
 tune-$(CONFIG_MIPS_TUNE_4KC) += -mtune=4kc
 tune-$(CONFIG_MIPS_TUNE_14KC) += -mtune=14kc
 tune-$(CONFIG_MIPS_TUNE_24KC) += -mtune=24kc
+tune-$(CONFIG_MIPS_TUNE_74KC) += -mtune=74kc
 
 # Include default header files
 cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
index 8d3b2f5c2b4e535ce12142f97b64874cc9f65430..391feb3250e42f665627c11cc7d07f182ffc2b4f 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <common.h>
 #include <command.h>
-#include <netdev.h>
 #include <linux/compiler.h>
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
index 1b56ca350a1cf0cb7bd3a1743ca6fb7125e0d76b..fc6dd66aa655b9e1c7a8b25c5311e96e0ff6f4cb 100644 (file)
@@ -164,12 +164,14 @@ reset:
        li      t0, -16
        PTR_LI  t1, CONFIG_SYS_INIT_SP_ADDR
        and     sp, t1, t0              # force 16 byte alignment
-       PTR_SUB sp, sp, GD_SIZE         # reserve space for gd
+       PTR_SUBU \
+               sp, sp, GD_SIZE         # reserve space for gd
        and     sp, sp, t0              # force 16 byte alignment
        move    k0, sp                  # save gd pointer
 #ifdef CONFIG_SYS_MALLOC_F_LEN
        li      t2, CONFIG_SYS_MALLOC_F_LEN
-       PTR_SUB sp, sp, t2              # reserve space for early malloc
+       PTR_SUBU \
+               sp, sp, t2              # reserve space for early malloc
        and     sp, sp, t0              # force 16 byte alignment
 #endif
        move    fp, sp
@@ -179,7 +181,7 @@ reset:
 1:
        PTR_S   zero, 0(t0)
        blt     t0, t1, 1b
-        PTR_ADDI t0, PTRSIZE
+        PTR_ADDIU t0, PTRSIZE
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
        PTR_S   sp, GD_MALLOC_BASE(k0)  # gd->malloc_base offset
@@ -237,7 +239,7 @@ ENTRY(relocate_code)
         move   a0, s2                  # a0 <-- destination address
 
        /* Jump to where we've relocated ourselves */
-       PTR_ADDI t0, s2, in_ram - _start
+       PTR_ADDIU t0, s2, in_ram - _start
        jr      t0
         nop
 
@@ -257,7 +259,7 @@ in_ram:
        PTR_L   t3, -(1 * PTRSIZE)(t0)  # t3 <-- num_got_entries
        PTR_L   t8, -(2 * PTRSIZE)(t0)  # t8 <-- _GLOBAL_OFFSET_TABLE_
        PTR_ADD t8, s1                  # t8 now holds relocated _G_O_T_
-       PTR_ADDI t8, t8, 2 * PTRSIZE    # skipping first two entries
+       PTR_ADDIU t8, t8, 2 * PTRSIZE   # skipping first two entries
        PTR_LI  t2, 2
 1:
        PTR_L   t1, 0(t8)
@@ -265,16 +267,16 @@ in_ram:
         PTR_ADD t1, s1
        PTR_S   t1, 0(t8)
 2:
-       PTR_ADDI t2, 1
+       PTR_ADDIU t2, 1
        blt     t2, t3, 1b
-        PTR_ADDI t8, PTRSIZE
+        PTR_ADDIU t8, PTRSIZE
 
        /* Update dynamic relocations */
        PTR_L   t1, -(4 * PTRSIZE)(t0)  # t1 <-- __rel_dyn_start
        PTR_L   t2, -(5 * PTRSIZE)(t0)  # t2 <-- __rel_dyn_end
 
        b       2f                      # skip first reserved entry
-        PTR_ADDI t1, 2 * PTRSIZE
+        PTR_ADDIU t1, 2 * PTRSIZE
 
 1:
        lw      t8, -4(t1)              # t8 <-- relocation info
@@ -293,7 +295,7 @@ in_ram:
 
 2:
        blt     t1, t2, 1b
-        PTR_ADDI t1, 2 * PTRSIZE       # each rel.dyn entry is 2*PTRSIZE bytes
+        PTR_ADDIU t1, 2 * PTRSIZE      # each rel.dyn entry is 2*PTRSIZE bytes
 
        /*
         * Clear BSS
@@ -307,7 +309,7 @@ in_ram:
 1:
        PTR_S   zero, 0(t1)
        blt     t1, t2, 1b
-        PTR_ADDI t1, PTRSIZE
+        PTR_ADDIU t1, PTRSIZE
 
        move    a0, s0                  # a0 <-- gd
        move    a1, s2
index b5139187c2068bb9905d68a8be07da24a4fddfb2..a94b74555073d5c0c59bfdaae1f07e1a0e13f542 100644 (file)
@@ -2,7 +2,10 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
+dtb-$(CONFIG_TARGET_AP121) += ap121.dtb
+dtb-$(CONFIG_TARGET_AP143) += ap143.dtb
 dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
+dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
 
 targets += $(dtb-y)
 
diff --git a/arch/mips/dts/ap121.dts b/arch/mips/dts/ap121.dts
new file mode 100644 (file)
index 0000000..e31f601
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+#include "ar933x.dtsi"
+
+/ {
+       model = "AP121 Reference Board";
+       compatible = "qca,ap121", "qca,ar933x";
+
+       aliases {
+               spi0 = &spi0;
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&xtal {
+       clock-frequency = <25000000>;
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&spi0 {
+       spi-max-frequency = <25000000>;
+       status = "okay";
+       spi-flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spi-flash";
+               memory-map = <0x9f000000 0x00800000>;
+               spi-max-frequency = <25000000>;
+               reg = <0>;
+       };
+};
diff --git a/arch/mips/dts/ap143.dts b/arch/mips/dts/ap143.dts
new file mode 100644 (file)
index 0000000..f53207e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+#include "qca953x.dtsi"
+
+/ {
+       model = "AP143 Reference Board";
+       compatible = "qca,ap143", "qca,qca953x";
+
+       aliases {
+               spi0 = &spi0;
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&xtal {
+       clock-frequency = <25000000>;
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&spi0 {
+       spi-max-frequency = <25000000>;
+       status = "okay";
+       spi-flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spi-flash";
+               memory-map = <0x9f000000 0x00800000>;
+               spi-max-frequency = <25000000>;
+               reg = <0>;
+       };
+};
diff --git a/arch/mips/dts/ar933x.dtsi b/arch/mips/dts/ar933x.dtsi
new file mode 100644 (file)
index 0000000..00896b2
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "skeleton.dtsi"
+
+/ {
+       compatible = "qca,ar933x";
+
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "mips,mips24Kc";
+                       reg = <0>;
+               };
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               xtal: xtal {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-output-names = "xtal";
+               };
+       };
+
+       pinctrl {
+               u-boot,dm-pre-reloc;
+               compatible = "qca,ar933x-pinctrl";
+               ranges;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x18040000 0x100>;
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               ranges;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               apb {
+                       compatible = "simple-bus";
+                       ranges;
+
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       ehci0: ehci@1b000100 {
+                               compatible = "generic-ehci";
+                               reg = <0x1b000100 0x100>;
+
+                               status = "disabled";
+                       };
+
+                       uart0: uart@18020000 {
+                               compatible = "qca,ar9330-uart";
+                               reg = <0x18020000 0x20>;
+                               interrupts = <128 IRQ_TYPE_LEVEL_HIGH>;
+
+                               status = "disabled";
+                       };
+
+                       gmac0: eth@0x19000000 {
+                               compatible = "qca,ag7240-mac";
+                               reg = <0x19000000 0x200>;
+                               phy = <&phy0>;
+                               phy-mode = "rmii";
+
+                               status = "disabled";
+
+                               mdio {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       phy0: ethernet-phy@0 {
+                                               reg = <0>;
+                                       };
+                               };
+                       };
+
+                       gmac1: eth@0x1a000000 {
+                               compatible = "qca,ag7240-mac";
+                               reg = <0x1a000000 0x200>;
+                               phy = <&phy0>;
+                               phy-mode = "rgmii";
+
+                               status = "disabled";
+                       };
+               };
+
+               spi0: spi@1f000000 {
+                       compatible = "qca,ar7100-spi";
+                       reg = <0x1f000000 0x10>;
+                       interrupts = <129 IRQ_TYPE_LEVEL_HIGH>;
+
+                       status = "disabled";
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+};
diff --git a/arch/mips/dts/ar934x.dtsi b/arch/mips/dts/ar934x.dtsi
new file mode 100644 (file)
index 0000000..7a036a8
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+       compatible = "qca,ar934x";
+
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "mips,mips74Kc";
+                       reg = <0>;
+               };
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               xtal: xtal {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-output-names = "xtal";
+               };
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               ranges;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               apb {
+                       compatible = "simple-bus";
+                       ranges;
+
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       ehci0: ehci@1b000100 {
+                               compatible = "generic-ehci";
+                               reg = <0x1b000100 0x100>;
+
+                               status = "disabled";
+                       };
+
+                       uart0: uart@18020000 {
+                               compatible = "ns16550";
+                               reg = <0x18020000 0x20>;
+                               reg-shift = <2>;
+
+                               status = "disabled";
+                       };
+
+                       gmac0: eth@0x19000000 {
+                               compatible = "qca,ag934x-mac";
+                               reg = <0x19000000 0x200>;
+                               phy = <&phy0>;
+                               phy-mode = "rgmii";
+
+                               status = "disabled";
+
+                               mdio {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       phy0: ethernet-phy@0 {
+                                               reg = <0>;
+                                       };
+                               };
+                       };
+
+                       gmac1: eth@0x1a000000 {
+                               compatible = "qca,ag934x-mac";
+                               reg = <0x1a000000 0x200>;
+                               phy = <&phy1>;
+                               phy-mode = "rgmii";
+
+                               status = "disabled";
+
+                               mdio {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       phy1: ethernet-phy@0 {
+                                               reg = <0>;
+                                       };
+                               };
+                       };
+               };
+
+               spi0: spi@1f000000 {
+                       compatible = "qca,ar7100-spi";
+                       reg = <0x1f000000 0x10>;
+
+                       status = "disabled";
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+};
diff --git a/arch/mips/dts/qca953x.dtsi b/arch/mips/dts/qca953x.dtsi
new file mode 100644 (file)
index 0000000..870010f
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "skeleton.dtsi"
+
+/ {
+       compatible = "qca,qca953x";
+
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "mips,mips24Kc";
+                       reg = <0>;
+               };
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               xtal: xtal {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-output-names = "xtal";
+               };
+       };
+
+       pinctrl {
+               u-boot,dm-pre-reloc;
+               compatible = "qca,qca953x-pinctrl";
+               ranges;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x18040000 0x100>;
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               ranges;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               apb {
+                       compatible = "simple-bus";
+                       ranges;
+
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       uart0: uart@18020000 {
+                               compatible = "ns16550";
+                               reg = <0x18020000 0x20>;
+                               reg-shift = <2>;
+                               clock-frequency = <25000000>;
+                               interrupts = <128 IRQ_TYPE_LEVEL_HIGH>;
+
+                               status = "disabled";
+                       };
+               };
+
+               spi0: spi@1f000000 {
+                       compatible = "qca,ar7100-spi";
+                       reg = <0x1f000000 0x10>;
+                       interrupts = <129 IRQ_TYPE_LEVEL_HIGH>;
+
+                       status = "disabled";
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+};
diff --git a/arch/mips/dts/tplink_wdr4300.dts b/arch/mips/dts/tplink_wdr4300.dts
new file mode 100644 (file)
index 0000000..cfda4df
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+#include "ar934x.dtsi"
+
+/ {
+       model = "TP-Link WDR4300 Board";
+       compatible = "tplink,wdr4300", "qca,ar934x";
+
+       aliases {
+               serial0 = &uart0;
+               spi0 = &spi0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&gmac0 {
+       phy-mode = "rgmii";
+       status = "okay";
+};
+
+&spi0 {
+       spi-max-frequency = <25000000>;
+       status = "okay";
+       spi-flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spi-flash";
+               memory-map = <0x1e000000 0x00800000>;
+               spi-max-frequency = <25000000>;
+               reg = <0>;
+       };
+};
+
+&uart0 {
+       clock-frequency = <40000000>;
+       status = "okay";
+};
+
+&xtal {
+       clock-frequency = <40000000>;
+};
index a1ca257db593a94f4cc7afedf2eaa1282315ca58..3f230b08f6042a0fc465bf341e4ea0863396683c 100644 (file)
@@ -23,6 +23,12 @@ struct arch_global_data {
        unsigned long tbl;
        unsigned long lastinc;
 #endif
+#ifdef CONFIG_ARCH_ATH79
+       unsigned long id;
+       unsigned long soc;
+       unsigned long rev;
+       unsigned long ver;
+#endif
 };
 
 #include <asm-generic/global_data.h>
index 14cc2c49fda23c30e7d9fdb2d2f2bf4ad88941ef..08b7c3af5254b80b08e2ecd04a815795e9ca458a 100644 (file)
@@ -64,7 +64,7 @@
        /* detect associativity */
        srl     \sz, $1, \off + MIPS_CONF1_DA_SHF - MIPS_CONF1_DA_SHF
        andi    \sz, \sz, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHF)
-       addi    \sz, \sz, 1
+       addiu   \sz, \sz, 1
 
        /* sz *= line_sz */
        mul     \sz, \sz, \line_sz
diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig
new file mode 100644 (file)
index 0000000..7d483aa
--- /dev/null
@@ -0,0 +1,55 @@
+menu "QCA/Atheros 7xxx/9xxx platforms"
+       depends on ARCH_ATH79
+
+config SYS_SOC
+       default "ath79"
+
+config SOC_AR933X
+       bool
+       select SUPPORTS_BIG_ENDIAN
+       select SUPPORTS_CPU_MIPS32_R1
+       select SUPPORTS_CPU_MIPS32_R2
+       select MIPS_TUNE_24KC
+       help
+         This supports QCA/Atheros ar933x family SOCs.
+
+config SOC_AR934X
+       bool
+       select SUPPORTS_BIG_ENDIAN
+       select SUPPORTS_CPU_MIPS32_R1
+       select SUPPORTS_CPU_MIPS32_R2
+       select MIPS_TUNE_74KC
+       help
+         This supports QCA/Atheros ar934x family SOCs.
+
+config SOC_QCA953X
+       bool
+       select SUPPORTS_BIG_ENDIAN
+       select SUPPORTS_CPU_MIPS32_R1
+       select SUPPORTS_CPU_MIPS32_R2
+       select MIPS_TUNE_24KC
+       help
+         This supports QCA/Atheros qca953x family SOCs.
+
+choice
+       prompt "Board select"
+
+config TARGET_AP121
+       bool "AP121 Reference Board"
+       select SOC_AR933X
+
+config TARGET_AP143
+       bool "AP143 Reference Board"
+       select SOC_QCA953X
+
+config BOARD_TPLINK_WDR4300
+       bool "TP-Link WDR4300 Board"
+       select SOC_AR934X
+
+endchoice
+
+source "board/qca/ap121/Kconfig"
+source "board/qca/ap143/Kconfig"
+source "board/tplink/wdr4300/Kconfig"
+
+endmenu
diff --git a/arch/mips/mach-ath79/Makefile b/arch/mips/mach-ath79/Makefile
new file mode 100644 (file)
index 0000000..d7e2666
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += reset.o
+obj-y += cpu.o
+obj-y += dram.o
+
+obj-$(CONFIG_SOC_AR933X)       += ar933x/
+obj-$(CONFIG_SOC_AR934X)       += ar934x/
+obj-$(CONFIG_SOC_QCA953X)      += qca953x/
diff --git a/arch/mips/mach-ath79/ar933x/Makefile b/arch/mips/mach-ath79/ar933x/Makefile
new file mode 100644 (file)
index 0000000..fd74f0c
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += clk.o
+obj-y += ddr.o
+obj-y += lowlevel_init.o
diff --git a/arch/mips/mach-ath79/ar933x/clk.c b/arch/mips/mach-ath79/ar933x/clk.c
new file mode 100644 (file)
index 0000000..9fcd496
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/reset.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static u32 ar933x_get_xtal(void)
+{
+       u32 val;
+
+       val = get_bootstrap();
+       if (val & AR933X_BOOTSTRAP_REF_CLK_40)
+               return 40000000;
+       else
+               return 25000000;
+}
+
+int get_serial_clock(void)
+{
+       return ar933x_get_xtal();
+}
+
+int get_clocks(void)
+{
+       void __iomem *regs;
+       u32 val, xtal, pll, div;
+
+       regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+                          MAP_NOCACHE);
+       xtal = ar933x_get_xtal();
+       val = readl(regs + AR933X_PLL_CPU_CONFIG_REG);
+
+       /* VCOOUT = XTAL * DIV_INT */
+       div = (val >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT)
+                       & AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
+       pll = xtal / div;
+
+       /* PLLOUT = VCOOUT * (1/2^OUTDIV) */
+       div = (val >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT)
+                       & AR933X_PLL_CPU_CONFIG_NINT_MASK;
+       pll *= div;
+       div = (val >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT)
+                       & AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
+       if (!div)
+               div = 1;
+       pll >>= div;
+
+       val = readl(regs + AR933X_PLL_CLK_CTRL_REG);
+
+       /* CPU_CLK = PLLOUT / CPU_POST_DIV */
+       div = ((val >> AR933X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT)
+                       & AR933X_PLL_CLK_CTRL_CPU_POST_DIV_MASK) + 1;
+       gd->cpu_clk = pll / div;
+
+       /* DDR_CLK = PLLOUT / DDR_POST_DIV */
+       div = ((val >> AR933X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT)
+                       & AR933X_PLL_CLK_CTRL_DDR_POST_DIV_MASK) + 1;
+       gd->mem_clk = pll / div;
+
+       /* AHB_CLK = PLLOUT / AHB_POST_DIV */
+       div = ((val >> AR933X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT)
+                       & AR933X_PLL_CLK_CTRL_AHB_POST_DIV_MASK) + 1;
+       gd->bus_clk = pll / div;
+
+       return 0;
+}
+
+ulong get_bus_freq(ulong dummy)
+{
+       if (!gd->bus_clk)
+               get_clocks();
+       return gd->bus_clk;
+}
+
+ulong get_ddr_freq(ulong dummy)
+{
+       if (!gd->mem_clk)
+               get_clocks();
+       return gd->mem_clk;
+}
diff --git a/arch/mips/mach-ath79/ar933x/ddr.c b/arch/mips/mach-ath79/ar933x/ddr.c
new file mode 100644 (file)
index 0000000..91452bc
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ * Based on Atheros LSDK/QSDK
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/reset.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define DDR_CTRL_UPD_EMR3S      BIT(5)
+#define DDR_CTRL_UPD_EMR2S      BIT(4)
+#define DDR_CTRL_PRECHARGE      BIT(3)
+#define DDR_CTRL_AUTO_REFRESH   BIT(2)
+#define DDR_CTRL_UPD_EMRS       BIT(1)
+#define DDR_CTRL_UPD_MRS        BIT(0)
+
+#define DDR_REFRESH_EN          BIT(14)
+#define DDR_REFRESH_M           0x3ff
+#define DDR_REFRESH(x)          ((x) & 0x3ff)
+#define DDR_REFRESH_VAL_25M     (DDR_REFRESH_EN | DDR_REFRESH(390))
+#define DDR_REFRESH_VAL_40M     (DDR_REFRESH_EN | DDR_REFRESH(624))
+
+#define DDR_TRAS_S              0
+#define DDR_TRAS_M              0x1f
+#define DDR_TRAS(x)             ((x) << DDR_TRAS_S)
+#define DDR_TRCD_M              0xf
+#define DDR_TRCD_S              5
+#define DDR_TRCD(x)             ((x) << DDR_TRCD_S)
+#define DDR_TRP_M               0xf
+#define DDR_TRP_S               9
+#define DDR_TRP(x)              ((x) << DDR_TRP_S)
+#define DDR_TRRD_M              0xf
+#define DDR_TRRD_S              13
+#define DDR_TRRD(x)             ((x) << DDR_TRRD_S)
+#define DDR_TRFC_M              0x7f
+#define DDR_TRFC_S              17
+#define DDR_TRFC(x)             ((x) << DDR_TRFC_S)
+#define DDR_TMRD_M              0xf
+#define DDR_TMRD_S              23
+#define DDR_TMRD(x)             ((x) << DDR_TMRD_S)
+#define DDR_CAS_L_M             0x17
+#define DDR_CAS_L_S             27
+#define DDR_CAS_L(x)            (((x) & DDR_CAS_L_M) << DDR_CAS_L_S)
+#define DDR_OPEN                BIT(30)
+#define DDR_CONF_REG_VAL        (DDR_TRAS(16) | DDR_TRCD(6) | \
+                                DDR_TRP(6) | DDR_TRRD(4) | \
+                                DDR_TRFC(30) | DDR_TMRD(15) | \
+                                DDR_CAS_L(7) | DDR_OPEN)
+
+#define DDR_BURST_LEN_S         0
+#define DDR_BURST_LEN_M         0xf
+#define DDR_BURST_LEN(x)        ((x) << DDR_BURST_LEN_S)
+#define DDR_BURST_TYPE          BIT(4)
+#define DDR_CNTL_OE_EN          BIT(5)
+#define DDR_PHASE_SEL           BIT(6)
+#define DDR_CKE                 BIT(7)
+#define DDR_TWR_S               8
+#define DDR_TWR_M               0xf
+#define DDR_TWR(x)              ((x) << DDR_TWR_S)
+#define DDR_TRTW_S              12
+#define DDR_TRTW_M              0x1f
+#define DDR_TRTW(x)             ((x) << DDR_TRTW_S)
+#define DDR_TRTP_S              17
+#define DDR_TRTP_M              0xf
+#define DDR_TRTP(x)             ((x) << DDR_TRTP_S)
+#define DDR_TWTR_S              21
+#define DDR_TWTR_M              0x1f
+#define DDR_TWTR(x)             ((x) << DDR_TWTR_S)
+#define DDR_G_OPEN_L_S          26
+#define DDR_G_OPEN_L_M          0xf
+#define DDR_G_OPEN_L(x)         ((x) << DDR_G_OPEN_L_S)
+#define DDR_HALF_WIDTH_LOW      BIT(31)
+#define DDR_CONF2_REG_VAL       (DDR_BURST_LEN(8) | DDR_CNTL_OE_EN | \
+                                DDR_CKE | DDR_TWR(6) | DDR_TRTW(14) | \
+                                DDR_TRTP(8) | DDR_TWTR(14) | \
+                                DDR_G_OPEN_L(7) | DDR_HALF_WIDTH_LOW)
+
+#define DDR2_CONF_TWL_S         10
+#define DDR2_CONF_TWL_M         0xf
+#define DDR2_CONF_TWL(x)        (((x) & DDR2_CONF_TWL_M) << DDR2_CONF_TWL_S)
+#define DDR2_CONF_ODT           BIT(9)
+#define DDR2_CONF_TFAW_S        2
+#define DDR2_CONF_TFAW_M        0x3f
+#define DDR2_CONF_TFAW(x)       (((x) & DDR2_CONF_TFAW_M) << DDR2_CONF_TFAW_S)
+#define DDR2_CONF_EN            BIT(0)
+#define DDR2_CONF_VAL           (DDR2_CONF_TWL(2) | DDR2_CONF_ODT | \
+                                DDR2_CONF_TFAW(22) | DDR2_CONF_EN)
+
+#define DDR1_EXT_MODE_VAL       0x02
+#define DDR2_EXT_MODE_VAL       0x402
+#define DDR2_EXT_MODE_OCD_VAL   0x382
+#define DDR1_MODE_DLL_VAL       0x133
+#define DDR2_MODE_DLL_VAL       0x100
+#define DDR1_MODE_VAL           0x33
+#define DDR2_MODE_VAL           0xa33
+#define DDR_TAP_VAL0            0x08
+#define DDR_TAP_VAL1            0x09
+
+void ddr_init(void)
+{
+       void __iomem *regs;
+       u32 val;
+
+       regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
+                          MAP_NOCACHE);
+
+       writel(DDR_CONF_REG_VAL, regs + AR71XX_DDR_REG_CONFIG);
+       writel(DDR_CONF2_REG_VAL, regs + AR71XX_DDR_REG_CONFIG2);
+
+       val = get_bootstrap();
+       if (val & AR933X_BOOTSTRAP_DDR2) {
+               /* AHB maximum timeout */
+               writel(0xfffff, regs + AR933X_DDR_REG_TIMEOUT_MAX);
+
+               /* Enable DDR2 */
+               writel(DDR2_CONF_VAL, regs + AR933X_DDR_REG_DDR2_CONFIG);
+
+               /* Precharge All */
+               writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Disable High Temperature Self-Refresh, Full Array */
+               writel(0x00, regs + AR933X_DDR_REG_EMR2);
+
+               /* Extended Mode Register 2 Set (EMR2S) */
+               writel(DDR_CTRL_UPD_EMR2S, regs + AR71XX_DDR_REG_CONTROL);
+
+               writel(0x00, regs + AR933X_DDR_REG_EMR3);
+
+               /* Extended Mode Register 3 Set (EMR3S) */
+               writel(DDR_CTRL_UPD_EMR3S, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Enable DLL,  Full strength, ODT Disabled */
+               writel(0x00, regs + AR71XX_DDR_REG_EMR);
+
+               /* Extended Mode Register Set (EMRS) */
+               writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Reset DLL */
+               writel(DDR2_MODE_DLL_VAL, regs + AR71XX_DDR_REG_MODE);
+
+               /* Mode Register Set (MRS) */
+               writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Precharge All */
+               writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Auto Refresh */
+               writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
+               writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Write recovery (WR) 6 clock, CAS Latency 3, Burst Length 8 */
+               writel(DDR2_MODE_VAL, regs + AR71XX_DDR_REG_MODE);
+               /* Mode Register Set (MRS) */
+               writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Enable OCD defaults, Enable DLL, Reduced Drive Strength */
+               writel(DDR2_EXT_MODE_OCD_VAL, regs + AR71XX_DDR_REG_EMR);
+
+               /* Extended Mode Register Set (EMRS) */
+               writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* OCD exit, Enable DLL, Enable /DQS, Reduced Drive Strength */
+               writel(DDR2_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
+               /* Extended Mode Register Set (EMRS) */
+               writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Refresh time control */
+               if (val & AR933X_BOOTSTRAP_REF_CLK_40)
+                       writel(DDR_REFRESH_VAL_40M, regs +
+                              AR71XX_DDR_REG_REFRESH);
+               else
+                       writel(DDR_REFRESH_VAL_25M, regs +
+                              AR71XX_DDR_REG_REFRESH);
+
+               /* DQS 0 Tap Control */
+               writel(DDR_TAP_VAL0, regs + AR71XX_DDR_REG_TAP_CTRL0);
+
+               /* DQS 1 Tap Control */
+               writel(DDR_TAP_VAL1, regs + AR71XX_DDR_REG_TAP_CTRL1);
+
+               /* For 16-bit DDR */
+               writel(0xff, regs + AR71XX_DDR_REG_RD_CYCLE);
+       } else {
+               /* AHB maximum timeout */
+               writel(0xfffff, regs + AR933X_DDR_REG_TIMEOUT_MAX);
+
+               /* Precharge All */
+               writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Reset DLL, Burst Length 8, CAS Latency 3 */
+               writel(DDR1_MODE_DLL_VAL, regs + AR71XX_DDR_REG_MODE);
+
+               /* Forces an MRS update cycle in DDR */
+               writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Enable DLL, Full strength */
+               writel(DDR1_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
+
+               /* Extended Mode Register Set (EMRS) */
+               writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Precharge All */
+               writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Normal DLL, Burst Length 8, CAS Latency 3 */
+               writel(DDR1_MODE_VAL, regs + AR71XX_DDR_REG_MODE);
+
+               /* Mode Register Set (MRS) */
+               writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
+
+               /* Refresh time control */
+               if (val & AR933X_BOOTSTRAP_REF_CLK_40)
+                       writel(DDR_REFRESH_VAL_40M, regs +
+                              AR71XX_DDR_REG_REFRESH);
+               else
+                       writel(DDR_REFRESH_VAL_25M, regs +
+                              AR71XX_DDR_REG_REFRESH);
+
+               /* DQS 0 Tap Control */
+               writel(DDR_TAP_VAL0, regs + AR71XX_DDR_REG_TAP_CTRL0);
+
+               /* DQS 1 Tap Control */
+               writel(DDR_TAP_VAL1, regs + AR71XX_DDR_REG_TAP_CTRL1);
+
+               /* For 16-bit DDR */
+               writel(0xff, regs + AR71XX_DDR_REG_RD_CYCLE);
+       }
+}
+
+void ddr_tap_tuning(void)
+{
+       void __iomem *regs;
+       u32 *addr_k0, *addr_k1, *addr;
+       u32 val, tap, upper, lower;
+       int i, j, dir, err, done;
+
+       regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
+                          MAP_NOCACHE);
+
+       /* Init memory pattern */
+       addr = (void *)CKSEG0ADDR(0x2000);
+       for (i = 0; i < 256; i++) {
+               val = 0;
+               for (j = 0; j < 8; j++) {
+                       if (i & (1 << j)) {
+                               if (j % 2)
+                                       val |= 0xffff0000;
+                               else
+                                       val |= 0x0000ffff;
+                       }
+
+                       if (j % 2) {
+                               *addr++ = val;
+                               val = 0;
+                       }
+               }
+       }
+
+       err = 0;
+       done = 0;
+       dir = 1;
+       tap = readl(regs + AR71XX_DDR_REG_TAP_CTRL0);
+       val = tap;
+       while (!done) {
+               err = 0;
+
+               /* Update new DDR tap value */
+               writel(val, regs + AR71XX_DDR_REG_TAP_CTRL0);
+               writel(val, regs + AR71XX_DDR_REG_TAP_CTRL1);
+
+               /* Compare DDR with cache */
+               for (i = 0; i < 2; i++) {
+                       addr_k1 = (void *)CKSEG1ADDR(0x2000);
+                       addr_k0 = (void *)CKSEG0ADDR(0x2000);
+                       addr = (void *)CKSEG0ADDR(0x3000);
+
+                       while (addr_k0 < addr) {
+                               if (*addr_k1++ != *addr_k0++) {
+                                       err = 1;
+                                       break;
+                               }
+                       }
+
+                       if (err)
+                               break;
+               }
+
+               if (err) {
+                       /* Save upper/lower threshold if error  */
+                       if (dir) {
+                               dir = 0;
+                               val--;
+                               upper = val;
+                               val = tap;
+                       } else {
+                               val++;
+                               lower = val;
+                               done = 1;
+                       }
+               } else {
+                       /* Try the next value until limitation */
+                       if (dir) {
+                               if (val < 0x20) {
+                                       val++;
+                               } else {
+                                       dir = 0;
+                                       upper = val;
+                                       val = tap;
+                               }
+                       } else {
+                               if (!val) {
+                                       lower = val;
+                                       done = 1;
+                               } else {
+                                       val--;
+                               }
+                       }
+               }
+       }
+
+       /* compute an intermediate value and write back */
+       val = (upper + lower) / 2;
+       writel(val, regs + AR71XX_DDR_REG_TAP_CTRL0);
+       val++;
+       writel(val, regs + AR71XX_DDR_REG_TAP_CTRL1);
+}
diff --git a/arch/mips/mach-ath79/ar933x/lowlevel_init.S b/arch/mips/mach-ath79/ar933x/lowlevel_init.S
new file mode 100644 (file)
index 0000000..1b847f5
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ * Based on Atheros LSDK/QSDK and u-boot_mod project
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <mach/ar71xx_regs.h>
+
+#define SET_BIT(val, bit)   ((val) | (1 << (bit)))
+#define SET_PLL_PD(val)     SET_BIT(val, 30)
+#define AHB_DIV_TO_4(val)   SET_BIT(SET_BIT(val, 15), 16)
+#define PLL_BYPASS(val)     SET_BIT(val, 2)
+
+#define MK_PLL_CONF(divint, refdiv, range, outdiv) \
+     (((0x3F & divint) << 10) | \
+     ((0x1F & refdiv) << 16) | \
+     ((0x1 & range)   << 21) | \
+     ((0x7 & outdiv)  << 23) )
+
+#define MK_CLK_CNTL(cpudiv, ddrdiv, ahbdiv) \
+    (((0x3 & (cpudiv - 1)) << 5)  | \
+    ((0x3 & (ddrdiv - 1)) << 10) | \
+    ((0x3 & (ahbdiv - 1)) << 15) )
+
+/*
+ * PLL_CPU_CONFIG_VAL
+ *
+ * Bit30 is set (CPU_PLLPWD = 1 -> power down control for CPU PLL)
+ * After PLL configuration we need to clear this bit
+ *
+ * Values written into CPU PLL Configuration (CPU_PLL_CONFIG)
+ *
+ * bits 10..15  (6bit)  DIV_INT (Integer part of the DIV to CPU PLL)
+ *                      =>  32  (0x20)  VCOOUT = XTAL * DIV_INT
+ * bits 16..20  (5bit)  REFDIV  (Reference clock divider)
+ *                      =>  1   (0x1)   [Must start at values 1]
+ * bits 21      (1bit)  RANGE   (VCO frequency range of the CPU PLL)
+ *                      =>  0   (0x0)   [Doesn't impact clock values]
+ * bits 23..25  (3bit)  OUTDIV  (Ratio between VCO and PLL output)
+ *                      =>  1   (0x1)   [0 is illegal!]
+ *                              PLLOUT = VCOOUT * (1/2^OUTDIV)
+ */
+/* DIV_INT=32 (25MHz*32/2=400MHz), REFDIV=1, RANGE=0, OUTDIV=1 */
+#define PLL_CPU_CONFIG_VAL_40M  MK_PLL_CONF(20, 1, 0, 1)
+/* DIV_INT=20 (40MHz*20/2=400MHz), REFDIV=1, RANGE=0, OUTDIV=1 */
+#define PLL_CPU_CONFIG_VAL_25M  MK_PLL_CONF(32, 1, 0, 1)
+
+/*
+ * PLL_CLK_CONTROL_VAL
+ *
+ * In PLL_CLK_CONTROL_VAL bit 2 is set (BYPASS = 1 -> bypass PLL)
+ * After PLL configuration we need to clear this bit
+ *
+ * Values written into CPU Clock Control Register CLOCK_CONTROL
+ *
+ * bits 2       (1bit)  BYPASS (Bypass PLL. This defaults to 1 for test.
+ *                      Software must enable the CPU PLL for normal and
+ *                      then set this bit to 0)
+ * bits 5..6    (2bit)  CPU_POST_DIV    =>  0   (DEFAULT, Ratio = 1)
+ *                      CPU_CLK = PLLOUT / CPU_POST_DIV
+ * bits 10..11  (2bit)  DDR_POST_DIV    =>  0   (DEFAULT, Ratio = 1)
+ *                      DDR_CLK = PLLOUT / DDR_POST_DIV
+ * bits 15..16  (2bit)  AHB_POST_DIV    =>  1   (DEFAULT, Ratio = 2)
+ *                      AHB_CLK = PLLOUT / AHB_POST_DIV
+ *
+ */
+#define PLL_CLK_CONTROL_VAL MK_CLK_CNTL(1, 1, 2)
+
+    .text
+    .set noreorder
+
+LEAF(lowlevel_init)
+       /* These three WLAN_RESET will avoid original issue */
+       li      t3, 0x03
+1:
+       li      t0, CKSEG1ADDR(AR71XX_RESET_BASE)
+       lw      t1, AR933X_RESET_REG_RESET_MODULE(t0)
+       ori     t1, t1, 0x0800
+       sw      t1, AR933X_RESET_REG_RESET_MODULE(t0)
+       nop
+       lw      t1, AR933X_RESET_REG_RESET_MODULE(t0)
+       li      t2, 0xfffff7ff
+       and     t1, t1, t2
+       sw      t1, AR933X_RESET_REG_RESET_MODULE(t0)
+       nop
+       addi    t3, t3, -1
+       bnez    t3, 1b
+       nop
+
+       li      t2, 0x20
+2:
+       beqz    t2, 1b
+       nop
+       addi    t2, t2, -1
+       lw      t5, AR933X_RESET_REG_BOOTSTRAP(t0)
+       andi    t1, t5, 0x10
+       bnez    t1, 2b
+       nop
+
+       li      t1, 0x02110E
+       sw      t1, AR933X_RESET_REG_BOOTSTRAP(t0)
+       nop
+
+       /* RTC Force Wake */
+       li      t0, CKSEG1ADDR(AR933X_RTC_BASE)
+       li      t1, 0x03
+       sw      t1, AR933X_RTC_REG_FORCE_WAKE(t0)
+       nop
+       nop
+
+       /* RTC Reset */
+       li      t1, 0x00
+       sw      t1, AR933X_RTC_REG_RESET(t0)
+       nop
+       nop
+
+       li      t1, 0x01
+       sw      t1, AR933X_RTC_REG_RESET(t0)
+       nop
+       nop
+
+       /* Wait for RTC in on state */
+1:
+       lw      t1, AR933X_RTC_REG_STATUS(t0)
+       andi    t1, t1, 0x02
+       beqz    t1, 1b
+       nop
+
+       /* Program ki/kd */
+       li      t0, CKSEG1ADDR(AR933X_SRIF_BASE)
+       andi    t1, t5, 0x01            # t5 BOOT_STRAP
+       bnez    t1, 1f
+       nop
+       li      t1, 0x19e82f01
+       b       2f
+       nop
+1:
+       li      t1, 0x18e82f01
+2:
+       sw      t1, AR933X_SRIF_DDR_DPLL2_REG(t0)
+
+       /* Program phase shift */
+       lw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
+       li      t2, 0xc07fffff
+       and     t1, t1, t2
+       li      t2, 0x800000
+       or      t1, t1, t2
+       sw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
+       nop
+
+       /* in some cases, the SoC doesn't start with higher clock on AHB */
+       li      t0, CKSEG1ADDR(AR71XX_PLL_BASE)
+       li      t1, AHB_DIV_TO_4(PLL_BYPASS(PLL_CLK_CONTROL_VAL))
+       sw      t1, AR933X_PLL_CLK_CTRL_REG(t0)
+       nop
+
+       /* Set SETTLE_TIME in CPU PLL */
+       andi    t1, t5, 0x01            # t5 BOOT_STRAP
+       bnez    t1, 1f
+       nop
+       li      t1, 0x0352
+       b       2f
+       nop
+1:
+       li      t1, 0x0550
+2:
+       sw      t1, AR71XX_PLL_REG_SEC_CONFIG(t0)
+       nop
+
+       /* Set nint, frac, refdiv, outdiv, range according to xtal */
+0:
+       andi    t1, t5, 0x01            # t5 BOOT_STRAP
+       bnez    t1, 1f
+       nop
+       li      t1, SET_PLL_PD(PLL_CPU_CONFIG_VAL_25M)
+       b       2f
+       nop
+1:
+       li      t1, SET_PLL_PD(PLL_CPU_CONFIG_VAL_40M)
+2:
+       sw      t1, AR933X_PLL_CPU_CONFIG_REG(t0)
+       nop
+1:
+       lw      t1, AR933X_PLL_CPU_CONFIG_REG(t0)
+       li      t2, 0x80000000
+       and     t1, t1, t2
+       bnez    t1, 1b
+       nop
+
+       /* Put frac bit19:10 configuration */
+       li      t1, 0x1003E8
+       sw      t1, AR933X_PLL_DITHER_FRAC_REG(t0)
+       nop
+
+       /* Clear PLL power down bit in CPU PLL configuration */
+       andi    t1, t5, 0x01            # t5 BOOT_STRAP
+       bnez    t1, 1f
+       nop
+       li      t1, PLL_CPU_CONFIG_VAL_25M
+       b       2f
+       nop
+1:
+       li      t1, PLL_CPU_CONFIG_VAL_40M
+2:
+       sw      t1, AR933X_PLL_CPU_CONFIG_REG(t0)
+       nop
+
+       /* Wait for PLL update -> bit 31 in CPU_PLL_CONFIG should be 0 */
+1:
+       lw      t1, AR933X_PLL_CPU_CONFIG_REG(t0)
+       li      t2, 0x80000000
+       and     t1, t1, t2
+       bnez    t1, 1b
+       nop
+
+       /* Confirm DDR PLL lock */
+       li      t3, 100
+       li      t4, 0
+
+2:
+       addi    t4, t4, 1
+       bgt     t4, t3, 0b
+       nop
+
+       li      t3, 5
+3:
+       /* Clear do_meas */
+       li      t0, CKSEG1ADDR(AR933X_SRIF_BASE)
+       lw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
+       li      t2, 0xBFFFFFFF
+       and     t1, t1, t2
+       sw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
+       nop
+
+       li      t2, 10
+1:
+       subu    t2, t2, 1
+       bnez    t2, 1b
+       nop
+
+       /* Set do_meas */
+       li      t2, 0x40000000
+       or      t1, t1, t2
+       sw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
+       nop
+
+       /* Check meas_done */
+1:
+       lw      t1, AR933X_SRIF_DDR_DPLL4_REG(t0)
+       andi    t1, t1, 0x8
+       beqz    t1, 1b
+       nop
+
+       lw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
+       li      t2, 0x007FFFF8
+       and     t1, t1, t2
+       srl     t1, t1, 3
+       li      t2, 0x4000
+       bgt     t1, t2, 2b
+       nop
+       addi    t3, t3, -1
+       bnez    t3, 3b
+       nop
+
+       /* clear PLL bypass (bit 2) in CPU CLOCK CONTROL register */
+       li      t0, CKSEG1ADDR(AR71XX_PLL_BASE)
+       li      t1, PLL_CLK_CONTROL_VAL
+       sw      t1, AR933X_PLL_CLK_CTRL_REG(t0)
+       nop
+
+       nop
+       jr ra
+       nop
+    END(lowlevel_init)
diff --git a/arch/mips/mach-ath79/ar934x/Makefile b/arch/mips/mach-ath79/ar934x/Makefile
new file mode 100644 (file)
index 0000000..348c65b
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += cpu.o
+obj-y += clk.o
+obj-y += ddr.o
diff --git a/arch/mips/mach-ath79/ar934x/clk.c b/arch/mips/mach-ath79/ar934x/clk.c
new file mode 100644 (file)
index 0000000..9c65184
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2016 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/reset.h>
+#include <wait_bit.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * The math for calculating PLL:
+ *                                       NFRAC * 2^8
+ *                               NINT + -------------
+ *                XTAL [MHz]              2^(18 - 1)
+ *   PLL [MHz] = ------------ * ----------------------
+ *                  REFDIV              2^OUTDIV
+ *
+ * Unfortunatelly, there is no way to reliably compute the variables.
+ * The vendor U-Boot port contains macros for various combinations of
+ * CPU PLL / DDR PLL / AHB bus speed and there is no obvious pattern
+ * in those numbers.
+ */
+struct ar934x_pll_config {
+       u8      range;
+       u8      refdiv;
+       u8      outdiv;
+       /* Index 0 is for XTAL=25MHz , Index 1 is for XTAL=40MHz */
+       u8      nint[2];
+};
+
+struct ar934x_clock_config {
+       u16                             cpu_freq;
+       u16                             ddr_freq;
+       u16                             ahb_freq;
+
+       struct ar934x_pll_config        cpu_pll;
+       struct ar934x_pll_config        ddr_pll;
+};
+
+static const struct ar934x_clock_config ar934x_clock_config[] = {
+       { 300, 300, 150, { 1, 1, 1, { 24, 15 } }, { 1, 1, 1, { 24, 15 } } },
+       { 400, 200, 200, { 1, 1, 1, { 32, 20 } }, { 1, 1, 2, { 32, 20 } } },
+       { 400, 400, 200, { 0, 1, 1, { 32, 20 } }, { 0, 1, 1, { 32, 20 } } },
+       { 500, 400, 200, { 1, 1, 0, { 20, 12 } }, { 0, 1, 1, { 32, 20 } } },
+       { 533, 400, 200, { 1, 1, 0, { 21, 13 } }, { 0, 1, 1, { 32, 20 } } },
+       { 533, 500, 250, { 1, 1, 0, { 21, 13 } }, { 0, 1, 0, { 20, 12 } } },
+       { 560, 480, 240, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 19, 12 } } },
+       { 566, 400, 200, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 16, 10 } } },
+       { 566, 450, 225, { 1, 1, 0, { 22, 14 } }, { 0, 1, 1, { 36, 22 } } },
+       { 566, 475, 237, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 19, 11 } } },
+       { 566, 500, 250, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 20, 12 } } },
+       { 566, 525, 262, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 21, 13 } } },
+       { 566, 550, 275, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 22, 13 } } },
+       { 600, 266, 133, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 21, 16 } } },
+       { 600, 266, 200, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 21, 16 } } },
+       { 600, 300, 150, { 0, 1, 0, { 24, 15 } }, { 0, 1, 1, { 24, 15 } } },
+       { 600, 332, 166, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 26, 16 } } },
+       { 600, 332, 200, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 26, 16 } } },
+       { 600, 400, 200, { 0, 1, 0, { 24, 15 } }, { 0, 1, 1, { 32, 20 } } },
+       { 600, 450, 200, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 18, 20 } } },
+       { 600, 500, 250, { 0, 1, 0, { 24, 15 } }, { 1, 1, 0, { 20, 12 } } },
+       { 600, 525, 262, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 21, 20 } } },
+       { 600, 550, 275, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 22, 20 } } },
+       { 600, 575, 287, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 23, 14 } } },
+       { 600, 600, 300, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 24, 20 } } },
+       { 600, 650, 325, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 26, 20 } } },
+       { 650, 600, 300, { 0, 1, 0, { 26, 15 } }, { 0, 1, 0, { 24, 20 } } },
+       { 700, 400, 200, { 3, 1, 0, { 28, 17 } }, { 0, 1, 1, { 32, 20 } } },
+};
+
+static void ar934x_srif_pll_cfg(void __iomem *pll_reg_base, const u32 srif_val)
+{
+       u32 reg;
+       do {
+               writel(0x10810f00, pll_reg_base + 0x4);
+               writel(srif_val, pll_reg_base + 0x0);
+               writel(0xd0810f00, pll_reg_base + 0x4);
+               writel(0x03000000, pll_reg_base + 0x8);
+               writel(0xd0800f00, pll_reg_base + 0x4);
+
+               clrbits_be32(pll_reg_base + 0x8, BIT(30));
+               udelay(5);
+               setbits_be32(pll_reg_base + 0x8, BIT(30));
+               udelay(5);
+
+               wait_for_bit("clk", pll_reg_base + 0xc, BIT(3), 1, 10, 0);
+
+               clrbits_be32(pll_reg_base + 0x8, BIT(30));
+               udelay(5);
+
+               /* Check if CPU SRIF PLL locked. */
+               reg = readl(pll_reg_base + 0x8);
+               reg = (reg & 0x7ffff8) >> 3;
+       } while (reg >= 0x40000);
+}
+
+void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz)
+{
+       void __iomem *srif_regs = map_physmem(AR934X_SRIF_BASE,
+                                             AR934X_SRIF_SIZE, MAP_NOCACHE);
+       void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
+                                            AR71XX_PLL_SIZE, MAP_NOCACHE);
+       const struct ar934x_pll_config *pll_cfg;
+       int i, pll_nint, pll_refdiv, xtal_40 = 0;
+       u32 reg, cpu_pll, cpu_srif, ddr_pll, ddr_srif;
+
+       /* Configure SRIF PLL with initial values. */
+       writel(0x13210f00, srif_regs + AR934X_SRIF_CPU_DPLL2_REG);
+       writel(0x03000000, srif_regs + AR934X_SRIF_CPU_DPLL3_REG);
+       writel(0x13210f00, srif_regs + AR934X_SRIF_DDR_DPLL2_REG);
+       writel(0x03000000, srif_regs + AR934X_SRIF_DDR_DPLL3_REG);
+       writel(0x03000000, srif_regs + 0x188); /* Undocumented reg :-) */
+
+       /* Test for 40MHz XTAL */
+       reg = get_bootstrap();
+       if (reg & AR934X_BOOTSTRAP_REF_CLK_40) {
+               xtal_40 = 1;
+               cpu_srif = 0x41c00000;
+               ddr_srif = 0x41680000;
+       } else {
+               xtal_40 = 0;
+               cpu_srif = 0x29c00000;
+               ddr_srif = 0x29680000;
+       }
+
+       /* Locate CPU/DDR PLL configuration */
+       for (i = 0; i < ARRAY_SIZE(ar934x_clock_config); i++) {
+               if (cpu_mhz != ar934x_clock_config[i].cpu_freq)
+                       continue;
+               if (ddr_mhz != ar934x_clock_config[i].ddr_freq)
+                       continue;
+               if (ahb_mhz != ar934x_clock_config[i].ahb_freq)
+                       continue;
+
+               /* Entry found */
+               pll_cfg = &ar934x_clock_config[i].cpu_pll;
+               pll_nint = pll_cfg->nint[xtal_40];
+               pll_refdiv = pll_cfg->refdiv;
+               cpu_pll =
+                       (pll_nint << AR934X_PLL_CPU_CONFIG_NINT_SHIFT) |
+                       (pll_refdiv << AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) |
+                       (pll_cfg->range << AR934X_PLL_CPU_CONFIG_RANGE_SHIFT) |
+                       (pll_cfg->outdiv << AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT);
+
+               pll_cfg = &ar934x_clock_config[i].ddr_pll;
+               pll_nint = pll_cfg->nint[xtal_40];
+               pll_refdiv = pll_cfg->refdiv;
+               ddr_pll =
+                       (pll_nint << AR934X_PLL_DDR_CONFIG_NINT_SHIFT) |
+                       (pll_refdiv << AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) |
+                       (pll_cfg->range << AR934X_PLL_DDR_CONFIG_RANGE_SHIFT) |
+                       (pll_cfg->outdiv << AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT);
+               break;
+       }
+
+       /* PLL configuration not found, hang. */
+       if (i == ARRAY_SIZE(ar934x_clock_config))
+               hang();
+
+       /* Set PLL Bypass */
+       setbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
+                    AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS);
+       setbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
+                    AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS);
+       setbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
+                    AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS);
+
+       /* Configure CPU PLL */
+       writel(cpu_pll | AR934X_PLL_CPU_CONFIG_PLLPWD,
+              pll_regs + AR934X_PLL_CPU_CONFIG_REG);
+       /* Configure DDR PLL */
+       writel(ddr_pll | AR934X_PLL_DDR_CONFIG_PLLPWD,
+              pll_regs + AR934X_PLL_DDR_CONFIG_REG);
+       /* Configure PLL routing */
+       writel(AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS |
+              AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS |
+              AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS |
+              (0 << AR934X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) |
+              (0 << AR934X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) |
+              (1 << AR934X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) |
+              AR934X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL |
+              AR934X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL |
+              AR934X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL,
+              pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
+
+       /* Configure SRIF PLLs, which is completely undocumented :-) */
+       ar934x_srif_pll_cfg(srif_regs + AR934X_SRIF_CPU_DPLL1_REG, cpu_srif);
+       ar934x_srif_pll_cfg(srif_regs + AR934X_SRIF_DDR_DPLL1_REG, ddr_srif);
+
+       /* Unset PLL Bypass */
+       clrbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
+                    AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS);
+       clrbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
+                    AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS);
+       clrbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
+                    AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS);
+
+       /* Enable PLL dithering */
+       writel((1 << AR934X_PLL_DDR_DIT_FRAC_STEP_SHIFT) |
+              (0xf << AR934X_PLL_DDR_DIT_UPD_CNT_SHIFT),
+              pll_regs + AR934X_PLL_DDR_DIT_FRAC_REG);
+       writel(48 << AR934X_PLL_CPU_DIT_UPD_CNT_SHIFT,
+              pll_regs + AR934X_PLL_CPU_DIT_FRAC_REG);
+}
+
+static u32 ar934x_get_xtal(void)
+{
+       u32 val;
+
+       val = get_bootstrap();
+       if (val & AR934X_BOOTSTRAP_REF_CLK_40)
+               return 40000000;
+       else
+               return 25000000;
+}
+
+int get_serial_clock(void)
+{
+       return ar934x_get_xtal();
+}
+
+static u32 ar934x_cpupll_to_hz(const u32 regval)
+{
+       const u32 outdiv = (regval >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
+                          AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
+       const u32 refdiv = (regval >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
+                          AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
+       const u32 nint = (regval >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
+                          AR934X_PLL_CPU_CONFIG_NINT_MASK;
+       const u32 nfrac = (regval >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
+                          AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
+       const u32 xtal = ar934x_get_xtal();
+
+       return (xtal * (nint + (nfrac >> 9))) / (refdiv * (1 << outdiv));
+}
+
+static u32 ar934x_ddrpll_to_hz(const u32 regval)
+{
+       const u32 outdiv = (regval >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
+                          AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
+       const u32 refdiv = (regval >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
+                          AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
+       const u32 nint = (regval >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
+                          AR934X_PLL_DDR_CONFIG_NINT_MASK;
+       const u32 nfrac = (regval >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
+                          AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
+       const u32 xtal = ar934x_get_xtal();
+
+       return (xtal * (nint + (nfrac >> 9))) / (refdiv * (1 << outdiv));
+}
+
+static void ar934x_update_clock(void)
+{
+       void __iomem *regs;
+       u32 ctrl, cpu, cpupll, ddr, ddrpll;
+       u32 cpudiv, ddrdiv, busdiv;
+       u32 cpuclk, ddrclk, busclk;
+
+       regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+                          MAP_NOCACHE);
+
+       cpu = readl(regs + AR934X_PLL_CPU_CONFIG_REG);
+       ddr = readl(regs + AR934X_PLL_DDR_CONFIG_REG);
+       ctrl = readl(regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
+
+       cpupll = ar934x_cpupll_to_hz(cpu);
+       ddrpll = ar934x_ddrpll_to_hz(ddr);
+
+       if (ctrl & AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
+               cpuclk = ar934x_get_xtal();
+       else if (ctrl & AR934X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
+               cpuclk = cpupll;
+       else
+               cpuclk = ddrpll;
+
+       if (ctrl & AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
+               ddrclk = ar934x_get_xtal();
+       else if (ctrl & AR934X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
+               ddrclk = ddrpll;
+       else
+               ddrclk = cpupll;
+
+       if (ctrl & AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
+               busclk = ar934x_get_xtal();
+       else if (ctrl & AR934X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
+               busclk = ddrpll;
+       else
+               busclk = cpupll;
+
+       cpudiv = (ctrl >> AR934X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
+                AR934X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
+       ddrdiv = (ctrl >> AR934X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
+                AR934X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
+       busdiv = (ctrl >> AR934X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
+                AR934X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
+
+       gd->cpu_clk = cpuclk / (cpudiv + 1);
+       gd->mem_clk = ddrclk / (ddrdiv + 1);
+       gd->bus_clk = busclk / (busdiv + 1);
+}
+
+ulong get_bus_freq(ulong dummy)
+{
+       ar934x_update_clock();
+       return gd->bus_clk;
+}
+
+ulong get_ddr_freq(ulong dummy)
+{
+       ar934x_update_clock();
+       return gd->mem_clk;
+}
+
+int do_ar934x_showclk(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       ar934x_update_clock();
+       printf("CPU:       %8ld MHz\n", gd->cpu_clk / 1000000);
+       printf("Memory:    %8ld MHz\n", gd->mem_clk / 1000000);
+       printf("AHB:       %8ld MHz\n", gd->bus_clk / 1000000);
+       return 0;
+}
+
+U_BOOT_CMD(
+       clocks, CONFIG_SYS_MAXARGS, 1, do_ar934x_showclk,
+       "display clocks",
+       ""
+);
diff --git a/arch/mips/mach-ath79/ar934x/cpu.c b/arch/mips/mach-ath79/ar934x/cpu.c
new file mode 100644 (file)
index 0000000..8fcdf65
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2016 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+
+/* The lowlevel_init() is not needed on AR934x */
+void lowlevel_init(void) {}
diff --git a/arch/mips/mach-ath79/ar934x/ddr.c b/arch/mips/mach-ath79/ar934x/ddr.c
new file mode 100644 (file)
index 0000000..4621d58
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2016 Marek Vasut <marex@denx.de>
+ *
+ * Based on RAM init sequence by Piotr Dymacz <pepe2k@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/reset.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+       AR934X_SDRAM = 0,
+       AR934X_DDR1,
+       AR934X_DDR2,
+};
+
+struct ar934x_mem_config {
+       u32     config1;
+       u32     config2;
+       u32     mode;
+       u32     extmode;
+       u32     tap;
+};
+
+static const struct ar934x_mem_config ar934x_mem_config[] = {
+       [AR934X_SDRAM] = { 0x7fbe8cd0, 0x959f66a8, 0x33, 0, 0x1f1f },
+       [AR934X_DDR1]  = { 0x7fd48cd0, 0x99d0e6a8, 0x33, 0, 0x14 },
+       [AR934X_DDR2]  = { 0xc7d48cd0, 0x9dd0e6a8, 0x33, 0, 0x10012 },
+};
+
+void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz)
+{
+       void __iomem *ddr_regs;
+       const struct ar934x_mem_config *memcfg;
+       int memtype;
+       u32 reg, cycle, ctl;
+
+       ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
+                              MAP_NOCACHE);
+
+       reg = get_bootstrap();
+       if (reg & AR934X_BOOTSTRAP_SDRAM_DISABLED) {    /* DDR */
+               if (reg & AR934X_BOOTSTRAP_DDR1) {      /* DDR 1 */
+                       memtype = AR934X_DDR1;
+                       cycle = 0xffff;
+               } else {                                /* DDR 2 */
+                       memtype = AR934X_DDR2;
+                       if (gd->arch.rev) {
+                               ctl = BIT(6);   /* Undocumented bit :-( */
+                               if (reg & BIT(3))
+                                       cycle = 0xff;
+                               else
+                                       cycle = 0xffff;
+                       } else {
+                               /* Force DDR2/x16 configuratio on old chips. */
+                               ctl = 0;
+                               cycle = 0xffff;         /* DDR2 16bit */
+                       }
+
+                       writel(0xe59, ddr_regs + AR934X_DDR_REG_DDR2_CONFIG);
+                       udelay(100);
+
+                       writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL);
+                       udelay(10);
+
+                       writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL);
+                       udelay(10);
+
+                       writel(ctl, ddr_regs + AR934X_DDR_REG_CTL_CONF);
+                       udelay(10);
+               }
+       } else {                                        /* SDRAM */
+               memtype = AR934X_SDRAM;
+               cycle = 0xffffffff;
+
+               writel(0x13b, ddr_regs + AR934X_DDR_REG_CTL_CONF);
+               udelay(100);
+
+               /* Undocumented register */
+               writel(0x13b, ddr_regs + 0x118);
+               udelay(100);
+       }
+
+       memcfg = &ar934x_mem_config[memtype];
+
+       writel(memcfg->config1, ddr_regs + AR71XX_DDR_REG_CONFIG);
+       udelay(100);
+
+       writel(memcfg->config2, ddr_regs + AR71XX_DDR_REG_CONFIG2);
+       udelay(100);
+
+       writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL);
+       udelay(10);
+
+       writel(memcfg->mode | 0x100, ddr_regs + AR71XX_DDR_REG_MODE);
+       mdelay(1);
+
+       writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL);
+       udelay(10);
+
+       if (memtype == AR934X_DDR2) {
+               writel(memcfg->mode | 0x100, ddr_regs + AR71XX_DDR_REG_EMR);
+               udelay(100);
+
+               writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL);
+               udelay(10);
+       }
+
+       if (memtype != AR934X_SDRAM)
+               writel(0x402, ddr_regs + AR71XX_DDR_REG_EMR);
+
+       udelay(100);
+
+       writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL);
+       udelay(10);
+
+       writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL);
+       udelay(10);
+
+       writel(memcfg->mode, ddr_regs + AR71XX_DDR_REG_MODE);
+       udelay(100);
+
+       writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL);
+       udelay(10);
+
+       writel(0x412c /* FIXME */, ddr_regs + AR71XX_DDR_REG_REFRESH);
+       udelay(100);
+
+       writel(memcfg->tap, ddr_regs + AR71XX_DDR_REG_TAP_CTRL0);
+       writel(memcfg->tap, ddr_regs + AR71XX_DDR_REG_TAP_CTRL1);
+
+       if (memtype != AR934X_SDRAM) {
+               if ((gd->arch.rev && (reg & BIT(3))) || !gd->arch.rev) {
+                       writel(memcfg->tap,
+                              ddr_regs + AR934X_DDR_REG_TAP_CTRL2);
+                       writel(memcfg->tap,
+                              ddr_regs + AR934X_DDR_REG_TAP_CTRL3);
+               }
+       }
+
+       writel(cycle, ddr_regs + AR71XX_DDR_REG_RD_CYCLE);
+       udelay(100);
+
+       writel(0x74444444, ddr_regs + AR934X_DDR_REG_BURST);
+       udelay(100);
+
+       writel(0x222, ddr_regs + AR934X_DDR_REG_BURST2);
+       udelay(100);
+
+       writel(0xfffff, ddr_regs + AR934X_DDR_REG_TIMEOUT_MAX);
+       udelay(100);
+}
+
+void ddr_tap_tuning(void)
+{
+}
diff --git a/arch/mips/mach-ath79/cpu.c b/arch/mips/mach-ath79/cpu.c
new file mode 100644 (file)
index 0000000..5756a06
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ath79.h>
+#include <mach/ar71xx_regs.h>
+
+struct ath79_soc_desc {
+       const enum ath79_soc_type soc;
+       const char *chip;
+       const int major;
+       const int minor;
+};
+
+static const struct ath79_soc_desc desc[] = {
+       {ATH79_SOC_AR7130,      "7130",
+        REV_ID_MAJOR_AR71XX,   AR71XX_REV_ID_MINOR_AR7130},
+       {ATH79_SOC_AR7141,      "7141",
+        REV_ID_MAJOR_AR71XX,   AR71XX_REV_ID_MINOR_AR7141},
+       {ATH79_SOC_AR7161,      "7161",
+        REV_ID_MAJOR_AR71XX,   AR71XX_REV_ID_MINOR_AR7161},
+       {ATH79_SOC_AR7240,      "7240", REV_ID_MAJOR_AR7240,    0},
+       {ATH79_SOC_AR7241,      "7241", REV_ID_MAJOR_AR7241,    0},
+       {ATH79_SOC_AR7242,      "7242", REV_ID_MAJOR_AR7242,    0},
+       {ATH79_SOC_AR9130,      "9130",
+        REV_ID_MAJOR_AR913X,   AR913X_REV_ID_MINOR_AR9130},
+       {ATH79_SOC_AR9132,      "9132",
+        REV_ID_MAJOR_AR913X,   AR913X_REV_ID_MINOR_AR9132},
+       {ATH79_SOC_AR9330,      "9330", REV_ID_MAJOR_AR9330,    0},
+       {ATH79_SOC_AR9331,      "9331", REV_ID_MAJOR_AR9331,    0},
+       {ATH79_SOC_AR9341,      "9341", REV_ID_MAJOR_AR9341,    0},
+       {ATH79_SOC_AR9342,      "9342", REV_ID_MAJOR_AR9342,    0},
+       {ATH79_SOC_AR9344,      "9344", REV_ID_MAJOR_AR9344,    0},
+       {ATH79_SOC_QCA9533,     "9533", REV_ID_MAJOR_QCA9533,   0},
+       {ATH79_SOC_QCA9533,     "9533",
+        REV_ID_MAJOR_QCA9533_V2,       0},
+       {ATH79_SOC_QCA9556,     "9556", REV_ID_MAJOR_QCA9556,   0},
+       {ATH79_SOC_QCA9558,     "9558", REV_ID_MAJOR_QCA9558,   0},
+       {ATH79_SOC_TP9343,      "9343", REV_ID_MAJOR_TP9343,    0},
+       {ATH79_SOC_QCA9561,     "9561", REV_ID_MAJOR_QCA9561,   0},
+};
+
+int arch_cpu_init(void)
+{
+       void __iomem *base;
+       enum ath79_soc_type soc = ATH79_SOC_UNKNOWN;
+       u32 id, major, minor = 0;
+       u32 rev = 0, ver = 1;
+       int i;
+
+       base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+                          MAP_NOCACHE);
+
+       id = readl(base + AR71XX_RESET_REG_REV_ID);
+       major = id & REV_ID_MAJOR_MASK;
+       switch (major) {
+       case REV_ID_MAJOR_AR71XX:
+       case REV_ID_MAJOR_AR913X:
+               minor = id & AR71XX_REV_ID_MINOR_MASK;
+               rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
+               rev &= AR71XX_REV_ID_REVISION_MASK;
+               break;
+
+       case REV_ID_MAJOR_QCA9533_V2:
+               ver = 2;
+               /* drop through */
+
+       case REV_ID_MAJOR_AR9341:
+       case REV_ID_MAJOR_AR9342:
+       case REV_ID_MAJOR_AR9344:
+       case REV_ID_MAJOR_QCA9533:
+       case REV_ID_MAJOR_QCA9556:
+       case REV_ID_MAJOR_QCA9558:
+       case REV_ID_MAJOR_TP9343:
+       case REV_ID_MAJOR_QCA9561:
+               rev = id & AR71XX_REV_ID_REVISION2_MASK;
+               break;
+       default:
+               rev = id & AR71XX_REV_ID_REVISION_MASK;
+               break;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(desc); i++) {
+               if ((desc[i].major == major) &&
+                   (desc[i].minor == minor)) {
+                       soc = desc[i].soc;
+                       break;
+               }
+       }
+
+       gd->arch.id = id;
+       gd->arch.soc = soc;
+       gd->arch.rev = rev;
+       gd->arch.ver = ver;
+       return 0;
+}
+
+int print_cpuinfo(void)
+{
+       enum ath79_soc_type soc = ATH79_SOC_UNKNOWN;
+       const char *chip = "????";
+       u32 id, rev, ver;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(desc); i++) {
+               if (desc[i].soc == gd->arch.soc) {
+                       chip = desc[i].chip;
+                       soc = desc[i].soc;
+                       break;
+               }
+       }
+
+       id = gd->arch.id;
+       rev = gd->arch.rev;
+       ver = gd->arch.ver;
+
+       switch (soc) {
+       case ATH79_SOC_QCA9533:
+       case ATH79_SOC_QCA9556:
+       case ATH79_SOC_QCA9558:
+       case ATH79_SOC_QCA9561:
+               printf("Qualcomm Atheros QCA%s ver %u rev %u\n", chip,
+                      ver, rev);
+               break;
+       case ATH79_SOC_TP9343:
+               printf("Qualcomm Atheros TP%s rev %u\n", chip, rev);
+               break;
+       case ATH79_SOC_UNKNOWN:
+               printf("ATH79: unknown SoC, id:0x%08x", id);
+               break;
+       default:
+               printf("Atheros AR%s rev %u\n", chip, rev);
+       }
+
+       return 0;
+}
diff --git a/arch/mips/mach-ath79/dram.c b/arch/mips/mach-ath79/dram.c
new file mode 100644 (file)
index 0000000..c29e98c
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/sizes.h>
+#include <asm/addrspace.h>
+#include <mach/ddr.h>
+
+phys_size_t initdram(int board_type)
+{
+       ddr_tap_tuning();
+       return get_ram_size((void *)KSEG1, SZ_256M);
+}
diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
new file mode 100644 (file)
index 0000000..a8e51cb
--- /dev/null
@@ -0,0 +1,1263 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SoC register definitions
+ *
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_MACH_AR71XX_REGS_H
+#define __ASM_MACH_AR71XX_REGS_H
+
+#ifndef __ASSEMBLY__
+#include <linux/bitops.h>
+#else
+#ifndef BIT
+#define BIT(nr)                (1 << (nr))
+#endif
+#endif
+
+#define AR71XX_APB_BASE                                        0x18000000
+#define AR71XX_GE0_BASE                                        0x19000000
+#define AR71XX_GE0_SIZE                                        0x10000
+#define AR71XX_GE1_BASE                                        0x1a000000
+#define AR71XX_GE1_SIZE                                        0x10000
+#define AR71XX_EHCI_BASE                               0x1b000000
+#define AR71XX_EHCI_SIZE                               0x1000
+#define AR71XX_OHCI_BASE                               0x1c000000
+#define AR71XX_OHCI_SIZE                               0x1000
+#define AR71XX_SPI_BASE                                        0x1f000000
+#define AR71XX_SPI_SIZE                                        0x01000000
+
+#define AR71XX_DDR_CTRL_BASE \
+       (AR71XX_APB_BASE + 0x00000000)
+#define AR71XX_DDR_CTRL_SIZE                           0x100
+#define AR71XX_UART_BASE \
+       (AR71XX_APB_BASE + 0x00020000)
+#define AR71XX_UART_SIZE                               0x100
+#define AR71XX_USB_CTRL_BASE \
+       (AR71XX_APB_BASE + 0x00030000)
+#define AR71XX_USB_CTRL_SIZE                           0x100
+#define AR71XX_GPIO_BASE \
+       (AR71XX_APB_BASE + 0x00040000)
+#define AR71XX_GPIO_SIZE                               0x100
+#define AR71XX_PLL_BASE \
+       (AR71XX_APB_BASE + 0x00050000)
+#define AR71XX_PLL_SIZE                                        0x100
+#define AR71XX_RESET_BASE \
+       (AR71XX_APB_BASE + 0x00060000)
+#define AR71XX_RESET_SIZE                              0x100
+#define AR71XX_MII_BASE \
+       (AR71XX_APB_BASE + 0x00070000)
+#define AR71XX_MII_SIZE                                        0x100
+
+#define AR71XX_PCI_MEM_BASE                            0x10000000
+#define AR71XX_PCI_MEM_SIZE                            0x07000000
+
+#define AR71XX_PCI_WIN0_OFFS                           0x10000000
+#define AR71XX_PCI_WIN1_OFFS                           0x11000000
+#define AR71XX_PCI_WIN2_OFFS                           0x12000000
+#define AR71XX_PCI_WIN3_OFFS                           0x13000000
+#define AR71XX_PCI_WIN4_OFFS                           0x14000000
+#define AR71XX_PCI_WIN5_OFFS                           0x15000000
+#define AR71XX_PCI_WIN6_OFFS                           0x16000000
+#define AR71XX_PCI_WIN7_OFFS                           0x07000000
+
+#define AR71XX_PCI_CFG_BASE \
+       (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000)
+#define AR71XX_PCI_CFG_SIZE                            0x100
+
+#define AR7240_USB_CTRL_BASE \
+       (AR71XX_APB_BASE + 0x00030000)
+#define AR7240_USB_CTRL_SIZE                           0x100
+#define AR7240_OHCI_BASE                               0x1b000000
+#define AR7240_OHCI_SIZE                               0x1000
+
+#define AR724X_PCI_MEM_BASE                            0x10000000
+#define AR724X_PCI_MEM_SIZE                            0x04000000
+
+#define AR724X_PCI_CFG_BASE                            0x14000000
+#define AR724X_PCI_CFG_SIZE                            0x1000
+#define AR724X_PCI_CRP_BASE \
+       (AR71XX_APB_BASE + 0x000c0000)
+#define AR724X_PCI_CRP_SIZE                            0x1000
+#define AR724X_PCI_CTRL_BASE \
+       (AR71XX_APB_BASE + 0x000f0000)
+#define AR724X_PCI_CTRL_SIZE                           0x100
+
+#define AR724X_EHCI_BASE                               0x1b000000
+#define AR724X_EHCI_SIZE                               0x1000
+
+#define AR913X_EHCI_BASE                               0x1b000000
+#define AR913X_EHCI_SIZE                               0x1000
+#define AR913X_WMAC_BASE \
+       (AR71XX_APB_BASE + 0x000C0000)
+#define AR913X_WMAC_SIZE                               0x30000
+
+#define AR933X_UART_BASE \
+       (AR71XX_APB_BASE + 0x00020000)
+#define AR933X_UART_SIZE                               0x14
+#define AR933X_GMAC_BASE \
+       (AR71XX_APB_BASE + 0x00070000)
+#define AR933X_GMAC_SIZE                               0x04
+#define AR933X_WMAC_BASE \
+       (AR71XX_APB_BASE + 0x00100000)
+#define AR933X_WMAC_SIZE                               0x20000
+#define AR933X_RTC_BASE \
+       (AR71XX_APB_BASE + 0x00107000)
+#define AR933X_RTC_SIZE                                        0x1000
+#define AR933X_EHCI_BASE                               0x1b000000
+#define AR933X_EHCI_SIZE                               0x1000
+#define AR933X_SRIF_BASE \
+       (AR71XX_APB_BASE + 0x00116000)
+#define AR933X_SRIF_SIZE                               0x1000
+
+#define AR934X_GMAC_BASE \
+       (AR71XX_APB_BASE + 0x00070000)
+#define AR934X_GMAC_SIZE                               0x14
+#define AR934X_WMAC_BASE \
+       (AR71XX_APB_BASE + 0x00100000)
+#define AR934X_WMAC_SIZE                               0x20000
+#define AR934X_EHCI_BASE                               0x1b000000
+#define AR934X_EHCI_SIZE                               0x200
+#define AR934X_NFC_BASE                                        0x1b000200
+#define AR934X_NFC_SIZE                                        0xb8
+#define AR934X_SRIF_BASE \
+       (AR71XX_APB_BASE + 0x00116000)
+#define AR934X_SRIF_SIZE                               0x1000
+
+#define QCA953X_GMAC_BASE \
+       (AR71XX_APB_BASE + 0x00070000)
+#define QCA953X_GMAC_SIZE                              0x14
+#define QCA953X_WMAC_BASE \
+       (AR71XX_APB_BASE + 0x00100000)
+#define QCA953X_WMAC_SIZE                              0x20000
+#define QCA953X_RTC_BASE \
+       (AR71XX_APB_BASE + 0x00107000)
+#define QCA953X_RTC_SIZE                               0x1000
+#define QCA953X_EHCI_BASE                              0x1b000000
+#define QCA953X_EHCI_SIZE                              0x200
+#define QCA953X_SRIF_BASE \
+       (AR71XX_APB_BASE + 0x00116000)
+#define QCA953X_SRIF_SIZE                              0x1000
+
+#define QCA953X_PCI_CFG_BASE0                          0x14000000
+#define QCA953X_PCI_CTRL_BASE0 \
+       (AR71XX_APB_BASE + 0x000f0000)
+#define QCA953X_PCI_CRP_BASE0 \
+       (AR71XX_APB_BASE + 0x000c0000)
+#define QCA953X_PCI_MEM_BASE0                          0x10000000
+#define QCA953X_PCI_MEM_SIZE                           0x02000000
+
+#define QCA955X_PCI_MEM_BASE0                          0x10000000
+#define QCA955X_PCI_MEM_BASE1                          0x12000000
+#define QCA955X_PCI_MEM_SIZE                           0x02000000
+#define QCA955X_PCI_CFG_BASE0                          0x14000000
+#define QCA955X_PCI_CFG_BASE1                          0x16000000
+#define QCA955X_PCI_CFG_SIZE                           0x1000
+#define QCA955X_PCI_CRP_BASE0 \
+       (AR71XX_APB_BASE + 0x000c0000)
+#define QCA955X_PCI_CRP_BASE1 \
+       (AR71XX_APB_BASE + 0x00250000)
+#define QCA955X_PCI_CRP_SIZE                           0x1000
+#define QCA955X_PCI_CTRL_BASE0 \
+       (AR71XX_APB_BASE + 0x000f0000)
+#define QCA955X_PCI_CTRL_BASE1 \
+       (AR71XX_APB_BASE + 0x00280000)
+#define QCA955X_PCI_CTRL_SIZE                          0x100
+
+#define QCA955X_GMAC_BASE \
+       (AR71XX_APB_BASE + 0x00070000)
+#define QCA955X_GMAC_SIZE                              0x40
+#define QCA955X_WMAC_BASE \
+       (AR71XX_APB_BASE + 0x00100000)
+#define QCA955X_WMAC_SIZE                              0x20000
+#define QCA955X_EHCI0_BASE                             0x1b000000
+#define QCA955X_EHCI1_BASE                             0x1b400000
+#define QCA955X_EHCI_SIZE                              0x1000
+#define QCA955X_NFC_BASE                               0x1b800200
+#define QCA955X_NFC_SIZE                               0xb8
+
+#define QCA956X_PCI_MEM_BASE1                          0x12000000
+#define QCA956X_PCI_MEM_SIZE                           0x02000000
+#define QCA956X_PCI_CFG_BASE1                          0x16000000
+#define QCA956X_PCI_CFG_SIZE                           0x1000
+#define QCA956X_PCI_CRP_BASE1 \
+       (AR71XX_APB_BASE + 0x00250000)
+#define QCA956X_PCI_CRP_SIZE                           0x1000
+#define QCA956X_PCI_CTRL_BASE1 \
+       (AR71XX_APB_BASE + 0x00280000)
+#define QCA956X_PCI_CTRL_SIZE                          0x100
+
+#define QCA956X_WMAC_BASE \
+       (AR71XX_APB_BASE + 0x00100000)
+#define QCA956X_WMAC_SIZE                              0x20000
+#define QCA956X_EHCI0_BASE                             0x1b000000
+#define QCA956X_EHCI1_BASE                             0x1b400000
+#define QCA956X_EHCI_SIZE                              0x200
+#define QCA956X_GMAC_BASE \
+       (AR71XX_APB_BASE + 0x00070000)
+#define QCA956X_GMAC_SIZE                              0x64
+
+/*
+ * DDR_CTRL block
+ */
+#define AR71XX_DDR_REG_CONFIG                          0x00
+#define AR71XX_DDR_REG_CONFIG2                         0x04
+#define AR71XX_DDR_REG_MODE                            0x08
+#define AR71XX_DDR_REG_EMR                             0x0c
+#define AR71XX_DDR_REG_CONTROL                         0x10
+#define AR71XX_DDR_REG_REFRESH                         0x14
+#define AR71XX_DDR_REG_RD_CYCLE                                0x18
+#define AR71XX_DDR_REG_TAP_CTRL0                       0x1c
+#define AR71XX_DDR_REG_TAP_CTRL1                       0x20
+
+#define AR71XX_DDR_REG_PCI_WIN0                                0x7c
+#define AR71XX_DDR_REG_PCI_WIN1                                0x80
+#define AR71XX_DDR_REG_PCI_WIN2                                0x84
+#define AR71XX_DDR_REG_PCI_WIN3                                0x88
+#define AR71XX_DDR_REG_PCI_WIN4                                0x8c
+#define AR71XX_DDR_REG_PCI_WIN5                                0x90
+#define AR71XX_DDR_REG_PCI_WIN6                                0x94
+#define AR71XX_DDR_REG_PCI_WIN7                                0x98
+#define AR71XX_DDR_REG_FLUSH_GE0                       0x9c
+#define AR71XX_DDR_REG_FLUSH_GE1                       0xa0
+#define AR71XX_DDR_REG_FLUSH_USB                       0xa4
+#define AR71XX_DDR_REG_FLUSH_PCI                       0xa8
+
+#define AR724X_DDR_REG_FLUSH_GE0                       0x7c
+#define AR724X_DDR_REG_FLUSH_GE1                       0x80
+#define AR724X_DDR_REG_FLUSH_USB                       0x84
+#define AR724X_DDR_REG_FLUSH_PCIE                      0x88
+
+#define AR913X_DDR_REG_FLUSH_GE0                       0x7c
+#define AR913X_DDR_REG_FLUSH_GE1                       0x80
+#define AR913X_DDR_REG_FLUSH_USB                       0x84
+#define AR913X_DDR_REG_FLUSH_WMAC                      0x88
+
+#define AR933X_DDR_REG_FLUSH_GE0                       0x7c
+#define AR933X_DDR_REG_FLUSH_GE1                       0x80
+#define AR933X_DDR_REG_FLUSH_USB                       0x84
+#define AR933X_DDR_REG_FLUSH_WMAC                      0x88
+#define AR933X_DDR_REG_DDR2_CONFIG                     0x8c
+#define AR933X_DDR_REG_EMR2                            0x90
+#define AR933X_DDR_REG_EMR3                            0x94
+#define AR933X_DDR_REG_BURST                           0x98
+#define AR933X_DDR_REG_TIMEOUT_MAX                     0x9c
+#define AR933X_DDR_REG_TIMEOUT_CNT                     0x9c
+#define AR933X_DDR_REG_TIMEOUT_ADDR                    0x9c
+
+#define AR934X_DDR_REG_TAP_CTRL2                       0x24
+#define AR934X_DDR_REG_TAP_CTRL3                       0x28
+#define AR934X_DDR_REG_FLUSH_GE0                       0x9c
+#define AR934X_DDR_REG_FLUSH_GE1                       0xa0
+#define AR934X_DDR_REG_FLUSH_USB                       0xa4
+#define AR934X_DDR_REG_FLUSH_PCIE                      0xa8
+#define AR934X_DDR_REG_FLUSH_WMAC                      0xac
+#define AR934X_DDR_REG_FLUSH_SRC1                      0xb0
+#define AR934X_DDR_REG_FLUSH_SRC2                      0xb4
+#define AR934X_DDR_REG_DDR2_CONFIG                     0xb8
+#define AR934X_DDR_REG_EMR2                            0xbc
+#define AR934X_DDR_REG_EMR3                            0xc0
+#define AR934X_DDR_REG_BURST                           0xc4
+#define AR934X_DDR_REG_BURST2                          0xc8
+#define AR934X_DDR_REG_TIMEOUT_MAX                     0xcc
+#define AR934X_DDR_REG_CTL_CONF                                0x108
+
+#define QCA953X_DDR_REG_FLUSH_GE0                      0x9c
+#define QCA953X_DDR_REG_FLUSH_GE1                      0xa0
+#define QCA953X_DDR_REG_FLUSH_USB                      0xa4
+#define QCA953X_DDR_REG_FLUSH_PCIE                     0xa8
+#define QCA953X_DDR_REG_FLUSH_WMAC                     0xac
+#define QCA953X_DDR_REG_DDR2_CONFIG                    0xb8
+#define QCA953X_DDR_REG_BURST                          0xc4
+#define QCA953X_DDR_REG_BURST2                         0xc8
+#define QCA953X_DDR_REG_TIMEOUT_MAX                    0xcc
+#define QCA953X_DDR_REG_CTL_CONF                       0x108
+#define QCA953X_DDR_REG_CONFIG3                                0x15c
+
+/*
+ * PLL block
+ */
+#define AR71XX_PLL_REG_CPU_CONFIG                      0x00
+#define AR71XX_PLL_REG_SEC_CONFIG                      0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK                  0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK                  0x14
+
+#define AR71XX_PLL_DIV_SHIFT                           3
+#define AR71XX_PLL_DIV_MASK                            0x1f
+#define AR71XX_CPU_DIV_SHIFT                           16
+#define AR71XX_CPU_DIV_MASK                            0x3
+#define AR71XX_DDR_DIV_SHIFT                           18
+#define AR71XX_DDR_DIV_MASK                            0x3
+#define AR71XX_AHB_DIV_SHIFT                           20
+#define AR71XX_AHB_DIV_MASK                            0x7
+
+#define AR71XX_ETH0_PLL_SHIFT                          17
+#define AR71XX_ETH1_PLL_SHIFT                          19
+
+#define AR724X_PLL_REG_CPU_CONFIG                      0x00
+#define AR724X_PLL_REG_PCIE_CONFIG                     0x18
+
+#define AR724X_PLL_DIV_SHIFT                           0
+#define AR724X_PLL_DIV_MASK                            0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT                       10
+#define AR724X_PLL_REF_DIV_MASK                                0xf
+#define AR724X_AHB_DIV_SHIFT                           19
+#define AR724X_AHB_DIV_MASK                            0x1
+#define AR724X_DDR_DIV_SHIFT                           22
+#define AR724X_DDR_DIV_MASK                            0x3
+
+#define AR7242_PLL_REG_ETH0_INT_CLOCK                  0x2c
+
+#define AR913X_PLL_REG_CPU_CONFIG                      0x00
+#define AR913X_PLL_REG_ETH_CONFIG                      0x04
+#define AR913X_PLL_REG_ETH0_INT_CLOCK                  0x14
+#define AR913X_PLL_REG_ETH1_INT_CLOCK                  0x18
+
+#define AR913X_PLL_DIV_SHIFT                           0
+#define AR913X_PLL_DIV_MASK                            0x3ff
+#define AR913X_DDR_DIV_SHIFT                           22
+#define AR913X_DDR_DIV_MASK                            0x3
+#define AR913X_AHB_DIV_SHIFT                           19
+#define AR913X_AHB_DIV_MASK                            0x1
+
+#define AR913X_ETH0_PLL_SHIFT                          20
+#define AR913X_ETH1_PLL_SHIFT                          22
+
+#define AR933X_PLL_CPU_CONFIG_REG                      0x00
+#define AR933X_PLL_CLK_CTRL_REG                                0x08
+#define AR933X_PLL_DITHER_FRAC_REG                     0x10
+
+#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT               10
+#define AR933X_PLL_CPU_CONFIG_NINT_MASK                        0x3f
+#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT             16
+#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK              0x1f
+#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT             23
+#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK              0x7
+
+#define AR933X_PLL_CLK_CTRL_BYPASS                     BIT(2)
+#define AR933X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT         5
+#define AR933X_PLL_CLK_CTRL_CPU_POST_DIV_MASK          0x3
+#define AR933X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT         10
+#define AR933X_PLL_CLK_CTRL_DDR_POST_DIV_MASK          0x3
+#define AR933X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT         15
+#define AR933X_PLL_CLK_CTRL_AHB_POST_DIV_MASK          0x7
+
+#define AR934X_PLL_CPU_CONFIG_REG                      0x00
+#define AR934X_PLL_DDR_CONFIG_REG                      0x04
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG                        0x08
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_REG            0x24
+#define AR934X_PLL_ETH_XMII_CONTROL_REG                        0x2c
+#define AR934X_PLL_DDR_DIT_FRAC_REG                    0x44
+#define AR934X_PLL_CPU_DIT_FRAC_REG                    0x48
+
+#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT              0
+#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK               0x3f
+#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT               6
+#define AR934X_PLL_CPU_CONFIG_NINT_MASK                        0x3f
+#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT             12
+#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK              0x1f
+#define AR934X_PLL_CPU_CONFIG_RANGE_SHIFT              17
+#define AR934X_PLL_CPU_CONFIG_RANGE_MASK               0x3
+#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT             19
+#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK              0x3
+#define AR934X_PLL_CPU_CONFIG_PLLPWD                   BIT(30)
+#define AR934X_PLL_CPU_CONFIG_UPDATING                 BIT(31)
+
+#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT              0
+#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK               0x3ff
+#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT               10
+#define AR934X_PLL_DDR_CONFIG_NINT_MASK                        0x3f
+#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT             16
+#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK              0x1f
+#define AR934X_PLL_DDR_CONFIG_RANGE_SHIFT              21
+#define AR934X_PLL_DDR_CONFIG_RANGE_MASK               0x3
+#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT             23
+#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK              0x7
+#define AR934X_PLL_DDR_CONFIG_PLLPWD                   BIT(30)
+#define AR934X_PLL_DDR_CONFIG_UPDATING                 BIT(31)
+
+#define AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS             BIT(2)
+#define AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS             BIT(3)
+#define AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS             BIT(4)
+#define AR934X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT         5
+#define AR934X_PLL_CLK_CTRL_CPU_POST_DIV_MASK          0x1f
+#define AR934X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT         10
+#define AR934X_PLL_CLK_CTRL_DDR_POST_DIV_MASK          0x1f
+#define AR934X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT         15
+#define AR934X_PLL_CLK_CTRL_AHB_POST_DIV_MASK          0x1f
+#define AR934X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL         BIT(20)
+#define AR934X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL         BIT(21)
+#define AR934X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL         BIT(24)
+
+#define AR934X_PLL_SWITCH_CLK_CTRL_MDIO_CLK_SEL                BIT(6)
+
+#define AR934X_PLL_DDR_DIT_FRAC_MAX_SHIFT              0
+#define AR934X_PLL_DDR_DIT_FRAC_MAX_MASK               0x3ff
+#define AR934X_PLL_DDR_DIT_FRAC_MIN_SHIFT              10
+#define AR934X_PLL_DDR_DIT_FRAC_MIN_MASK               0x3ff
+#define AR934X_PLL_DDR_DIT_FRAC_STEP_SHIFT             20
+#define AR934X_PLL_DDR_DIT_FRAC_STEP_MASK              0x3f
+#define AR934X_PLL_DDR_DIT_UPD_CNT_SHIFT               27
+#define AR934X_PLL_DDR_DIT_UPD_CNT_MASK                        0x3f
+#define AR934X_PLL_DDR_DIT_DITHER_EN                   BIT(31)
+
+#define AR934X_PLL_CPU_DIT_FRAC_MAX_SHIFT              0
+#define AR934X_PLL_CPU_DIT_FRAC_MAX_MASK               0x3f
+#define AR934X_PLL_CPU_DIT_FRAC_MIN_SHIFT              6
+#define AR934X_PLL_CPU_DIT_FRAC_MIN_MASK               0x3f
+#define AR934X_PLL_CPU_DIT_FRAC_STEP_SHIFT             12
+#define AR934X_PLL_CPU_DIT_FRAC_STEP_MASK              0x3f
+#define AR934X_PLL_CPU_DIT_UPD_CNT_SHIFT               18
+#define AR934X_PLL_CPU_DIT_UPD_CNT_MASK                        0x3f
+#define AR934X_PLL_CPU_DIT_DITHER_EN                   BIT(31)
+
+#define QCA953X_PLL_CPU_CONFIG_REG                     0x00
+#define QCA953X_PLL_DDR_CONFIG_REG                     0x04
+#define QCA953X_PLL_CLK_CTRL_REG                       0x08
+#define QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG           0x24
+#define QCA953X_PLL_ETH_XMII_CONTROL_REG               0x2c
+#define QCA953X_PLL_DDR_DIT_FRAC_REG                   0x44
+#define QCA953X_PLL_CPU_DIT_FRAC_REG                   0x48
+
+#define QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT             0
+#define QCA953X_PLL_CPU_CONFIG_NFRAC_MASK              0x3f
+#define QCA953X_PLL_CPU_CONFIG_NINT_SHIFT              6
+#define QCA953X_PLL_CPU_CONFIG_NINT_MASK               0x3f
+#define QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT            12
+#define QCA953X_PLL_CPU_CONFIG_REFDIV_MASK             0x1f
+#define QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT            19
+#define QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK             0x7
+
+#define QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT             0
+#define QCA953X_PLL_DDR_CONFIG_NFRAC_MASK              0x3ff
+#define QCA953X_PLL_DDR_CONFIG_NINT_SHIFT              10
+#define QCA953X_PLL_DDR_CONFIG_NINT_MASK               0x3f
+#define QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT            16
+#define QCA953X_PLL_DDR_CONFIG_REFDIV_MASK             0x1f
+#define QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT            23
+#define QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK             0x7
+
+#define QCA953X_PLL_CONFIG_PWD         BIT(30)
+
+#define QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS            BIT(2)
+#define QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS            BIT(3)
+#define QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS            BIT(4)
+#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT                5
+#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK         0x1f
+#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT                10
+#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK         0x1f
+#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT                15
+#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK         0x1f
+#define QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL                BIT(20)
+#define QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL                BIT(21)
+#define QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL                BIT(24)
+
+#define QCA953X_PLL_CPU_DIT_FRAC_MAX_SHIFT             0
+#define QCA953X_PLL_CPU_DIT_FRAC_MAX_MASK              0x3f
+#define QCA953X_PLL_CPU_DIT_FRAC_MIN_SHIFT             6
+#define QCA953X_PLL_CPU_DIT_FRAC_MIN_MASK              0x3f
+#define QCA953X_PLL_CPU_DIT_FRAC_STEP_SHIFT            12
+#define QCA953X_PLL_CPU_DIT_FRAC_STEP_MASK             0x3f
+#define QCA953X_PLL_CPU_DIT_UPD_CNT_SHIFT              18
+#define QCA953X_PLL_CPU_DIT_UPD_CNT_MASK               0x3f
+
+#define QCA953X_PLL_DDR_DIT_FRAC_MAX_SHIFT             0
+#define QCA953X_PLL_DDR_DIT_FRAC_MAX_MASK              0x3ff
+#define QCA953X_PLL_DDR_DIT_FRAC_MIN_SHIFT             9
+#define QCA953X_PLL_DDR_DIT_FRAC_MIN_MASK              0x3ff
+#define QCA953X_PLL_DDR_DIT_FRAC_STEP_SHIFT            20
+#define QCA953X_PLL_DDR_DIT_FRAC_STEP_MASK             0x3f
+#define QCA953X_PLL_DDR_DIT_UPD_CNT_SHIFT              27
+#define QCA953X_PLL_DDR_DIT_UPD_CNT_MASK               0x3f
+
+#define QCA953X_PLL_DIT_FRAC_EN                                BIT(31)
+
+#define QCA955X_PLL_CPU_CONFIG_REG                     0x00
+#define QCA955X_PLL_DDR_CONFIG_REG                     0x04
+#define QCA955X_PLL_CLK_CTRL_REG                       0x08
+#define QCA955X_PLL_ETH_XMII_CONTROL_REG               0x28
+#define QCA955X_PLL_ETH_SGMII_CONTROL_REG              0x48
+
+#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT             0
+#define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK              0x3f
+#define QCA955X_PLL_CPU_CONFIG_NINT_SHIFT              6
+#define QCA955X_PLL_CPU_CONFIG_NINT_MASK               0x3f
+#define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT            12
+#define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK             0x1f
+#define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT            19
+#define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK             0x3
+
+#define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT             0
+#define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK              0x3ff
+#define QCA955X_PLL_DDR_CONFIG_NINT_SHIFT              10
+#define QCA955X_PLL_DDR_CONFIG_NINT_MASK               0x3f
+#define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT            16
+#define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK             0x1f
+#define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT            23
+#define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK             0x7
+
+#define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS            BIT(2)
+#define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS            BIT(3)
+#define QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS            BIT(4)
+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT                5
+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK         0x1f
+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT                10
+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK         0x1f
+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT                15
+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK         0x1f
+#define QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL                BIT(20)
+#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL                BIT(21)
+#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL                BIT(24)
+
+#define QCA956X_PLL_CPU_CONFIG_REG                     0x00
+#define QCA956X_PLL_CPU_CONFIG1_REG                    0x04
+#define QCA956X_PLL_DDR_CONFIG_REG                     0x08
+#define QCA956X_PLL_DDR_CONFIG1_REG                    0x0c
+#define QCA956X_PLL_CLK_CTRL_REG                       0x10
+
+#define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT            12
+#define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK             0x1f
+#define QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT            19
+#define QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK             0x7
+
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT          0
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK           0x1f
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT          5
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK           0x3fff
+#define QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT             18
+#define QCA956X_PLL_CPU_CONFIG1_NINT_MASK              0x1ff
+
+#define QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT            16
+#define QCA956X_PLL_DDR_CONFIG_REFDIV_MASK             0x1f
+#define QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT            23
+#define QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK             0x7
+
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT          0
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK           0x1f
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT          5
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK           0x3fff
+#define QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT             18
+#define QCA956X_PLL_DDR_CONFIG1_NINT_MASK              0x1ff
+
+#define QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS            BIT(2)
+#define QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS            BIT(3)
+#define QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS            BIT(4)
+#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT                5
+#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK         0x1f
+#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT                10
+#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK         0x1f
+#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT                15
+#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK         0x1f
+#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL    BIT(20)
+#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL    BIT(21)
+#define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL                BIT(24)
+
+/*
+ * USB_CONFIG block
+ */
+#define AR71XX_USB_CTRL_REG_FLADJ                      0x00
+#define AR71XX_USB_CTRL_REG_CONFIG                     0x04
+
+/*
+ * RESET block
+ */
+#define AR71XX_RESET_REG_TIMER                         0x00
+#define AR71XX_RESET_REG_TIMER_RELOAD                  0x04
+#define AR71XX_RESET_REG_WDOG_CTRL                     0x08
+#define AR71XX_RESET_REG_WDOG                          0x0c
+#define AR71XX_RESET_REG_MISC_INT_STATUS               0x10
+#define AR71XX_RESET_REG_MISC_INT_ENABLE               0x14
+#define AR71XX_RESET_REG_PCI_INT_STATUS                        0x18
+#define AR71XX_RESET_REG_PCI_INT_ENABLE                        0x1c
+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS             0x20
+#define AR71XX_RESET_REG_RESET_MODULE                  0x24
+#define AR71XX_RESET_REG_PERFC_CTRL                    0x2c
+#define AR71XX_RESET_REG_PERFC0                                0x30
+#define AR71XX_RESET_REG_PERFC1                                0x34
+#define AR71XX_RESET_REG_REV_ID                                0x90
+
+#define AR913X_RESET_REG_GLOBAL_INT_STATUS             0x18
+#define AR913X_RESET_REG_RESET_MODULE                  0x1c
+#define AR913X_RESET_REG_PERF_CTRL                     0x20
+#define AR913X_RESET_REG_PERFC0                                0x24
+#define AR913X_RESET_REG_PERFC1                                0x28
+
+#define AR724X_RESET_REG_RESET_MODULE                  0x1c
+
+#define AR933X_RESET_REG_RESET_MODULE                  0x1c
+#define AR933X_RESET_REG_BOOTSTRAP                     0xac
+
+#define AR934X_RESET_REG_RESET_MODULE                  0x1c
+#define AR934X_RESET_REG_BOOTSTRAP                     0xb0
+#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS          0xac
+
+#define QCA953X_RESET_REG_RESET_MODULE                 0x1c
+#define QCA953X_RESET_REG_BOOTSTRAP                    0xb0
+#define QCA953X_RESET_REG_PCIE_WMAC_INT_STATUS         0xac
+
+#define QCA955X_RESET_REG_RESET_MODULE                 0x1c
+#define QCA955X_RESET_REG_BOOTSTRAP                    0xb0
+#define QCA955X_RESET_REG_EXT_INT_STATUS               0xac
+
+#define QCA956X_RESET_REG_RESET_MODULE                 0x1c
+#define QCA956X_RESET_REG_BOOTSTRAP                    0xb0
+#define QCA956X_RESET_REG_EXT_INT_STATUS               0xac
+
+#define MISC_INT_MIPS_SI_TIMERINT_MASK                 BIT(28)
+#define MISC_INT_ETHSW                                 BIT(12)
+#define MISC_INT_TIMER4                                        BIT(10)
+#define MISC_INT_TIMER3                                        BIT(9)
+#define MISC_INT_TIMER2                                        BIT(8)
+#define MISC_INT_DMA                                   BIT(7)
+#define MISC_INT_OHCI                                  BIT(6)
+#define MISC_INT_PERFC                                 BIT(5)
+#define MISC_INT_WDOG                                  BIT(4)
+#define MISC_INT_UART                                  BIT(3)
+#define MISC_INT_GPIO                                  BIT(2)
+#define MISC_INT_ERROR                                 BIT(1)
+#define MISC_INT_TIMER                                 BIT(0)
+
+#define AR71XX_RESET_EXTERNAL                          BIT(28)
+#define AR71XX_RESET_FULL_CHIP                         BIT(24)
+#define AR71XX_RESET_CPU_NMI                           BIT(21)
+#define AR71XX_RESET_CPU_COLD                          BIT(20)
+#define AR71XX_RESET_DMA                               BIT(19)
+#define AR71XX_RESET_SLIC                              BIT(18)
+#define AR71XX_RESET_STEREO                            BIT(17)
+#define AR71XX_RESET_DDR                               BIT(16)
+#define AR71XX_RESET_GE1_MAC                           BIT(13)
+#define AR71XX_RESET_GE1_PHY                           BIT(12)
+#define AR71XX_RESET_USBSUS_OVERRIDE                   BIT(10)
+#define AR71XX_RESET_GE0_MAC                           BIT(9)
+#define AR71XX_RESET_GE0_PHY                           BIT(8)
+#define AR71XX_RESET_USB_OHCI_DLL                      BIT(6)
+#define AR71XX_RESET_USB_HOST                          BIT(5)
+#define AR71XX_RESET_USB_PHY                           BIT(4)
+#define AR71XX_RESET_PCI_BUS                           BIT(1)
+#define AR71XX_RESET_PCI_CORE                          BIT(0)
+
+#define AR7240_RESET_USB_HOST                          BIT(5)
+#define AR7240_RESET_OHCI_DLL                          BIT(3)
+
+#define AR724X_RESET_GE1_MDIO                          BIT(23)
+#define AR724X_RESET_GE0_MDIO                          BIT(22)
+#define AR724X_RESET_PCIE_PHY_SERIAL                   BIT(10)
+#define AR724X_RESET_PCIE_PHY                          BIT(7)
+#define AR724X_RESET_PCIE                              BIT(6)
+#define AR724X_RESET_USB_HOST                          BIT(5)
+#define AR724X_RESET_USB_PHY                           BIT(4)
+#define AR724X_RESET_USBSUS_OVERRIDE                   BIT(3)
+
+#define AR913X_RESET_AMBA2WMAC                         BIT(22)
+#define AR913X_RESET_USBSUS_OVERRIDE                   BIT(10)
+#define AR913X_RESET_USB_HOST                          BIT(5)
+#define AR913X_RESET_USB_PHY                           BIT(4)
+
+#define AR933X_RESET_GE1_MDIO                          BIT(23)
+#define AR933X_RESET_GE0_MDIO                          BIT(22)
+#define AR933X_RESET_GE1_MAC                           BIT(13)
+#define AR933X_RESET_WMAC                              BIT(11)
+#define AR933X_RESET_GE0_MAC                           BIT(9)
+#define AR933X_RESET_ETH_SWITCH                                BIT(8)
+#define AR933X_RESET_USB_HOST                          BIT(5)
+#define AR933X_RESET_USB_PHY                           BIT(4)
+#define AR933X_RESET_USBSUS_OVERRIDE                   BIT(3)
+
+#define AR934X_RESET_HOST                              BIT(31)
+#define AR934X_RESET_SLIC                              BIT(30)
+#define AR934X_RESET_HDMA                              BIT(29)
+#define AR934X_RESET_EXTERNAL                          BIT(28)
+#define AR934X_RESET_RTC                               BIT(27)
+#define AR934X_RESET_PCIE_EP_INT                       BIT(26)
+#define AR934X_RESET_CHKSUM_ACC                                BIT(25)
+#define AR934X_RESET_FULL_CHIP                         BIT(24)
+#define AR934X_RESET_GE1_MDIO                          BIT(23)
+#define AR934X_RESET_GE0_MDIO                          BIT(22)
+#define AR934X_RESET_CPU_NMI                           BIT(21)
+#define AR934X_RESET_CPU_COLD                          BIT(20)
+#define AR934X_RESET_HOST_RESET_INT                    BIT(19)
+#define AR934X_RESET_PCIE_EP                           BIT(18)
+#define AR934X_RESET_UART1                             BIT(17)
+#define AR934X_RESET_DDR                               BIT(16)
+#define AR934X_RESET_USB_PHY_PLL_PWD_EXT               BIT(15)
+#define AR934X_RESET_NANDF                             BIT(14)
+#define AR934X_RESET_GE1_MAC                           BIT(13)
+#define AR934X_RESET_ETH_SWITCH_ANALOG                 BIT(12)
+#define AR934X_RESET_USB_PHY_ANALOG                    BIT(11)
+#define AR934X_RESET_HOST_DMA_INT                      BIT(10)
+#define AR934X_RESET_GE0_MAC                           BIT(9)
+#define AR934X_RESET_ETH_SWITCH                                BIT(8)
+#define AR934X_RESET_PCIE_PHY                          BIT(7)
+#define AR934X_RESET_PCIE                              BIT(6)
+#define AR934X_RESET_USB_HOST                          BIT(5)
+#define AR934X_RESET_USB_PHY                           BIT(4)
+#define AR934X_RESET_USBSUS_OVERRIDE                   BIT(3)
+#define AR934X_RESET_LUT                               BIT(2)
+#define AR934X_RESET_MBOX                              BIT(1)
+#define AR934X_RESET_I2S                               BIT(0)
+
+#define QCA953X_RESET_USB_EXT_PWR                      BIT(29)
+#define QCA953X_RESET_EXTERNAL                         BIT(28)
+#define QCA953X_RESET_RTC                              BIT(27)
+#define QCA953X_RESET_FULL_CHIP                                BIT(24)
+#define QCA953X_RESET_GE1_MDIO                         BIT(23)
+#define QCA953X_RESET_GE0_MDIO                         BIT(22)
+#define QCA953X_RESET_CPU_NMI                          BIT(21)
+#define QCA953X_RESET_CPU_COLD                         BIT(20)
+#define QCA953X_RESET_DDR                              BIT(16)
+#define QCA953X_RESET_USB_PHY_PLL_PWD_EXT              BIT(15)
+#define QCA953X_RESET_GE1_MAC                          BIT(13)
+#define QCA953X_RESET_ETH_SWITCH_ANALOG                        BIT(12)
+#define QCA953X_RESET_USB_PHY_ANALOG                   BIT(11)
+#define QCA953X_RESET_GE0_MAC                          BIT(9)
+#define QCA953X_RESET_ETH_SWITCH                       BIT(8)
+#define QCA953X_RESET_PCIE_PHY                         BIT(7)
+#define QCA953X_RESET_PCIE                             BIT(6)
+#define QCA953X_RESET_USB_HOST                         BIT(5)
+#define QCA953X_RESET_USB_PHY                          BIT(4)
+#define QCA953X_RESET_USBSUS_OVERRIDE                  BIT(3)
+
+#define QCA955X_RESET_HOST                             BIT(31)
+#define QCA955X_RESET_SLIC                             BIT(30)
+#define QCA955X_RESET_HDMA                             BIT(29)
+#define QCA955X_RESET_EXTERNAL                         BIT(28)
+#define QCA955X_RESET_RTC                              BIT(27)
+#define QCA955X_RESET_PCIE_EP_INT                      BIT(26)
+#define QCA955X_RESET_CHKSUM_ACC                       BIT(25)
+#define QCA955X_RESET_FULL_CHIP                                BIT(24)
+#define QCA955X_RESET_GE1_MDIO                         BIT(23)
+#define QCA955X_RESET_GE0_MDIO                         BIT(22)
+#define QCA955X_RESET_CPU_NMI                          BIT(21)
+#define QCA955X_RESET_CPU_COLD                         BIT(20)
+#define QCA955X_RESET_HOST_RESET_INT                   BIT(19)
+#define QCA955X_RESET_PCIE_EP                          BIT(18)
+#define QCA955X_RESET_UART1                            BIT(17)
+#define QCA955X_RESET_DDR                              BIT(16)
+#define QCA955X_RESET_USB_PHY_PLL_PWD_EXT              BIT(15)
+#define QCA955X_RESET_NANDF                            BIT(14)
+#define QCA955X_RESET_GE1_MAC                          BIT(13)
+#define QCA955X_RESET_SGMII_ANALOG                     BIT(12)
+#define QCA955X_RESET_USB_PHY_ANALOG                   BIT(11)
+#define QCA955X_RESET_HOST_DMA_INT                     BIT(10)
+#define QCA955X_RESET_GE0_MAC                          BIT(9)
+#define QCA955X_RESET_SGMII                            BIT(8)
+#define QCA955X_RESET_PCIE_PHY                         BIT(7)
+#define QCA955X_RESET_PCIE                             BIT(6)
+#define QCA955X_RESET_USB_HOST                         BIT(5)
+#define QCA955X_RESET_USB_PHY                          BIT(4)
+#define QCA955X_RESET_USBSUS_OVERRIDE                  BIT(3)
+#define QCA955X_RESET_LUT                              BIT(2)
+#define QCA955X_RESET_MBOX                             BIT(1)
+#define QCA955X_RESET_I2S                              BIT(0)
+
+#define AR933X_BOOTSTRAP_MDIO_GPIO_EN                  BIT(18)
+#define AR933X_BOOTSTRAP_DDR2                          BIT(13)
+#define AR933X_BOOTSTRAP_EEPBUSY                       BIT(4)
+#define AR933X_BOOTSTRAP_REF_CLK_40                    BIT(0)
+
+#define AR934X_BOOTSTRAP_SW_OPTION8                    BIT(23)
+#define AR934X_BOOTSTRAP_SW_OPTION7                    BIT(22)
+#define AR934X_BOOTSTRAP_SW_OPTION6                    BIT(21)
+#define AR934X_BOOTSTRAP_SW_OPTION5                    BIT(20)
+#define AR934X_BOOTSTRAP_SW_OPTION4                    BIT(19)
+#define AR934X_BOOTSTRAP_SW_OPTION3                    BIT(18)
+#define AR934X_BOOTSTRAP_SW_OPTION2                    BIT(17)
+#define AR934X_BOOTSTRAP_SW_OPTION1                    BIT(16)
+#define AR934X_BOOTSTRAP_USB_MODE_DEVICE               BIT(7)
+#define AR934X_BOOTSTRAP_PCIE_RC                       BIT(6)
+#define AR934X_BOOTSTRAP_EJTAG_MODE                    BIT(5)
+#define AR934X_BOOTSTRAP_REF_CLK_40                    BIT(4)
+#define AR934X_BOOTSTRAP_BOOT_FROM_SPI                 BIT(2)
+#define AR934X_BOOTSTRAP_SDRAM_DISABLED                        BIT(1)
+#define AR934X_BOOTSTRAP_DDR1                          BIT(0)
+
+#define QCA953X_BOOTSTRAP_SW_OPTION2                   BIT(12)
+#define QCA953X_BOOTSTRAP_SW_OPTION1                   BIT(11)
+#define QCA953X_BOOTSTRAP_EJTAG_MODE                   BIT(5)
+#define QCA953X_BOOTSTRAP_REF_CLK_40                   BIT(4)
+#define QCA953X_BOOTSTRAP_SDRAM_DISABLED               BIT(1)
+#define QCA953X_BOOTSTRAP_DDR1                         BIT(0)
+
+#define QCA955X_BOOTSTRAP_REF_CLK_40                   BIT(4)
+
+#define QCA956X_BOOTSTRAP_REF_CLK_40                   BIT(2)
+
+#define AR934X_PCIE_WMAC_INT_WMAC_MISC                 BIT(0)
+#define AR934X_PCIE_WMAC_INT_WMAC_TX                   BIT(1)
+#define AR934X_PCIE_WMAC_INT_WMAC_RXLP                 BIT(2)
+#define AR934X_PCIE_WMAC_INT_WMAC_RXHP                 BIT(3)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC                   BIT(4)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC0                  BIT(5)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC1                  BIT(6)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC2                  BIT(7)
+#define AR934X_PCIE_WMAC_INT_PCIE_RC3                  BIT(8)
+#define AR934X_PCIE_WMAC_INT_WMAC_ALL \
+       (AR934X_PCIE_WMAC_INT_WMAC_MISC | AR934X_PCIE_WMAC_INT_WMAC_TX | \
+        AR934X_PCIE_WMAC_INT_WMAC_RXLP | AR934X_PCIE_WMAC_INT_WMAC_RXHP)
+
+#define AR934X_PCIE_WMAC_INT_PCIE_ALL \
+       (AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \
+        AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \
+        AR934X_PCIE_WMAC_INT_PCIE_RC3)
+
+#define QCA953X_PCIE_WMAC_INT_WMAC_MISC                        BIT(0)
+#define QCA953X_PCIE_WMAC_INT_WMAC_TX                  BIT(1)
+#define QCA953X_PCIE_WMAC_INT_WMAC_RXLP                        BIT(2)
+#define QCA953X_PCIE_WMAC_INT_WMAC_RXHP                        BIT(3)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC                  BIT(4)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC0                 BIT(5)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC1                 BIT(6)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC2                 BIT(7)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC3                 BIT(8)
+#define QCA953X_PCIE_WMAC_INT_WMAC_ALL \
+       (QCA953X_PCIE_WMAC_INT_WMAC_MISC | QCA953X_PCIE_WMAC_INT_WMAC_TX | \
+        QCA953X_PCIE_WMAC_INT_WMAC_RXLP | QCA953X_PCIE_WMAC_INT_WMAC_RXHP)
+
+#define QCA953X_PCIE_WMAC_INT_PCIE_ALL \
+       (QCA953X_PCIE_WMAC_INT_PCIE_RC | QCA953X_PCIE_WMAC_INT_PCIE_RC0 | \
+        QCA953X_PCIE_WMAC_INT_PCIE_RC1 | QCA953X_PCIE_WMAC_INT_PCIE_RC2 | \
+        QCA953X_PCIE_WMAC_INT_PCIE_RC3)
+
+#define QCA955X_EXT_INT_WMAC_MISC                      BIT(0)
+#define QCA955X_EXT_INT_WMAC_TX                                BIT(1)
+#define QCA955X_EXT_INT_WMAC_RXLP                      BIT(2)
+#define QCA955X_EXT_INT_WMAC_RXHP                      BIT(3)
+#define QCA955X_EXT_INT_PCIE_RC1                       BIT(4)
+#define QCA955X_EXT_INT_PCIE_RC1_INT0                  BIT(5)
+#define QCA955X_EXT_INT_PCIE_RC1_INT1                  BIT(6)
+#define QCA955X_EXT_INT_PCIE_RC1_INT2                  BIT(7)
+#define QCA955X_EXT_INT_PCIE_RC1_INT3                  BIT(8)
+#define QCA955X_EXT_INT_PCIE_RC2                       BIT(12)
+#define QCA955X_EXT_INT_PCIE_RC2_INT0                  BIT(13)
+#define QCA955X_EXT_INT_PCIE_RC2_INT1                  BIT(14)
+#define QCA955X_EXT_INT_PCIE_RC2_INT2                  BIT(15)
+#define QCA955X_EXT_INT_PCIE_RC2_INT3                  BIT(16)
+#define QCA955X_EXT_INT_USB1                           BIT(24)
+#define QCA955X_EXT_INT_USB2                           BIT(28)
+
+#define QCA955X_EXT_INT_WMAC_ALL \
+       (QCA955X_EXT_INT_WMAC_MISC | QCA955X_EXT_INT_WMAC_TX | \
+        QCA955X_EXT_INT_WMAC_RXLP | QCA955X_EXT_INT_WMAC_RXHP)
+
+#define QCA955X_EXT_INT_PCIE_RC1_ALL \
+       (QCA955X_EXT_INT_PCIE_RC1 | QCA955X_EXT_INT_PCIE_RC1_INT0 | \
+        QCA955X_EXT_INT_PCIE_RC1_INT1 | QCA955X_EXT_INT_PCIE_RC1_INT2 | \
+        QCA955X_EXT_INT_PCIE_RC1_INT3)
+
+#define QCA955X_EXT_INT_PCIE_RC2_ALL \
+       (QCA955X_EXT_INT_PCIE_RC2 | QCA955X_EXT_INT_PCIE_RC2_INT0 | \
+        QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \
+        QCA955X_EXT_INT_PCIE_RC2_INT3)
+
+#define QCA956X_EXT_INT_WMAC_MISC                      BIT(0)
+#define QCA956X_EXT_INT_WMAC_TX                                BIT(1)
+#define QCA956X_EXT_INT_WMAC_RXLP                      BIT(2)
+#define QCA956X_EXT_INT_WMAC_RXHP                      BIT(3)
+#define QCA956X_EXT_INT_PCIE_RC1                       BIT(4)
+#define QCA956X_EXT_INT_PCIE_RC1_INT0                  BIT(5)
+#define QCA956X_EXT_INT_PCIE_RC1_INT1                  BIT(6)
+#define QCA956X_EXT_INT_PCIE_RC1_INT2                  BIT(7)
+#define QCA956X_EXT_INT_PCIE_RC1_INT3                  BIT(8)
+#define QCA956X_EXT_INT_PCIE_RC2                       BIT(12)
+#define QCA956X_EXT_INT_PCIE_RC2_INT0                  BIT(13)
+#define QCA956X_EXT_INT_PCIE_RC2_INT1                  BIT(14)
+#define QCA956X_EXT_INT_PCIE_RC2_INT2                  BIT(15)
+#define QCA956X_EXT_INT_PCIE_RC2_INT3                  BIT(16)
+#define QCA956X_EXT_INT_USB1                           BIT(24)
+#define QCA956X_EXT_INT_USB2                           BIT(28)
+
+#define QCA956X_EXT_INT_WMAC_ALL \
+       (QCA956X_EXT_INT_WMAC_MISC | QCA956X_EXT_INT_WMAC_TX | \
+        QCA956X_EXT_INT_WMAC_RXLP | QCA956X_EXT_INT_WMAC_RXHP)
+
+#define QCA956X_EXT_INT_PCIE_RC1_ALL \
+       (QCA956X_EXT_INT_PCIE_RC1 | QCA956X_EXT_INT_PCIE_RC1_INT0 | \
+        QCA956X_EXT_INT_PCIE_RC1_INT1 | QCA956X_EXT_INT_PCIE_RC1_INT2 | \
+        QCA956X_EXT_INT_PCIE_RC1_INT3)
+
+#define QCA956X_EXT_INT_PCIE_RC2_ALL \
+       (QCA956X_EXT_INT_PCIE_RC2 | QCA956X_EXT_INT_PCIE_RC2_INT0 | \
+        QCA956X_EXT_INT_PCIE_RC2_INT1 | QCA956X_EXT_INT_PCIE_RC2_INT2 | \
+        QCA956X_EXT_INT_PCIE_RC2_INT3)
+
+#define REV_ID_MAJOR_MASK                              0xfff0
+#define REV_ID_MAJOR_AR71XX                            0x00a0
+#define REV_ID_MAJOR_AR913X                            0x00b0
+#define REV_ID_MAJOR_AR7240                            0x00c0
+#define REV_ID_MAJOR_AR7241                            0x0100
+#define REV_ID_MAJOR_AR7242                            0x1100
+#define REV_ID_MAJOR_AR9330                            0x0110
+#define REV_ID_MAJOR_AR9331                            0x1110
+#define REV_ID_MAJOR_AR9341                            0x0120
+#define REV_ID_MAJOR_AR9342                            0x1120
+#define REV_ID_MAJOR_AR9344                            0x2120
+#define REV_ID_MAJOR_QCA9533                           0x0140
+#define REV_ID_MAJOR_QCA9533_V2                                0x0160
+#define REV_ID_MAJOR_QCA9556                           0x0130
+#define REV_ID_MAJOR_QCA9558                           0x1130
+#define REV_ID_MAJOR_TP9343                            0x0150
+#define REV_ID_MAJOR_QCA9561                           0x1150
+
+#define AR71XX_REV_ID_MINOR_MASK                       0x3
+#define AR71XX_REV_ID_MINOR_AR7130                     0x0
+#define AR71XX_REV_ID_MINOR_AR7141                     0x1
+#define AR71XX_REV_ID_MINOR_AR7161                     0x2
+#define AR913X_REV_ID_MINOR_AR9130                     0x0
+#define AR913X_REV_ID_MINOR_AR9132                     0x1
+
+#define AR71XX_REV_ID_REVISION_MASK                    0x3
+#define AR71XX_REV_ID_REVISION_SHIFT                   2
+#define AR71XX_REV_ID_REVISION2_MASK                   0xf
+
+/*
+ * RTC block
+ */
+#define AR933X_RTC_REG_RESET                           0x40
+#define AR933X_RTC_REG_STATUS                          0x44
+#define AR933X_RTC_REG_DERIVED                         0x48
+#define AR933X_RTC_REG_FORCE_WAKE                      0x4c
+#define AR933X_RTC_REG_INT_CAUSE                       0x50
+#define AR933X_RTC_REG_CAUSE_CLR                       0x50
+#define AR933X_RTC_REG_INT_ENABLE                      0x54
+#define AR933X_RTC_REG_INT_MASKE                       0x58
+
+#define QCA953X_RTC_REG_SYNC_RESET                     0x40
+#define QCA953X_RTC_REG_SYNC_STATUS                    0x44
+
+/*
+ * SPI block
+ */
+#define AR71XX_SPI_REG_FS                              0x00
+#define AR71XX_SPI_REG_CTRL                            0x04
+#define AR71XX_SPI_REG_IOC                             0x08
+#define AR71XX_SPI_REG_RDS                             0x0c
+
+#define AR71XX_SPI_FS_GPIO                             BIT(0)
+
+#define AR71XX_SPI_CTRL_RD                             BIT(6)
+#define AR71XX_SPI_CTRL_DIV_MASK                       0x3f
+
+#define AR71XX_SPI_IOC_DO                              BIT(0)
+#define AR71XX_SPI_IOC_CLK                             BIT(8)
+#define AR71XX_SPI_IOC_CS(n)                           BIT(16 + (n))
+#define AR71XX_SPI_IOC_CS0                             AR71XX_SPI_IOC_CS(0)
+#define AR71XX_SPI_IOC_CS1                             AR71XX_SPI_IOC_CS(1)
+#define AR71XX_SPI_IOC_CS2                             AR71XX_SPI_IOC_CS(2)
+#define AR71XX_SPI_IOC_CS_ALL \
+       (AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | AR71XX_SPI_IOC_CS2)
+
+/*
+ * GPIO block
+ */
+#define AR71XX_GPIO_REG_OE                             0x00
+#define AR71XX_GPIO_REG_IN                             0x04
+#define AR71XX_GPIO_REG_OUT                            0x08
+#define AR71XX_GPIO_REG_SET                            0x0c
+#define AR71XX_GPIO_REG_CLEAR                          0x10
+#define AR71XX_GPIO_REG_INT_MODE                       0x14
+#define AR71XX_GPIO_REG_INT_TYPE                       0x18
+#define AR71XX_GPIO_REG_INT_POLARITY                   0x1c
+#define AR71XX_GPIO_REG_INT_PENDING                    0x20
+#define AR71XX_GPIO_REG_INT_ENABLE                     0x24
+#define AR71XX_GPIO_REG_FUNC                           0x28
+#define AR933X_GPIO_REG_FUNC                           0x30
+
+#define AR934X_GPIO_REG_OUT_FUNC0                      0x2c
+#define AR934X_GPIO_REG_OUT_FUNC1                      0x30
+#define AR934X_GPIO_REG_OUT_FUNC2                      0x34
+#define AR934X_GPIO_REG_OUT_FUNC3                      0x38
+#define AR934X_GPIO_REG_OUT_FUNC4                      0x3c
+#define AR934X_GPIO_REG_OUT_FUNC5                      0x40
+#define AR934X_GPIO_REG_FUNC                           0x6c
+
+#define QCA953X_GPIO_REG_OUT_FUNC0                     0x2c
+#define QCA953X_GPIO_REG_OUT_FUNC1                     0x30
+#define QCA953X_GPIO_REG_OUT_FUNC2                     0x34
+#define QCA953X_GPIO_REG_OUT_FUNC3                     0x38
+#define QCA953X_GPIO_REG_OUT_FUNC4                     0x3c
+#define QCA953X_GPIO_REG_IN_ENABLE0                    0x44
+#define QCA953X_GPIO_REG_FUNC                          0x6c
+
+#define QCA955X_GPIO_REG_OUT_FUNC0                     0x2c
+#define QCA955X_GPIO_REG_OUT_FUNC1                     0x30
+#define QCA955X_GPIO_REG_OUT_FUNC2                     0x34
+#define QCA955X_GPIO_REG_OUT_FUNC3                     0x38
+#define QCA955X_GPIO_REG_OUT_FUNC4                     0x3c
+#define QCA955X_GPIO_REG_OUT_FUNC5                     0x40
+#define QCA955X_GPIO_REG_FUNC                          0x6c
+
+#define QCA956X_GPIO_REG_OUT_FUNC0                     0x2c
+#define QCA956X_GPIO_REG_OUT_FUNC1                     0x30
+#define QCA956X_GPIO_REG_OUT_FUNC2                     0x34
+#define QCA956X_GPIO_REG_OUT_FUNC3                     0x38
+#define QCA956X_GPIO_REG_OUT_FUNC4                     0x3c
+#define QCA956X_GPIO_REG_OUT_FUNC5                     0x40
+#define QCA956X_GPIO_REG_IN_ENABLE0                    0x44
+#define QCA956X_GPIO_REG_IN_ENABLE3                    0x50
+#define QCA956X_GPIO_REG_FUNC                          0x6c
+
+#define AR71XX_GPIO_FUNC_STEREO_EN                     BIT(17)
+#define AR71XX_GPIO_FUNC_SLIC_EN                       BIT(16)
+#define AR71XX_GPIO_FUNC_SPI_CS2_EN                    BIT(13)
+#define AR71XX_GPIO_FUNC_SPI_CS1_EN                    BIT(12)
+#define AR71XX_GPIO_FUNC_UART_EN                       BIT(8)
+#define AR71XX_GPIO_FUNC_USB_OC_EN                     BIT(4)
+#define AR71XX_GPIO_FUNC_USB_CLK_EN                    BIT(0)
+
+#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN                        BIT(19)
+#define AR724X_GPIO_FUNC_SPI_EN                                BIT(18)
+#define AR724X_GPIO_FUNC_SPI_CS_EN2                    BIT(14)
+#define AR724X_GPIO_FUNC_SPI_CS_EN1                    BIT(13)
+#define AR724X_GPIO_FUNC_CLK_OBS5_EN                   BIT(12)
+#define AR724X_GPIO_FUNC_CLK_OBS4_EN                   BIT(11)
+#define AR724X_GPIO_FUNC_CLK_OBS3_EN                   BIT(10)
+#define AR724X_GPIO_FUNC_CLK_OBS2_EN                   BIT(9)
+#define AR724X_GPIO_FUNC_CLK_OBS1_EN                   BIT(8)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN            BIT(7)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN            BIT(6)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN            BIT(5)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN            BIT(4)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN            BIT(3)
+#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN               BIT(2)
+#define AR724X_GPIO_FUNC_UART_EN                       BIT(1)
+#define AR724X_GPIO_FUNC_JTAG_DISABLE                  BIT(0)
+
+#define AR913X_GPIO_FUNC_WMAC_LED_EN                   BIT(22)
+#define AR913X_GPIO_FUNC_EXP_PORT_CS_EN                        BIT(21)
+#define AR913X_GPIO_FUNC_I2S_REFCLKEN                  BIT(20)
+#define AR913X_GPIO_FUNC_I2S_MCKEN                     BIT(19)
+#define AR913X_GPIO_FUNC_I2S1_EN                       BIT(18)
+#define AR913X_GPIO_FUNC_I2S0_EN                       BIT(17)
+#define AR913X_GPIO_FUNC_SLIC_EN                       BIT(16)
+#define AR913X_GPIO_FUNC_UART_RTSCTS_EN                        BIT(9)
+#define AR913X_GPIO_FUNC_UART_EN                       BIT(8)
+#define AR913X_GPIO_FUNC_USB_CLK_EN                    BIT(4)
+
+#define AR933X_GPIO(x)                                 BIT(x)
+#define AR933X_GPIO_FUNC_SPDIF2TCK                     BIT(31)
+#define AR933X_GPIO_FUNC_SPDIF_EN                      BIT(30)
+#define AR933X_GPIO_FUNC_I2SO_22_18_EN                 BIT(29)
+#define AR933X_GPIO_FUNC_I2S_MCK_EN                    BIT(27)
+#define AR933X_GPIO_FUNC_I2SO_EN                       BIT(26)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_DUPL           BIT(25)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_COLL           BIT(24)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_ACT            BIT(23)
+#define AR933X_GPIO_FUNC_SPI_EN                                BIT(18)
+#define AR933X_GPIO_FUNC_RES_TRUE                      BIT(15)
+#define AR933X_GPIO_FUNC_SPI_CS_EN2                    BIT(14)
+#define AR933X_GPIO_FUNC_SPI_CS_EN1                    BIT(13)
+#define AR933X_GPIO_FUNC_XLNA_EN                       BIT(12)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN            BIT(7)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN            BIT(6)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN            BIT(5)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN            BIT(4)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN            BIT(3)
+#define AR933X_GPIO_FUNC_UART_RTS_CTS_EN               BIT(2)
+#define AR933X_GPIO_FUNC_UART_EN                       BIT(1)
+#define AR933X_GPIO_FUNC_JTAG_DISABLE                  BIT(0)
+
+#define AR934X_GPIO_FUNC_CLK_OBS7_EN                   BIT(9)
+#define AR934X_GPIO_FUNC_CLK_OBS6_EN                   BIT(8)
+#define AR934X_GPIO_FUNC_CLK_OBS5_EN                   BIT(7)
+#define AR934X_GPIO_FUNC_CLK_OBS4_EN                   BIT(6)
+#define AR934X_GPIO_FUNC_CLK_OBS3_EN                   BIT(5)
+#define AR934X_GPIO_FUNC_CLK_OBS2_EN                   BIT(4)
+#define AR934X_GPIO_FUNC_CLK_OBS1_EN                   BIT(3)
+#define AR934X_GPIO_FUNC_CLK_OBS0_EN                   BIT(2)
+#define AR934X_GPIO_FUNC_JTAG_DISABLE                  BIT(1)
+
+#define AR934X_GPIO_OUT_GPIO                           0
+#define AR934X_GPIO_OUT_SPI_CS1                                7
+#define AR934X_GPIO_OUT_LED_LINK0                      41
+#define AR934X_GPIO_OUT_LED_LINK1                      42
+#define AR934X_GPIO_OUT_LED_LINK2                      43
+#define AR934X_GPIO_OUT_LED_LINK3                      44
+#define AR934X_GPIO_OUT_LED_LINK4                      45
+#define AR934X_GPIO_OUT_EXT_LNA0                       46
+#define AR934X_GPIO_OUT_EXT_LNA1                       47
+
+#define QCA953X_GPIO(x)                                        BIT(x)
+#define QCA953X_GPIO_MUX_MASK(x)                       (0xff << (x))
+#define QCA953X_GPIO_OUT_MUX_SPI_CS1                   10
+#define QCA953X_GPIO_OUT_MUX_SPI_CS2                   11
+#define QCA953X_GPIO_OUT_MUX_SPI_CS0                   9
+#define QCA953X_GPIO_OUT_MUX_SPI_CLK                   8
+#define QCA953X_GPIO_OUT_MUX_SPI_MOSI                  12
+#define QCA953X_GPIO_OUT_MUX_UART0_SOUT                        22
+#define QCA953X_GPIO_OUT_MUX_LED_LINK1                 41
+#define QCA953X_GPIO_OUT_MUX_LED_LINK2                 42
+#define QCA953X_GPIO_OUT_MUX_LED_LINK3                 43
+#define QCA953X_GPIO_OUT_MUX_LED_LINK4                 44
+#define QCA953X_GPIO_OUT_MUX_LED_LINK5                 45
+
+#define QCA953X_GPIO_IN_MUX_UART0_SIN                  9
+#define QCA953X_GPIO_IN_MUX_SPI_DATA_IN                        8
+
+#define QCA956X_GPIO_OUT_MUX_GE0_MDO                   32
+#define QCA956X_GPIO_OUT_MUX_GE0_MDC                   33
+
+#define AR71XX_GPIO_COUNT                              16
+#define AR7240_GPIO_COUNT                              18
+#define AR7241_GPIO_COUNT                              20
+#define AR913X_GPIO_COUNT                              22
+#define AR933X_GPIO_COUNT                              30
+#define AR934X_GPIO_COUNT                              23
+#define QCA953X_GPIO_COUNT                             18
+#define QCA955X_GPIO_COUNT                             24
+#define QCA956X_GPIO_COUNT                             23
+
+/*
+ * SRIF block
+ */
+#define AR933X_SRIF_DDR_DPLL1_REG                      0x240
+#define AR933X_SRIF_DDR_DPLL2_REG                      0x244
+#define AR933X_SRIF_DDR_DPLL3_REG                      0x248
+#define AR933X_SRIF_DDR_DPLL4_REG                      0x24c
+
+#define AR934X_SRIF_CPU_DPLL1_REG                      0x1c0
+#define AR934X_SRIF_CPU_DPLL2_REG                      0x1c4
+#define AR934X_SRIF_CPU_DPLL3_REG                      0x1c8
+#define AR934X_SRIF_CPU_DPLL4_REG                      0x1cc
+
+#define AR934X_SRIF_DDR_DPLL1_REG                      0x240
+#define AR934X_SRIF_DDR_DPLL2_REG                      0x244
+#define AR934X_SRIF_DDR_DPLL3_REG                      0x248
+#define AR934X_SRIF_DDR_DPLL4_REG                      0x24c
+
+#define AR934X_SRIF_DPLL1_REFDIV_SHIFT                 27
+#define AR934X_SRIF_DPLL1_REFDIV_MASK                  0x1f
+#define AR934X_SRIF_DPLL1_NINT_SHIFT                   18
+#define AR934X_SRIF_DPLL1_NINT_MASK                    0x1ff
+#define AR934X_SRIF_DPLL1_NFRAC_MASK                   0x0003ffff
+
+#define AR934X_SRIF_DPLL2_LOCAL_PLL                    BIT(30)
+#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT                 13
+#define AR934X_SRIF_DPLL2_OUTDIV_MASK                  0x7
+
+#define QCA953X_SRIF_BB_DPLL1_REG                      0x180
+#define QCA953X_SRIF_BB_DPLL2_REG                      0x184
+#define QCA953X_SRIF_BB_DPLL3_REG                      0x188
+
+#define QCA953X_SRIF_CPU_DPLL1_REG                     0x1c0
+#define QCA953X_SRIF_CPU_DPLL2_REG                     0x1c4
+#define QCA953X_SRIF_CPU_DPLL3_REG                     0x1c8
+
+#define QCA953X_SRIF_DDR_DPLL1_REG                     0x240
+#define QCA953X_SRIF_DDR_DPLL2_REG                     0x244
+#define QCA953X_SRIF_DDR_DPLL3_REG                     0x248
+
+#define QCA953X_SRIF_PCIE_DPLL1_REG                    0xc00
+#define QCA953X_SRIF_PCIE_DPLL2_REG                    0xc04
+#define QCA953X_SRIF_PCIE_DPLL3_REG                    0xc08
+
+#define QCA953X_SRIF_PMU1_REG                          0xc40
+#define QCA953X_SRIF_PMU2_REG                          0xc44
+
+#define QCA953X_SRIF_DPLL1_REFDIV_SHIFT                        27
+#define QCA953X_SRIF_DPLL1_REFDIV_MASK                 0x1f
+
+#define QCA953X_SRIF_DPLL1_NINT_SHIFT                  18
+#define QCA953X_SRIF_DPLL1_NINT_MASK                   0x1ff
+#define QCA953X_SRIF_DPLL1_NFRAC_MASK                  0x0003ffff
+
+#define QCA953X_SRIF_DPLL2_LOCAL_PLL                   BIT(30)
+
+#define QCA953X_SRIF_DPLL2_KI_SHIFT                    29
+#define QCA953X_SRIF_DPLL2_KI_MASK                     0x3
+
+#define QCA953X_SRIF_DPLL2_KD_SHIFT                    25
+#define QCA953X_SRIF_DPLL2_KD_MASK                     0xf
+
+#define QCA953X_SRIF_DPLL2_PWD                         BIT(22)
+
+#define QCA953X_SRIF_DPLL2_OUTDIV_SHIFT                        13
+#define QCA953X_SRIF_DPLL2_OUTDIV_MASK                 0x7
+
+/*
+ * MII_CTRL block
+ */
+#define AR71XX_MII_REG_MII0_CTRL                       0x00
+#define AR71XX_MII_REG_MII1_CTRL                       0x04
+
+#define AR71XX_MII_CTRL_IF_MASK                                3
+#define AR71XX_MII_CTRL_SPEED_SHIFT                    4
+#define AR71XX_MII_CTRL_SPEED_MASK                     3
+#define AR71XX_MII_CTRL_SPEED_10                       0
+#define AR71XX_MII_CTRL_SPEED_100                      1
+#define AR71XX_MII_CTRL_SPEED_1000                     2
+
+#define AR71XX_MII0_CTRL_IF_GMII                       0
+#define AR71XX_MII0_CTRL_IF_MII                                1
+#define AR71XX_MII0_CTRL_IF_RGMII                      2
+#define AR71XX_MII0_CTRL_IF_RMII                       3
+
+#define AR71XX_MII1_CTRL_IF_RGMII                      0
+#define AR71XX_MII1_CTRL_IF_RMII                       1
+
+/*
+ * AR933X GMAC interface
+ */
+#define AR933X_GMAC_REG_ETH_CFG                                0x00
+
+#define AR933X_ETH_CFG_RGMII_GE0                       BIT(0)
+#define AR933X_ETH_CFG_MII_GE0                         BIT(1)
+#define AR933X_ETH_CFG_GMII_GE0                                BIT(2)
+#define AR933X_ETH_CFG_MII_GE0_MASTER                  BIT(3)
+#define AR933X_ETH_CFG_MII_GE0_SLAVE                   BIT(4)
+#define AR933X_ETH_CFG_MII_GE0_ERR_EN                  BIT(5)
+#define AR933X_ETH_CFG_SW_PHY_SWAP                     BIT(7)
+#define AR933X_ETH_CFG_SW_PHY_ADDR_SWAP                        BIT(8)
+#define AR933X_ETH_CFG_RMII_GE0                                BIT(9)
+#define AR933X_ETH_CFG_RMII_GE0_SPD_10                 0
+#define AR933X_ETH_CFG_RMII_GE0_SPD_100                        BIT(10)
+
+/*
+ * AR934X GMAC Interface
+ */
+#define AR934X_GMAC_REG_ETH_CFG                                0x00
+
+#define AR934X_ETH_CFG_RGMII_GMAC0                     BIT(0)
+#define AR934X_ETH_CFG_MII_GMAC0                       BIT(1)
+#define AR934X_ETH_CFG_GMII_GMAC0                      BIT(2)
+#define AR934X_ETH_CFG_MII_GMAC0_MASTER                        BIT(3)
+#define AR934X_ETH_CFG_MII_GMAC0_SLAVE                 BIT(4)
+#define AR934X_ETH_CFG_MII_GMAC0_ERR_EN                        BIT(5)
+#define AR934X_ETH_CFG_SW_ONLY_MODE                    BIT(6)
+#define AR934X_ETH_CFG_SW_PHY_SWAP                     BIT(7)
+#define AR934X_ETH_CFG_SW_APB_ACCESS                   BIT(9)
+#define AR934X_ETH_CFG_RMII_GMAC0                      BIT(10)
+#define AR933X_ETH_CFG_MII_CNTL_SPEED                  BIT(11)
+#define AR934X_ETH_CFG_RMII_GMAC0_MASTER                       BIT(12)
+#define AR933X_ETH_CFG_SW_ACC_MSB_FIRST                        BIT(13)
+#define AR934X_ETH_CFG_RXD_DELAY                       BIT(14)
+#define AR934X_ETH_CFG_RXD_DELAY_MASK                  0x3
+#define AR934X_ETH_CFG_RXD_DELAY_SHIFT                 14
+#define AR934X_ETH_CFG_RDV_DELAY                       BIT(16)
+#define AR934X_ETH_CFG_RDV_DELAY_MASK                  0x3
+#define AR934X_ETH_CFG_RDV_DELAY_SHIFT                 16
+
+/*
+ * QCA953X GMAC Interface
+ */
+#define QCA953X_GMAC_REG_ETH_CFG                       0x00
+
+#define QCA953X_ETH_CFG_SW_ONLY_MODE                   BIT(6)
+#define QCA953X_ETH_CFG_SW_PHY_SWAP                    BIT(7)
+#define QCA953X_ETH_CFG_SW_APB_ACCESS                  BIT(9)
+#define QCA953X_ETH_CFG_SW_ACC_MSB_FIRST               BIT(13)
+
+/*
+ * QCA955X GMAC Interface
+ */
+
+#define QCA955X_GMAC_REG_ETH_CFG                       0x00
+
+#define QCA955X_ETH_CFG_RGMII_EN                       BIT(0)
+#define QCA955X_ETH_CFG_GE0_SGMII                      BIT(6)
+
+#endif /* __ASM_AR71XX_H */
diff --git a/arch/mips/mach-ath79/include/mach/ath79.h b/arch/mips/mach-ath79/include/mach/ath79.h
new file mode 100644 (file)
index 0000000..17af082
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __ASM_MACH_ATH79_H
+#define __ASM_MACH_ATH79_H
+
+#include <linux/types.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum ath79_soc_type {
+       ATH79_SOC_UNKNOWN,
+       ATH79_SOC_AR7130,
+       ATH79_SOC_AR7141,
+       ATH79_SOC_AR7161,
+       ATH79_SOC_AR7240,
+       ATH79_SOC_AR7241,
+       ATH79_SOC_AR7242,
+       ATH79_SOC_AR9130,
+       ATH79_SOC_AR9132,
+       ATH79_SOC_AR9330,
+       ATH79_SOC_AR9331,
+       ATH79_SOC_AR9341,
+       ATH79_SOC_AR9342,
+       ATH79_SOC_AR9344,
+       ATH79_SOC_QCA9533,
+       ATH79_SOC_QCA9556,
+       ATH79_SOC_QCA9558,
+       ATH79_SOC_TP9343,
+       ATH79_SOC_QCA9561,
+};
+
+static inline int soc_is_ar71xx(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR7130 ||
+               gd->arch.soc == ATH79_SOC_AR7141 ||
+               gd->arch.soc == ATH79_SOC_AR7161;
+}
+
+static inline int soc_is_ar724x(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR7240 ||
+               gd->arch.soc == ATH79_SOC_AR7241 ||
+               gd->arch.soc == ATH79_SOC_AR7242;
+}
+
+static inline int soc_is_ar7240(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR7240;
+}
+
+static inline int soc_is_ar7241(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR7241;
+}
+
+static inline int soc_is_ar7242(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR7242;
+}
+
+static inline int soc_is_ar913x(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR9130 ||
+               gd->arch.soc == ATH79_SOC_AR9132;
+}
+
+static inline int soc_is_ar933x(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR9330 ||
+               gd->arch.soc == ATH79_SOC_AR9331;
+}
+
+static inline int soc_is_ar9341(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR9341;
+}
+
+static inline int soc_is_ar9342(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR9342;
+}
+
+static inline int soc_is_ar9344(void)
+{
+       return gd->arch.soc == ATH79_SOC_AR9344;
+}
+
+static inline int soc_is_ar934x(void)
+{
+       return soc_is_ar9341() ||
+               soc_is_ar9342() ||
+               soc_is_ar9344();
+}
+
+static inline int soc_is_qca9533(void)
+{
+       return gd->arch.soc == ATH79_SOC_QCA9533;
+}
+
+static inline int soc_is_qca953x(void)
+{
+       return soc_is_qca9533();
+}
+
+static inline int soc_is_qca9556(void)
+{
+       return gd->arch.soc == ATH79_SOC_QCA9556;
+}
+
+static inline int soc_is_qca9558(void)
+{
+       return gd->arch.soc == ATH79_SOC_QCA9558;
+}
+
+static inline int soc_is_qca955x(void)
+{
+       return soc_is_qca9556() || soc_is_qca9558();
+}
+
+static inline int soc_is_tp9343(void)
+{
+       return gd->arch.soc == ATH79_SOC_TP9343;
+}
+
+static inline int soc_is_qca9561(void)
+{
+       return gd->arch.soc == ATH79_SOC_QCA9561;
+}
+
+static inline int soc_is_qca956x(void)
+{
+       return soc_is_tp9343() || soc_is_qca9561();
+}
+
+int ath79_eth_reset(void);
+int ath79_usb_reset(void);
+
+void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz);
+void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz);
+
+#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/mach-ath79/include/mach/ddr.h b/arch/mips/mach-ath79/include/mach/ddr.h
new file mode 100644 (file)
index 0000000..181179a
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __ASM_MACH_DDR_H
+#define __ASM_MACH_DDR_H
+
+void ddr_init(void);
+void ddr_tap_tuning(void);
+
+#endif /* __ASM_MACH_DDR_H */
diff --git a/arch/mips/mach-ath79/include/mach/reset.h b/arch/mips/mach-ath79/include/mach/reset.h
new file mode 100644 (file)
index 0000000..c383bfe
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __ASM_MACH_RESET_H
+#define __ASM_MACH_RESET_H
+
+#include <linux/types.h>
+
+u32 get_bootstrap(void);
+
+#endif /* __ASM_MACH_RESET_H */
diff --git a/arch/mips/mach-ath79/qca953x/Makefile b/arch/mips/mach-ath79/qca953x/Makefile
new file mode 100644 (file)
index 0000000..fd74f0c
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += clk.o
+obj-y += ddr.o
+obj-y += lowlevel_init.o
diff --git a/arch/mips/mach-ath79/qca953x/clk.c b/arch/mips/mach-ath79/qca953x/clk.c
new file mode 100644 (file)
index 0000000..ef0a28e
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/reset.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static u32 qca953x_get_xtal(void)
+{
+       u32 val;
+
+       val = get_bootstrap();
+       if (val & QCA953X_BOOTSTRAP_REF_CLK_40)
+               return 40000000;
+       else
+               return 25000000;
+}
+
+int get_serial_clock(void)
+{
+       return qca953x_get_xtal();
+}
+
+int get_clocks(void)
+{
+       void __iomem *regs;
+       u32 val, ctrl, xtal, pll, div;
+
+       regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+                          MAP_NOCACHE);
+
+       xtal = qca953x_get_xtal();
+       ctrl = readl(regs + QCA953X_PLL_CLK_CTRL_REG);
+       val = readl(regs + QCA953X_PLL_CPU_CONFIG_REG);
+
+       /* VCOOUT = XTAL * DIV_INT */
+       div = (val >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT)
+                       & QCA953X_PLL_CPU_CONFIG_REFDIV_MASK;
+       pll = xtal / div;
+
+       /* PLLOUT = VCOOUT * (1/2^OUTDIV) */
+       div = (val >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT)
+                       & QCA953X_PLL_CPU_CONFIG_NINT_MASK;
+       pll *= div;
+       div = (val >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT)
+                       & QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK;
+       if (!div)
+               div = 1;
+       pll >>= div;
+
+       /* CPU_CLK = PLLOUT / CPU_POST_DIV */
+       div = ((ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT)
+                       & QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK) + 1;
+       gd->cpu_clk = pll / div;
+
+
+       val = readl(regs + QCA953X_PLL_DDR_CONFIG_REG);
+       /* VCOOUT = XTAL * DIV_INT */
+       div = (val >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT)
+                       & QCA953X_PLL_DDR_CONFIG_REFDIV_MASK;
+       pll = xtal / div;
+
+       /* PLLOUT = VCOOUT * (1/2^OUTDIV) */
+       div = (val >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT)
+                       & QCA953X_PLL_DDR_CONFIG_NINT_MASK;
+       pll *= div;
+       div = (val >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT)
+                       & QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK;
+       if (!div)
+               div = 1;
+       pll >>= div;
+
+       /* DDR_CLK = PLLOUT / DDR_POST_DIV */
+       div = ((ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT)
+                       & QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK) + 1;
+       gd->mem_clk = pll / div;
+
+       div = ((ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT)
+                       & QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK) + 1;
+       if (ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) {
+               /* AHB_CLK = DDR_CLK / AHB_POST_DIV */
+               gd->bus_clk = gd->mem_clk / (div + 1);
+       } else {
+               /* AHB_CLK = CPU_CLK / AHB_POST_DIV */
+               gd->bus_clk = gd->cpu_clk / (div + 1);
+       }
+
+       return 0;
+}
+
+ulong get_bus_freq(ulong dummy)
+{
+       if (!gd->bus_clk)
+               get_clocks();
+       return gd->bus_clk;
+}
+
+ulong get_ddr_freq(ulong dummy)
+{
+       if (!gd->mem_clk)
+               get_clocks();
+       return gd->mem_clk;
+}
diff --git a/arch/mips/mach-ath79/qca953x/ddr.c b/arch/mips/mach-ath79/qca953x/ddr.c
new file mode 100644 (file)
index 0000000..ac0130c
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ * Based on Atheros LSDK/QSDK
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/reset.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define DDR_CTRL_UPD_EMR3S      BIT(5)
+#define DDR_CTRL_UPD_EMR2S      BIT(4)
+#define DDR_CTRL_PRECHARGE      BIT(3)
+#define DDR_CTRL_AUTO_REFRESH   BIT(2)
+#define DDR_CTRL_UPD_EMRS       BIT(1)
+#define DDR_CTRL_UPD_MRS        BIT(0)
+
+#define DDR_REFRESH_EN          BIT(14)
+#define DDR_REFRESH_M           0x3ff
+#define DDR_REFRESH(x)          ((x) & DDR_REFRESH_M)
+#define DDR_REFRESH_VAL         (DDR_REFRESH_EN | DDR_REFRESH(312))
+
+#define DDR_TRAS_S              0
+#define DDR_TRAS_M              0x1f
+#define DDR_TRAS(x)             (((x) & DDR_TRAS_M) << DDR_TRAS_S)
+#define DDR_TRCD_M              0xf
+#define DDR_TRCD_S              5
+#define DDR_TRCD(x)             (((x) & DDR_TRCD_M) << DDR_TRCD_S)
+#define DDR_TRP_M               0xf
+#define DDR_TRP_S               9
+#define DDR_TRP(x)              (((x) & DDR_TRP_M) << DDR_TRP_S)
+#define DDR_TRRD_M              0xf
+#define DDR_TRRD_S              13
+#define DDR_TRRD(x)             (((x) & DDR_TRRD_M) << DDR_TRRD_S)
+#define DDR_TRFC_M              0x7f
+#define DDR_TRFC_S              17
+#define DDR_TRFC(x)             (((x) & DDR_TRFC_M) << DDR_TRFC_S)
+#define DDR_TMRD_M              0xf
+#define DDR_TMRD_S              23
+#define DDR_TMRD(x)             (((x) & DDR_TMRD_M) << DDR_TMRD_S)
+#define DDR_CAS_L_M             0x17
+#define DDR_CAS_L_S             27
+#define DDR_CAS_L(x)            (((x) & DDR_CAS_L_M) << DDR_CAS_L_S)
+#define DDR_OPEN                BIT(30)
+#define DDR1_CONF_REG_VAL       (DDR_TRAS(16) | DDR_TRCD(6) | \
+                                DDR_TRP(6) | DDR_TRRD(4) | \
+                                DDR_TRFC(7) | DDR_TMRD(5) | \
+                                DDR_CAS_L(7) | DDR_OPEN)
+#define DDR2_CONF_REG_VAL       (DDR_TRAS(27) | DDR_TRCD(9) | \
+                                DDR_TRP(9) | DDR_TRRD(7) | \
+                                DDR_TRFC(21) | DDR_TMRD(15) | \
+                                DDR_CAS_L(17) | DDR_OPEN)
+
+#define DDR_BURST_LEN_S         0
+#define DDR_BURST_LEN_M         0xf
+#define DDR_BURST_LEN(x)        ((x) << DDR_BURST_LEN_S)
+#define DDR_BURST_TYPE          BIT(4)
+#define DDR_CNTL_OE_EN          BIT(5)
+#define DDR_PHASE_SEL           BIT(6)
+#define DDR_CKE                 BIT(7)
+#define DDR_TWR_S               8
+#define DDR_TWR_M               0xf
+#define DDR_TWR(x)              (((x) & DDR_TWR_M) << DDR_TWR_S)
+#define DDR_TRTW_S              12
+#define DDR_TRTW_M              0x1f
+#define DDR_TRTW(x)             (((x) & DDR_TRTW_M) << DDR_TRTW_S)
+#define DDR_TRTP_S              17
+#define DDR_TRTP_M              0xf
+#define DDR_TRTP(x)             (((x) & DDR_TRTP_M) << DDR_TRTP_S)
+#define DDR_TWTR_S              21
+#define DDR_TWTR_M              0x1f
+#define DDR_TWTR(x)             (((x) & DDR_TWTR_M) << DDR_TWTR_S)
+#define DDR_G_OPEN_L_S          26
+#define DDR_G_OPEN_L_M          0xf
+#define DDR_G_OPEN_L(x)         ((x) << DDR_G_OPEN_L_S)
+#define DDR_HALF_WIDTH_LOW      BIT(31)
+#define DDR1_CONF2_REG_VAL      (DDR_BURST_LEN(8) | DDR_CNTL_OE_EN | \
+                                DDR_CKE | DDR_TWR(13) | DDR_TRTW(14) | \
+                                DDR_TRTP(8) | DDR_TWTR(14) | \
+                                DDR_G_OPEN_L(6) | DDR_HALF_WIDTH_LOW)
+#define DDR2_CONF2_REG_VAL      (DDR_BURST_LEN(8) | DDR_CNTL_OE_EN | \
+                                DDR_CKE | DDR_TWR(1) | DDR_TRTW(14) | \
+                                DDR_TRTP(9) | DDR_TWTR(21) | \
+                                DDR_G_OPEN_L(8) | DDR_HALF_WIDTH_LOW)
+
+#define DDR_TWR_MSB             BIT(3)
+#define DDR_TRAS_MSB            BIT(2)
+#define DDR_TRFC_MSB_M          0x3
+#define DDR_TRFC_MSB(x)         (x)
+#define DDR1_CONF3_REG_VAL      0
+#define DDR2_CONF3_REG_VAL      (DDR_TWR_MSB | DDR_TRFC_MSB(2))
+
+#define DDR_CTL_SRAM_TSEL       BIT(30)
+#define DDR_CTL_SRAM_GE0_SYNC   BIT(20)
+#define DDR_CTL_SRAM_GE1_SYNC   BIT(19)
+#define DDR_CTL_SRAM_USB_SYNC   BIT(18)
+#define DDR_CTL_SRAM_PCIE_SYNC  BIT(17)
+#define DDR_CTL_SRAM_WMAC_SYNC  BIT(16)
+#define DDR_CTL_SRAM_MISC1_SYNC BIT(15)
+#define DDR_CTL_SRAM_MISC2_SYNC BIT(14)
+#define DDR_CTL_PAD_DDR2_SEL    BIT(6)
+#define DDR_CTL_HALF_WIDTH      BIT(1)
+#define DDR_CTL_CONFIG_VAL      (DDR_CTL_SRAM_TSEL | \
+                                DDR_CTL_SRAM_GE0_SYNC | \
+                                DDR_CTL_SRAM_GE1_SYNC | \
+                                DDR_CTL_SRAM_USB_SYNC | \
+                                DDR_CTL_SRAM_PCIE_SYNC | \
+                                DDR_CTL_SRAM_WMAC_SYNC | \
+                                DDR_CTL_HALF_WIDTH)
+
+#define DDR_BURST_GE0_MAX_BL_S  0
+#define DDR_BURST_GE0_MAX_BL_M  0xf
+#define DDR_BURST_GE0_MAX_BL(x) \
+       (((x) & DDR_BURST_GE0_MAX_BL_M) << DDR_BURST_GE0_MAX_BL_S)
+#define DDR_BURST_GE1_MAX_BL_S  4
+#define DDR_BURST_GE1_MAX_BL_M  0xf
+#define DDR_BURST_GE1_MAX_BL(x) \
+       (((x) & DDR_BURST_GE1_MAX_BL_M) << DDR_BURST_GE1_MAX_BL_S)
+#define DDR_BURST_PCIE_MAX_BL_S 8
+#define DDR_BURST_PCIE_MAX_BL_M 0xf
+#define DDR_BURST_PCIE_MAX_BL(x) \
+       (((x) & DDR_BURST_PCIE_MAX_BL_M) << DDR_BURST_PCIE_MAX_BL_S)
+#define DDR_BURST_USB_MAX_BL_S  12
+#define DDR_BURST_USB_MAX_BL_M  0xf
+#define DDR_BURST_USB_MAX_BL(x) \
+       (((x) & DDR_BURST_USB_MAX_BL_M) << DDR_BURST_USB_MAX_BL_S)
+#define DDR_BURST_CPU_MAX_BL_S  16
+#define DDR_BURST_CPU_MAX_BL_M  0xf
+#define DDR_BURST_CPU_MAX_BL(x) \
+       (((x) & DDR_BURST_CPU_MAX_BL_M) << DDR_BURST_CPU_MAX_BL_S)
+#define DDR_BURST_RD_MAX_BL_S   20
+#define DDR_BURST_RD_MAX_BL_M   0xf
+#define DDR_BURST_RD_MAX_BL(x) \
+       (((x) & DDR_BURST_RD_MAX_BL_M) << DDR_BURST_RD_MAX_BL_S)
+#define DDR_BURST_WR_MAX_BL_S   24
+#define DDR_BURST_WR_MAX_BL_M   0xf
+#define DDR_BURST_WR_MAX_BL(x) \
+       (((x) & DDR_BURST_WR_MAX_BL_M) << DDR_BURST_WR_MAX_BL_S)
+#define DDR_BURST_RWP_MASK_EN_S 28
+#define DDR_BURST_RWP_MASK_EN_M 0x3
+#define DDR_BURST_RWP_MASK_EN(x) \
+       (((x) & DDR_BURST_RWP_MASK_EN_M) << DDR_BURST_RWP_MASK_EN_S)
+#define DDR_BURST_CPU_PRI_BE    BIT(30)
+#define DDR_BURST_CPU_PRI       BIT(31)
+#define DDR_BURST_VAL           (DDR_BURST_CPU_PRI_BE | \
+                                DDR_BURST_RWP_MASK_EN(3) | \
+                                DDR_BURST_WR_MAX_BL(4) | \
+                                DDR_BURST_RD_MAX_BL(4) | \
+                                DDR_BURST_CPU_MAX_BL(4) | \
+                                DDR_BURST_USB_MAX_BL(4) | \
+                                DDR_BURST_PCIE_MAX_BL(4) | \
+                                DDR_BURST_GE1_MAX_BL(4) | \
+                                DDR_BURST_GE0_MAX_BL(4))
+
+#define DDR_BURST_WMAC_MAX_BL_S 0
+#define DDR_BURST_WMAC_MAX_BL_M 0xf
+#define DDR_BURST_WMAC_MAX_BL(x) \
+       (((x) & DDR_BURST_WMAC_MAX_BL_M) << DDR_BURST_WMAC_MAX_BL_S)
+#define DDR_BURST2_VAL          DDR_BURST_WMAC_MAX_BL(4)
+
+#define DDR2_CONF_TWL_S         10
+#define DDR2_CONF_TWL_M         0xf
+#define DDR2_CONF_TWL(x) \
+       (((x) & DDR2_CONF_TWL_M) << DDR2_CONF_TWL_S)
+#define DDR2_CONF_ODT           BIT(9)
+#define DDR2_CONF_TFAW_S        2
+#define DDR2_CONF_TFAW_M        0x3f
+#define DDR2_CONF_TFAW(x) \
+       (((x) & DDR2_CONF_TFAW_M) << DDR2_CONF_TFAW_S)
+#define DDR2_CONF_EN            BIT(0)
+#define DDR2_CONF_VAL           (DDR2_CONF_TWL(5) | \
+                                DDR2_CONF_TFAW(31) | \
+                                DDR2_CONF_ODT | \
+                                DDR2_CONF_EN)
+
+#define DDR1_EXT_MODE_VAL       0
+#define DDR2_EXT_MODE_VAL       0x402
+#define DDR2_EXT_MODE_OCD_VAL   0x782
+#define DDR1_MODE_DLL_VAL       0x133
+#define DDR2_MODE_DLL_VAL       0x143
+#define DDR1_MODE_VAL           0x33
+#define DDR2_MODE_VAL           0x43
+#define DDR1_TAP_VAL            0x20
+#define DDR2_TAP_VAL            0x10
+
+#define DDR_REG_BIST_MASK_ADDR_0        0x2c
+#define DDR_REG_BIST_MASK_ADDR_1        0x30
+#define DDR_REG_BIST_MASK_AHB_GE0_0     0x34
+#define DDR_REG_BIST_COMP_AHB_GE0_0     0x38
+#define DDR_REG_BIST_MASK_AHB_GE1_0     0x3c
+#define DDR_REG_BIST_COMP_AHB_GE1_0     0x40
+#define DDR_REG_BIST_COMP_ADDR_0        0x64
+#define DDR_REG_BIST_COMP_ADDR_1        0x68
+#define DDR_REG_BIST_MASK_AHB_GE0_1     0x6c
+#define DDR_REG_BIST_COMP_AHB_GE0_1     0x70
+#define DDR_REG_BIST_MASK_AHB_GE1_1     0x74
+#define DDR_REG_BIST_COMP_AHB_GE1_1     0x78
+#define DDR_REG_BIST                    0x11c
+#define DDR_REG_BIST_STATUS             0x120
+
+#define DDR_BIST_COMP_CNT_S     1
+#define DDR_BIST_COMP_CNT_M     0xff
+#define DDR_BIST_COMP_CNT(x) \
+       (((x) & DDR_BIST_COMP_CNT_M) << DDR_BIST_COMP_CNT_S)
+#define DDR_BIST_COMP_CNT_MASK \
+       (DDR_BIST_COMP_CNT_M << DDR_BIST_COMP_CNT_S)
+#define DDR_BIST_TEST_START     BIT(0)
+#define DDR_BIST_STATUS_DONE    BIT(0)
+
+/* 4 Row Address Bits, 4 Column Address Bits, 2 BA bits */
+#define DDR_BIST_MASK_ADDR_VAL  0xfa5de83f
+
+#define DDR_TAP_MAGIC_VAL       0xaa55aa55
+#define DDR_TAP_MAX_VAL         0x40
+
+void ddr_init(void)
+{
+       void __iomem *regs;
+       u32 val;
+
+       regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
+                          MAP_NOCACHE);
+       val = get_bootstrap();
+       if (val & QCA953X_BOOTSTRAP_DDR1) {
+               writel(DDR_CTL_CONFIG_VAL, regs + QCA953X_DDR_REG_CTL_CONF);
+               udelay(10);
+
+               /* For 16-bit DDR */
+               writel(0xffff, regs + AR71XX_DDR_REG_RD_CYCLE);
+               udelay(100);
+
+               /* Burst size */
+               writel(DDR_BURST_VAL, regs + QCA953X_DDR_REG_BURST);
+               udelay(100);
+               writel(DDR_BURST2_VAL, regs + QCA953X_DDR_REG_BURST2);
+               udelay(100);
+
+               /* AHB maximum timeout */
+               writel(0xfffff, regs + QCA953X_DDR_REG_TIMEOUT_MAX);
+               udelay(100);
+
+               /* DRAM timing */
+               writel(DDR1_CONF_REG_VAL, regs + AR71XX_DDR_REG_CONFIG);
+               udelay(100);
+               writel(DDR1_CONF2_REG_VAL, regs + AR71XX_DDR_REG_CONFIG2);
+               udelay(100);
+               writel(DDR1_CONF3_REG_VAL, regs + QCA953X_DDR_REG_CONFIG3);
+               udelay(100);
+
+               /* Precharge All */
+               writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* ODT disable, Full strength, Enable DLL */
+               writel(DDR1_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
+               udelay(100);
+
+               /* Update Extended Mode Register Set (EMRS) */
+               writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Reset DLL, CAS Latency 3, Burst Length 8 */
+               writel(DDR1_MODE_DLL_VAL, regs + AR71XX_DDR_REG_MODE);
+               udelay(100);
+
+               /* Update Mode Register Set (MRS) */
+               writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Precharge All */
+               writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Auto Refresh */
+               writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+               writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Normal DLL, CAS Latency 3, Burst Length 8 */
+               writel(DDR1_MODE_VAL, regs + AR71XX_DDR_REG_MODE);
+               udelay(100);
+
+               /* Update Mode Register Set (MRS) */
+               writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Refresh time control */
+               writel(DDR_REFRESH_VAL, regs + AR71XX_DDR_REG_REFRESH);
+               udelay(100);
+
+               /* DQS 0 Tap Control */
+               writel(DDR1_TAP_VAL, regs + AR71XX_DDR_REG_TAP_CTRL0);
+
+               /* DQS 1 Tap Control */
+               writel(DDR1_TAP_VAL, regs + AR71XX_DDR_REG_TAP_CTRL1);
+       } else {
+               writel(DDR_CTRL_UPD_EMR2S, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(10);
+               writel(DDR_CTRL_UPD_EMR3S, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(10);
+               writel(DDR_CTL_CONFIG_VAL | DDR_CTL_PAD_DDR2_SEL,
+                      regs + QCA953X_DDR_REG_CTL_CONF);
+               udelay(10);
+
+               /* For 16-bit DDR */
+               writel(0xffff, regs + AR71XX_DDR_REG_RD_CYCLE);
+               udelay(100);
+
+               /* Burst size */
+               writel(DDR_BURST_VAL, regs + QCA953X_DDR_REG_BURST);
+               udelay(100);
+               writel(DDR_BURST2_VAL, regs + QCA953X_DDR_REG_BURST2);
+               udelay(100);
+
+               /* AHB maximum timeout */
+               writel(0xfffff, regs + QCA953X_DDR_REG_TIMEOUT_MAX);
+               udelay(100);
+
+               /* DRAM timing */
+               writel(DDR2_CONF_REG_VAL, regs + AR71XX_DDR_REG_CONFIG);
+               udelay(100);
+               writel(DDR2_CONF2_REG_VAL, regs + AR71XX_DDR_REG_CONFIG2);
+               udelay(100);
+               writel(DDR2_CONF3_REG_VAL, regs + QCA953X_DDR_REG_CONFIG3);
+               udelay(100);
+
+               /* Enable DDR2 */
+               writel(DDR2_CONF_VAL, regs + QCA953X_DDR_REG_DDR2_CONFIG);
+               udelay(100);
+
+               /* Precharge All */
+               writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Update Extended Mode Register 2 Set (EMR2S) */
+               writel(DDR_CTRL_UPD_EMR2S, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Update Extended Mode Register 3 Set (EMR3S) */
+               writel(DDR_CTRL_UPD_EMR3S, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* 150 ohm, Reduced strength, Enable DLL */
+               writel(DDR2_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
+               udelay(100);
+
+               /* Update Extended Mode Register Set (EMRS) */
+               writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Reset DLL, CAS Latency 4, Burst Length 8 */
+               writel(DDR2_MODE_DLL_VAL, regs + AR71XX_DDR_REG_MODE);
+               udelay(100);
+
+               /* Update Mode Register Set (MRS) */
+               writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Precharge All */
+               writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Auto Refresh */
+               writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+               writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Normal DLL, CAS Latency 4, Burst Length 8 */
+               writel(DDR2_MODE_VAL, regs + AR71XX_DDR_REG_MODE);
+               udelay(100);
+
+               /* Mode Register Set (MRS) */
+               writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Enable OCD, Enable DLL, Reduced Drive Strength */
+               writel(DDR2_EXT_MODE_OCD_VAL, regs + AR71XX_DDR_REG_EMR);
+               udelay(100);
+
+               /* Update Extended Mode Register Set (EMRS) */
+               writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* OCD diable, Enable DLL, Reduced Drive Strength */
+               writel(DDR2_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
+               udelay(100);
+
+               /* Update Extended Mode Register Set (EMRS) */
+               writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
+               udelay(100);
+
+               /* Refresh time control */
+               writel(DDR_REFRESH_VAL, regs + AR71XX_DDR_REG_REFRESH);
+               udelay(100);
+
+               /* DQS 0 Tap Control */
+               writel(DDR2_TAP_VAL, regs + AR71XX_DDR_REG_TAP_CTRL0);
+
+               /* DQS 1 Tap Control */
+               writel(DDR2_TAP_VAL, regs + AR71XX_DDR_REG_TAP_CTRL1);
+       }
+}
+
+void ddr_tap_tuning(void)
+{
+       void __iomem *regs;
+       u32 val, pass, tap, cnt, tap_val, last, first;
+
+       regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
+                          MAP_NOCACHE);
+
+       tap_val = readl(regs + AR71XX_DDR_REG_TAP_CTRL0);
+       first = DDR_TAP_MAGIC_VAL;
+       last = 0;
+       cnt = 0;
+       tap = 0;
+
+       do {
+               writel(tap, regs + AR71XX_DDR_REG_TAP_CTRL0);
+               writel(tap, regs + AR71XX_DDR_REG_TAP_CTRL1);
+
+               writel(DDR_BIST_COMP_CNT(8), regs + DDR_REG_BIST_COMP_ADDR_1);
+               writel(DDR_BIST_MASK_ADDR_VAL, regs + DDR_REG_BIST_MASK_ADDR_0);
+               writel(0xffff, regs + DDR_REG_BIST_COMP_AHB_GE0_1);
+               writel(0xffff, regs + DDR_REG_BIST_COMP_AHB_GE1_0);
+               writel(0xffff, regs + DDR_REG_BIST_COMP_AHB_GE1_1);
+               writel(0xffff, regs + DDR_REG_BIST_MASK_AHB_GE0_0);
+               writel(0xffff, regs + DDR_REG_BIST_MASK_AHB_GE0_1);
+               writel(0xffff, regs + DDR_REG_BIST_MASK_AHB_GE1_0);
+               writel(0xffff, regs + DDR_REG_BIST_MASK_AHB_GE1_1);
+               writel(0xffff, regs + DDR_REG_BIST_COMP_AHB_GE0_0);
+
+               /* Start BIST test */
+               writel(DDR_BIST_TEST_START, regs + DDR_REG_BIST);
+
+               do {
+                       val = readl(regs + DDR_REG_BIST_STATUS);
+               } while (!(val & DDR_BIST_STATUS_DONE));
+
+               /* Stop BIST test */
+               writel(0, regs + DDR_REG_BIST);
+
+               pass = val & DDR_BIST_COMP_CNT_MASK;
+               pass ^= DDR_BIST_COMP_CNT(8);
+               if (!pass) {
+                       if (first != DDR_TAP_MAGIC_VAL) {
+                               last = tap;
+                       } else  {
+                               first = tap;
+                               last = tap;
+                       }
+                       cnt++;
+               }
+               tap++;
+       } while (tap < DDR_TAP_MAX_VAL);
+
+       if (cnt) {
+               tap_val = (first + last) / 2;
+               tap_val %= DDR_TAP_MAX_VAL;
+       }
+
+       writel(tap_val, regs + AR71XX_DDR_REG_TAP_CTRL0);
+       writel(tap_val, regs + AR71XX_DDR_REG_TAP_CTRL1);
+}
diff --git a/arch/mips/mach-ath79/qca953x/lowlevel_init.S b/arch/mips/mach-ath79/qca953x/lowlevel_init.S
new file mode 100644 (file)
index 0000000..d7038fa
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ * Based on Atheros LSDK/QSDK
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <mach/ar71xx_regs.h>
+
+#define MK_PLL_CONF(divint, refdiv, range, outdiv) \
+     (((0x3F & divint) << 10) | \
+     ((0x1F & refdiv) << 16) | \
+     ((0x1 & range)   << 21) | \
+     ((0x7 & outdiv)  << 23) )
+
+#define MK_CLK_CNTL(cpudiv, ddrdiv, ahbdiv) \
+    (((0x3 & (cpudiv - 1)) << 5)  | \
+    ((0x3 & (ddrdiv - 1)) << 10) | \
+    ((0x3 & (ahbdiv - 1)) << 15) )
+
+#define SET_FIELD(name, v)      (((v) & QCA953X_##name##_MASK) << \
+                                QCA953X_##name##_SHIFT)
+
+#define DPLL2_KI(v)             SET_FIELD(SRIF_DPLL2_KI, v)
+#define DPLL2_KD(v)             SET_FIELD(SRIF_DPLL2_KD, v)
+#define DPLL2_PWD               QCA953X_SRIF_DPLL2_PWD
+#define MK_DPLL2(ki, kd)        (DPLL2_KI(ki) | DPLL2_KD(kd) | DPLL2_PWD)
+
+#define PLL_CPU_NFRAC(v)        SET_FIELD(PLL_CPU_CONFIG_NFRAC, v)
+#define PLL_CPU_NINT(v)         SET_FIELD(PLL_CPU_CONFIG_NINT, v)
+#define PLL_CPU_REFDIV(v)       SET_FIELD(PLL_CPU_CONFIG_REFDIV, v)
+#define PLL_CPU_OUTDIV(v)       SET_FIELD(PLL_CPU_CONFIG_OUTDIV, v)
+#define MK_PLL_CPU_CONF(frac, nint, ref, outdiv) \
+                               (PLL_CPU_NFRAC(frac) | \
+                                PLL_CPU_NINT(nint) | \
+                                PLL_CPU_REFDIV(ref) | \
+                                PLL_CPU_OUTDIV(outdiv))
+
+#define PLL_DDR_NFRAC(v)        SET_FIELD(PLL_DDR_CONFIG_NFRAC, v)
+#define PLL_DDR_NINT(v)         SET_FIELD(PLL_DDR_CONFIG_NINT, v)
+#define PLL_DDR_REFDIV(v)       SET_FIELD(PLL_DDR_CONFIG_REFDIV, v)
+#define PLL_DDR_OUTDIV(v)       SET_FIELD(PLL_DDR_CONFIG_OUTDIV, v)
+#define MK_PLL_DDR_CONF(frac, nint, ref, outdiv) \
+                               (PLL_DDR_NFRAC(frac) | \
+                                PLL_DDR_REFDIV(ref) | \
+                                PLL_DDR_NINT(nint) | \
+                                PLL_DDR_OUTDIV(outdiv) | \
+                                QCA953X_PLL_CONFIG_PWD)
+
+#define PLL_CPU_CONF_VAL        MK_PLL_CPU_CONF(0, 26, 1, 0)
+#define PLL_DDR_CONF_VAL        MK_PLL_DDR_CONF(0, 15, 1, 0)
+
+#define PLL_CLK_CTRL_PLL_BYPASS (QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS | \
+                                QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS | \
+                                QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
+
+#define PLL_CLK_CTRL_CPU_DIV(v) SET_FIELD(PLL_CLK_CTRL_CPU_POST_DIV, v)
+#define PLL_CLK_CTRL_DDR_DIV(v) SET_FIELD(PLL_CLK_CTRL_DDR_POST_DIV, v)
+#define PLL_CLK_CTRL_AHB_DIV(v) SET_FIELD(PLL_CLK_CTRL_AHB_POST_DIV, v)
+#define MK_PLL_CLK_CTRL(cpu, ddr, ahb) \
+                               (PLL_CLK_CTRL_CPU_DIV(cpu) | \
+                                PLL_CLK_CTRL_DDR_DIV(ddr) | \
+                                PLL_CLK_CTRL_AHB_DIV(ahb))
+#define PLL_CLK_CTRL_VAL    (MK_PLL_CLK_CTRL(0, 0, 2) | \
+                            PLL_CLK_CTRL_PLL_BYPASS | \
+                            QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL | \
+                            QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
+
+#define PLL_DDR_DIT_FRAC_MAX(v)     SET_FIELD(PLL_DDR_DIT_FRAC_MAX, v)
+#define PLL_DDR_DIT_FRAC_MIN(v)     SET_FIELD(PLL_DDR_DIT_FRAC_MIN, v)
+#define PLL_DDR_DIT_FRAC_STEP(v)    SET_FIELD(PLL_DDR_DIT_FRAC_STEP, v)
+#define PLL_DDR_DIT_UPD_CNT(v)      SET_FIELD(PLL_DDR_DIT_UPD_CNT, v)
+#define PLL_CPU_DIT_FRAC_MAX(v)     SET_FIELD(PLL_CPU_DIT_FRAC_MAX, v)
+#define PLL_CPU_DIT_FRAC_MIN(v)     SET_FIELD(PLL_CPU_DIT_FRAC_MIN, v)
+#define PLL_CPU_DIT_FRAC_STEP(v)    SET_FIELD(PLL_CPU_DIT_FRAC_STEP, v)
+#define PLL_CPU_DIT_UPD_CNT(v)      SET_FIELD(PLL_CPU_DIT_UPD_CNT, v)
+#define MK_PLL_DDR_DIT_FRAC(max, min, step, cnt) \
+                               (QCA953X_PLL_DIT_FRAC_EN | \
+                                PLL_DDR_DIT_FRAC_MAX(max) | \
+                                PLL_DDR_DIT_FRAC_MIN(min) | \
+                                PLL_DDR_DIT_FRAC_STEP(step) | \
+                                PLL_DDR_DIT_UPD_CNT(cnt))
+#define MK_PLL_CPU_DIT_FRAC(max, min, step, cnt) \
+                               (QCA953X_PLL_DIT_FRAC_EN | \
+                                PLL_CPU_DIT_FRAC_MAX(max) | \
+                                PLL_CPU_DIT_FRAC_MIN(min) | \
+                                PLL_CPU_DIT_FRAC_STEP(step) | \
+                                PLL_CPU_DIT_UPD_CNT(cnt))
+#define PLL_CPU_DIT_FRAC_VAL    MK_PLL_CPU_DIT_FRAC(63, 0, 1, 15)
+#define PLL_DDR_DIT_FRAC_VAL    MK_PLL_DDR_DIT_FRAC(763, 635, 1, 15)
+
+    .text
+    .set noreorder
+
+LEAF(lowlevel_init)
+       /* RTC Reset */
+       li      t0, CKSEG1ADDR(AR71XX_RESET_BASE)
+       lw      t1, QCA953X_RESET_REG_RESET_MODULE(t0)
+       li      t2, 0x08000000
+       or      t1, t1, t2
+       sw      t1, QCA953X_RESET_REG_RESET_MODULE(t0)
+       nop
+       lw      t1, QCA953X_RESET_REG_RESET_MODULE(t0)
+       li      t2, 0xf7ffffff
+       and     t1, t1, t2
+       sw      t1, QCA953X_RESET_REG_RESET_MODULE(t0)
+       nop
+
+       /* RTC Force Wake */
+       li      t0, CKSEG1ADDR(QCA953X_RTC_BASE)
+       li      t1, 0x01
+       sw      t1, QCA953X_RTC_REG_SYNC_RESET(t0)
+       nop
+       nop
+
+       /* Wait for RTC in on state */
+1:
+       lw      t1, QCA953X_RTC_REG_SYNC_STATUS(t0)
+       andi    t1, t1, 0x02
+       beqz    t1, 1b
+       nop
+
+       li      t0, CKSEG1ADDR(QCA953X_SRIF_BASE)
+       li      t1, MK_DPLL2(2, 16)
+       sw      t1, QCA953X_SRIF_BB_DPLL2_REG(t0)
+       sw      t1, QCA953X_SRIF_PCIE_DPLL2_REG(t0)
+       sw      t1, QCA953X_SRIF_DDR_DPLL2_REG(t0)
+       sw      t1, QCA953X_SRIF_CPU_DPLL2_REG(t0)
+
+       li      t0, CKSEG1ADDR(AR71XX_PLL_BASE)
+       lw      t1, QCA953X_PLL_CLK_CTRL_REG(t0)
+       ori     t1, PLL_CLK_CTRL_PLL_BYPASS
+       sw      t1, QCA953X_PLL_CLK_CTRL_REG(t0)
+       nop
+
+       li      t1, PLL_CPU_CONF_VAL
+       sw      t1, QCA953X_PLL_CPU_CONFIG_REG(t0)
+       nop
+
+       li      t1, PLL_DDR_CONF_VAL
+       sw      t1, QCA953X_PLL_DDR_CONFIG_REG(t0)
+       nop
+
+       li      t1, PLL_CLK_CTRL_VAL
+       sw      t1, QCA953X_PLL_CLK_CTRL_REG(t0)
+       nop
+
+       lw      t1, QCA953X_PLL_CPU_CONFIG_REG(t0)
+       li      t2, ~QCA953X_PLL_CONFIG_PWD
+       and     t1, t1, t2
+       sw      t1, QCA953X_PLL_CPU_CONFIG_REG(t0)
+       nop
+
+       lw      t1, QCA953X_PLL_DDR_CONFIG_REG(t0)
+       li      t2, ~QCA953X_PLL_CONFIG_PWD
+       and     t1, t1, t2
+       sw      t1, QCA953X_PLL_DDR_CONFIG_REG(t0)
+       nop
+
+       lw      t1, QCA953X_PLL_CLK_CTRL_REG(t0)
+       li      t2, ~PLL_CLK_CTRL_PLL_BYPASS
+       and     t1, t1, t2
+       sw      t1, QCA953X_PLL_CLK_CTRL_REG(t0)
+       nop
+
+       li      t1, PLL_DDR_DIT_FRAC_VAL
+       sw      t1, QCA953X_PLL_DDR_DIT_FRAC_REG(t0)
+       nop
+
+       li      t1, PLL_CPU_DIT_FRAC_VAL
+       sw      t1, QCA953X_PLL_CPU_DIT_FRAC_REG(t0)
+       nop
+
+       li      t0, CKSEG1ADDR(AR71XX_RESET_BASE)
+       lui     t1, 0x03fc
+       sw      t1, 0xb4(t0)
+
+       nop
+       jr ra
+        nop
+    END(lowlevel_init)
diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c
new file mode 100644 (file)
index 0000000..188eccb
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ath79.h>
+#include <mach/ar71xx_regs.h>
+
+void _machine_restart(void)
+{
+       void __iomem *base;
+       u32 reg = 0;
+
+       base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+                          MAP_NOCACHE);
+       if (soc_is_ar71xx())
+               reg = AR71XX_RESET_REG_RESET_MODULE;
+       else if (soc_is_ar724x())
+               reg = AR724X_RESET_REG_RESET_MODULE;
+       else if (soc_is_ar913x())
+               reg = AR913X_RESET_REG_RESET_MODULE;
+       else if (soc_is_ar933x())
+               reg = AR933X_RESET_REG_RESET_MODULE;
+       else if (soc_is_ar934x())
+               reg = AR934X_RESET_REG_RESET_MODULE;
+       else if (soc_is_qca953x())
+               reg = QCA953X_RESET_REG_RESET_MODULE;
+       else if (soc_is_qca955x())
+               reg = QCA955X_RESET_REG_RESET_MODULE;
+       else if (soc_is_qca956x())
+               reg = QCA956X_RESET_REG_RESET_MODULE;
+       else
+               puts("Reset register not defined for this SOC\n");
+
+       if (reg)
+               setbits_be32(base + reg, AR71XX_RESET_FULL_CHIP);
+
+       while (1)
+               /* NOP */;
+}
+
+u32 get_bootstrap(void)
+{
+       void __iomem *base;
+       u32 reg = 0;
+
+       base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+                          MAP_NOCACHE);
+       if (soc_is_ar933x())
+               reg = AR933X_RESET_REG_BOOTSTRAP;
+       else if (soc_is_ar934x())
+               reg = AR934X_RESET_REG_BOOTSTRAP;
+       else if (soc_is_qca953x())
+               reg = QCA953X_RESET_REG_BOOTSTRAP;
+       else if (soc_is_qca955x())
+               reg = QCA955X_RESET_REG_BOOTSTRAP;
+       else if (soc_is_qca956x())
+               reg = QCA956X_RESET_REG_BOOTSTRAP;
+       else
+               puts("Bootstrap register not defined for this SOC\n");
+
+       if (reg)
+               return readl(base + reg);
+
+       return 0;
+}
+
+static int eth_init_ar933x(void)
+{
+       void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+                                         MAP_NOCACHE);
+       void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+                                         MAP_NOCACHE);
+       void __iomem *gregs = map_physmem(AR933X_GMAC_BASE, AR933X_GMAC_SIZE,
+                                         MAP_NOCACHE);
+       const u32 mask = AR933X_RESET_GE0_MAC | AR933X_RESET_GE0_MDIO |
+                        AR933X_RESET_GE1_MAC | AR933X_RESET_GE1_MDIO |
+                        AR933X_RESET_ETH_SWITCH;
+
+       /* Clear MDIO slave EN bit. */
+       clrbits_be32(rregs + AR933X_RESET_REG_BOOTSTRAP, BIT(17));
+       mdelay(10);
+
+       /* Get Atheros S26 PHY out of reset. */
+       clrsetbits_be32(pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG,
+                       0x1f, 0x10);
+       mdelay(10);
+
+       setbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
+       mdelay(10);
+       clrbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
+       mdelay(10);
+
+       /* Configure AR93xx GMAC register. */
+       clrsetbits_be32(gregs + AR933X_GMAC_REG_ETH_CFG,
+                       AR933X_ETH_CFG_MII_GE0_MASTER |
+                       AR933X_ETH_CFG_MII_GE0_SLAVE,
+                       AR933X_ETH_CFG_MII_GE0_SLAVE);
+       return 0;
+}
+
+static int eth_init_ar934x(void)
+{
+       void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+                                         MAP_NOCACHE);
+       void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+                                         MAP_NOCACHE);
+       void __iomem *gregs = map_physmem(AR934X_GMAC_BASE, AR934X_GMAC_SIZE,
+                                         MAP_NOCACHE);
+       const u32 mask = AR934X_RESET_GE0_MAC | AR934X_RESET_GE0_MDIO |
+                        AR934X_RESET_GE1_MAC | AR934X_RESET_GE1_MDIO |
+                        AR934X_RESET_ETH_SWITCH_ANALOG;
+       u32 reg;
+
+       reg = readl(rregs + AR934X_RESET_REG_BOOTSTRAP);
+       if (reg & AR934X_BOOTSTRAP_REF_CLK_40)
+               writel(0x570, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
+       else
+               writel(0x271, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
+       writel(BIT(26) | BIT(25), pregs + AR934X_PLL_ETH_XMII_CONTROL_REG);
+
+       setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
+       mdelay(1);
+       clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
+       mdelay(1);
+
+       /* Configure AR934x GMAC register. */
+       writel(AR934X_ETH_CFG_RGMII_GMAC0, gregs + AR934X_GMAC_REG_ETH_CFG);
+       return 0;
+}
+
+int ath79_eth_reset(void)
+{
+       /*
+        * Un-reset ethernet. DM still doesn't have any notion of reset
+        * framework, so we do it by hand here.
+        */
+       if (soc_is_ar933x())
+               return eth_init_ar933x();
+       if (soc_is_ar934x())
+               return eth_init_ar934x();
+
+       return -EINVAL;
+}
+
+static int usb_reset_ar933x(void __iomem *reset_regs)
+{
+       /* Ungate the USB block */
+       setbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
+                    AR933X_RESET_USBSUS_OVERRIDE);
+       mdelay(1);
+       clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
+                    AR933X_RESET_USB_HOST);
+       mdelay(1);
+       clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
+                    AR933X_RESET_USB_PHY);
+       mdelay(1);
+
+       return 0;
+}
+
+static int usb_reset_ar934x(void __iomem *reset_regs)
+{
+       /* Ungate the USB block */
+       setbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
+                    AR934X_RESET_USBSUS_OVERRIDE);
+       mdelay(1);
+       clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
+                    AR934X_RESET_USB_PHY);
+       mdelay(1);
+       clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
+                    AR934X_RESET_USB_PHY_ANALOG);
+       mdelay(1);
+       clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
+                    AR934X_RESET_USB_HOST);
+       mdelay(1);
+
+       return 0;
+}
+
+int ath79_usb_reset(void)
+{
+       void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE,
+                                             AR71XX_USB_CTRL_SIZE,
+                                             MAP_NOCACHE);
+       void __iomem *reset_regs = map_physmem(AR71XX_RESET_BASE,
+                                              AR71XX_RESET_SIZE,
+                                              MAP_NOCACHE);
+       /*
+        * Turn on the Buff and Desc swap bits.
+        * NOTE: This write into an undocumented register in mandatory to
+        *       get the USB controller operational in BigEndian mode.
+        */
+       writel(0xf0000, usbc_regs + AR71XX_USB_CTRL_REG_CONFIG);
+
+       if (soc_is_ar933x())
+               return usb_reset_ar933x(reset_regs);
+       if (soc_is_ar934x())
+               return usb_reset_ar934x(reset_regs);
+
+       return -EINVAL;
+}
index cbbc8342735946436abfaef674887c98d9d95d7b..d2586f94f51fc1e68f2ce449b421cb9637980174 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <asm/types.h>
 
-typedef struct fsl_i2c {
+typedef struct fsl_i2c_base {
 
        u8 adr;         /* I2C slave address */
        u8 res0[3];
@@ -68,4 +68,14 @@ typedef struct fsl_i2c {
        u8 res6[0xE8];
 } fsl_i2c_t;
 
+#ifdef CONFIG_DM_I2C
+struct fsl_i2c_dev {
+       struct fsl_i2c_base __iomem *base;      /* register base */
+       u32 i2c_clk;
+       u32 index;
+       u8 slaveadd;
+       uint speed;
+};
+#endif
+
 #endif /* _ASM_I2C_H_ */
index 53ca6d94d644b93bc553bc6f02c811db232a15a0..07d2adf71f1d8777107ee57bdaca84e39246a46e 100644 (file)
@@ -120,8 +120,8 @@ typedef struct ccsr_local_ecm {
 
 /* I2C Registers */
 typedef struct ccsr_i2c {
-       struct fsl_i2c  i2c[1];
-       u8      res[4096 - 1 * sizeof(struct fsl_i2c)];
+       struct fsl_i2c_base     i2c[1];
+       u8      res[4096 - 1 * sizeof(struct fsl_i2c_base)];
 } ccsr_i2c_t;
 
 #if defined(CONFIG_MPC8540) \
index 177918b7f967e7302bcbe0efffef71611f9e1871..b078569c45ebe824be7f16802242e40e1aac82e4 100644 (file)
@@ -92,8 +92,8 @@ typedef struct ccsr_local_mcm {
 
 /* Daul I2C Registers(0x3000-0x4000) */
 typedef struct ccsr_i2c {
-       struct fsl_i2c  i2c[2];
-       u8      res[4096 - 2 * sizeof(struct fsl_i2c)];
+       struct fsl_i2c_base     i2c[2];
+       u8      res[4096 - 2 * sizeof(struct fsl_i2c_base)];
 } ccsr_i2c_t;
 
 /* DUART Registers(0x4000-0x5000) */
index b87ee19427f10b489865a3b8cff2c6a2cda155d7..69196329d76a5924bb1969c4917910c000d17a29 100644 (file)
@@ -56,6 +56,21 @@ void outl(unsigned int value, unsigned int addr);
 void outw(unsigned int value, unsigned int addr);
 void outb(unsigned int value, unsigned int addr);
 
+static inline void _insw(volatile u16 *port, void *buf, int ns)
+{
+}
+
+static inline void _outsw(volatile u16 *port, const void *buf, int ns)
+{
+}
+
+#define insw(port, buf, ns)            _insw((u16 *)port, buf, ns)
+#define outsw(port, buf, ns)           _outsw((u16 *)port, buf, ns)
+
+/* For systemace.c */
+#define out16(addr, val)
+#define in16(addr)             0
+
 #include <iotrace.h>
 #include <asm/types.h>
 
index 4ef27dc87a38f1fbf421f40735292fcba7d3c833..396023eee8deaf057027cc291d1f284da69536c4 100644 (file)
@@ -47,6 +47,9 @@ source "arch/x86/cpu/queensbay/Kconfig"
 
 # architecture-specific options below
 
+config AHCI
+       default y
+
 config SYS_MALLOC_F_LEN
        default 0x800
 
index dfb8486d0621e2b663bc1cad219f2834745fc8a4..2e4708262c1daa41411a7acc9b3b1e37778d3fbe 100644 (file)
@@ -261,7 +261,7 @@ static const struct udevice_id broadwell_ahci_ids[] = {
 
 U_BOOT_DRIVER(ahci_broadwell_drv) = {
        .name           = "ahci_broadwell",
-       .id             = UCLASS_DISK,
+       .id             = UCLASS_AHCI,
        .of_match       = broadwell_ahci_ids,
        .ofdata_to_platdata     = broadwell_sata_ofdata_to_platdata,
        .probe          = broadwell_sata_probe,
index 93e4505e4de50d635e2e7dd2353437d9115f86fa..0fdef6f3690b50ef1c472fa07fd4b7d8de771634 100644 (file)
@@ -58,7 +58,7 @@ int cpu_common_init(void)
                return -ENODEV;
 
        /* Cause the SATA device to do its early init */
-       uclass_first_device(UCLASS_DISK, &dev);
+       uclass_first_device(UCLASS_AHCI, &dev);
 
        return 0;
 }
index 4c039ac9c67317f50acb2e25440968de8e8958b1..5b58d6c427e9a1547798b867cb4f363840dc522b 100644 (file)
@@ -162,7 +162,7 @@ static int bd82x6x_probe(struct udevice *dev)
                return 0;
 
        /* Cause the SATA device to do its init */
-       uclass_first_device(UCLASS_DISK, &dev);
+       uclass_first_device(UCLASS_AHCI, &dev);
 
        ret = syscon_get_by_driver_data(X86_SYSCON_GMA, &gma_dev);
        if (ret)
index c3d1057c291d5b9aaf022b275b520e00c673b7cd..1ce81959e3ff1ece17ea69855895acb3eff4571c 100644 (file)
@@ -233,7 +233,7 @@ static const struct udevice_id bd82x6x_ahci_ids[] = {
 
 U_BOOT_DRIVER(ahci_ivybridge_drv) = {
        .name           = "ahci_ivybridge",
-       .id             = UCLASS_DISK,
+       .id             = UCLASS_AHCI,
        .of_match       = bd82x6x_ahci_ids,
        .probe          = bd82x6x_sata_probe,
 };
index 2ed90de9d529d41c01bafec0c6ec92407eb97729..4740c8394c5fa699088c2316df10e11f4ea06597 100644 (file)
@@ -105,7 +105,7 @@ static int load_rescue_image(ulong addr)
 
        /* Detect storage device */
        for (devno = 0; devno < USB_MAX_STOR_DEV; devno++) {
-               stor_dev = usb_stor_get_dev(devno);
+               stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno);
                if (stor_dev->type != DEV_TYPE_UNKNOWN)
                        break;
        }
index 630446820cc5fc3bbff02f1194f0c5eb671da5ec..b5f1aa61cb8dd135ee10165c847fa555f9908a9e 100644 (file)
@@ -9,6 +9,9 @@
 
 #include <common.h>
 #include <i2c.h>
+#include <eeprom_layout.h>
+#include <eeprom_field.h>
+#include <linux/kernel.h>
 #include "eeprom.h"
 
 #ifndef CONFIG_SYS_I2C_EEPROM_ADDR
@@ -181,3 +184,344 @@ int cl_eeprom_get_product_name(uchar *buf, uint eeprom_bus)
 
        return err;
 }
+
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+/**
+ * eeprom_field_print_bin_ver() - print a "version field" which contains binary
+ *                               data
+ *
+ * Treat the field data as simple binary data, and print it formatted as a
+ * version number (2 digits after decimal point).
+ * The field size must be exactly 2 bytes.
+ *
+ * Sample output:
+ *      Field Name      123.45
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_bin_ver(const struct eeprom_field *field)
+{
+       if ((field->buf[0] == 0xff) && (field->buf[1] == 0xff)) {
+               field->buf[0] = 0;
+               field->buf[1] = 0;
+       }
+
+       printf(PRINT_FIELD_SEGMENT, field->name);
+       int major = (field->buf[1] << 8 | field->buf[0]) / 100;
+       int minor = (field->buf[1] << 8 | field->buf[0]) - major * 100;
+       printf("%d.%02d\n", major, minor);
+}
+
+/**
+ * eeprom_field_update_bin_ver() - update a "version field" which contains
+ *                                binary data
+ *
+ * This function takes a version string in the form of x.y (x and y are both
+ * decimal values, y is limited to two digits), translates it to the binary
+ * form, then writes it to the field. The field size must be exactly 2 bytes.
+ *
+ * This function strictly enforces the data syntax, and will not update the
+ * field if there's any deviation from it. It also protects from overflow.
+ *
+ * @field:     an initialized field
+ * @value:     a version string
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int eeprom_field_update_bin_ver(struct eeprom_field *field, char *value)
+{
+       char *endptr;
+       char *tok = strtok(value, ".");
+       if (tok == NULL)
+               return -1;
+
+       int num = simple_strtol(tok, &endptr, 0);
+       if (*endptr != '\0')
+               return -1;
+
+       tok = strtok(NULL, "");
+       if (tok == NULL)
+               return -1;
+
+       int remainder = simple_strtol(tok, &endptr, 0);
+       if (*endptr != '\0')
+               return -1;
+
+       num = num * 100 + remainder;
+       if (num >> 16)
+               return -1;
+
+       field->buf[0] = (unsigned char)num;
+       field->buf[1] = num >> 8;
+
+       return 0;
+}
+
+char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+/**
+ * eeprom_field_print_date() - print a field which contains date data
+ *
+ * Treat the field data as simple binary data, and print it formatted as a date.
+ * Sample output:
+ *      Field Name      07/Feb/2014
+ *      Field Name      56/BAD/9999
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_date(const struct eeprom_field *field)
+{
+       printf(PRINT_FIELD_SEGMENT, field->name);
+       printf("%02d/", field->buf[0]);
+       if (field->buf[1] >= 1 && field->buf[1] <= 12)
+               printf("%s", months[field->buf[1] - 1]);
+       else
+               printf("BAD");
+
+       printf("/%d\n", field->buf[3] << 8 | field->buf[2]);
+}
+
+static int validate_date(unsigned char day, unsigned char month,
+                       unsigned int year)
+{
+       int days_in_february;
+
+       switch (month) {
+       case 0:
+       case 2:
+       case 4:
+       case 6:
+       case 7:
+       case 9:
+       case 11:
+               if (day > 31)
+                       return -1;
+               break;
+       case 3:
+       case 5:
+       case 8:
+       case 10:
+               if (day > 30)
+                       return -1;
+               break;
+       case 1:
+               days_in_february = 28;
+               if (year % 4 == 0) {
+                       if (year % 100 != 0)
+                               days_in_february = 29;
+                       else if (year % 400 == 0)
+                               days_in_february = 29;
+               }
+
+               if (day > days_in_february)
+                       return -1;
+
+               break;
+       default:
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * eeprom_field_update_date() - update a date field which contains binary data
+ *
+ * This function takes a date string in the form of x/Mon/y (x and y are both
+ * decimal values), translates it to the binary representation, then writes it
+ * to the field.
+ *
+ * This function strictly enforces the data syntax, and will not update the
+ * field if there's any deviation from it. It also protects from overflow in the
+ * year value, and checks the validity of the date.
+ *
+ * @field:     an initialized field
+ * @value:     a date string
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int eeprom_field_update_date(struct eeprom_field *field, char *value)
+{
+       char *endptr;
+       char *tok1 = strtok(value, "/");
+       char *tok2 = strtok(NULL, "/");
+       char *tok3 = strtok(NULL, "/");
+
+       if (tok1 == NULL || tok2 == NULL || tok3 == NULL) {
+               printf("%s: syntax error\n", field->name);
+               return -1;
+       }
+
+       unsigned char day = (unsigned char)simple_strtol(tok1, &endptr, 0);
+       if (*endptr != '\0' || day == 0) {
+               printf("%s: invalid day\n", field->name);
+               return -1;
+       }
+
+       unsigned char month;
+       for (month = 1; month <= 12; month++)
+               if (!strcmp(tok2, months[month - 1]))
+                       break;
+
+       unsigned int year = simple_strtol(tok3, &endptr, 0);
+       if (*endptr != '\0') {
+               printf("%s: invalid year\n", field->name);
+               return -1;
+       }
+
+       if (validate_date(day, month - 1, year)) {
+               printf("%s: invalid date\n", field->name);
+               return -1;
+       }
+
+       if (year >> 16) {
+               printf("%s: year overflow\n", field->name);
+               return -1;
+       }
+
+       field->buf[0] = day;
+       field->buf[1] = month;
+       field->buf[2] = (unsigned char)year;
+       field->buf[3] = (unsigned char)(year >> 8);
+
+       return 0;
+}
+
+#define        LAYOUT_VERSION_LEGACY 1
+#define        LAYOUT_VERSION_VER1 2
+#define        LAYOUT_VERSION_VER2 3
+#define        LAYOUT_VERSION_VER3 4
+
+extern struct eeprom_field layout_unknown[1];
+
+#define DEFINE_PRINT_UPDATE(x) eeprom_field_print_##x, eeprom_field_update_##x
+
+#ifdef CONFIG_CM_T3X
+struct eeprom_field layout_legacy[5] = {
+       { "MAC address",          6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Board Revision",       2, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { "Serial Number",        8, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { "Board Configuration", 64, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { RESERVED_FIELDS,      176, NULL, eeprom_field_print_reserved,
+                                          eeprom_field_update_ascii },
+};
+#else
+#define layout_legacy layout_unknown
+#endif
+
+#if defined(CONFIG_CM_T3X) || defined(CONFIG_CM_T3517)
+struct eeprom_field layout_v1[12] = {
+       { "Major Revision",      2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "Minor Revision",      2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "1st MAC Address",     6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "2nd MAC Address",     6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Production Date",     4, NULL, DEFINE_PRINT_UPDATE(date) },
+       { "Serial Number",      12, NULL, DEFINE_PRINT_UPDATE(bin_rev) },
+       { RESERVED_FIELDS,      96, NULL, DEFINE_PRINT_UPDATE(reserved) },
+       { "Product Name",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #1", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #2", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #3", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { RESERVED_FIELDS,      64, NULL, eeprom_field_print_reserved,
+                                         eeprom_field_update_ascii },
+};
+#else
+#define layout_v1 layout_unknown
+#endif
+
+struct eeprom_field layout_v2[15] = {
+       { "Major Revision",            2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "Minor Revision",            2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "1st MAC Address",           6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "2nd MAC Address",           6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Production Date",           4, NULL, DEFINE_PRINT_UPDATE(date) },
+       { "Serial Number",            12, NULL, DEFINE_PRINT_UPDATE(bin_rev) },
+       { "3rd MAC Address (WIFI)",    6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "4th MAC Address (Bluetooth)", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Layout Version",            1, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { RESERVED_FIELDS,            83, NULL, DEFINE_PRINT_UPDATE(reserved) },
+       { "Product Name",             16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #1",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #2",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #3",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { RESERVED_FIELDS,            64, NULL, eeprom_field_print_reserved,
+                                               eeprom_field_update_ascii },
+};
+
+struct eeprom_field layout_v3[16] = {
+       { "Major Revision",            2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "Minor Revision",            2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "1st MAC Address",           6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "2nd MAC Address",           6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Production Date",           4, NULL, DEFINE_PRINT_UPDATE(date) },
+       { "Serial Number",            12, NULL, DEFINE_PRINT_UPDATE(bin_rev) },
+       { "3rd MAC Address (WIFI)",    6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "4th MAC Address (Bluetooth)", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Layout Version",            1, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { "CompuLab EEPROM ID",        3, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { RESERVED_FIELDS,            80, NULL, DEFINE_PRINT_UPDATE(reserved) },
+       { "Product Name",             16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #1",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #2",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #3",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { RESERVED_FIELDS,            64, NULL, eeprom_field_print_reserved,
+                                               eeprom_field_update_ascii },
+};
+
+void eeprom_layout_assign(struct eeprom_layout *layout, int layout_version)
+{
+       switch (layout->layout_version) {
+       case LAYOUT_VERSION_LEGACY:
+               layout->fields = layout_legacy;
+               layout->num_of_fields = ARRAY_SIZE(layout_legacy);
+               break;
+       case LAYOUT_VERSION_VER1:
+               layout->fields = layout_v1;
+               layout->num_of_fields = ARRAY_SIZE(layout_v1);
+               break;
+       case LAYOUT_VERSION_VER2:
+               layout->fields = layout_v2;
+               layout->num_of_fields = ARRAY_SIZE(layout_v2);
+               break;
+       case LAYOUT_VERSION_VER3:
+               layout->fields = layout_v3;
+               layout->num_of_fields = ARRAY_SIZE(layout_v3);
+               break;
+       default:
+               __eeprom_layout_assign(layout, layout_version);
+       }
+}
+
+int eeprom_parse_layout_version(char *str)
+{
+       if (!strcmp(str, "legacy"))
+               return LAYOUT_VERSION_LEGACY;
+       else if (!strcmp(str, "v1"))
+               return LAYOUT_VERSION_VER1;
+       else if (!strcmp(str, "v2"))
+               return LAYOUT_VERSION_VER2;
+       else if (!strcmp(str, "v3"))
+               return LAYOUT_VERSION_VER3;
+       else
+               return LAYOUT_VERSION_UNRECOGNIZED;
+}
+
+int eeprom_layout_detect(unsigned char *data)
+{
+       switch (data[EEPROM_LAYOUT_VER_OFFSET]) {
+       case 0xff:
+       case 0:
+               return LAYOUT_VERSION_VER1;
+       case 2:
+               return LAYOUT_VERSION_VER2;
+       case 3:
+               return LAYOUT_VERSION_VER3;
+       }
+
+       if (data[EEPROM_LAYOUT_VER_OFFSET] >= 0x20)
+               return LAYOUT_VERSION_LEGACY;
+
+       return LAYOUT_VERSION_UNRECOGNIZED;
+}
+#endif
index ae09c27d07ec61d1743e89ceafff94fda82fa2dd..534db1d83245b010a086fc8523741ce2235068cd 100644 (file)
@@ -24,7 +24,6 @@
 
        .text
        .set noreorder
-       .set mips32
 
        .globl  lowlevel_init
 lowlevel_init:
index c961937530ac6945bb33e1021004b5f7a40cc5f6..f0b528d1c8ffdd2d7b96627ac72cb93e706dbd84 100644 (file)
 
 static void i2c_write_start_seq(void)
 {
-       struct fsl_i2c *dev;
-       dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
+       struct fsl_i2c_base *base;
+       base = (struct fsl_i2c_base *)(CONFIG_SYS_IMMR +
+                       CONFIG_SYS_I2C_OFFSET);
        udelay(DELAY_ABORT_SEQ);
-       out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
+       out_8(&base->cr, (I2C_CR_MEN | I2C_CR_MSTA));
        udelay(DELAY_ABORT_SEQ);
-       out_8(&dev->cr, (I2C_CR_MEN));
+       out_8(&base->cr, (I2C_CR_MEN));
 }
 
 int i2c_make_abort(void)
 {
-       struct fsl_i2c *dev;
-       dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
+       struct fsl_i2c_base *base;
+       base = (struct fsl_i2c_base *)(CONFIG_SYS_IMMR +
+                       CONFIG_SYS_I2C_OFFSET);
        uchar   last;
        int     nbr_read = 0;
        int     i = 0;
        int         ret = 0;
 
        /* wait after each operation to finsh with a delay */
-       out_8(&dev->cr, (I2C_CR_MSTA));
+       out_8(&base->cr, (I2C_CR_MSTA));
        udelay(DELAY_ABORT_SEQ);
-       out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
+       out_8(&base->cr, (I2C_CR_MEN | I2C_CR_MSTA));
        udelay(DELAY_ABORT_SEQ);
-       in_8(&dev->dr);
+       in_8(&base->dr);
        udelay(DELAY_ABORT_SEQ);
-       last = in_8(&dev->dr);
+       last = in_8(&base->dr);
        nbr_read++;
 
        /*
@@ -47,7 +49,7 @@ int i2c_make_abort(void)
        while (((last & 0x01) != 0x01) &&
                (nbr_read < CONFIG_SYS_IVM_EEPROM_MAX_LEN)) {
                udelay(DELAY_ABORT_SEQ);
-               last = in_8(&dev->dr);
+               last = in_8(&base->dr);
                nbr_read++;
        }
        if ((last & 0x01) != 0x01)
@@ -56,10 +58,10 @@ int i2c_make_abort(void)
                printf("[INFO] i2c abort after %d bytes (0x%02x)\n",
                        nbr_read, last);
        udelay(DELAY_ABORT_SEQ);
-       out_8(&dev->cr, (I2C_CR_MEN));
+       out_8(&base->cr, (I2C_CR_MEN));
        udelay(DELAY_ABORT_SEQ);
        /* clear status reg */
-       out_8(&dev->sr, 0);
+       out_8(&base->sr, 0);
 
        for (i = 0; i < 5; i++)
                i2c_write_start_seq();
index e900c56f1591fdebd4b2d94816949c98c39d5b54..f039817b79374d5bbc6722e452b075e94ecfad3c 100644 (file)
@@ -32,8 +32,8 @@ Changed files:
 - include/cmd_bsp.h            added PIP405 commands definitions
 - include/cmd_condefs.h                added Floppy and SCSI support
 - include/cmd_disk.h           changed to work with block device description
-- include/config_LANTEC.h      excluded CONFIG_CMD_FDC and CONFIG_CMD_SCSI
-- include/config_hymod.h       excluded CONFIG_CMD_FDC and CONFIG_CMD_SCSI
+- include/config_LANTEC.h      excluded CONFIG_CMD_FDC and CONFIG_SCSI
+- include/config_hymod.h       excluded CONFIG_CMD_FDC and CONFIG_SCSI
 - include/flash.h              added INTEL_ID_28F320C3T  0x88C488C4
 - include/i2c.h                        added "defined(CONFIG_PIP405)"
 - include/image.h              added IH_OS_U_BOOT, IH_TYPE_FIRMWARE
@@ -86,7 +86,7 @@ section "Changes".
 
 New Commands:
 -------------
-CONFIG_CMD_SCSI        SCSI Support
+CONFIG_SCSI    SCSI Support
 CONFIG_CMF_FDC Floppy disk support
 
 IDE additions:
diff --git a/board/qca/ap121/Kconfig b/board/qca/ap121/Kconfig
new file mode 100644 (file)
index 0000000..f7e768a
--- /dev/null
@@ -0,0 +1,12 @@
+if TARGET_AP121
+
+config SYS_VENDOR
+       default "qca"
+
+config SYS_BOARD
+       default "ap121"
+
+config SYS_CONFIG_NAME
+       default "ap121"
+
+endif
diff --git a/board/qca/ap121/MAINTAINERS b/board/qca/ap121/MAINTAINERS
new file mode 100644 (file)
index 0000000..8b02988
--- /dev/null
@@ -0,0 +1,6 @@
+AP121 BOARD
+M:     Wills Wang <wills.wang@live.com>
+S:     Maintained
+F:     board/qca/ap121/
+F:     include/configs/ap121.h
+F:     configs/ap121_defconfig
diff --git a/board/qca/ap121/Makefile b/board/qca/ap121/Makefile
new file mode 100644 (file)
index 0000000..ced5432
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  = ap121.o
diff --git a/board/qca/ap121/ap121.c b/board/qca/ap121/ap121.c
new file mode 100644 (file)
index 0000000..d6c60fe
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/ddr.h>
+#include <debug_uart.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+       void __iomem *regs;
+       u32 val;
+
+       regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+                          MAP_NOCACHE);
+
+       /*
+        * GPIO9 as input, GPIO10 as output
+        */
+       val = readl(regs + AR71XX_GPIO_REG_OE);
+       val &= ~AR933X_GPIO(9);
+       val |= AR933X_GPIO(10);
+       writel(val, regs + AR71XX_GPIO_REG_OE);
+
+       /*
+        * Enable UART, GPIO9 as UART_SI, GPIO10 as UART_SO
+        */
+       val = readl(regs + AR71XX_GPIO_REG_FUNC);
+       val |= AR933X_GPIO_FUNC_UART_EN | AR933X_GPIO_FUNC_RES_TRUE;
+       writel(val, regs + AR71XX_GPIO_REG_FUNC);
+}
+#endif
+
+int board_early_init_f(void)
+{
+#ifdef CONFIG_DEBUG_UART
+       debug_uart_init();
+#endif
+       ddr_init();
+       return 0;
+}
diff --git a/board/qca/ap143/Kconfig b/board/qca/ap143/Kconfig
new file mode 100644 (file)
index 0000000..4cdac0d
--- /dev/null
@@ -0,0 +1,12 @@
+if TARGET_AP143
+
+config SYS_VENDOR
+       default "qca"
+
+config SYS_BOARD
+       default "ap143"
+
+config SYS_CONFIG_NAME
+       default "ap143"
+
+endif
diff --git a/board/qca/ap143/MAINTAINERS b/board/qca/ap143/MAINTAINERS
new file mode 100644 (file)
index 0000000..11cb14f
--- /dev/null
@@ -0,0 +1,6 @@
+AP143 BOARD
+M:     Wills Wang <wills.wang@live.com>
+S:     Maintained
+F:     board/qca/ap143/
+F:     include/configs/ap143.h
+F:     configs/ap143_defconfig
diff --git a/board/qca/ap143/Makefile b/board/qca/ap143/Makefile
new file mode 100644 (file)
index 0000000..00f7837
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  = ap143.o
diff --git a/board/qca/ap143/ap143.c b/board/qca/ap143/ap143.c
new file mode 100644 (file)
index 0000000..1572472
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/ddr.h>
+#include <debug_uart.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+       void __iomem *regs;
+       u32 val;
+
+       regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+                          MAP_NOCACHE);
+
+       /*
+        * GPIO9 as input, GPIO10 as output
+        */
+       val = readl(regs + AR71XX_GPIO_REG_OE);
+       val |= QCA953X_GPIO(9);
+       val &= ~QCA953X_GPIO(10);
+       writel(val, regs + AR71XX_GPIO_REG_OE);
+
+       /*
+        * Enable GPIO10 as UART0_SOUT
+        */
+       val = readl(regs + QCA953X_GPIO_REG_OUT_FUNC2);
+       val &= ~QCA953X_GPIO_MUX_MASK(16);
+       val |= QCA953X_GPIO_OUT_MUX_UART0_SOUT << 16;
+       writel(val, regs + QCA953X_GPIO_REG_OUT_FUNC2);
+
+       /*
+        * Enable GPIO9 as UART0_SIN
+        */
+       val = readl(regs + QCA953X_GPIO_REG_IN_ENABLE0);
+       val &= ~QCA953X_GPIO_MUX_MASK(8);
+       val |= QCA953X_GPIO_IN_MUX_UART0_SIN << 8;
+       writel(val, regs + QCA953X_GPIO_REG_IN_ENABLE0);
+
+       /*
+        * Enable GPIO10 output
+        */
+       val = readl(regs + AR71XX_GPIO_REG_OUT);
+       val |= QCA953X_GPIO(10);
+       writel(val, regs + AR71XX_GPIO_REG_OUT);
+}
+#endif
+
+int board_early_init_f(void)
+{
+#ifdef CONFIG_DEBUG_UART
+       debug_uart_init();
+#endif
+       ddr_init();
+       return 0;
+}
index 10d88a28a6f6bd3b8ce31c4a8d9063116732f7ea..f5db773a478ec827b525487207013fe1410c0da4 100644 (file)
@@ -4,3 +4,10 @@ S:     Maintained
 F:     board/sandbox/
 F:     include/configs/sandbox.h
 F:     configs/sandbox_defconfig
+
+SANDBOX_NOBLK BOARD
+M:     Simon Glass <sjg@chromium.org>
+S:     Maintained
+F:     board/sandbox/
+F:     include/configs/sandbox.h
+F:     configs/sandbox_noblk_defconfig
diff --git a/board/tplink/wdr4300/Kconfig b/board/tplink/wdr4300/Kconfig
new file mode 100644 (file)
index 0000000..902abf5
--- /dev/null
@@ -0,0 +1,15 @@
+if BOARD_TPLINK_WDR4300
+
+config SYS_VENDOR
+       default "tplink"
+
+config SYS_SOC
+       default "ath79"
+
+config SYS_BOARD
+       default "wdr4300"
+
+config SYS_CONFIG_NAME
+       default "tplink_wdr4300"
+
+endif
diff --git a/board/tplink/wdr4300/MAINTAINERS b/board/tplink/wdr4300/MAINTAINERS
new file mode 100644 (file)
index 0000000..db239c2
--- /dev/null
@@ -0,0 +1,6 @@
+TPLINK_WDR4300 BOARD
+M:     Marek Vasut <marex@denx.de>
+S:     Maintained
+F:     board/tplink/wdr4300/
+F:     include/configs/tplink_wdr4300.h
+F:     configs/tplink_wdr4300_defconfig
diff --git a/board/tplink/wdr4300/Makefile b/board/tplink/wdr4300/Makefile
new file mode 100644 (file)
index 0000000..4f0c296
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  = wdr4300.o
diff --git a/board/tplink/wdr4300/wdr4300.c b/board/tplink/wdr4300/wdr4300.c
new file mode 100644 (file)
index 0000000..6e070fd
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ath79.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/ddr.h>
+#include <debug_uart.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_USB
+static void wdr4300_usb_start(void)
+{
+       void __iomem *gpio_regs = map_physmem(AR71XX_GPIO_BASE,
+                                             AR71XX_GPIO_SIZE, MAP_NOCACHE);
+       if (!gpio_regs)
+               return;
+
+       /* Power up the USB HUB. */
+       clrbits_be32(gpio_regs + AR71XX_GPIO_REG_OE, BIT(21) | BIT(22));
+       writel(BIT(21) | BIT(22), gpio_regs + AR71XX_GPIO_REG_SET);
+       mdelay(1);
+
+       ath79_usb_reset();
+}
+#else
+static inline void wdr4300_usb_start(void) {}
+#endif
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+       void __iomem *regs;
+
+       regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+                          MAP_NOCACHE);
+
+       /* Assure JTAG is not disconnected. */
+       writel(0x40, regs + AR934X_GPIO_REG_FUNC);
+
+       /* Configure default GPIO input/output regs. */
+       writel(0x3031b, regs + AR71XX_GPIO_REG_OE);
+       writel(0x0f804, regs + AR71XX_GPIO_REG_OUT);
+
+       /* Configure pin multiplexing. */
+       writel(0x00000000, regs + AR934X_GPIO_REG_OUT_FUNC0);
+       writel(0x0b0a0980, regs + AR934X_GPIO_REG_OUT_FUNC1);
+       writel(0x00180000, regs + AR934X_GPIO_REG_OUT_FUNC2);
+       writel(0x00000000, regs + AR934X_GPIO_REG_OUT_FUNC3);
+       writel(0x0000004d, regs + AR934X_GPIO_REG_OUT_FUNC4);
+       writel(0x00000000, regs + AR934X_GPIO_REG_OUT_FUNC5);
+
+#ifdef CONFIG_DEBUG_UART
+       debug_uart_init();
+#endif
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+       ar934x_pll_init(560, 480, 240);
+       ar934x_ddr_init(560, 480, 240);
+#endif
+
+       wdr4300_usb_start();
+       ath79_eth_reset();
+
+       return 0;
+}
+#endif
index f95759e6704424ea9edfb258d79937d68d783c91..e3e0c74ffc66d4de872466a18b9291c2ee18ae59 100644 (file)
@@ -112,7 +112,7 @@ obj-$(CONFIG_CMD_REMOTEPROC) += remoteproc.o
 obj-$(CONFIG_SANDBOX) += host.o
 obj-$(CONFIG_CMD_SATA) += sata.o
 obj-$(CONFIG_CMD_SF) += sf.o
-obj-$(CONFIG_CMD_SCSI) += scsi.o
+obj-$(CONFIG_SCSI) += scsi.o
 obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
 obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
 obj-$(CONFIG_CMD_SOFTSWITCH) += softswitch.o
@@ -155,12 +155,6 @@ obj-$(CONFIG_CMD_PMIC) += pmic.o
 obj-$(CONFIG_CMD_REGULATOR) += regulator.o
 endif # !CONFIG_SPL_BUILD
 
-ifdef CONFIG_SPL_BUILD
-ifdef CONFIG_SPL_SATA_SUPPORT
-obj-$(CONFIG_CMD_SCSI) += scsi.o
-endif
-endif # CONFIG_SPL_BUILD
-
 obj-$(CONFIG_CMD_BLOB) += blob.o
 
 # core command
index 8eda68b4f9972e1be0bb46f1c69f76be893402d6..1c4bed96b5b75fc753cfb89485202cb4fb19f22d 100644 (file)
@@ -341,6 +341,8 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        print_eth(0);
        printf("ip_addr     = %s\n", getenv("ipaddr"));
        printf("baudrate    = %u bps\n", gd->baudrate);
+       print_num("relocaddr", gd->relocaddr);
+       print_num("reloc off", gd->reloc_off);
 
        return 0;
 }
index 2fd1717e6a44680107f2c242ab29855a9baaad41..fcc412312719b755eef21e780345b80932175127 100644 (file)
@@ -8,7 +8,7 @@
 #include <command.h>
 #include <part.h>
 
-#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_SCSI) || \
+#if defined(CONFIG_CMD_IDE) || defined(CONFIG_SCSI) || \
        defined(CONFIG_USB_STORAGE)
 int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
                    char *const argv[])
index e5457ba0cf44d82344517a1b9b4fbaa1d1853f96..0a0e4a2c1cc8f365c5f4d9539dd91eeec24d0e9e 100644 (file)
@@ -24,6 +24,7 @@
 #include <config.h>
 #include <command.h>
 #include <i2c.h>
+#include <eeprom_layout.h>
 
 #ifndef        CONFIG_SYS_I2C_SPEED
 #define        CONFIG_SYS_I2C_SPEED    50000
@@ -72,7 +73,7 @@ void eeprom_init(int bus)
 #endif
 
        /* I2C EEPROM */
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C_SOFT)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
 #if defined(CONFIG_SYS_I2C)
        if (bus >= 0)
                i2c_set_bus_num(bus);
@@ -207,63 +208,243 @@ int eeprom_write(unsigned dev_addr, unsigned offset,
        return ret;
 }
 
-static int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int parse_numeric_param(char *str)
 {
-       const char *const fmt =
-               "\nEEPROM @0x%lX %s: addr %08lx  off %04lx  count %ld ... ";
-       char * const *args = &argv[2];
-       int rcode;
-       ulong dev_addr, addr, off, cnt;
-       int bus_addr;
+       char *endptr;
+       int value = simple_strtol(str, &endptr, 16);
+
+       return (*endptr != '\0') ? -1 : value;
+}
+
+/**
+ * parse_i2c_bus_addr - parse the i2c bus and i2c devaddr parameters
+ *
+ * @i2c_bus:   address to store the i2c bus
+ * @i2c_addr:  address to store the device i2c address
+ * @argc:      count of command line arguments left to parse
+ * @argv:      command line arguments left to parse
+ * @argc_no_bus_addr:  argc value we expect to see when bus & addr aren't given
+ *
+ * @returns:   number of arguments parsed or CMD_RET_USAGE if error
+ */
+static int parse_i2c_bus_addr(int *i2c_bus, ulong *i2c_addr, int argc,
+                             char * const argv[], int argc_no_bus_addr)
+{
+       int argc_no_bus = argc_no_bus_addr + 1;
+       int argc_bus_addr = argc_no_bus_addr + 2;
 
-       switch (argc) {
 #ifdef CONFIG_SYS_DEF_EEPROM_ADDR
-       case 5:
-               bus_addr = -1;
-               dev_addr = CONFIG_SYS_DEF_EEPROM_ADDR;
-               break;
+       if (argc == argc_no_bus_addr) {
+               *i2c_bus = -1;
+               *i2c_addr = CONFIG_SYS_DEF_EEPROM_ADDR;
+
+               return 0;
+       }
 #endif
-       case 6:
-               bus_addr = -1;
-               dev_addr = simple_strtoul(*args++, NULL, 16);
-               break;
-       case 7:
-               bus_addr = simple_strtoul(*args++, NULL, 16);
-               dev_addr = simple_strtoul(*args++, NULL, 16);
-               break;
-       default:
-               return CMD_RET_USAGE;
+       if (argc == argc_no_bus) {
+               *i2c_bus = -1;
+               *i2c_addr = parse_numeric_param(argv[0]);
+
+               return 1;
        }
 
-       addr = simple_strtoul(*args++, NULL, 16);
-       off = simple_strtoul(*args++, NULL, 16);
-       cnt = simple_strtoul(*args++, NULL, 16);
+       if (argc == argc_bus_addr) {
+               *i2c_bus = parse_numeric_param(argv[0]);
+               *i2c_addr = parse_numeric_param(argv[1]);
+
+               return 2;
+       }
+
+       return CMD_RET_USAGE;
+}
+
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+
+__weak int eeprom_parse_layout_version(char *str)
+{
+       return LAYOUT_VERSION_UNRECOGNIZED;
+}
 
-       eeprom_init(bus_addr);
+static unsigned char eeprom_buf[CONFIG_SYS_EEPROM_SIZE];
 
-       if (strcmp(argv[1], "read") == 0) {
-               printf(fmt, dev_addr, argv[1], addr, off, cnt);
+#ifndef CONFIG_EEPROM_LAYOUT_HELP_STRING
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "<not defined>"
+#endif
 
-               rcode = eeprom_read(dev_addr, off, (uchar *)addr, cnt);
+#endif
+
+enum eeprom_action {
+       EEPROM_READ,
+       EEPROM_WRITE,
+       EEPROM_PRINT,
+       EEPROM_UPDATE,
+       EEPROM_ACTION_INVALID,
+};
+
+static enum eeprom_action parse_action(char *cmd)
+{
+       if (!strncmp(cmd, "read", 4))
+               return EEPROM_READ;
+       if (!strncmp(cmd, "write", 5))
+               return EEPROM_WRITE;
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       if (!strncmp(cmd, "print", 5))
+               return EEPROM_PRINT;
+       if (!strncmp(cmd, "update", 6))
+               return EEPROM_UPDATE;
+#endif
+
+       return EEPROM_ACTION_INVALID;
+}
+
+static int eeprom_execute_command(enum eeprom_action action, int i2c_bus,
+                                 ulong i2c_addr, int layout_ver, char *key,
+                                 char *value, ulong addr, ulong off, ulong cnt)
+{
+       int rcode = 0;
+       const char *const fmt =
+               "\nEEPROM @0x%lX %s: addr %08lx  off %04lx  count %ld ... ";
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       struct eeprom_layout layout;
+#endif
+
+       if (action == EEPROM_ACTION_INVALID)
+               return CMD_RET_USAGE;
+
+       eeprom_init(i2c_bus);
+       if (action == EEPROM_READ) {
+               printf(fmt, i2c_addr, "read", addr, off, cnt);
+
+               rcode = eeprom_read(i2c_addr, off, (uchar *)addr, cnt);
 
                puts("done\n");
                return rcode;
-       } else if (strcmp(argv[1], "write") == 0) {
-               printf(fmt, dev_addr, argv[1], addr, off, cnt);
+       } else if (action == EEPROM_WRITE) {
+               printf(fmt, i2c_addr, "write", addr, off, cnt);
 
-               rcode = eeprom_write(dev_addr, off, (uchar *)addr, cnt);
+               rcode = eeprom_write(i2c_addr, off, (uchar *)addr, cnt);
 
                puts("done\n");
                return rcode;
        }
 
-       return CMD_RET_USAGE;
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       rcode = eeprom_read(i2c_addr, 0, eeprom_buf, CONFIG_SYS_EEPROM_SIZE);
+       if (rcode < 0)
+               return rcode;
+
+       eeprom_layout_setup(&layout, eeprom_buf, CONFIG_SYS_EEPROM_SIZE,
+                           layout_ver);
+
+       if (action == EEPROM_PRINT) {
+               layout.print(&layout);
+               return 0;
+       }
+
+       layout.update(&layout, key, value);
+
+       rcode = eeprom_write(i2c_addr, 0, layout.data, CONFIG_SYS_EEPROM_SIZE);
+#endif
+
+       return rcode;
+}
+
+#define NEXT_PARAM(argc, index)        { (argc)--; (index)++; }
+int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       int layout_ver = LAYOUT_VERSION_AUTODETECT;
+       enum eeprom_action action = EEPROM_ACTION_INVALID;
+       int i2c_bus = -1, index = 0;
+       ulong i2c_addr = -1, addr = 0, cnt = 0, off = 0;
+       int ret;
+       char *field_name = "";
+       char *field_value = "";
+
+       if (argc <= 1)
+               return CMD_RET_USAGE;
+
+       NEXT_PARAM(argc, index); /* Skip program name */
+
+       action = parse_action(argv[index]);
+       NEXT_PARAM(argc, index);
+
+       if (action == EEPROM_ACTION_INVALID)
+               return CMD_RET_USAGE;
+
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       if (action == EEPROM_PRINT || action == EEPROM_UPDATE) {
+               if (!strcmp(argv[index], "-l")) {
+                       NEXT_PARAM(argc, index);
+                       layout_ver = eeprom_parse_layout_version(argv[index]);
+                       NEXT_PARAM(argc, index);
+               }
+       }
+#endif
+
+       switch (action) {
+       case EEPROM_READ:
+       case EEPROM_WRITE:
+               ret = parse_i2c_bus_addr(&i2c_bus, &i2c_addr, argc,
+                                        argv + index, 3);
+               break;
+       case EEPROM_PRINT:
+               ret = parse_i2c_bus_addr(&i2c_bus, &i2c_addr, argc,
+                                        argv + index, 0);
+               break;
+       case EEPROM_UPDATE:
+               ret = parse_i2c_bus_addr(&i2c_bus, &i2c_addr, argc,
+                                        argv + index, 2);
+               break;
+       default:
+               /* Get compiler to stop whining */
+               return CMD_RET_USAGE;
+       }
+
+       if (ret == CMD_RET_USAGE)
+               return ret;
+
+       while (ret--)
+               NEXT_PARAM(argc, index);
+
+       if (action == EEPROM_READ || action == EEPROM_WRITE) {
+               addr = parse_numeric_param(argv[index]);
+               NEXT_PARAM(argc, index);
+               off = parse_numeric_param(argv[index]);
+               NEXT_PARAM(argc, index);
+               cnt = parse_numeric_param(argv[index]);
+       }
+
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       if (action == EEPROM_UPDATE) {
+               field_name = argv[index];
+               NEXT_PARAM(argc, index);
+               field_value = argv[index];
+               NEXT_PARAM(argc, index);
+       }
+#endif
+
+       return eeprom_execute_command(action, i2c_bus, i2c_addr, layout_ver,
+                                     field_name, field_value, addr, off, cnt);
 }
 
 U_BOOT_CMD(
-       eeprom, 7,      1,      do_eeprom,
+       eeprom, 8,      1,      do_eeprom,
        "EEPROM sub-system",
        "read  <bus> <devaddr> addr off cnt\n"
        "eeprom write <bus> <devaddr> addr off cnt\n"
        "       - read/write `cnt' bytes from `devaddr` EEPROM at offset `off'"
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       "\n"
+       "eeprom print [-l <layout_version>] <bus> <devaddr>\n"
+       "       - Print layout fields and their data in human readable format\n"
+       "eeprom update [-l <layout_version>] <bus> <devaddr> field_name field_value\n"
+       "       - Update a specific eeprom field with new data.\n"
+       "         The new data must be written in the same human readable format as shown by the print command.\n"
+       "\n"
+       "LAYOUT VERSIONS\n"
+       "The -l option can be used to force the command to interpret the EEPROM data using the chosen layout.\n"
+       "If the -l option is omitted, the command will auto detect the layout based on the data in the EEPROM.\n"
+       "The values which can be provided with the -l option are:\n"
+       CONFIG_EEPROM_LAYOUT_HELP_STRING"\n"
+#endif
 )
index c4c08c8855d131f63e4f22b0266d75757d7f10aa..c942744e72e6b3a71e243e6b5d1f44a7d3b4ebca 100644 (file)
--- a/cmd/ide.c
+++ b/cmd/ide.c
 # include <status_led.h>
 #endif
 
-#ifdef __PPC__
-# define EIEIO         __asm__ volatile ("eieio")
-# define SYNC          __asm__ volatile ("sync")
-#else
-# define EIEIO         /* nothing */
-# define SYNC          /* nothing */
-#endif
-
-/* ------------------------------------------------------------------------- */
-
 /* Current I/O Device  */
 static int curr_device = -1;
 
-/* Current offset for IDE0 / IDE1 bus access   */
-ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = {
-#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
-       CONFIG_SYS_ATA_IDE0_OFFSET,
-#endif
-#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) && (CONFIG_SYS_IDE_MAXBUS > 1)
-       CONFIG_SYS_ATA_IDE1_OFFSET,
-#endif
-};
-
-static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS];
-
-struct blk_desc ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
-/* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_IDE_RESET
-static void  ide_reset (void);
-#else
-#define ide_reset()    /* dummy */
-#endif
-
-static void ide_ident(struct blk_desc *dev_desc);
-static uchar ide_wait  (int dev, ulong t);
-
-#define IDE_TIME_OUT   2000    /* 2 sec timeout */
-
-#define ATAPI_TIME_OUT 7000    /* 7 sec timeout (5 sec seems to work...) */
-
-#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */
-
-static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
-
-#ifndef CONFIG_SYS_ATA_PORT_ADDR
-#define CONFIG_SYS_ATA_PORT_ADDR(port) (port)
-#endif
-
-#ifdef CONFIG_ATAPI
-static void    atapi_inquiry(struct blk_desc *dev_desc);
-static ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr,
-                       lbaint_t blkcnt, void *buffer);
-#endif
-
-
-/* ------------------------------------------------------------------------- */
-
 int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
        int rcode = 0;
@@ -106,79 +51,41 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                        ide_init();
                        return 0;
                } else if (strncmp(argv[1], "inf", 3) == 0) {
-                       int i;
-
-                       putc('\n');
-
-                       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
-                               if (ide_dev_desc[i].type == DEV_TYPE_UNKNOWN)
-                                       continue;  /* list only known devices */
-                               printf("IDE device %d: ", i);
-                               dev_print(&ide_dev_desc[i]);
-                       }
+                       blk_list_devices(IF_TYPE_IDE);
                        return 0;
 
                } else if (strncmp(argv[1], "dev", 3) == 0) {
-                       if ((curr_device < 0)
-                           || (curr_device >= CONFIG_SYS_IDE_MAXDEVICE)) {
-                               puts("\nno IDE devices available\n");
-                               return 1;
+                       if (blk_print_device_num(IF_TYPE_IDE, curr_device)) {
+                               printf("\nno IDE devices available\n");
+                               return CMD_RET_FAILURE;
                        }
-                       printf("\nIDE device %d: ", curr_device);
-                       dev_print(&ide_dev_desc[curr_device]);
+
                        return 0;
                } else if (strncmp(argv[1], "part", 4) == 0) {
-                       int dev, ok;
-
-                       for (ok = 0, dev = 0;
-                            dev < CONFIG_SYS_IDE_MAXDEVICE;
-                            ++dev) {
-                               if (ide_dev_desc[dev].part_type !=
-                                   PART_TYPE_UNKNOWN) {
-                                       ++ok;
-                                       if (dev)
-                                               putc('\n');
-                                       part_print(&ide_dev_desc[dev]);
-                               }
-                       }
-                       if (!ok) {
-                               puts("\nno IDE devices available\n");
-                               rcode++;
-                       }
-                       return rcode;
+                       if (blk_list_part(IF_TYPE_IDE))
+                               printf("\nno IDE devices available\n");
+                       return 1;
                }
                return CMD_RET_USAGE;
        case 3:
                if (strncmp(argv[1], "dev", 3) == 0) {
-                       int dev = (int) simple_strtoul(argv[2], NULL, 10);
+                       int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-                       printf("\nIDE device %d: ", dev);
-                       if (dev >= CONFIG_SYS_IDE_MAXDEVICE) {
-                               puts("unknown device\n");
-                               return 1;
+                       if (!blk_show_device(IF_TYPE_IDE, dev)) {
+                               curr_device = dev;
+                               printf("... is now current device\n");
+                       } else {
+                               return CMD_RET_FAILURE;
                        }
-                       dev_print(&ide_dev_desc[dev]);
-                       /*ide_print (dev); */
-
-                       if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
-                               return 1;
-
-                       curr_device = dev;
-
-                       puts("... is now current device\n");
-
                        return 0;
                } else if (strncmp(argv[1], "part", 4) == 0) {
-                       int dev = (int) simple_strtoul(argv[2], NULL, 10);
+                       int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-                       if (ide_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
-                               part_print(&ide_dev_desc[dev]);
-                       } else {
-                               printf("\nIDE device %d not available\n",
-                                      dev);
-                               rcode = 1;
+                       if (blk_print_part_devnum(IF_TYPE_IDE, dev)) {
+                               printf("\nIDE device %d not available\n", dev);
+                               return CMD_RET_FAILURE;
                        }
-                       return rcode;
+                       return 1;
                }
 
                return CMD_RET_USAGE;
@@ -188,26 +95,22 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                if (strcmp(argv[1], "read") == 0) {
                        ulong addr = simple_strtoul(argv[2], NULL, 16);
                        ulong cnt = simple_strtoul(argv[4], NULL, 16);
-                       struct blk_desc *dev_desc;
                        ulong n;
 
 #ifdef CONFIG_SYS_64BIT_LBA
                        lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
 
-                       printf("\nIDE read: device %d block # %lld, count %ld ... ",
-                               curr_device, blk, cnt);
+                       printf("\nIDE read: device %d block # %lld, count %ld...",
+                              curr_device, blk, cnt);
 #else
                        lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
 
-                       printf("\nIDE read: device %d block # %ld, count %ld ... ",
-                               curr_device, blk, cnt);
+                       printf("\nIDE read: device %d block # %ld, count %ld...",
+                              curr_device, blk, cnt);
 #endif
 
-                       dev_desc = &ide_dev_desc[curr_device];
-                       n = blk_dread(dev_desc, blk, cnt, (ulong *)addr);
-                       /* flush cache after read */
-                       flush_cache(addr,
-                                   cnt * ide_dev_desc[curr_device].blksz);
+                       n = blk_read_devnum(IF_TYPE_IDE, curr_device, blk, cnt,
+                                           (ulong *)addr);
 
                        printf("%ld blocks read: %s\n",
                               n, (n == cnt) ? "OK" : "ERROR");
@@ -223,19 +126,19 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 #ifdef CONFIG_SYS_64BIT_LBA
                        lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
 
-                       printf("\nIDE write: device %d block # %lld, count %ld ... ",
-                               curr_device, blk, cnt);
+                       printf("\nIDE write: device %d block # %lld, count %ld...",
+                              curr_device, blk, cnt);
 #else
                        lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
 
-                       printf("\nIDE write: device %d block # %ld, count %ld ... ",
-                               curr_device, blk, cnt);
+                       printf("\nIDE write: device %d block # %ld, count %ld...",
+                              curr_device, blk, cnt);
 #endif
-                       n = ide_write(&ide_dev_desc[curr_device], blk, cnt,
-                                     (ulong *)addr);
+                       n = blk_write_devnum(IF_TYPE_IDE, curr_device, blk, cnt,
+                                            (ulong *)addr);
 
-                       printf("%ld blocks written: %s\n",
-                               n, (n == cnt) ? "OK" : "ERROR");
+                       printf("%ld blocks written: %s\n", n,
+                              n == cnt ? "OK" : "ERROR");
                        if (n == cnt)
                                return 0;
                        else
@@ -253,1195 +156,6 @@ int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        return common_diskboot(cmdtp, "ide", argc, argv);
 }
 
-/* ------------------------------------------------------------------------- */
-
-__weak void ide_led(uchar led, uchar status)
-{
-#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */
-       static uchar led_buffer;        /* Buffer for current LED status */
-
-       uchar *led_port = LED_PORT;
-
-       if (status)             /* switch LED on        */
-               led_buffer |= led;
-       else                    /* switch LED off       */
-               led_buffer &= ~led;
-
-       *led_port = led_buffer;
-#endif
-}
-
-#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */
-# define DEVICE_LED(x) 0
-# define LED_IDE1 1
-# define LED_IDE2 2
-#endif
-
-/* ------------------------------------------------------------------------- */
-
-__weak void ide_outb(int dev, int port, unsigned char val)
-{
-       debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
-             dev, port, val,
-             (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
-
-#if defined(CONFIG_IDE_AHB)
-       if (port) {
-               /* write command */
-               ide_write_register(dev, port, val);
-       } else {
-               /* write data */
-               outb(val, (ATA_CURR_BASE(dev)));
-       }
-#else
-       outb(val, (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
-#endif
-}
-
-__weak unsigned char ide_inb(int dev, int port)
-{
-       uchar val;
-
-#if defined(CONFIG_IDE_AHB)
-       val = ide_read_register(dev, port);
-#else
-       val = inb((ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
-#endif
-
-       debug("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
-             dev, port,
-             (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)), val);
-       return val;
-}
-
-void ide_init(void)
-{
-       unsigned char c;
-       int i, bus;
-
-#ifdef CONFIG_IDE_8xx_PCCARD
-       extern int ide_devices_found;   /* Initialized in check_ide_device() */
-#endif /* CONFIG_IDE_8xx_PCCARD */
-
-#ifdef CONFIG_IDE_PREINIT
-       WATCHDOG_RESET();
-
-       if (ide_preinit()) {
-               puts("ide_preinit failed\n");
-               return;
-       }
-#endif /* CONFIG_IDE_PREINIT */
-
-       WATCHDOG_RESET();
-
-       /*
-        * Reset the IDE just to be sure.
-        * Light LED's to show
-        */
-       ide_led((LED_IDE1 | LED_IDE2), 1);      /* LED's on     */
-
-       /* ATAPI Drives seems to need a proper IDE Reset */
-       ide_reset();
-
-#ifdef CONFIG_IDE_INIT_POSTRESET
-       WATCHDOG_RESET();
-
-       if (ide_init_postreset()) {
-               puts("ide_preinit_postreset failed\n");
-               return;
-       }
-#endif /* CONFIG_IDE_INIT_POSTRESET */
-
-       /*
-        * Wait for IDE to get ready.
-        * According to spec, this can take up to 31 seconds!
-        */
-       for (bus = 0; bus < CONFIG_SYS_IDE_MAXBUS; ++bus) {
-               int dev =
-                       bus * (CONFIG_SYS_IDE_MAXDEVICE /
-                              CONFIG_SYS_IDE_MAXBUS);
-
-#ifdef CONFIG_IDE_8xx_PCCARD
-               /* Skip non-ide devices from probing */
-               if ((ide_devices_found & (1 << bus)) == 0) {
-                       ide_led((LED_IDE1 | LED_IDE2), 0);      /* LED's off */
-                       continue;
-               }
-#endif
-               printf("Bus %d: ", bus);
-
-               ide_bus_ok[bus] = 0;
-
-               /* Select device
-                */
-               udelay(100000); /* 100 ms */
-               ide_outb(dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
-               udelay(100000); /* 100 ms */
-               i = 0;
-               do {
-                       udelay(10000);  /* 10 ms */
-
-                       c = ide_inb(dev, ATA_STATUS);
-                       i++;
-                       if (i > (ATA_RESET_TIME * 100)) {
-                               puts("** Timeout **\n");
-                               /* LED's off */
-                               ide_led((LED_IDE1 | LED_IDE2), 0);
-                               return;
-                       }
-                       if ((i >= 100) && ((i % 100) == 0))
-                               putc('.');
-
-               } while (c & ATA_STAT_BUSY);
-
-               if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
-                       puts("not available  ");
-                       debug("Status = 0x%02X ", c);
-#ifndef CONFIG_ATAPI           /* ATAPI Devices do not set DRDY */
-               } else if ((c & ATA_STAT_READY) == 0) {
-                       puts("not available  ");
-                       debug("Status = 0x%02X ", c);
-#endif
-               } else {
-                       puts("OK ");
-                       ide_bus_ok[bus] = 1;
-               }
-               WATCHDOG_RESET();
-       }
-
-       putc('\n');
-
-       ide_led((LED_IDE1 | LED_IDE2), 0);      /* LED's off    */
-
-       curr_device = -1;
-       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
-               int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
-               ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
-               ide_dev_desc[i].if_type = IF_TYPE_IDE;
-               ide_dev_desc[i].devnum = i;
-               ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
-               ide_dev_desc[i].blksz = 0;
-               ide_dev_desc[i].log2blksz =
-                       LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));
-               ide_dev_desc[i].lba = 0;
-               ide_dev_desc[i].block_read = ide_read;
-               ide_dev_desc[i].block_write = ide_write;
-               if (!ide_bus_ok[IDE_BUS(i)])
-                       continue;
-               ide_led(led, 1);        /* LED on       */
-               ide_ident(&ide_dev_desc[i]);
-               ide_led(led, 0);        /* LED off      */
-               dev_print(&ide_dev_desc[i]);
-
-               if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
-                       /* initialize partition type */
-                       part_init(&ide_dev_desc[i]);
-                       if (curr_device < 0)
-                               curr_device = i;
-               }
-       }
-       WATCHDOG_RESET();
-}
-
-/* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *ide_get_dev(int dev)
-{
-       return (dev < CONFIG_SYS_IDE_MAXDEVICE) ? &ide_dev_desc[dev] : NULL;
-}
-#endif
-
-/* ------------------------------------------------------------------------- */
-
-/* We only need to swap data if we are running on a big endian cpu. */
-#if defined(__LITTLE_ENDIAN)
-__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
-{
-       ide_input_data(dev, sect_buf, words);
-}
-#else
-__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
-{
-       volatile ushort *pbuf =
-               (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       ushort *dbuf = (ushort *) sect_buf;
-
-       debug("in input swap data base for read is %lx\n",
-             (unsigned long) pbuf);
-
-       while (words--) {
-#ifdef __MIPS__
-               *dbuf++ = swab16p((u16 *) pbuf);
-               *dbuf++ = swab16p((u16 *) pbuf);
-#else
-               *dbuf++ = ld_le16(pbuf);
-               *dbuf++ = ld_le16(pbuf);
-#endif /* !MIPS */
-       }
-}
-#endif /* __LITTLE_ENDIAN */
-
-
-#if defined(CONFIG_IDE_SWAP_IO)
-__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
-{
-       ushort *dbuf;
-       volatile ushort *pbuf;
-
-       pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       dbuf = (ushort *) sect_buf;
-       while (words--) {
-               EIEIO;
-               *pbuf = *dbuf++;
-               EIEIO;
-               *pbuf = *dbuf++;
-       }
-}
-#else  /* ! CONFIG_IDE_SWAP_IO */
-__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
-{
-#if defined(CONFIG_IDE_AHB)
-       ide_write_data(dev, sect_buf, words);
-#else
-       outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1);
-#endif
-}
-#endif /* CONFIG_IDE_SWAP_IO */
-
-#if defined(CONFIG_IDE_SWAP_IO)
-__weak void ide_input_data(int dev, ulong *sect_buf, int words)
-{
-       ushort *dbuf;
-       volatile ushort *pbuf;
-
-       pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       dbuf = (ushort *) sect_buf;
-
-       debug("in input data base for read is %lx\n", (unsigned long) pbuf);
-
-       while (words--) {
-               EIEIO;
-               *dbuf++ = *pbuf;
-               EIEIO;
-               *dbuf++ = *pbuf;
-       }
-}
-#else  /* ! CONFIG_IDE_SWAP_IO */
-__weak void ide_input_data(int dev, ulong *sect_buf, int words)
-{
-#if defined(CONFIG_IDE_AHB)
-       ide_read_data(dev, sect_buf, words);
-#else
-       insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1);
-#endif
-}
-
-#endif /* CONFIG_IDE_SWAP_IO */
-
-/* -------------------------------------------------------------------------
- */
-static void ide_ident(struct blk_desc *dev_desc)
-{
-       unsigned char c;
-       hd_driveid_t iop;
-
-#ifdef CONFIG_ATAPI
-       int retries = 0;
-#endif
-       int device;
-
-       device = dev_desc->devnum;
-       printf("  Device %d: ", device);
-
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-       /* Select device
-        */
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       dev_desc->if_type = IF_TYPE_IDE;
-#ifdef CONFIG_ATAPI
-
-       retries = 0;
-
-       /* Warning: This will be tricky to read */
-       while (retries <= 1) {
-               /* check signature */
-               if ((ide_inb(device, ATA_SECT_CNT) == 0x01) &&
-                   (ide_inb(device, ATA_SECT_NUM) == 0x01) &&
-                   (ide_inb(device, ATA_CYL_LOW) == 0x14) &&
-                   (ide_inb(device, ATA_CYL_HIGH) == 0xEB)) {
-                       /* ATAPI Signature found */
-                       dev_desc->if_type = IF_TYPE_ATAPI;
-                       /*
-                        * Start Ident Command
-                        */
-                       ide_outb(device, ATA_COMMAND, ATAPI_CMD_IDENT);
-                       /*
-                        * Wait for completion - ATAPI devices need more time
-                        * to become ready
-                        */
-                       c = ide_wait(device, ATAPI_TIME_OUT);
-               } else
-#endif
-               {
-                       /*
-                        * Start Ident Command
-                        */
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_IDENT);
-
-                       /*
-                        * Wait for completion
-                        */
-                       c = ide_wait(device, IDE_TIME_OUT);
-               }
-               ide_led(DEVICE_LED(device), 0); /* LED off      */
-
-               if (((c & ATA_STAT_DRQ) == 0) ||
-                   ((c & (ATA_STAT_FAULT | ATA_STAT_ERR)) != 0)) {
-#ifdef CONFIG_ATAPI
-                       {
-                               /*
-                                * Need to soft reset the device
-                                * in case it's an ATAPI...
-                                */
-                               debug("Retrying...\n");
-                               ide_outb(device, ATA_DEV_HD,
-                                        ATA_LBA | ATA_DEVICE(device));
-                               udelay(100000);
-                               ide_outb(device, ATA_COMMAND, 0x08);
-                               udelay(500000); /* 500 ms */
-                       }
-                       /*
-                        * Select device
-                        */
-                       ide_outb(device, ATA_DEV_HD,
-                                ATA_LBA | ATA_DEVICE(device));
-                       retries++;
-#else
-                       return;
-#endif
-               }
-#ifdef CONFIG_ATAPI
-               else
-                       break;
-       }                       /* see above - ugly to read */
-
-       if (retries == 2)       /* Not found */
-               return;
-#endif
-
-       ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS);
-
-       ident_cpy((unsigned char *) dev_desc->revision, iop.fw_rev,
-                 sizeof(dev_desc->revision));
-       ident_cpy((unsigned char *) dev_desc->vendor, iop.model,
-                 sizeof(dev_desc->vendor));
-       ident_cpy((unsigned char *) dev_desc->product, iop.serial_no,
-                 sizeof(dev_desc->product));
-#ifdef __LITTLE_ENDIAN
-       /*
-        * firmware revision, model, and serial number have Big Endian Byte
-        * order in Word. Convert all three to little endian.
-        *
-        * See CF+ and CompactFlash Specification Revision 2.0:
-        * 6.2.1.6: Identify Drive, Table 39 for more details
-        */
-
-       strswab(dev_desc->revision);
-       strswab(dev_desc->vendor);
-       strswab(dev_desc->product);
-#endif /* __LITTLE_ENDIAN */
-
-       if ((iop.config & 0x0080) == 0x0080)
-               dev_desc->removable = 1;
-       else
-               dev_desc->removable = 0;
-
-#ifdef CONFIG_ATAPI
-       if (dev_desc->if_type == IF_TYPE_ATAPI) {
-               atapi_inquiry(dev_desc);
-               return;
-       }
-#endif /* CONFIG_ATAPI */
-
-#ifdef __BIG_ENDIAN
-       /* swap shorts */
-       dev_desc->lba = (iop.lba_capacity << 16) | (iop.lba_capacity >> 16);
-#else  /* ! __BIG_ENDIAN */
-       /*
-        * do not swap shorts on little endian
-        *
-        * See CF+ and CompactFlash Specification Revision 2.0:
-        * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details.
-        */
-       dev_desc->lba = iop.lba_capacity;
-#endif /* __BIG_ENDIAN */
-
-#ifdef CONFIG_LBA48
-       if (iop.command_set_2 & 0x0400) {       /* LBA 48 support */
-               dev_desc->lba48 = 1;
-               dev_desc->lba = (unsigned long long) iop.lba48_capacity[0] |
-                       ((unsigned long long) iop.lba48_capacity[1] << 16) |
-                       ((unsigned long long) iop.lba48_capacity[2] << 32) |
-                       ((unsigned long long) iop.lba48_capacity[3] << 48);
-       } else {
-               dev_desc->lba48 = 0;
-       }
-#endif /* CONFIG_LBA48 */
-       /* assuming HD */
-       dev_desc->type = DEV_TYPE_HARDDISK;
-       dev_desc->blksz = ATA_BLOCKSIZE;
-       dev_desc->log2blksz = LOG2(dev_desc->blksz);
-       dev_desc->lun = 0;      /* just to fill something in... */
-
-#if 0                          /* only used to test the powersaving mode,
-                                * if enabled, the drive goes after 5 sec
-                                * in standby mode */
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       c = ide_wait(device, IDE_TIME_OUT);
-       ide_outb(device, ATA_SECT_CNT, 1);
-       ide_outb(device, ATA_LBA_LOW, 0);
-       ide_outb(device, ATA_LBA_MID, 0);
-       ide_outb(device, ATA_LBA_HIGH, 0);
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       ide_outb(device, ATA_COMMAND, 0xe3);
-       udelay(50);
-       c = ide_wait(device, IDE_TIME_OUT);     /* can't take over 500 ms */
-#endif
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
-              void *buffer)
-{
-       int device = block_dev->devnum;
-       ulong n = 0;
-       unsigned char c;
-       unsigned char pwrsave = 0;      /* power save */
-
-#ifdef CONFIG_LBA48
-       unsigned char lba48 = 0;
-
-       if (blknr & 0x0000fffff0000000ULL) {
-               /* more than 28 bits used, use 48bit mode */
-               lba48 = 1;
-       }
-#endif
-       debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n",
-             device, blknr, blkcnt, (ulong) buffer);
-
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-
-       /* Select device
-        */
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       c = ide_wait(device, IDE_TIME_OUT);
-
-       if (c & ATA_STAT_BUSY) {
-               printf("IDE read: device %d not ready\n", device);
-               goto IDE_READ_E;
-       }
-
-       /* first check if the drive is in Powersaving mode, if yes,
-        * increase the timeout value */
-       ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_PWR);
-       udelay(50);
-
-       c = ide_wait(device, IDE_TIME_OUT);     /* can't take over 500 ms */
-
-       if (c & ATA_STAT_BUSY) {
-               printf("IDE read: device %d not ready\n", device);
-               goto IDE_READ_E;
-       }
-       if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
-               printf("No Powersaving mode %X\n", c);
-       } else {
-               c = ide_inb(device, ATA_SECT_CNT);
-               debug("Powersaving %02X\n", c);
-               if (c == 0)
-                       pwrsave = 1;
-       }
-
-
-       while (blkcnt-- > 0) {
-
-               c = ide_wait(device, IDE_TIME_OUT);
-
-               if (c & ATA_STAT_BUSY) {
-                       printf("IDE read: device %d not ready\n", device);
-                       break;
-               }
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       /* write high bits */
-                       ide_outb(device, ATA_SECT_CNT, 0);
-                       ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
-#ifdef CONFIG_SYS_64BIT_LBA
-                       ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
-                       ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
-#else
-                       ide_outb(device, ATA_LBA_MID, 0);
-                       ide_outb(device, ATA_LBA_HIGH, 0);
-#endif
-               }
-#endif
-               ide_outb(device, ATA_SECT_CNT, 1);
-               ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
-               ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
-               ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
-
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       ide_outb(device, ATA_DEV_HD,
-                                ATA_LBA | ATA_DEVICE(device));
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_READ_EXT);
-
-               } else
-#endif
-               {
-                       ide_outb(device, ATA_DEV_HD, ATA_LBA |
-                                ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_READ);
-               }
-
-               udelay(50);
-
-               if (pwrsave) {
-                       /* may take up to 4 sec */
-                       c = ide_wait(device, IDE_SPIN_UP_TIME_OUT);
-                       pwrsave = 0;
-               } else {
-                       /* can't take over 500 ms */
-                       c = ide_wait(device, IDE_TIME_OUT);
-               }
-
-               if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
-                   ATA_STAT_DRQ) {
-                       printf("Error (no IRQ) dev %d blk " LBAF ": status "
-                              "%#02x\n", device, blknr, c);
-                       break;
-               }
-
-               ide_input_data(device, buffer, ATA_SECTORWORDS);
-               (void) ide_inb(device, ATA_STATUS);     /* clear IRQ */
-
-               ++n;
-               ++blknr;
-               buffer += ATA_BLOCKSIZE;
-       }
-IDE_READ_E:
-       ide_led(DEVICE_LED(device), 0); /* LED off      */
-       return (n);
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
-               const void *buffer)
-{
-       int device = block_dev->devnum;
-       ulong n = 0;
-       unsigned char c;
-
-#ifdef CONFIG_LBA48
-       unsigned char lba48 = 0;
-
-       if (blknr & 0x0000fffff0000000ULL) {
-               /* more than 28 bits used, use 48bit mode */
-               lba48 = 1;
-       }
-#endif
-
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-
-       /* Select device
-        */
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-
-       while (blkcnt-- > 0) {
-
-               c = ide_wait(device, IDE_TIME_OUT);
-
-               if (c & ATA_STAT_BUSY) {
-                       printf("IDE read: device %d not ready\n", device);
-                       goto WR_OUT;
-               }
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       /* write high bits */
-                       ide_outb(device, ATA_SECT_CNT, 0);
-                       ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
-#ifdef CONFIG_SYS_64BIT_LBA
-                       ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
-                       ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
-#else
-                       ide_outb(device, ATA_LBA_MID, 0);
-                       ide_outb(device, ATA_LBA_HIGH, 0);
-#endif
-               }
-#endif
-               ide_outb(device, ATA_SECT_CNT, 1);
-               ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
-               ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
-               ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
-
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       ide_outb(device, ATA_DEV_HD,
-                                ATA_LBA | ATA_DEVICE(device));
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE_EXT);
-
-               } else
-#endif
-               {
-                       ide_outb(device, ATA_DEV_HD, ATA_LBA |
-                                ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE);
-               }
-
-               udelay(50);
-
-               /* can't take over 500 ms */
-               c = ide_wait(device, IDE_TIME_OUT);
-
-               if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
-                   ATA_STAT_DRQ) {
-                       printf("Error (no IRQ) dev %d blk " LBAF ": status "
-                               "%#02x\n", device, blknr, c);
-                       goto WR_OUT;
-               }
-
-               ide_output_data(device, buffer, ATA_SECTORWORDS);
-               c = ide_inb(device, ATA_STATUS);        /* clear IRQ */
-               ++n;
-               ++blknr;
-               buffer += ATA_BLOCKSIZE;
-       }
-WR_OUT:
-       ide_led(DEVICE_LED(device), 0); /* LED off      */
-       return (n);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * copy src to dest, skipping leading and trailing blanks and null
- * terminate the string
- * "len" is the size of available memory including the terminating '\0'
- */
-static void ident_cpy(unsigned char *dst, unsigned char *src,
-                     unsigned int len)
-{
-       unsigned char *end, *last;
-
-       last = dst;
-       end = src + len - 1;
-
-       /* reserve space for '\0' */
-       if (len < 2)
-               goto OUT;
-
-       /* skip leading white space */
-       while ((*src) && (src < end) && (*src == ' '))
-               ++src;
-
-       /* copy string, omitting trailing white space */
-       while ((*src) && (src < end)) {
-               *dst++ = *src;
-               if (*src++ != ' ')
-                       last = dst;
-       }
-OUT:
-       *last = '\0';
-}
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * Wait until Busy bit is off, or timeout (in ms)
- * Return last status
- */
-static uchar ide_wait(int dev, ulong t)
-{
-       ulong delay = 10 * t;   /* poll every 100 us */
-       uchar c;
-
-       while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) {
-               udelay(100);
-               if (delay-- == 0)
-                       break;
-       }
-       return (c);
-}
-
-/* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_IDE_RESET
-extern void ide_set_reset(int idereset);
-
-static void ide_reset(void)
-{
-       int i;
-
-       curr_device = -1;
-       for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; ++i)
-               ide_bus_ok[i] = 0;
-       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i)
-               ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
-
-       ide_set_reset(1);       /* assert reset */
-
-       /* the reset signal shall be asserted for et least 25 us */
-       udelay(25);
-
-       WATCHDOG_RESET();
-
-       /* de-assert RESET signal */
-       ide_set_reset(0);
-
-       /* wait 250 ms */
-       for (i = 0; i < 250; ++i)
-               udelay(1000);
-}
-
-#endif /* CONFIG_IDE_RESET */
-
-/* ------------------------------------------------------------------------- */
-
-#if defined(CONFIG_OF_IDE_FIXUP)
-int ide_device_present(int dev)
-{
-       if (dev >= CONFIG_SYS_IDE_MAXBUS)
-               return 0;
-       return (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN ? 0 : 1);
-}
-#endif
-/* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ATAPI
-/****************************************************************************
- * ATAPI Support
- */
-
-#if defined(CONFIG_IDE_SWAP_IO)
-/* since ATAPI may use commands with not 4 bytes alligned length
- * we have our own transfer functions, 2 bytes alligned */
-__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
-{
-       ushort *dbuf;
-       volatile ushort *pbuf;
-
-       pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       dbuf = (ushort *) sect_buf;
-
-       debug("in output data shorts base for read is %lx\n",
-             (unsigned long) pbuf);
-
-       while (shorts--) {
-               EIEIO;
-               *pbuf = *dbuf++;
-       }
-}
-
-__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
-{
-       ushort *dbuf;
-       volatile ushort *pbuf;
-
-       pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       dbuf = (ushort *) sect_buf;
-
-       debug("in input data shorts base for read is %lx\n",
-             (unsigned long) pbuf);
-
-       while (shorts--) {
-               EIEIO;
-               *dbuf++ = *pbuf;
-       }
-}
-
-#else  /* ! CONFIG_IDE_SWAP_IO */
-__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
-{
-       outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
-}
-
-__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
-{
-       insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
-}
-
-#endif /* CONFIG_IDE_SWAP_IO */
-
-/*
- * Wait until (Status & mask) == res, or timeout (in ms)
- * Return last status
- * This is used since some ATAPI CD ROMs clears their Busy Bit first
- * and then they set their DRQ Bit
- */
-static uchar atapi_wait_mask(int dev, ulong t, uchar mask, uchar res)
-{
-       ulong delay = 10 * t;   /* poll every 100 us */
-       uchar c;
-
-       /* prevents to read the status before valid */
-       c = ide_inb(dev, ATA_DEV_CTL);
-
-       while (((c = ide_inb(dev, ATA_STATUS)) & mask) != res) {
-               /* break if error occurs (doesn't make sense to wait more) */
-               if ((c & ATA_STAT_ERR) == ATA_STAT_ERR)
-                       break;
-               udelay(100);
-               if (delay-- == 0)
-                       break;
-       }
-       return (c);
-}
-
-/*
- * issue an atapi command
- */
-unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
-                         unsigned char *buffer, int buflen)
-{
-       unsigned char c, err, mask, res;
-       int n;
-
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-
-       /* Select device
-        */
-       mask = ATA_STAT_BUSY | ATA_STAT_DRQ;
-       res = 0;
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
-       if ((c & mask) != res) {
-               printf("ATAPI_ISSUE: device %d not ready status %X\n", device,
-                      c);
-               err = 0xFF;
-               goto AI_OUT;
-       }
-       /* write taskfile */
-       ide_outb(device, ATA_ERROR_REG, 0);     /* no DMA, no overlaped */
-       ide_outb(device, ATA_SECT_CNT, 0);
-       ide_outb(device, ATA_SECT_NUM, 0);
-       ide_outb(device, ATA_CYL_LOW, (unsigned char) (buflen & 0xFF));
-       ide_outb(device, ATA_CYL_HIGH,
-                (unsigned char) ((buflen >> 8) & 0xFF));
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-
-       ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET);
-       udelay(50);
-
-       mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
-       res = ATA_STAT_DRQ;
-       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
-
-       if ((c & mask) != res) {        /* DRQ must be 1, BSY 0 */
-               printf("ATAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n",
-                       device, c);
-               err = 0xFF;
-               goto AI_OUT;
-       }
-
-       /* write command block */
-       ide_output_data_shorts(device, (unsigned short *) ccb, ccblen / 2);
-
-       /* ATAPI Command written wait for completition */
-       udelay(5000);           /* device must set bsy */
-
-       mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
-       /*
-        * if no data wait for DRQ = 0 BSY = 0
-        * if data wait for DRQ = 1 BSY = 0
-        */
-       res = 0;
-       if (buflen)
-               res = ATA_STAT_DRQ;
-       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
-       if ((c & mask) != res) {
-               if (c & ATA_STAT_ERR) {
-                       err = (ide_inb(device, ATA_ERROR_REG)) >> 4;
-                       debug("atapi_issue 1 returned sense key %X status %02X\n",
-                               err, c);
-               } else {
-                       printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x)  status 0x%02x\n",
-                               ccb[0], c);
-                       err = 0xFF;
-               }
-               goto AI_OUT;
-       }
-       n = ide_inb(device, ATA_CYL_HIGH);
-       n <<= 8;
-       n += ide_inb(device, ATA_CYL_LOW);
-       if (n > buflen) {
-               printf("ERROR, transfer bytes %d requested only %d\n", n,
-                      buflen);
-               err = 0xff;
-               goto AI_OUT;
-       }
-       if ((n == 0) && (buflen < 0)) {
-               printf("ERROR, transfer bytes %d requested %d\n", n, buflen);
-               err = 0xff;
-               goto AI_OUT;
-       }
-       if (n != buflen) {
-               debug("WARNING, transfer bytes %d not equal with requested %d\n",
-                       n, buflen);
-       }
-       if (n != 0) {           /* data transfer */
-               debug("ATAPI_ISSUE: %d Bytes to transfer\n", n);
-               /* we transfer shorts */
-               n >>= 1;
-               /* ok now decide if it is an in or output */
-               if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) {
-                       debug("Write to device\n");
-                       ide_output_data_shorts(device,
-                               (unsigned short *) buffer, n);
-               } else {
-                       debug("Read from device @ %p shorts %d\n", buffer, n);
-                       ide_input_data_shorts(device,
-                               (unsigned short *) buffer, n);
-               }
-       }
-       udelay(5000);           /* seems that some CD ROMs need this... */
-       mask = ATA_STAT_BUSY | ATA_STAT_ERR;
-       res = 0;
-       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
-       if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
-               err = (ide_inb(device, ATA_ERROR_REG) >> 4);
-               debug("atapi_issue 2 returned sense key %X status %X\n", err,
-                     c);
-       } else {
-               err = 0;
-       }
-AI_OUT:
-       ide_led(DEVICE_LED(device), 0); /* LED off      */
-       return (err);
-}
-
-/*
- * sending the command to atapi_issue. If an status other than good
- * returns, an request_sense will be issued
- */
-
-#define ATAPI_DRIVE_NOT_READY  100
-#define ATAPI_UNIT_ATTN                10
-
-unsigned char atapi_issue_autoreq(int device,
-                                 unsigned char *ccb,
-                                 int ccblen,
-                                 unsigned char *buffer, int buflen)
-{
-       unsigned char sense_data[18], sense_ccb[12];
-       unsigned char res, key, asc, ascq;
-       int notready, unitattn;
-
-       unitattn = ATAPI_UNIT_ATTN;
-       notready = ATAPI_DRIVE_NOT_READY;
-
-retry:
-       res = atapi_issue(device, ccb, ccblen, buffer, buflen);
-       if (res == 0)
-               return 0;       /* Ok */
-
-       if (res == 0xFF)
-               return 0xFF;    /* error */
-
-       debug("(auto_req)atapi_issue returned sense key %X\n", res);
-
-       memset(sense_ccb, 0, sizeof(sense_ccb));
-       memset(sense_data, 0, sizeof(sense_data));
-       sense_ccb[0] = ATAPI_CMD_REQ_SENSE;
-       sense_ccb[4] = 18;      /* allocation Length */
-
-       res = atapi_issue(device, sense_ccb, 12, sense_data, 18);
-       key = (sense_data[2] & 0xF);
-       asc = (sense_data[12]);
-       ascq = (sense_data[13]);
-
-       debug("ATAPI_CMD_REQ_SENSE returned %x\n", res);
-       debug(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",
-             sense_data[0], key, asc, ascq);
-
-       if ((key == 0))
-               return 0;       /* ok device ready */
-
-       if ((key == 6) || (asc == 0x29) || (asc == 0x28)) { /* Unit Attention */
-               if (unitattn-- > 0) {
-                       udelay(200 * 1000);
-                       goto retry;
-               }
-               printf("Unit Attention, tried %d\n", ATAPI_UNIT_ATTN);
-               goto error;
-       }
-       if ((asc == 0x4) && (ascq == 0x1)) {
-               /* not ready, but will be ready soon */
-               if (notready-- > 0) {
-                       udelay(200 * 1000);
-                       goto retry;
-               }
-               printf("Drive not ready, tried %d times\n",
-                      ATAPI_DRIVE_NOT_READY);
-               goto error;
-       }
-       if (asc == 0x3a) {
-               debug("Media not present\n");
-               goto error;
-       }
-
-       printf("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n", key, asc,
-              ascq);
-error:
-       debug("ERROR Sense key %02X ASC %02X ASCQ %02X\n", key, asc, ascq);
-       return (0xFF);
-}
-
-
-static void atapi_inquiry(struct blk_desc *dev_desc)
-{
-       unsigned char ccb[12];  /* Command descriptor block */
-       unsigned char iobuf[64];        /* temp buf */
-       unsigned char c;
-       int device;
-
-       device = dev_desc->devnum;
-       dev_desc->type = DEV_TYPE_UNKNOWN;      /* not yet valid */
-       dev_desc->block_read = atapi_read;
-
-       memset(ccb, 0, sizeof(ccb));
-       memset(iobuf, 0, sizeof(iobuf));
-
-       ccb[0] = ATAPI_CMD_INQUIRY;
-       ccb[4] = 40;            /* allocation Legnth */
-       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *) iobuf, 40);
-
-       debug("ATAPI_CMD_INQUIRY returned %x\n", c);
-       if (c != 0)
-               return;
-
-       /* copy device ident strings */
-       ident_cpy((unsigned char *) dev_desc->vendor, &iobuf[8], 8);
-       ident_cpy((unsigned char *) dev_desc->product, &iobuf[16], 16);
-       ident_cpy((unsigned char *) dev_desc->revision, &iobuf[32], 5);
-
-       dev_desc->lun = 0;
-       dev_desc->lba = 0;
-       dev_desc->blksz = 0;
-       dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz));
-       dev_desc->type = iobuf[0] & 0x1f;
-
-       if ((iobuf[1] & 0x80) == 0x80)
-               dev_desc->removable = 1;
-       else
-               dev_desc->removable = 0;
-
-       memset(ccb, 0, sizeof(ccb));
-       memset(iobuf, 0, sizeof(iobuf));
-       ccb[0] = ATAPI_CMD_START_STOP;
-       ccb[4] = 0x03;          /* start */
-
-       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *) iobuf, 0);
-
-       debug("ATAPI_CMD_START_STOP returned %x\n", c);
-       if (c != 0)
-               return;
-
-       memset(ccb, 0, sizeof(ccb));
-       memset(iobuf, 0, sizeof(iobuf));
-       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *) iobuf, 0);
-
-       debug("ATAPI_CMD_UNIT_TEST_READY returned %x\n", c);
-       if (c != 0)
-               return;
-
-       memset(ccb, 0, sizeof(ccb));
-       memset(iobuf, 0, sizeof(iobuf));
-       ccb[0] = ATAPI_CMD_READ_CAP;
-       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *) iobuf, 8);
-       debug("ATAPI_CMD_READ_CAP returned %x\n", c);
-       if (c != 0)
-               return;
-
-       debug("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",
-             iobuf[0], iobuf[1], iobuf[2], iobuf[3],
-             iobuf[4], iobuf[5], iobuf[6], iobuf[7]);
-
-       dev_desc->lba = ((unsigned long) iobuf[0] << 24) +
-               ((unsigned long) iobuf[1] << 16) +
-               ((unsigned long) iobuf[2] << 8) + ((unsigned long) iobuf[3]);
-       dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
-               ((unsigned long) iobuf[5] << 16) +
-               ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
-       dev_desc->log2blksz = LOG2(dev_desc->blksz);
-#ifdef CONFIG_LBA48
-       /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
-       dev_desc->lba48 = 0;
-#endif
-       return;
-}
-
-
-/*
- * atapi_read:
- * we transfer only one block per command, since the multiple DRQ per
- * command is not yet implemented
- */
-#define ATAPI_READ_MAX_BYTES   2048    /* we read max 2kbytes */
-#define ATAPI_READ_BLOCK_SIZE  2048    /* assuming CD part */
-#define ATAPI_READ_MAX_BLOCK   (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)
-
-ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
-                void *buffer)
-{
-       int device = block_dev->devnum;
-       ulong n = 0;
-       unsigned char ccb[12];  /* Command descriptor block */
-       ulong cnt;
-
-       debug("atapi_read dev %d start " LBAF " blocks " LBAF " buffer at %lX\n",
-             device, blknr, blkcnt, (ulong) buffer);
-
-       do {
-               if (blkcnt > ATAPI_READ_MAX_BLOCK)
-                       cnt = ATAPI_READ_MAX_BLOCK;
-               else
-                       cnt = blkcnt;
-
-               ccb[0] = ATAPI_CMD_READ_12;
-               ccb[1] = 0;     /* reserved */
-               ccb[2] = (unsigned char) (blknr >> 24) & 0xFF;  /* MSB Block */
-               ccb[3] = (unsigned char) (blknr >> 16) & 0xFF;  /*  */
-               ccb[4] = (unsigned char) (blknr >> 8) & 0xFF;
-               ccb[5] = (unsigned char) blknr & 0xFF;  /* LSB Block */
-               ccb[6] = (unsigned char) (cnt >> 24) & 0xFF; /* MSB Block cnt */
-               ccb[7] = (unsigned char) (cnt >> 16) & 0xFF;
-               ccb[8] = (unsigned char) (cnt >> 8) & 0xFF;
-               ccb[9] = (unsigned char) cnt & 0xFF;    /* LSB Block */
-               ccb[10] = 0;    /* reserved */
-               ccb[11] = 0;    /* reserved */
-
-               if (atapi_issue_autoreq(device, ccb, 12,
-                                       (unsigned char *) buffer,
-                                       cnt * ATAPI_READ_BLOCK_SIZE)
-                   == 0xFF) {
-                       return (n);
-               }
-               n += cnt;
-               blkcnt -= cnt;
-               blknr += cnt;
-               buffer += (cnt * ATAPI_READ_BLOCK_SIZE);
-       } while (blkcnt > 0);
-       return (n);
-}
-
-/* ------------------------------------------------------------------------- */
-
-#endif /* CONFIG_ATAPI */
-
 U_BOOT_CMD(ide, 5, 1, do_ide,
           "IDE sub-system",
           "reset - reset IDE controller\n"
index c5454bf2e130fac5b5d577fbfb2ee97ed3aaa268..eb4a547a9707939c71ad5396fe2fe386d9912084 100644 (file)
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -314,12 +314,14 @@ static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag,
        }
        /* Switch to the RPMB partition */
        original_part = mmc->block_dev.hwpart;
-       if (mmc_select_hwpart(curr_device, MMC_PART_RPMB) != 0)
+       if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) !=
+           0)
                return CMD_RET_FAILURE;
        ret = cp->cmd(cmdtp, flag, argc, argv);
 
        /* Return to original partition */
-       if (mmc_select_hwpart(curr_device, original_part) != 0)
+       if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) !=
+           0)
                return CMD_RET_FAILURE;
        return ret;
 }
@@ -346,7 +348,7 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
        printf("\nMMC read: dev # %d, block # %d, count %d ... ",
               curr_device, blk, cnt);
 
-       n = blk_dread(&mmc->block_dev, blk, cnt, addr);
+       n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
        /* flush cache after read */
        flush_cache((ulong)addr, cnt * 512); /* FIXME */
        printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
@@ -378,7 +380,7 @@ static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
                printf("Error: card is write protected!\n");
                return CMD_RET_FAILURE;
        }
-       n = blk_dwrite(&mmc->block_dev, blk, cnt, addr);
+       n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
        printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
 
        return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
@@ -406,7 +408,7 @@ static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
                printf("Error: card is write protected!\n");
                return CMD_RET_FAILURE;
        }
-       n = blk_derase(&mmc->block_dev, blk, cnt);
+       n = blk_derase(mmc_get_blk_desc(mmc), blk, cnt);
        printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR");
 
        return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
@@ -432,7 +434,7 @@ static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
        if (!mmc)
                return CMD_RET_FAILURE;
 
-       mmc_dev = mmc_get_dev(curr_device);
+       mmc_dev = blk_get_devnum_by_type(IF_TYPE_MMC, curr_device);
        if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
                part_print(mmc_dev);
                return CMD_RET_SUCCESS;
@@ -467,7 +469,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
        if (!mmc)
                return CMD_RET_FAILURE;
 
-       ret = mmc_select_hwpart(dev, part);
+       ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
        printf("switch to partitions #%d, %s\n",
               part, (!ret) ? "OK" : "ERROR");
        if (ret)
@@ -478,7 +480,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
                printf("mmc%d is current device\n", curr_device);
        else
                printf("mmc%d(part %d) is current device\n",
-                      curr_device, mmc->block_dev.hwpart);
+                      curr_device, mmc_get_blk_desc(mmc)->hwpart);
 
        return CMD_RET_SUCCESS;
 }
index 8748ccef69685fee1b250633118f908fac69db5c..d18b5233e6aa973457f29893c22d8463d825ecaa 100644 (file)
 #include <sata.h>
 
 static int sata_curr_device = -1;
-struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
-
-static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start,
-                               lbaint_t blkcnt, void *dst)
-{
-       return sata_read(block_dev->devnum, start, blkcnt, dst);
-}
-
-static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
-                                lbaint_t blkcnt, const void *buffer)
-{
-       return sata_write(block_dev->devnum, start, blkcnt, buffer);
-}
-
-int __sata_initialize(void)
-{
-       int rc;
-       int i;
-
-       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
-               memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
-               sata_dev_desc[i].if_type = IF_TYPE_SATA;
-               sata_dev_desc[i].devnum = i;
-               sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
-               sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
-               sata_dev_desc[i].lba = 0;
-               sata_dev_desc[i].blksz = 512;
-               sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
-               sata_dev_desc[i].block_read = sata_bread;
-               sata_dev_desc[i].block_write = sata_bwrite;
-
-               rc = init_sata(i);
-               if (!rc) {
-                       rc = scan_sata(i);
-                       if (!rc && (sata_dev_desc[i].lba > 0) &&
-                               (sata_dev_desc[i].blksz > 0))
-                               part_init(&sata_dev_desc[i]);
-               }
-       }
-       sata_curr_device = 0;
-       return rc;
-}
-int sata_initialize(void) __attribute__((weak,alias("__sata_initialize")));
-
-__weak int __sata_stop(void)
-{
-       int i, err = 0;
-
-       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++)
-               err |= reset_sata(i);
-
-       if (err)
-               printf("Could not reset some SATA devices\n");
-
-       return err;
-}
-int sata_stop(void) __attribute__((weak, alias("__sata_stop")));
-
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *sata_get_dev(int dev)
-{
-       return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
-}
-#endif
 
 static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -105,69 +41,40 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        case 1:
                return CMD_RET_USAGE;
        case 2:
-               if (strncmp(argv[1],"inf", 3) == 0) {
-                       int i;
-                       putc('\n');
-                       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; ++i) {
-                               if (sata_dev_desc[i].type == DEV_TYPE_UNKNOWN)
-                                       continue;
-                               printf ("SATA device %d: ", i);
-                               dev_print(&sata_dev_desc[i]);
-                       }
+               if (strncmp(argv[1], "inf", 3) == 0) {
+                       blk_list_devices(IF_TYPE_SATA);
                        return 0;
-               } else if (strncmp(argv[1],"dev", 3) == 0) {
-                       if ((sata_curr_device < 0) || (sata_curr_device >= CONFIG_SYS_SATA_MAX_DEVICE)) {
-                               puts("\nno SATA devices available\n");
-                               return 1;
+               } else if (strncmp(argv[1], "dev", 3) == 0) {
+                       if (blk_print_device_num(IF_TYPE_SATA,
+                                                sata_curr_device)) {
+                               printf("\nno SATA devices available\n");
+                               return CMD_RET_FAILURE;
                        }
-                       printf("\nSATA device %d: ", sata_curr_device);
-                       dev_print(&sata_dev_desc[sata_curr_device]);
                        return 0;
-               } else if (strncmp(argv[1],"part",4) == 0) {
-                       int dev, ok;
-
-                       for (ok = 0, dev = 0; dev < CONFIG_SYS_SATA_MAX_DEVICE; ++dev) {
-                               if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
-                                       ++ok;
-                                       if (dev)
-                                               putc ('\n');
-                                       part_print(&sata_dev_desc[dev]);
-                               }
-                       }
-                       if (!ok) {
+               } else if (strncmp(argv[1], "part", 4) == 0) {
+                       if (blk_list_part(IF_TYPE_SATA))
                                puts("\nno SATA devices available\n");
-                               rc ++;
-                       }
-                       return rc;
+                       return 0;
                }
                return CMD_RET_USAGE;
        case 3:
                if (strncmp(argv[1], "dev", 3) == 0) {
                        int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-                       printf("\nSATA device %d: ", dev);
-                       if (dev >= CONFIG_SYS_SATA_MAX_DEVICE) {
-                               puts ("unknown device\n");
-                               return 1;
+                       if (!blk_show_device(IF_TYPE_SATA, dev)) {
+                               sata_curr_device = dev;
+                               printf("... is now current device\n");
+                       } else {
+                               return CMD_RET_FAILURE;
                        }
-                       dev_print(&sata_dev_desc[dev]);
-
-                       if (sata_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
-                               return 1;
-
-                       sata_curr_device = dev;
-
-                       puts("... is now current device\n");
-
                        return 0;
                } else if (strncmp(argv[1], "part", 4) == 0) {
                        int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-                       if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
-                               part_print(&sata_dev_desc[dev]);
-                       } else {
-                               printf("\nSATA device %d not available\n", dev);
-                               rc = 1;
+                       if (blk_print_part_devnum(IF_TYPE_SATA, dev)) {
+                               printf("\nSATA device %d not available\n",
+                                      dev);
+                               return CMD_RET_FAILURE;
                        }
                        return rc;
                }
@@ -183,11 +90,8 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        printf("\nSATA read: device %d block # %ld, count %ld ... ",
                                sata_curr_device, blk, cnt);
 
-                       n = blk_dread(&sata_dev_desc[sata_curr_device],
-                                     blk, cnt, (u32 *)addr);
-
-                       /* flush cache after read */
-                       flush_cache(addr, cnt * sata_dev_desc[sata_curr_device].blksz);
+                       n = blk_read_devnum(IF_TYPE_SATA, sata_curr_device, blk,
+                                           cnt, (ulong *)addr);
 
                        printf("%ld blocks read: %s\n",
                                n, (n==cnt) ? "OK" : "ERROR");
@@ -202,8 +106,8 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        printf("\nSATA write: device %d block # %ld, count %ld ... ",
                                sata_curr_device, blk, cnt);
 
-                       n = blk_dwrite(&sata_dev_desc[sata_curr_device],
-                                      blk, cnt, (u32 *)addr);
+                       n = blk_write_devnum(IF_TYPE_SATA, sata_curr_device,
+                                            blk, cnt, (ulong *)addr);
 
                        printf("%ld blocks written: %s\n",
                                n, (n == cnt) ? "OK" : "ERROR");
index 8991125c66248a00f650e5846f6c586592e232d3..387ca1a262ab505c9e680c8874111a91bcf4bc5d 100644 (file)
  */
 #include <common.h>
 #include <command.h>
-#include <inttypes.h>
-#include <asm/processor.h>
 #include <scsi.h>
-#include <image.h>
-#include <pci.h>
-
-#ifdef CONFIG_SCSI_DEV_LIST
-#define SCSI_DEV_LIST CONFIG_SCSI_DEV_LIST
-#else
-#ifdef CONFIG_SCSI_SYM53C8XX
-#define SCSI_VEND_ID   0x1000
-#ifndef CONFIG_SCSI_DEV_ID
-#define SCSI_DEV_ID            0x0001
-#else
-#define SCSI_DEV_ID            CONFIG_SCSI_DEV_ID
-#endif
-#elif defined CONFIG_SATA_ULI5288
-
-#define SCSI_VEND_ID 0x10b9
-#define SCSI_DEV_ID  0x5288
-
-#elif !defined(CONFIG_SCSI_AHCI_PLAT)
-#error no scsi device defined
-#endif
-#define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID}
-#endif
-
-#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
-const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST };
-#endif
-static ccb tempccb;    /* temporary scsi command buffer */
-
-static unsigned char tempbuff[512]; /* temporary data buffer */
-
-static int scsi_max_devs; /* number of highest available scsi device */
 
 static int scsi_curr_dev; /* current device */
 
-static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
-
-/********************************************************************************
- *  forward declerations of some Setup Routines
- */
-void scsi_setup_test_unit_ready(ccb * pccb);
-void scsi_setup_read6(ccb * pccb, lbaint_t start, unsigned short blocks);
-void scsi_setup_read_ext(ccb * pccb, lbaint_t start, unsigned short blocks);
-void scsi_setup_read16(ccb * pccb, lbaint_t start, unsigned long blocks);
-
-static void scsi_setup_write_ext(ccb *pccb, lbaint_t start,
-                               unsigned short blocks);
-void scsi_setup_inquiry(ccb * pccb);
-void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
-
-
-static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity,
-                             unsigned long *blksz);
-static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
-                      lbaint_t blkcnt, void *buffer);
-static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
-                       lbaint_t blkcnt, const void *buffer);
-
-
-/*********************************************************************************
- * (re)-scan the scsi bus and reports scsi device info
- * to the user if mode = 1
- */
-void scsi_scan(int mode)
-{
-       unsigned char i,perq,modi,lun;
-       lbaint_t capacity;
-       unsigned long blksz;
-       ccb* pccb=(ccb *)&tempccb;
-
-       if(mode==1) {
-               printf("scanning bus for devices...\n");
-       }
-       for(i=0;i<CONFIG_SYS_SCSI_MAX_DEVICE;i++) {
-               scsi_dev_desc[i].target=0xff;
-               scsi_dev_desc[i].lun=0xff;
-               scsi_dev_desc[i].lba=0;
-               scsi_dev_desc[i].blksz=0;
-               scsi_dev_desc[i].log2blksz =
-                       LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));
-               scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN;
-               scsi_dev_desc[i].vendor[0]=0;
-               scsi_dev_desc[i].product[0]=0;
-               scsi_dev_desc[i].revision[0]=0;
-               scsi_dev_desc[i].removable = false;
-               scsi_dev_desc[i].if_type=IF_TYPE_SCSI;
-               scsi_dev_desc[i].devnum = i;
-               scsi_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
-               scsi_dev_desc[i].block_read=scsi_read;
-               scsi_dev_desc[i].block_write = scsi_write;
-       }
-       scsi_max_devs=0;
-       for(i=0;i<CONFIG_SYS_SCSI_MAX_SCSI_ID;i++) {
-               pccb->target=i;
-               for(lun=0;lun<CONFIG_SYS_SCSI_MAX_LUN;lun++) {
-                       pccb->lun=lun;
-                       pccb->pdata=(unsigned char *)&tempbuff;
-                       pccb->datalen=512;
-                       scsi_setup_inquiry(pccb);
-                       if (scsi_exec(pccb) != true) {
-                               if(pccb->contr_stat==SCSI_SEL_TIME_OUT) {
-                                       debug ("Selection timeout ID %d\n",pccb->target);
-                                       continue; /* selection timeout => assuming no device present */
-                               }
-                               scsi_print_error(pccb);
-                               continue;
-                       }
-                       perq=tempbuff[0];
-                       modi=tempbuff[1];
-                       if((perq & 0x1f)==0x1f) {
-                               continue; /* skip unknown devices */
-                       }
-                       if((modi&0x80)==0x80) /* drive is removable */
-                               scsi_dev_desc[scsi_max_devs].removable=true;
-                       /* get info for this device */
-                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].vendor[0],
-                                      &tempbuff[8], 8);
-                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].product[0],
-                                      &tempbuff[16], 16);
-                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].revision[0],
-                                      &tempbuff[32], 4);
-                       scsi_dev_desc[scsi_max_devs].target=pccb->target;
-                       scsi_dev_desc[scsi_max_devs].lun=pccb->lun;
-
-                       pccb->datalen=0;
-                       scsi_setup_test_unit_ready(pccb);
-                       if (scsi_exec(pccb) != true) {
-                               if (scsi_dev_desc[scsi_max_devs].removable == true) {
-                                       scsi_dev_desc[scsi_max_devs].type=perq;
-                                       goto removable;
-                               }
-                               scsi_print_error(pccb);
-                               continue;
-                       }
-                       if (scsi_read_capacity(pccb, &capacity, &blksz)) {
-                               scsi_print_error(pccb);
-                               continue;
-                       }
-                       scsi_dev_desc[scsi_max_devs].lba=capacity;
-                       scsi_dev_desc[scsi_max_devs].blksz=blksz;
-                       scsi_dev_desc[scsi_max_devs].log2blksz =
-                               LOG2(scsi_dev_desc[scsi_max_devs].blksz);
-                       scsi_dev_desc[scsi_max_devs].type=perq;
-                       part_init(&scsi_dev_desc[scsi_max_devs]);
-removable:
-                       if(mode==1) {
-                               printf ("  Device %d: ", scsi_max_devs);
-                               dev_print(&scsi_dev_desc[scsi_max_devs]);
-                       } /* if mode */
-                       scsi_max_devs++;
-               } /* next LUN */
-       }
-       if(scsi_max_devs>0)
-               scsi_curr_dev=0;
-       else
-               scsi_curr_dev = -1;
-
-       printf("Found %d device(s).\n", scsi_max_devs);
-#ifndef CONFIG_SPL_BUILD
-       setenv_ulong("scsidevs", scsi_max_devs);
-#endif
-}
-
-int scsi_get_disk_count(void)
-{
-       return scsi_max_devs;
-}
-
-#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
-void scsi_init(void)
-{
-       int busdevfunc = -1;
-       int i;
-       /*
-        * Find a device from the list, this driver will support a single
-        * controller.
-        */
-       for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
-               /* get PCI Device ID */
-#ifdef CONFIG_DM_PCI
-               struct udevice *dev;
-               int ret;
-
-               ret = dm_pci_find_device(scsi_device_list[i].vendor,
-                                        scsi_device_list[i].device, 0, &dev);
-               if (!ret) {
-                       busdevfunc = dm_pci_get_bdf(dev);
-                       break;
-               }
-#else
-               busdevfunc = pci_find_device(scsi_device_list[i].vendor,
-                                            scsi_device_list[i].device,
-                                            0);
-#endif
-               if (busdevfunc != -1)
-                       break;
-       }
-
-       if (busdevfunc == -1) {
-               printf("Error: SCSI Controller(s) ");
-               for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
-                       printf("%04X:%04X ",
-                              scsi_device_list[i].vendor,
-                              scsi_device_list[i].device);
-               }
-               printf("not found\n");
-               return;
-       }
-#ifdef DEBUG
-       else {
-               printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",
-                      scsi_device_list[i].vendor,
-                      scsi_device_list[i].device,
-                      (busdevfunc >> 16) & 0xFF,
-                      (busdevfunc >> 11) & 0x1F,
-                      (busdevfunc >> 8) & 0x7);
-       }
-#endif
-       bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
-       scsi_low_level_init(busdevfunc);
-       scsi_scan(1);
-       bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
-}
-#endif
-
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *scsi_get_dev(int dev)
-{
-       return (dev < CONFIG_SYS_SCSI_MAX_DEVICE) ? &scsi_dev_desc[dev] : NULL;
-}
-#endif
-
-#ifndef CONFIG_SPL_BUILD
-/******************************************************************************
+/*
  * scsi boot command intepreter. Derived from diskboot
  */
-int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_scsiboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
        return common_diskboot(cmdtp, "scsi", argc, argv);
 }
 
-/*********************************************************************************
+/*
  * scsi command intepreter
  */
-int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
        switch (argc) {
        case 0:
        case 1:
                return CMD_RET_USAGE;
-
        case 2:
-                       if (strncmp(argv[1],"res",3) == 0) {
-                               printf("\nReset SCSI\n");
-                               scsi_bus_reset();
-                               scsi_scan(1);
-                               return 0;
-                       }
-                       if (strncmp(argv[1],"inf",3) == 0) {
-                               int i;
-                               for (i=0; i<CONFIG_SYS_SCSI_MAX_DEVICE; ++i) {
-                                       if(scsi_dev_desc[i].type==DEV_TYPE_UNKNOWN)
-                                               continue; /* list only known devices */
-                                       printf ("SCSI dev. %d:  ", i);
-                                       dev_print(&scsi_dev_desc[i]);
-                               }
-                               return 0;
-                       }
-                       if (strncmp(argv[1],"dev",3) == 0) {
-                               if ((scsi_curr_dev < 0) || (scsi_curr_dev >= CONFIG_SYS_SCSI_MAX_DEVICE)) {
-                                       printf("\nno SCSI devices available\n");
-                                       return 1;
-                               }
-                               printf ("\n    Device %d: ", scsi_curr_dev);
-                               dev_print(&scsi_dev_desc[scsi_curr_dev]);
-                               return 0;
-                       }
-                       if (strncmp(argv[1],"scan",4) == 0) {
-                               scsi_scan(1);
-                               return 0;
-                       }
-                       if (strncmp(argv[1],"part",4) == 0) {
-                               int dev, ok;
-                               for (ok=0, dev=0; dev<CONFIG_SYS_SCSI_MAX_DEVICE; ++dev) {
-                                       if (scsi_dev_desc[dev].type!=DEV_TYPE_UNKNOWN) {
-                                               ok++;
-                                               if (dev)
-                                                       printf("\n");
-                                               debug ("print_part of %x\n",dev);
-                                               part_print(&scsi_dev_desc[dev]);
-                                       }
-                               }
-                               if (!ok)
-                                       printf("\nno SCSI devices available\n");
-                               return 1;
+               if (strncmp(argv[1], "res", 3) == 0) {
+                       printf("\nReset SCSI\n");
+                       scsi_bus_reset();
+                       scsi_scan(1);
+                       return 0;
+               }
+               if (strncmp(argv[1], "inf", 3) == 0) {
+                       blk_list_devices(IF_TYPE_SCSI);
+                       return 0;
+               }
+               if (strncmp(argv[1], "dev", 3) == 0) {
+                       if (blk_print_device_num(IF_TYPE_SCSI, scsi_curr_dev)) {
+                               printf("\nno SCSI devices available\n");
+                               return CMD_RET_FAILURE;
                        }
-                       return CMD_RET_USAGE;
+
+                       return 0;
+               }
+               if (strncmp(argv[1], "scan", 4) == 0) {
+                       scsi_scan(1);
+                       return 0;
+               }
+               if (strncmp(argv[1], "part", 4) == 0) {
+                       if (blk_list_part(IF_TYPE_SCSI))
+                               printf("\nno SCSI devices available\n");
+                       return 0;
+               }
+               return CMD_RET_USAGE;
        case 3:
-                       if (strncmp(argv[1],"dev",3) == 0) {
-                               int dev = (int)simple_strtoul(argv[2], NULL, 10);
-                               printf ("\nSCSI device %d: ", dev);
-                               if (dev >= CONFIG_SYS_SCSI_MAX_DEVICE) {
-                                       printf("unknown device\n");
-                                       return 1;
-                               }
-                               printf ("\n    Device %d: ", dev);
-                               dev_print(&scsi_dev_desc[dev]);
-                               if(scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
-                                       return 1;
-                               }
+               if (strncmp(argv[1], "dev", 3) == 0) {
+                       int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+                       if (!blk_show_device(IF_TYPE_SCSI, dev)) {
                                scsi_curr_dev = dev;
                                printf("... is now current device\n");
-                               return 0;
+                       } else {
+                               return CMD_RET_FAILURE;
                        }
-                       if (strncmp(argv[1],"part",4) == 0) {
-                               int dev = (int)simple_strtoul(argv[2], NULL, 10);
-                               if(scsi_dev_desc[dev].type != DEV_TYPE_UNKNOWN) {
-                                       part_print(&scsi_dev_desc[dev]);
-                               }
-                               else {
-                                       printf ("\nSCSI device %d not available\n", dev);
-                               }
-                               return 1;
-                       }
-                       return CMD_RET_USAGE;
-    default:
-                       /* at least 4 args */
-                       if (strcmp(argv[1],"read") == 0) {
-                               ulong addr = simple_strtoul(argv[2], NULL, 16);
-                               ulong blk  = simple_strtoul(argv[3], NULL, 16);
-                               ulong cnt  = simple_strtoul(argv[4], NULL, 16);
-                               ulong n;
-                               printf ("\nSCSI read: device %d block # %ld, count %ld ... ",
-                                               scsi_curr_dev, blk, cnt);
-                               n = scsi_read(&scsi_dev_desc[scsi_curr_dev],
-                                             blk, cnt, (ulong *)addr);
-                               printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR");
-                               return 0;
-                       } else if (strcmp(argv[1], "write") == 0) {
-                               ulong addr = simple_strtoul(argv[2], NULL, 16);
-                               ulong blk = simple_strtoul(argv[3], NULL, 16);
-                               ulong cnt = simple_strtoul(argv[4], NULL, 16);
-                               ulong n;
-                               printf("\nSCSI write: device %d block # %ld, "
-                                      "count %ld ... ",
-                                      scsi_curr_dev, blk, cnt);
-                               n = scsi_write(&scsi_dev_desc[scsi_curr_dev],
-                                              blk, cnt, (ulong *)addr);
-                               printf("%ld blocks written: %s\n", n,
-                                      (n == cnt) ? "OK" : "ERROR");
-                               return 0;
+                       return 0;
+               }
+               if (strncmp(argv[1], "part", 4) == 0) {
+                       int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+                       if (blk_print_part_devnum(IF_TYPE_SCSI, dev)) {
+                               printf("\nSCSI device %d not available\n",
+                                      dev);
+                               return CMD_RET_FAILURE;
                        }
+                       return 0;
+               }
+               return CMD_RET_USAGE;
+       default:
+               /* at least 4 args */
+               if (strcmp(argv[1], "read") == 0) {
+                       ulong addr = simple_strtoul(argv[2], NULL, 16);
+                       ulong blk  = simple_strtoul(argv[3], NULL, 16);
+                       ulong cnt  = simple_strtoul(argv[4], NULL, 16);
+                       ulong n;
+
+                       printf("\nSCSI read: device %d block # %ld, count %ld ... ",
+                              scsi_curr_dev, blk, cnt);
+                       n = blk_read_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk,
+                                           cnt, (ulong *)addr);
+                       printf("%ld blocks read: %s\n", n,
+                              n == cnt ? "OK" : "ERROR");
+                       return 0;
+               } else if (strcmp(argv[1], "write") == 0) {
+                       ulong addr = simple_strtoul(argv[2], NULL, 16);
+                       ulong blk = simple_strtoul(argv[3], NULL, 16);
+                       ulong cnt = simple_strtoul(argv[4], NULL, 16);
+                       ulong n;
+
+                       printf("\nSCSI write: device %d block # %ld, count %ld ... ",
+                              scsi_curr_dev, blk, cnt);
+                       n = blk_write_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk,
+                                            cnt, (ulong *)addr);
+                       printf("%ld blocks written: %s\n", n,
+                              n == cnt ? "OK" : "ERROR");
+                       return 0;
+               }
        } /* switch */
        return CMD_RET_USAGE;
 }
@@ -388,347 +135,3 @@ U_BOOT_CMD(
        "boot from SCSI device",
        "loadAddr dev:part"
 );
-#endif
-
-/****************************************************************************************
- * scsi_read
- */
-
-/* almost the maximum amount of the scsi_ext command.. */
-#define SCSI_MAX_READ_BLK 0xFFFF
-#define SCSI_LBA48_READ        0xFFFFFFF
-
-static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
-                      lbaint_t blkcnt, void *buffer)
-{
-       int device = block_dev->devnum;
-       lbaint_t start, blks;
-       uintptr_t buf_addr;
-       unsigned short smallblks = 0;
-       ccb* pccb=(ccb *)&tempccb;
-       device&=0xff;
-       /* Setup  device
-        */
-       pccb->target=scsi_dev_desc[device].target;
-       pccb->lun=scsi_dev_desc[device].lun;
-       buf_addr=(unsigned long)buffer;
-       start=blknr;
-       blks=blkcnt;
-       debug("\nscsi_read: dev %d startblk " LBAF
-             ", blccnt " LBAF " buffer %lx\n",
-             device, start, blks, (unsigned long)buffer);
-       do {
-               pccb->pdata=(unsigned char *)buf_addr;
-#ifdef CONFIG_SYS_64BIT_LBA
-               if (start > SCSI_LBA48_READ) {
-                       unsigned long blocks;
-                       blocks = min_t(lbaint_t, blks, SCSI_MAX_READ_BLK);
-                       pccb->datalen = scsi_dev_desc[device].blksz * blocks;
-                       scsi_setup_read16(pccb, start, blocks);
-                       start += blocks;
-                       blks -= blocks;
-               } else
-#endif
-               if (blks > SCSI_MAX_READ_BLK) {
-                       pccb->datalen=scsi_dev_desc[device].blksz * SCSI_MAX_READ_BLK;
-                       smallblks=SCSI_MAX_READ_BLK;
-                       scsi_setup_read_ext(pccb,start,smallblks);
-                       start+=SCSI_MAX_READ_BLK;
-                       blks-=SCSI_MAX_READ_BLK;
-               }
-               else {
-                       pccb->datalen=scsi_dev_desc[device].blksz * blks;
-                       smallblks=(unsigned short) blks;
-                       scsi_setup_read_ext(pccb,start,smallblks);
-                       start+=blks;
-                       blks=0;
-               }
-               debug("scsi_read_ext: startblk " LBAF
-                     ", blccnt %x buffer %" PRIXPTR "\n",
-                     start, smallblks, buf_addr);
-               if (scsi_exec(pccb) != true) {
-                       scsi_print_error(pccb);
-                       blkcnt-=blks;
-                       break;
-               }
-               buf_addr+=pccb->datalen;
-       } while(blks!=0);
-       debug("scsi_read_ext: end startblk " LBAF
-             ", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr);
-       return(blkcnt);
-}
-
-/*******************************************************************************
- * scsi_write
- */
-
-/* Almost the maximum amount of the scsi_ext command.. */
-#define SCSI_MAX_WRITE_BLK 0xFFFF
-
-static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
-                       lbaint_t blkcnt, const void *buffer)
-{
-       int device = block_dev->devnum;
-       lbaint_t start, blks;
-       uintptr_t buf_addr;
-       unsigned short smallblks;
-       ccb* pccb = (ccb *)&tempccb;
-       device &= 0xff;
-       /* Setup  device
-        */
-       pccb->target = scsi_dev_desc[device].target;
-       pccb->lun = scsi_dev_desc[device].lun;
-       buf_addr = (unsigned long)buffer;
-       start = blknr;
-       blks = blkcnt;
-       debug("\n%s: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
-             __func__, device, start, blks, (unsigned long)buffer);
-       do {
-               pccb->pdata = (unsigned char *)buf_addr;
-               if (blks > SCSI_MAX_WRITE_BLK) {
-                       pccb->datalen = (scsi_dev_desc[device].blksz *
-                                        SCSI_MAX_WRITE_BLK);
-                       smallblks = SCSI_MAX_WRITE_BLK;
-                       scsi_setup_write_ext(pccb, start, smallblks);
-                       start += SCSI_MAX_WRITE_BLK;
-                       blks -= SCSI_MAX_WRITE_BLK;
-               } else {
-                       pccb->datalen = scsi_dev_desc[device].blksz * blks;
-                       smallblks = (unsigned short)blks;
-                       scsi_setup_write_ext(pccb, start, smallblks);
-                       start += blks;
-                       blks = 0;
-               }
-               debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
-                     __func__, start, smallblks, buf_addr);
-               if (scsi_exec(pccb) != true) {
-                       scsi_print_error(pccb);
-                       blkcnt -= blks;
-                       break;
-               }
-               buf_addr += pccb->datalen;
-       } while (blks != 0);
-       debug("%s: end startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
-             __func__, start, smallblks, buf_addr);
-       return blkcnt;
-}
-
-/* copy src to dest, skipping leading and trailing blanks
- * and null terminate the string
- */
-void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
-{
-       int start,end;
-
-       start=0;
-       while(start<len) {
-               if(src[start]!=' ')
-                       break;
-               start++;
-       }
-       end=len-1;
-       while(end>start) {
-               if(src[end]!=' ')
-                       break;
-               end--;
-       }
-       for( ; start<=end; start++) {
-               *dest++=src[start];
-       }
-       *dest='\0';
-}
-
-
-/* Trim trailing blanks, and NUL-terminate string
- */
-void scsi_trim_trail (unsigned char *str, unsigned int len)
-{
-       unsigned char *p = str + len - 1;
-
-       while (len-- > 0) {
-               *p-- = '\0';
-               if (*p != ' ') {
-                       return;
-               }
-       }
-}
-
-int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
-{
-       *capacity = 0;
-
-       memset(pccb->cmd, 0, sizeof(pccb->cmd));
-       pccb->cmd[0] = SCSI_RD_CAPAC10;
-       pccb->cmd[1] = pccb->lun << 5;
-       pccb->cmdlen = 10;
-       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
-
-       pccb->datalen = 8;
-       if (scsi_exec(pccb) != true)
-               return 1;
-
-       *capacity = ((lbaint_t)pccb->pdata[0] << 24) |
-                   ((lbaint_t)pccb->pdata[1] << 16) |
-                   ((lbaint_t)pccb->pdata[2] << 8)  |
-                   ((lbaint_t)pccb->pdata[3]);
-
-       if (*capacity != 0xffffffff) {
-               /* Read capacity (10) was sufficient for this drive. */
-               *blksz = ((unsigned long)pccb->pdata[4] << 24) |
-                        ((unsigned long)pccb->pdata[5] << 16) |
-                        ((unsigned long)pccb->pdata[6] << 8)  |
-                        ((unsigned long)pccb->pdata[7]);
-               return 0;
-       }
-
-       /* Read capacity (10) was insufficient. Use read capacity (16). */
-
-       memset(pccb->cmd, 0, sizeof(pccb->cmd));
-       pccb->cmd[0] = SCSI_RD_CAPAC16;
-       pccb->cmd[1] = 0x10;
-       pccb->cmdlen = 16;
-       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
-
-       pccb->datalen = 16;
-       if (scsi_exec(pccb) != true)
-               return 1;
-
-       *capacity = ((uint64_t)pccb->pdata[0] << 56) |
-                   ((uint64_t)pccb->pdata[1] << 48) |
-                   ((uint64_t)pccb->pdata[2] << 40) |
-                   ((uint64_t)pccb->pdata[3] << 32) |
-                   ((uint64_t)pccb->pdata[4] << 24) |
-                   ((uint64_t)pccb->pdata[5] << 16) |
-                   ((uint64_t)pccb->pdata[6] << 8)  |
-                   ((uint64_t)pccb->pdata[7]);
-
-       *blksz = ((uint64_t)pccb->pdata[8]  << 56) |
-                ((uint64_t)pccb->pdata[9]  << 48) |
-                ((uint64_t)pccb->pdata[10] << 40) |
-                ((uint64_t)pccb->pdata[11] << 32) |
-                ((uint64_t)pccb->pdata[12] << 24) |
-                ((uint64_t)pccb->pdata[13] << 16) |
-                ((uint64_t)pccb->pdata[14] << 8)  |
-                ((uint64_t)pccb->pdata[15]);
-
-       return 0;
-}
-
-
-/************************************************************************************
- * Some setup (fill-in) routines
- */
-void scsi_setup_test_unit_ready(ccb * pccb)
-{
-       pccb->cmd[0]=SCSI_TST_U_RDY;
-       pccb->cmd[1]=pccb->lun<<5;
-       pccb->cmd[2]=0;
-       pccb->cmd[3]=0;
-       pccb->cmd[4]=0;
-       pccb->cmd[5]=0;
-       pccb->cmdlen=6;
-       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
-}
-
-#ifdef CONFIG_SYS_64BIT_LBA
-void scsi_setup_read16(ccb * pccb, lbaint_t start, unsigned long blocks)
-{
-       pccb->cmd[0] = SCSI_READ16;
-       pccb->cmd[1] = pccb->lun<<5;
-       pccb->cmd[2] = ((unsigned char) (start >> 56)) & 0xff;
-       pccb->cmd[3] = ((unsigned char) (start >> 48)) & 0xff;
-       pccb->cmd[4] = ((unsigned char) (start >> 40)) & 0xff;
-       pccb->cmd[5] = ((unsigned char) (start >> 32)) & 0xff;
-       pccb->cmd[6] = ((unsigned char) (start >> 24)) & 0xff;
-       pccb->cmd[7] = ((unsigned char) (start >> 16)) & 0xff;
-       pccb->cmd[8] = ((unsigned char) (start >> 8)) & 0xff;
-       pccb->cmd[9] = ((unsigned char) (start)) & 0xff;
-       pccb->cmd[10] = 0;
-       pccb->cmd[11] = ((unsigned char) (blocks >> 24)) & 0xff;
-       pccb->cmd[12] = ((unsigned char) (blocks >> 16)) & 0xff;
-       pccb->cmd[13] = ((unsigned char) (blocks >> 8)) & 0xff;
-       pccb->cmd[14] = (unsigned char) blocks & 0xff;
-       pccb->cmd[15] = 0;
-       pccb->cmdlen = 16;
-       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
-       debug ("scsi_setup_read16: cmd: %02X %02X "
-              "startblk %02X%02X%02X%02X%02X%02X%02X%02X "
-              "blccnt %02X%02X%02X%02X\n",
-               pccb->cmd[0], pccb->cmd[1],
-               pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
-               pccb->cmd[6], pccb->cmd[7], pccb->cmd[8], pccb->cmd[9],
-               pccb->cmd[11], pccb->cmd[12], pccb->cmd[13], pccb->cmd[14]);
-}
-#endif
-
-void scsi_setup_read_ext(ccb * pccb, lbaint_t start, unsigned short blocks)
-{
-       pccb->cmd[0]=SCSI_READ10;
-       pccb->cmd[1]=pccb->lun<<5;
-       pccb->cmd[2]=((unsigned char) (start>>24))&0xff;
-       pccb->cmd[3]=((unsigned char) (start>>16))&0xff;
-       pccb->cmd[4]=((unsigned char) (start>>8))&0xff;
-       pccb->cmd[5]=((unsigned char) (start))&0xff;
-       pccb->cmd[6]=0;
-       pccb->cmd[7]=((unsigned char) (blocks>>8))&0xff;
-       pccb->cmd[8]=(unsigned char) blocks & 0xff;
-       pccb->cmd[6]=0;
-       pccb->cmdlen=10;
-       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
-       debug ("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
-               pccb->cmd[0],pccb->cmd[1],
-               pccb->cmd[2],pccb->cmd[3],pccb->cmd[4],pccb->cmd[5],
-               pccb->cmd[7],pccb->cmd[8]);
-}
-
-void scsi_setup_write_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
-{
-       pccb->cmd[0] = SCSI_WRITE10;
-       pccb->cmd[1] = pccb->lun << 5;
-       pccb->cmd[2] = ((unsigned char) (start>>24)) & 0xff;
-       pccb->cmd[3] = ((unsigned char) (start>>16)) & 0xff;
-       pccb->cmd[4] = ((unsigned char) (start>>8)) & 0xff;
-       pccb->cmd[5] = ((unsigned char) (start)) & 0xff;
-       pccb->cmd[6] = 0;
-       pccb->cmd[7] = ((unsigned char) (blocks>>8)) & 0xff;
-       pccb->cmd[8] = (unsigned char)blocks & 0xff;
-       pccb->cmd[9] = 0;
-       pccb->cmdlen = 10;
-       pccb->msgout[0] = SCSI_IDENTIFY;  /* NOT USED */
-       debug("%s: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
-             __func__,
-             pccb->cmd[0], pccb->cmd[1],
-             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
-             pccb->cmd[7], pccb->cmd[8]);
-}
-
-void scsi_setup_read6(ccb * pccb, lbaint_t start, unsigned short blocks)
-{
-       pccb->cmd[0]=SCSI_READ6;
-       pccb->cmd[1]=pccb->lun<<5 | (((unsigned char)(start>>16))&0x1f);
-       pccb->cmd[2]=((unsigned char) (start>>8))&0xff;
-       pccb->cmd[3]=((unsigned char) (start))&0xff;
-       pccb->cmd[4]=(unsigned char) blocks & 0xff;
-       pccb->cmd[5]=0;
-       pccb->cmdlen=6;
-       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
-       debug ("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
-               pccb->cmd[0],pccb->cmd[1],
-               pccb->cmd[2],pccb->cmd[3],pccb->cmd[4]);
-}
-
-
-void scsi_setup_inquiry(ccb * pccb)
-{
-       pccb->cmd[0]=SCSI_INQUIRY;
-       pccb->cmd[1]=pccb->lun<<5;
-       pccb->cmd[2]=0;
-       pccb->cmd[3]=0;
-       if(pccb->datalen>255)
-               pccb->cmd[4]=255;
-       else
-               pccb->cmd[4]=(unsigned char)pccb->datalen;
-       pccb->cmd[5]=0;
-       pccb->cmdlen=6;
-       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
-}
index f1a7debdf3d918f0ca5c23dc94efbc0e956b647d..b83d3233b789fffb49599ce2c9cf63abcc21112e 100644 (file)
--- a/cmd/usb.c
+++ b/cmd/usb.c
@@ -723,7 +723,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                int devno, ok = 0;
                if (argc == 2) {
                        for (devno = 0; ; ++devno) {
-                               stor_dev = usb_stor_get_dev(devno);
+                               stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
+                                                                 devno);
                                if (stor_dev == NULL)
                                        break;
                                if (stor_dev->type != DEV_TYPE_UNKNOWN) {
@@ -736,7 +737,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        }
                } else {
                        devno = simple_strtoul(argv[2], NULL, 16);
-                       stor_dev = usb_stor_get_dev(devno);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno);
                        if (stor_dev != NULL &&
                            stor_dev->type != DEV_TYPE_UNKNOWN) {
                                ok++;
@@ -762,7 +763,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        unsigned long n;
                        printf("\nUSB read: device %d block # %ld, count %ld"
                                " ... ", usb_stor_curr_dev, blk, cnt);
-                       stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
+                                                         usb_stor_curr_dev);
                        n = blk_dread(stor_dev, blk, cnt, (ulong *)addr);
                        printf("%ld blocks read: %s\n", n,
                                (n == cnt) ? "OK" : "ERROR");
@@ -783,7 +785,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        unsigned long n;
                        printf("\nUSB write: device %d block # %ld, count %ld"
                                " ... ", usb_stor_curr_dev, blk, cnt);
-                       stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
+                                                         usb_stor_curr_dev);
                        n = blk_dwrite(stor_dev, blk, cnt, (ulong *)addr);
                        printf("%ld blocks write: %s\n", n,
                                (n == cnt) ? "OK" : "ERROR");
@@ -796,7 +799,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                if (argc == 3) {
                        int dev = (int)simple_strtoul(argv[2], NULL, 10);
                        printf("\nUSB device %d: ", dev);
-                       stor_dev = usb_stor_get_dev(dev);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, dev);
                        if (stor_dev == NULL) {
                                printf("unknown device\n");
                                return 1;
@@ -810,7 +813,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        return 0;
                } else {
                        printf("\nUSB device %d: ", usb_stor_curr_dev);
-                       stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
+                                                         usb_stor_curr_dev);
                        dev_print(stor_dev);
                        if (stor_dev->type == DEV_TYPE_UNKNOWN)
                                return 1;
index b23f31200636e7b9bdbe6b54be0fb145cfaea635..0562d5cea46a5d50b1364451fd8b7701348551bb 100644 (file)
@@ -84,6 +84,8 @@ obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o
 obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o
 obj-$(CONFIG_LYNXKDI) += lynxkdi.o
 obj-$(CONFIG_MENU) += menu.o
+obj-$(CONFIG_CMD_SATA) += sata.o
+obj-$(CONFIG_SCSI) += scsi.o
 obj-$(CONFIG_UPDATE_TFTP) += update.o
 obj-$(CONFIG_DFU_TFTP) += update.o
 obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
@@ -112,6 +114,9 @@ obj-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
 obj-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
 obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 endif
+ifdef CONFIG_SPL_SATA_SUPPORT
+obj-$(CONFIG_SCSI) += scsi.o
+endif
 endif
 #environment
 obj-y += env_common.o
@@ -130,6 +135,7 @@ obj-y += dlmalloc.o
 ifdef CONFIG_SYS_MALLOC_F_LEN
 obj-y += malloc_simple.o
 endif
+obj-$(CONFIG_CMD_IDE) += ide.o
 obj-y += image.o
 obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
 obj-$(CONFIG_$(SPL_)OF_LIBFDT) += image-fdt.o
@@ -150,6 +156,9 @@ obj-y += fb_nand.o
 endif
 endif
 
+ifdef CONFIG_CMD_EEPROM_LAYOUT
+obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
+endif
 # We always have this since drivers/ddr/fs/interactive.c needs it
 obj-$(CONFIG_CMDLINE) += cli_simple.o
 
index ad02549311ea84f64c377601de81aa6d3cd636e1..d959ad3c6f90ea2c2a422b6878c11a5437764a2c 100644 (file)
@@ -620,7 +620,7 @@ static int initr_ambapp_print(void)
 }
 #endif
 
-#if defined(CONFIG_CMD_SCSI)
+#if defined(CONFIG_SCSI)
 static int initr_scsi(void)
 {
        puts("SCSI:  ");
@@ -923,7 +923,7 @@ init_fnc_t init_sequence_r[] = {
        initr_ambapp_print,
 #endif
 #endif
-#ifdef CONFIG_CMD_SCSI
+#ifdef CONFIG_SCSI
        INIT_FUNC_WATCHDOG_RESET
        initr_scsi,
 #endif
index b09f5249a902c7991986517dc91f0cfd447789f9..adc680e95938b7bb6b213f7c691e7de3cad69d1e 100644 (file)
@@ -1909,6 +1909,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
   * fulfill the user's request.
   */
   if (m == NULL) {
+    size_t extra, extra2;
     /*
      * Use bytes not nb, since mALLOc internally calls request2size too, and
      * each call increases the size to allocate, to account for the header.
@@ -1917,9 +1918,27 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
     /* Aligned -> return it */
     if ((((unsigned long)(m)) % alignment) == 0)
       return m;
-    /* Otherwise, fail */
+    /*
+     * Otherwise, try again, requesting enough extra space to be able to
+     * acquire alignment.
+     */
     fREe(m);
-    m = NULL;
+    /* Add in extra bytes to match misalignment of unexpanded allocation */
+    extra = alignment - (((unsigned long)(m)) % alignment);
+    m  = (char*)(mALLOc(bytes + extra));
+    /*
+     * m might not be the same as before. Validate that the previous value of
+     * extra still works for the current value of m.
+     * If (!m), extra2=alignment so 
+     */
+    if (m) {
+      extra2 = alignment - (((unsigned long)(m)) % alignment);
+      if (extra2 > extra) {
+        fREe(m);
+        m = NULL;
+      }
+    }
+    /* Fall through to original NULL check and chunk splitting logic */
   }
 
   if (m == NULL) return NULL; /* propagate failure */
diff --git a/common/eeprom/eeprom_field.c b/common/eeprom/eeprom_field.c
new file mode 100644 (file)
index 0000000..7f095a6
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * (C) Copyright 2009-2016 CompuLab, Ltd.
+ *
+ * Authors: Nikita Kiryanov <nikita@compulab.co.il>
+ *         Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/string.h>
+#include <eeprom_field.h>
+
+static void __eeprom_field_print_bin(const struct eeprom_field *field,
+                                    char *delimiter, bool reverse)
+{
+       int i;
+       int from = reverse ? field->size - 1 : 0;
+       int to = reverse ? 0 : field->size - 1;
+
+       printf(PRINT_FIELD_SEGMENT, field->name);
+       for (i = from; i != to; reverse ? i-- : i++)
+               printf("%02x%s", field->buf[i], delimiter);
+
+       printf("%02x\n", field->buf[i]);
+}
+
+static int __eeprom_field_update_bin(struct eeprom_field *field,
+                                    const char *value, bool reverse)
+{
+       int len = strlen(value);
+       int k, j, i = reverse ? len - 1 : 0;
+       unsigned char byte;
+       char *endptr;
+
+       /* each two characters in the string fit in one byte */
+       if (len > field->size * 2)
+               return -1;
+
+       memset(field->buf, 0, field->size);
+
+       /* i - string iterator, j - buf iterator */
+       for (j = 0; j < field->size; j++) {
+               byte = 0;
+               char tmp[3] = { 0, 0, 0 };
+
+               if ((reverse && i < 0) || (!reverse && i >= len))
+                       break;
+
+               for (k = 0; k < 2; k++) {
+                       if (reverse && i == 0) {
+                               tmp[k] = value[i];
+                               break;
+                       }
+
+                       tmp[k] = value[reverse ? i - 1 + k : i + k];
+               }
+
+               byte = simple_strtoul(tmp, &endptr, 0);
+               if (*endptr != '\0' || byte < 0)
+                       return -1;
+
+               field->buf[j] = byte;
+               i = reverse ? i - 2 : i + 2;
+       }
+
+       return 0;
+}
+
+static int __eeprom_field_update_bin_delim(struct eeprom_field *field,
+                                          char *value, char *delimiter)
+{
+       int count = 0;
+       int i, val;
+       const char *tmp = value;
+       char *tok;
+       char *endptr;
+
+       tmp = strstr(tmp, delimiter);
+       while (tmp != NULL) {
+               count++;
+               tmp++;
+               tmp = strstr(tmp, delimiter);
+       }
+
+       if (count > field->size)
+               return -1;
+
+       tok = strtok(value, delimiter);
+       for (i = 0; tok && i < field->size; i++) {
+               val = simple_strtoul(tok, &endptr, 0);
+               if (*endptr != '\0')
+                       return -1;
+
+               /* here we assume that each tok is no more than byte long */
+               field->buf[i] = (unsigned char)val;
+               tok = strtok(NULL, delimiter);
+       }
+
+       return 0;
+}
+
+/**
+ * eeprom_field_print_bin() - print a field which contains binary data
+ *
+ * Treat the field data as simple binary data, and print it as two digit
+ * hexadecimal values.
+ * Sample output:
+ *      Field Name       0102030405060708090a
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_bin(const struct eeprom_field *field)
+{
+       __eeprom_field_print_bin(field, "", false);
+}
+
+/**
+ * eeprom_field_update_bin() - Update field with new data in binary form
+ *
+ * @field:     an initialized field
+ * @value:     a string of values (i.e. "10b234a")
+ */
+int eeprom_field_update_bin(struct eeprom_field *field, char *value)
+{
+       return __eeprom_field_update_bin(field, value, false);
+}
+
+/**
+ * eeprom_field_update_reserved() - Update reserved field with new data in
+ *                                 binary form
+ *
+ * @field:     an initialized field
+ * @value:     a space delimited string of byte values (i.e. "1 02 3 0x4")
+ */
+int eeprom_field_update_reserved(struct eeprom_field *field, char *value)
+{
+       return __eeprom_field_update_bin_delim(field, value, " ");
+}
+
+/**
+ * eeprom_field_print_bin_rev() - print a field which contains binary data in
+ *                               reverse order
+ *
+ * Treat the field data as simple binary data, and print it in reverse order
+ * as two digit hexadecimal values.
+ *
+ * Data in field:
+ *                      0102030405060708090a
+ * Sample output:
+ *      Field Name      0a090807060504030201
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_bin_rev(const struct eeprom_field *field)
+{
+       __eeprom_field_print_bin(field, "", true);
+}
+
+/**
+ * eeprom_field_update_bin_rev() - Update field with new data in binary form,
+ *                                storing it in reverse
+ *
+ * This function takes a string of byte values, and stores them
+ * in the field in the reverse order. i.e. if the input string was "1234",
+ * "3412" will be written to the field.
+ *
+ * @field:     an initialized field
+ * @value:     a string of byte values
+ */
+int eeprom_field_update_bin_rev(struct eeprom_field *field, char *value)
+{
+       return __eeprom_field_update_bin(field, value, true);
+}
+
+/**
+ * eeprom_field_print_mac_addr() - print a field which contains a mac address
+ *
+ * Treat the field data as simple binary data, and print it formatted as a MAC
+ * address.
+ * Sample output:
+ *      Field Name     01:02:03:04:05:06
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_mac(const struct eeprom_field *field)
+{
+       __eeprom_field_print_bin(field, ":", false);
+}
+
+/**
+ * eeprom_field_update_mac() - Update a mac address field which contains binary
+ *                            data
+ *
+ * @field:     an initialized field
+ * @value:     a colon delimited string of byte values (i.e. "1:02:3:ff")
+ */
+int eeprom_field_update_mac(struct eeprom_field *field, char *value)
+{
+       return __eeprom_field_update_bin_delim(field, value, ":");
+}
+
+/**
+ * eeprom_field_print_ascii() - print a field which contains ASCII data
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_ascii(const struct eeprom_field *field)
+{
+       char format[8];
+
+       sprintf(format, "%%.%ds\n", field->size);
+       printf(PRINT_FIELD_SEGMENT, field->name);
+       printf(format, field->buf);
+}
+
+/**
+ * eeprom_field_update_ascii() - Update field with new data in ASCII form
+ * @field:     an initialized field
+ * @value:     the new string data
+ *
+ * Returns 0 on success, -1 of failure (new string too long).
+ */
+int eeprom_field_update_ascii(struct eeprom_field *field, char *value)
+{
+       if (strlen(value) >= field->size) {
+               printf("%s: new data too long\n", field->name);
+               return -1;
+       }
+
+       strncpy((char *)field->buf, value, field->size - 1);
+       field->buf[field->size - 1] = '\0';
+
+       return 0;
+}
+
+/**
+ * eeprom_field_print_reserved() - print the "Reserved fields" field
+ *
+ * Print a notice that the following field_size bytes are reserved.
+ *
+ * Sample output:
+ *      Reserved fields              (64 bytes)
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_reserved(const struct eeprom_field *field)
+{
+       printf(PRINT_FIELD_SEGMENT, "Reserved fields\t");
+       printf("(%d bytes)\n", field->size);
+}
diff --git a/common/eeprom/eeprom_layout.c b/common/eeprom/eeprom_layout.c
new file mode 100644 (file)
index 0000000..c059233
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * (C) Copyright 2009-2016 CompuLab, Ltd.
+ *
+ * Authors: Nikita Kiryanov <nikita@compulab.co.il>
+ *         Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/kernel.h>
+#include <eeprom_layout.h>
+#include <eeprom_field.h>
+
+#define NO_LAYOUT_FIELDS       "Unknown layout. Dumping raw data\n"
+
+struct eeprom_field layout_unknown[1] = {
+       { NO_LAYOUT_FIELDS, 256, NULL, eeprom_field_print_bin,
+                                      eeprom_field_update_bin },
+};
+
+/*
+ * eeprom_layout_detect() - detect layout based on the contents of the data.
+ * @data: Pointer to the data to be analyzed.
+ *
+ * Returns: the detected layout version.
+ */
+__weak int eeprom_layout_detect(unsigned char *data)
+{
+       return LAYOUT_VERSION_UNRECOGNIZED;
+}
+
+/*
+ * __eeprom_layout_assign() - set the layout fields
+ * @layout:            A pointer to an existing struct layout.
+ * @layout_version:    The version number of the desired layout
+ */
+__weak void __eeprom_layout_assign(struct eeprom_layout *layout,
+                                  int layout_version)
+{
+       layout->fields = layout_unknown;
+       layout->num_of_fields = ARRAY_SIZE(layout_unknown);
+}
+void eeprom_layout_assign(struct eeprom_layout *layout, int layout_version) \
+               __attribute__((weak, alias("__eeprom_layout_assign")));
+
+/*
+ * eeprom_layout_print() - print the layout and the data which is assigned to it
+ * @layout: A pointer to an existing struct layout.
+ */
+static void eeprom_layout_print(const struct eeprom_layout *layout)
+{
+       int i;
+       struct eeprom_field *fields = layout->fields;
+
+       for (i = 0; i < layout->num_of_fields; i++)
+               fields[i].print(&fields[i]);
+}
+
+/*
+ * eeprom_layout_update_field() - update a single field in the layout data.
+ * @layout:    A pointer to an existing struct layout.
+ * @field_name:        The name of the field to update.
+ * @new_data:  The new field data (a string. Format depends on the field)
+ *
+ * Returns: 0 on success, negative error value on failure.
+ */
+static int eeprom_layout_update_field(struct eeprom_layout *layout,
+                                     char *field_name, char *new_data)
+{
+       int i, err;
+       struct eeprom_field *fields = layout->fields;
+
+       if (new_data == NULL)
+               return 0;
+
+       if (field_name == NULL)
+               return -1;
+
+       for (i = 0; i < layout->num_of_fields; i++) {
+               if (fields[i].name == RESERVED_FIELDS ||
+                   strcmp(fields[i].name, field_name))
+                       continue;
+
+               err = fields[i].update(&fields[i], new_data);
+               if (err)
+                       printf("Invalid data for field %s\n", field_name);
+
+               return err;
+       }
+
+       printf("No such field '%s'\n", field_name);
+
+       return -1;
+}
+
+/*
+ * eeprom_layout_setup() - setup layout struct with the layout data and
+ *                        metadata as dictated by layout_version
+ * @layout:    A pointer to an existing struct layout.
+ * @buf:       A buffer initialized with the eeprom data.
+ * @buf_size:  Size of buf in bytes.
+ * @layout version: The version number of the layout.
+ */
+void eeprom_layout_setup(struct eeprom_layout *layout, unsigned char *buf,
+                        unsigned int buf_size, int layout_version)
+{
+       int i;
+
+       if (layout_version == LAYOUT_VERSION_AUTODETECT)
+               layout->layout_version = eeprom_layout_detect(buf);
+       else
+               layout->layout_version = layout_version;
+
+       eeprom_layout_assign(layout, layout_version);
+       layout->data = buf;
+       for (i = 0; i < layout->num_of_fields; i++) {
+               layout->fields[i].buf = buf;
+               buf += layout->fields[i].size;
+       }
+
+       layout->data_size = buf_size;
+       layout->print = eeprom_layout_print;
+       layout->update = eeprom_layout_update_field;
+}
index bdb452e58c598731c9edc8e93d5e37f19e280919..c7fef188cd21b9a6b816ab7b8c997de788b2d822 100644 (file)
@@ -86,8 +86,8 @@ static int mmc_set_env_part(struct mmc *mmc)
        dev = 0;
 #endif
 
-       env_mmc_orig_hwpart = mmc->block_dev.hwpart;
-       ret = mmc_select_hwpart(dev, part);
+       env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
+       ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
        if (ret)
                puts("MMC partition switch failed\n");
 
@@ -119,7 +119,7 @@ static void fini_mmc_for_env(struct mmc *mmc)
 #ifdef CONFIG_SPL_BUILD
        dev = 0;
 #endif
-       mmc_select_hwpart(dev, env_mmc_orig_hwpart);
+       blk_select_hwpart_devnum(IF_TYPE_MMC, dev, env_mmc_orig_hwpart);
 #endif
 }
 
diff --git a/common/ide.c b/common/ide.c
new file mode 100644 (file)
index 0000000..ac5b91c
--- /dev/null
@@ -0,0 +1,1231 @@
+/*
+ * (C) Copyright 2000-2011
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <ata.h>
+#include <dm.h>
+#include <ide.h>
+#include <watchdog.h>
+#include <asm/io.h>
+
+#ifdef __PPC__
+# define EIEIO         __asm__ volatile ("eieio")
+# define SYNC          __asm__ volatile ("sync")
+#else
+# define EIEIO         /* nothing */
+# define SYNC          /* nothing */
+#endif
+
+/* Current offset for IDE0 / IDE1 bus access   */
+ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = {
+#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
+       CONFIG_SYS_ATA_IDE0_OFFSET,
+#endif
+#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) && (CONFIG_SYS_IDE_MAXBUS > 1)
+       CONFIG_SYS_ATA_IDE1_OFFSET,
+#endif
+};
+
+static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS];
+
+struct blk_desc ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
+
+#define IDE_TIME_OUT   2000    /* 2 sec timeout */
+
+#define ATAPI_TIME_OUT 7000    /* 7 sec timeout (5 sec seems to work...) */
+
+#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */
+
+#ifndef CONFIG_SYS_ATA_PORT_ADDR
+#define CONFIG_SYS_ATA_PORT_ADDR(port) (port)
+#endif
+
+#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */
+# define DEVICE_LED(x) 0
+# define LED_IDE1 1
+# define LED_IDE2 2
+#endif
+
+#ifdef CONFIG_IDE_RESET
+extern void ide_set_reset(int idereset);
+
+static void ide_reset(void)
+{
+       int i;
+
+       for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; ++i)
+               ide_bus_ok[i] = 0;
+       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i)
+               ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
+
+       ide_set_reset(1);       /* assert reset */
+
+       /* the reset signal shall be asserted for et least 25 us */
+       udelay(25);
+
+       WATCHDOG_RESET();
+
+       /* de-assert RESET signal */
+       ide_set_reset(0);
+
+       /* wait 250 ms */
+       for (i = 0; i < 250; ++i)
+               udelay(1000);
+}
+#else
+#define ide_reset()    /* dummy */
+#endif /* CONFIG_IDE_RESET */
+
+/*
+ * Wait until Busy bit is off, or timeout (in ms)
+ * Return last status
+ */
+static uchar ide_wait(int dev, ulong t)
+{
+       ulong delay = 10 * t;   /* poll every 100 us */
+       uchar c;
+
+       while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) {
+               udelay(100);
+               if (delay-- == 0)
+                       break;
+       }
+       return c;
+}
+
+/*
+ * copy src to dest, skipping leading and trailing blanks and null
+ * terminate the string
+ * "len" is the size of available memory including the terminating '\0'
+ */
+static void ident_cpy(unsigned char *dst, unsigned char *src,
+                     unsigned int len)
+{
+       unsigned char *end, *last;
+
+       last = dst;
+       end = src + len - 1;
+
+       /* reserve space for '\0' */
+       if (len < 2)
+               goto OUT;
+
+       /* skip leading white space */
+       while ((*src) && (src < end) && (*src == ' '))
+               ++src;
+
+       /* copy string, omitting trailing white space */
+       while ((*src) && (src < end)) {
+               *dst++ = *src;
+               if (*src++ != ' ')
+                       last = dst;
+       }
+OUT:
+       *last = '\0';
+}
+
+#ifdef CONFIG_ATAPI
+/****************************************************************************
+ * ATAPI Support
+ */
+
+#if defined(CONFIG_IDE_SWAP_IO)
+/* since ATAPI may use commands with not 4 bytes alligned length
+ * we have our own transfer functions, 2 bytes alligned */
+__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+       ushort *dbuf;
+       volatile ushort *pbuf;
+
+       pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       dbuf = (ushort *)sect_buf;
+
+       debug("in output data shorts base for read is %lx\n",
+             (unsigned long) pbuf);
+
+       while (shorts--) {
+               EIEIO;
+               *pbuf = *dbuf++;
+       }
+}
+
+__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+       ushort *dbuf;
+       volatile ushort *pbuf;
+
+       pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       dbuf = (ushort *)sect_buf;
+
+       debug("in input data shorts base for read is %lx\n",
+             (unsigned long) pbuf);
+
+       while (shorts--) {
+               EIEIO;
+               *dbuf++ = *pbuf;
+       }
+}
+
+#else  /* ! CONFIG_IDE_SWAP_IO */
+__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+       outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
+}
+
+__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+       insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
+}
+
+#endif /* CONFIG_IDE_SWAP_IO */
+
+/*
+ * Wait until (Status & mask) == res, or timeout (in ms)
+ * Return last status
+ * This is used since some ATAPI CD ROMs clears their Busy Bit first
+ * and then they set their DRQ Bit
+ */
+static uchar atapi_wait_mask(int dev, ulong t, uchar mask, uchar res)
+{
+       ulong delay = 10 * t;   /* poll every 100 us */
+       uchar c;
+
+       /* prevents to read the status before valid */
+       c = ide_inb(dev, ATA_DEV_CTL);
+
+       while (((c = ide_inb(dev, ATA_STATUS)) & mask) != res) {
+               /* break if error occurs (doesn't make sense to wait more) */
+               if ((c & ATA_STAT_ERR) == ATA_STAT_ERR)
+                       break;
+               udelay(100);
+               if (delay-- == 0)
+                       break;
+       }
+       return c;
+}
+
+/*
+ * issue an atapi command
+ */
+unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
+                         unsigned char *buffer, int buflen)
+{
+       unsigned char c, err, mask, res;
+       int n;
+
+       ide_led(DEVICE_LED(device), 1); /* LED on       */
+
+       /* Select device
+        */
+       mask = ATA_STAT_BUSY | ATA_STAT_DRQ;
+       res = 0;
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
+       if ((c & mask) != res) {
+               printf("ATAPI_ISSUE: device %d not ready status %X\n", device,
+                      c);
+               err = 0xFF;
+               goto AI_OUT;
+       }
+       /* write taskfile */
+       ide_outb(device, ATA_ERROR_REG, 0);     /* no DMA, no overlaped */
+       ide_outb(device, ATA_SECT_CNT, 0);
+       ide_outb(device, ATA_SECT_NUM, 0);
+       ide_outb(device, ATA_CYL_LOW, (unsigned char) (buflen & 0xFF));
+       ide_outb(device, ATA_CYL_HIGH,
+                (unsigned char) ((buflen >> 8) & 0xFF));
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+
+       ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET);
+       udelay(50);
+
+       mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
+       res = ATA_STAT_DRQ;
+       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
+
+       if ((c & mask) != res) {        /* DRQ must be 1, BSY 0 */
+               printf("ATAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n",
+                      device, c);
+               err = 0xFF;
+               goto AI_OUT;
+       }
+
+       /* write command block */
+       ide_output_data_shorts(device, (unsigned short *)ccb, ccblen / 2);
+
+       /* ATAPI Command written wait for completition */
+       udelay(5000);           /* device must set bsy */
+
+       mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
+       /*
+        * if no data wait for DRQ = 0 BSY = 0
+        * if data wait for DRQ = 1 BSY = 0
+        */
+       res = 0;
+       if (buflen)
+               res = ATA_STAT_DRQ;
+       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
+       if ((c & mask) != res) {
+               if (c & ATA_STAT_ERR) {
+                       err = (ide_inb(device, ATA_ERROR_REG)) >> 4;
+                       debug("atapi_issue 1 returned sense key %X status %02X\n",
+                             err, c);
+               } else {
+                       printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x)  status 0x%02x\n",
+                              ccb[0], c);
+                       err = 0xFF;
+               }
+               goto AI_OUT;
+       }
+       n = ide_inb(device, ATA_CYL_HIGH);
+       n <<= 8;
+       n += ide_inb(device, ATA_CYL_LOW);
+       if (n > buflen) {
+               printf("ERROR, transfer bytes %d requested only %d\n", n,
+                      buflen);
+               err = 0xff;
+               goto AI_OUT;
+       }
+       if ((n == 0) && (buflen < 0)) {
+               printf("ERROR, transfer bytes %d requested %d\n", n, buflen);
+               err = 0xff;
+               goto AI_OUT;
+       }
+       if (n != buflen) {
+               debug("WARNING, transfer bytes %d not equal with requested %d\n",
+                     n, buflen);
+       }
+       if (n != 0) {           /* data transfer */
+               debug("ATAPI_ISSUE: %d Bytes to transfer\n", n);
+               /* we transfer shorts */
+               n >>= 1;
+               /* ok now decide if it is an in or output */
+               if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) {
+                       debug("Write to device\n");
+                       ide_output_data_shorts(device, (unsigned short *)buffer,
+                                              n);
+               } else {
+                       debug("Read from device @ %p shorts %d\n", buffer, n);
+                       ide_input_data_shorts(device, (unsigned short *)buffer,
+                                             n);
+               }
+       }
+       udelay(5000);           /* seems that some CD ROMs need this... */
+       mask = ATA_STAT_BUSY | ATA_STAT_ERR;
+       res = 0;
+       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
+       if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
+               err = (ide_inb(device, ATA_ERROR_REG) >> 4);
+               debug("atapi_issue 2 returned sense key %X status %X\n", err,
+                     c);
+       } else {
+               err = 0;
+       }
+AI_OUT:
+       ide_led(DEVICE_LED(device), 0); /* LED off      */
+       return err;
+}
+
+/*
+ * sending the command to atapi_issue. If an status other than good
+ * returns, an request_sense will be issued
+ */
+
+#define ATAPI_DRIVE_NOT_READY  100
+#define ATAPI_UNIT_ATTN                10
+
+unsigned char atapi_issue_autoreq(int device,
+                                 unsigned char *ccb,
+                                 int ccblen,
+                                 unsigned char *buffer, int buflen)
+{
+       unsigned char sense_data[18], sense_ccb[12];
+       unsigned char res, key, asc, ascq;
+       int notready, unitattn;
+
+       unitattn = ATAPI_UNIT_ATTN;
+       notready = ATAPI_DRIVE_NOT_READY;
+
+retry:
+       res = atapi_issue(device, ccb, ccblen, buffer, buflen);
+       if (res == 0)
+               return 0;       /* Ok */
+
+       if (res == 0xFF)
+               return 0xFF;    /* error */
+
+       debug("(auto_req)atapi_issue returned sense key %X\n", res);
+
+       memset(sense_ccb, 0, sizeof(sense_ccb));
+       memset(sense_data, 0, sizeof(sense_data));
+       sense_ccb[0] = ATAPI_CMD_REQ_SENSE;
+       sense_ccb[4] = 18;      /* allocation Length */
+
+       res = atapi_issue(device, sense_ccb, 12, sense_data, 18);
+       key = (sense_data[2] & 0xF);
+       asc = (sense_data[12]);
+       ascq = (sense_data[13]);
+
+       debug("ATAPI_CMD_REQ_SENSE returned %x\n", res);
+       debug(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",
+             sense_data[0], key, asc, ascq);
+
+       if ((key == 0))
+               return 0;       /* ok device ready */
+
+       if ((key == 6) || (asc == 0x29) || (asc == 0x28)) { /* Unit Attention */
+               if (unitattn-- > 0) {
+                       udelay(200 * 1000);
+                       goto retry;
+               }
+               printf("Unit Attention, tried %d\n", ATAPI_UNIT_ATTN);
+               goto error;
+       }
+       if ((asc == 0x4) && (ascq == 0x1)) {
+               /* not ready, but will be ready soon */
+               if (notready-- > 0) {
+                       udelay(200 * 1000);
+                       goto retry;
+               }
+               printf("Drive not ready, tried %d times\n",
+                      ATAPI_DRIVE_NOT_READY);
+               goto error;
+       }
+       if (asc == 0x3a) {
+               debug("Media not present\n");
+               goto error;
+       }
+
+       printf("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n", key, asc,
+              ascq);
+error:
+       debug("ERROR Sense key %02X ASC %02X ASCQ %02X\n", key, asc, ascq);
+       return 0xFF;
+}
+
+/*
+ * atapi_read:
+ * we transfer only one block per command, since the multiple DRQ per
+ * command is not yet implemented
+ */
+#define ATAPI_READ_MAX_BYTES   2048    /* we read max 2kbytes */
+#define ATAPI_READ_BLOCK_SIZE  2048    /* assuming CD part */
+#define ATAPI_READ_MAX_BLOCK   (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)
+
+ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
+                void *buffer)
+{
+       int device = block_dev->devnum;
+       ulong n = 0;
+       unsigned char ccb[12];  /* Command descriptor block */
+       ulong cnt;
+
+       debug("atapi_read dev %d start " LBAF " blocks " LBAF
+             " buffer at %lX\n", device, blknr, blkcnt, (ulong) buffer);
+
+       do {
+               if (blkcnt > ATAPI_READ_MAX_BLOCK)
+                       cnt = ATAPI_READ_MAX_BLOCK;
+               else
+                       cnt = blkcnt;
+
+               ccb[0] = ATAPI_CMD_READ_12;
+               ccb[1] = 0;     /* reserved */
+               ccb[2] = (unsigned char) (blknr >> 24) & 0xFF;  /* MSB Block */
+               ccb[3] = (unsigned char) (blknr >> 16) & 0xFF;  /*  */
+               ccb[4] = (unsigned char) (blknr >> 8) & 0xFF;
+               ccb[5] = (unsigned char) blknr & 0xFF;  /* LSB Block */
+               ccb[6] = (unsigned char) (cnt >> 24) & 0xFF; /* MSB Block cnt */
+               ccb[7] = (unsigned char) (cnt >> 16) & 0xFF;
+               ccb[8] = (unsigned char) (cnt >> 8) & 0xFF;
+               ccb[9] = (unsigned char) cnt & 0xFF;    /* LSB Block */
+               ccb[10] = 0;    /* reserved */
+               ccb[11] = 0;    /* reserved */
+
+               if (atapi_issue_autoreq(device, ccb, 12,
+                                       (unsigned char *)buffer,
+                                       cnt * ATAPI_READ_BLOCK_SIZE)
+                   == 0xFF) {
+                       return n;
+               }
+               n += cnt;
+               blkcnt -= cnt;
+               blknr += cnt;
+               buffer += (cnt * ATAPI_READ_BLOCK_SIZE);
+       } while (blkcnt > 0);
+       return n;
+}
+
+static void atapi_inquiry(struct blk_desc *dev_desc)
+{
+       unsigned char ccb[12];  /* Command descriptor block */
+       unsigned char iobuf[64];        /* temp buf */
+       unsigned char c;
+       int device;
+
+       device = dev_desc->devnum;
+       dev_desc->type = DEV_TYPE_UNKNOWN;      /* not yet valid */
+       dev_desc->block_read = atapi_read;
+
+       memset(ccb, 0, sizeof(ccb));
+       memset(iobuf, 0, sizeof(iobuf));
+
+       ccb[0] = ATAPI_CMD_INQUIRY;
+       ccb[4] = 40;            /* allocation Legnth */
+       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 40);
+
+       debug("ATAPI_CMD_INQUIRY returned %x\n", c);
+       if (c != 0)
+               return;
+
+       /* copy device ident strings */
+       ident_cpy((unsigned char *)dev_desc->vendor, &iobuf[8], 8);
+       ident_cpy((unsigned char *)dev_desc->product, &iobuf[16], 16);
+       ident_cpy((unsigned char *)dev_desc->revision, &iobuf[32], 5);
+
+       dev_desc->lun = 0;
+       dev_desc->lba = 0;
+       dev_desc->blksz = 0;
+       dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz));
+       dev_desc->type = iobuf[0] & 0x1f;
+
+       if ((iobuf[1] & 0x80) == 0x80)
+               dev_desc->removable = 1;
+       else
+               dev_desc->removable = 0;
+
+       memset(ccb, 0, sizeof(ccb));
+       memset(iobuf, 0, sizeof(iobuf));
+       ccb[0] = ATAPI_CMD_START_STOP;
+       ccb[4] = 0x03;          /* start */
+
+       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0);
+
+       debug("ATAPI_CMD_START_STOP returned %x\n", c);
+       if (c != 0)
+               return;
+
+       memset(ccb, 0, sizeof(ccb));
+       memset(iobuf, 0, sizeof(iobuf));
+       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0);
+
+       debug("ATAPI_CMD_UNIT_TEST_READY returned %x\n", c);
+       if (c != 0)
+               return;
+
+       memset(ccb, 0, sizeof(ccb));
+       memset(iobuf, 0, sizeof(iobuf));
+       ccb[0] = ATAPI_CMD_READ_CAP;
+       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 8);
+       debug("ATAPI_CMD_READ_CAP returned %x\n", c);
+       if (c != 0)
+               return;
+
+       debug("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",
+             iobuf[0], iobuf[1], iobuf[2], iobuf[3],
+             iobuf[4], iobuf[5], iobuf[6], iobuf[7]);
+
+       dev_desc->lba = ((unsigned long) iobuf[0] << 24) +
+               ((unsigned long) iobuf[1] << 16) +
+               ((unsigned long) iobuf[2] << 8) + ((unsigned long) iobuf[3]);
+       dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
+               ((unsigned long) iobuf[5] << 16) +
+               ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
+       dev_desc->log2blksz = LOG2(dev_desc->blksz);
+#ifdef CONFIG_LBA48
+       /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
+       dev_desc->lba48 = 0;
+#endif
+       return;
+}
+
+#endif /* CONFIG_ATAPI */
+
+static void ide_ident(struct blk_desc *dev_desc)
+{
+       unsigned char c;
+       hd_driveid_t iop;
+
+#ifdef CONFIG_ATAPI
+       int retries = 0;
+#endif
+       int device;
+
+       device = dev_desc->devnum;
+       printf("  Device %d: ", device);
+
+       ide_led(DEVICE_LED(device), 1); /* LED on       */
+       /* Select device
+        */
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       dev_desc->if_type = IF_TYPE_IDE;
+#ifdef CONFIG_ATAPI
+
+       retries = 0;
+
+       /* Warning: This will be tricky to read */
+       while (retries <= 1) {
+               /* check signature */
+               if ((ide_inb(device, ATA_SECT_CNT) == 0x01) &&
+                   (ide_inb(device, ATA_SECT_NUM) == 0x01) &&
+                   (ide_inb(device, ATA_CYL_LOW) == 0x14) &&
+                   (ide_inb(device, ATA_CYL_HIGH) == 0xEB)) {
+                       /* ATAPI Signature found */
+                       dev_desc->if_type = IF_TYPE_ATAPI;
+                       /*
+                        * Start Ident Command
+                        */
+                       ide_outb(device, ATA_COMMAND, ATAPI_CMD_IDENT);
+                       /*
+                        * Wait for completion - ATAPI devices need more time
+                        * to become ready
+                        */
+                       c = ide_wait(device, ATAPI_TIME_OUT);
+               } else
+#endif
+               {
+                       /*
+                        * Start Ident Command
+                        */
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_IDENT);
+
+                       /*
+                        * Wait for completion
+                        */
+                       c = ide_wait(device, IDE_TIME_OUT);
+               }
+               ide_led(DEVICE_LED(device), 0); /* LED off      */
+
+               if (((c & ATA_STAT_DRQ) == 0) ||
+                   ((c & (ATA_STAT_FAULT | ATA_STAT_ERR)) != 0)) {
+#ifdef CONFIG_ATAPI
+                       {
+                               /*
+                                * Need to soft reset the device
+                                * in case it's an ATAPI...
+                                */
+                               debug("Retrying...\n");
+                               ide_outb(device, ATA_DEV_HD,
+                                        ATA_LBA | ATA_DEVICE(device));
+                               udelay(100000);
+                               ide_outb(device, ATA_COMMAND, 0x08);
+                               udelay(500000); /* 500 ms */
+                       }
+                       /*
+                        * Select device
+                        */
+                       ide_outb(device, ATA_DEV_HD,
+                                ATA_LBA | ATA_DEVICE(device));
+                       retries++;
+#else
+                       return;
+#endif
+               }
+#ifdef CONFIG_ATAPI
+               else
+                       break;
+       }                       /* see above - ugly to read */
+
+       if (retries == 2)       /* Not found */
+               return;
+#endif
+
+       ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS);
+
+       ident_cpy((unsigned char *)dev_desc->revision, iop.fw_rev,
+                 sizeof(dev_desc->revision));
+       ident_cpy((unsigned char *)dev_desc->vendor, iop.model,
+                 sizeof(dev_desc->vendor));
+       ident_cpy((unsigned char *)dev_desc->product, iop.serial_no,
+                 sizeof(dev_desc->product));
+#ifdef __LITTLE_ENDIAN
+       /*
+        * firmware revision, model, and serial number have Big Endian Byte
+        * order in Word. Convert all three to little endian.
+        *
+        * See CF+ and CompactFlash Specification Revision 2.0:
+        * 6.2.1.6: Identify Drive, Table 39 for more details
+        */
+
+       strswab(dev_desc->revision);
+       strswab(dev_desc->vendor);
+       strswab(dev_desc->product);
+#endif /* __LITTLE_ENDIAN */
+
+       if ((iop.config & 0x0080) == 0x0080)
+               dev_desc->removable = 1;
+       else
+               dev_desc->removable = 0;
+
+#ifdef CONFIG_ATAPI
+       if (dev_desc->if_type == IF_TYPE_ATAPI) {
+               atapi_inquiry(dev_desc);
+               return;
+       }
+#endif /* CONFIG_ATAPI */
+
+#ifdef __BIG_ENDIAN
+       /* swap shorts */
+       dev_desc->lba = (iop.lba_capacity << 16) | (iop.lba_capacity >> 16);
+#else  /* ! __BIG_ENDIAN */
+       /*
+        * do not swap shorts on little endian
+        *
+        * See CF+ and CompactFlash Specification Revision 2.0:
+        * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details.
+        */
+       dev_desc->lba = iop.lba_capacity;
+#endif /* __BIG_ENDIAN */
+
+#ifdef CONFIG_LBA48
+       if (iop.command_set_2 & 0x0400) {       /* LBA 48 support */
+               dev_desc->lba48 = 1;
+               dev_desc->lba = (unsigned long long) iop.lba48_capacity[0] |
+                       ((unsigned long long) iop.lba48_capacity[1] << 16) |
+                       ((unsigned long long) iop.lba48_capacity[2] << 32) |
+                       ((unsigned long long) iop.lba48_capacity[3] << 48);
+       } else {
+               dev_desc->lba48 = 0;
+       }
+#endif /* CONFIG_LBA48 */
+       /* assuming HD */
+       dev_desc->type = DEV_TYPE_HARDDISK;
+       dev_desc->blksz = ATA_BLOCKSIZE;
+       dev_desc->log2blksz = LOG2(dev_desc->blksz);
+       dev_desc->lun = 0;      /* just to fill something in... */
+
+#if 0                          /* only used to test the powersaving mode,
+                                * if enabled, the drive goes after 5 sec
+                                * in standby mode */
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       c = ide_wait(device, IDE_TIME_OUT);
+       ide_outb(device, ATA_SECT_CNT, 1);
+       ide_outb(device, ATA_LBA_LOW, 0);
+       ide_outb(device, ATA_LBA_MID, 0);
+       ide_outb(device, ATA_LBA_HIGH, 0);
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       ide_outb(device, ATA_COMMAND, 0xe3);
+       udelay(50);
+       c = ide_wait(device, IDE_TIME_OUT);     /* can't take over 500 ms */
+#endif
+}
+
+__weak void ide_led(uchar led, uchar status)
+{
+#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */
+       static uchar led_buffer;        /* Buffer for current LED status */
+
+       uchar *led_port = LED_PORT;
+
+       if (status)             /* switch LED on        */
+               led_buffer |= led;
+       else                    /* switch LED off       */
+               led_buffer &= ~led;
+
+       *led_port = led_buffer;
+#endif
+}
+
+__weak void ide_outb(int dev, int port, unsigned char val)
+{
+       debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
+             dev, port, val,
+             (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
+
+#if defined(CONFIG_IDE_AHB)
+       if (port) {
+               /* write command */
+               ide_write_register(dev, port, val);
+       } else {
+               /* write data */
+               outb(val, (ATA_CURR_BASE(dev)));
+       }
+#else
+       outb(val, (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
+#endif
+}
+
+__weak unsigned char ide_inb(int dev, int port)
+{
+       uchar val;
+
+#if defined(CONFIG_IDE_AHB)
+       val = ide_read_register(dev, port);
+#else
+       val = inb((ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
+#endif
+
+       debug("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
+             dev, port,
+             (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)), val);
+       return val;
+}
+
+void ide_init(void)
+{
+       unsigned char c;
+       int i, bus;
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+       extern int ide_devices_found;   /* Initialized in check_ide_device() */
+#endif /* CONFIG_IDE_8xx_PCCARD */
+
+#ifdef CONFIG_IDE_PREINIT
+       WATCHDOG_RESET();
+
+       if (ide_preinit()) {
+               puts("ide_preinit failed\n");
+               return;
+       }
+#endif /* CONFIG_IDE_PREINIT */
+
+       WATCHDOG_RESET();
+
+       /*
+        * Reset the IDE just to be sure.
+        * Light LED's to show
+        */
+       ide_led((LED_IDE1 | LED_IDE2), 1);      /* LED's on     */
+
+       /* ATAPI Drives seems to need a proper IDE Reset */
+       ide_reset();
+
+#ifdef CONFIG_IDE_INIT_POSTRESET
+       WATCHDOG_RESET();
+
+       if (ide_init_postreset()) {
+               puts("ide_preinit_postreset failed\n");
+               return;
+       }
+#endif /* CONFIG_IDE_INIT_POSTRESET */
+
+       /*
+        * Wait for IDE to get ready.
+        * According to spec, this can take up to 31 seconds!
+        */
+       for (bus = 0; bus < CONFIG_SYS_IDE_MAXBUS; ++bus) {
+               int dev =
+                       bus * (CONFIG_SYS_IDE_MAXDEVICE /
+                              CONFIG_SYS_IDE_MAXBUS);
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+               /* Skip non-ide devices from probing */
+               if ((ide_devices_found & (1 << bus)) == 0) {
+                       ide_led((LED_IDE1 | LED_IDE2), 0);      /* LED's off */
+                       continue;
+               }
+#endif
+               printf("Bus %d: ", bus);
+
+               ide_bus_ok[bus] = 0;
+
+               /* Select device
+                */
+               udelay(100000); /* 100 ms */
+               ide_outb(dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
+               udelay(100000); /* 100 ms */
+               i = 0;
+               do {
+                       udelay(10000);  /* 10 ms */
+
+                       c = ide_inb(dev, ATA_STATUS);
+                       i++;
+                       if (i > (ATA_RESET_TIME * 100)) {
+                               puts("** Timeout **\n");
+                               /* LED's off */
+                               ide_led((LED_IDE1 | LED_IDE2), 0);
+                               return;
+                       }
+                       if ((i >= 100) && ((i % 100) == 0))
+                               putc('.');
+
+               } while (c & ATA_STAT_BUSY);
+
+               if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
+                       puts("not available  ");
+                       debug("Status = 0x%02X ", c);
+#ifndef CONFIG_ATAPI           /* ATAPI Devices do not set DRDY */
+               } else if ((c & ATA_STAT_READY) == 0) {
+                       puts("not available  ");
+                       debug("Status = 0x%02X ", c);
+#endif
+               } else {
+                       puts("OK ");
+                       ide_bus_ok[bus] = 1;
+               }
+               WATCHDOG_RESET();
+       }
+
+       putc('\n');
+
+       ide_led((LED_IDE1 | LED_IDE2), 0);      /* LED's off    */
+
+       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
+               int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
+               ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
+               ide_dev_desc[i].if_type = IF_TYPE_IDE;
+               ide_dev_desc[i].devnum = i;
+               ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+               ide_dev_desc[i].blksz = 0;
+               ide_dev_desc[i].log2blksz =
+                       LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));
+               ide_dev_desc[i].lba = 0;
+#ifndef CONFIG_BLK
+               ide_dev_desc[i].block_read = ide_read;
+               ide_dev_desc[i].block_write = ide_write;
+#endif
+               if (!ide_bus_ok[IDE_BUS(i)])
+                       continue;
+               ide_led(led, 1);        /* LED on       */
+               ide_ident(&ide_dev_desc[i]);
+               ide_led(led, 0);        /* LED off      */
+               dev_print(&ide_dev_desc[i]);
+
+               if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
+                       /* initialize partition type */
+                       part_init(&ide_dev_desc[i]);
+               }
+       }
+       WATCHDOG_RESET();
+}
+
+/* We only need to swap data if we are running on a big endian cpu. */
+#if defined(__LITTLE_ENDIAN)
+__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
+{
+       ide_input_data(dev, sect_buf, words);
+}
+#else
+__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
+{
+       volatile ushort *pbuf =
+               (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       ushort *dbuf = (ushort *)sect_buf;
+
+       debug("in input swap data base for read is %lx\n",
+             (unsigned long) pbuf);
+
+       while (words--) {
+#ifdef __MIPS__
+               *dbuf++ = swab16p((u16 *)pbuf);
+               *dbuf++ = swab16p((u16 *)pbuf);
+#else
+               *dbuf++ = ld_le16(pbuf);
+               *dbuf++ = ld_le16(pbuf);
+#endif /* !MIPS */
+       }
+}
+#endif /* __LITTLE_ENDIAN */
+
+
+#if defined(CONFIG_IDE_SWAP_IO)
+__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
+{
+       ushort *dbuf;
+       volatile ushort *pbuf;
+
+       pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       dbuf = (ushort *)sect_buf;
+       while (words--) {
+               EIEIO;
+               *pbuf = *dbuf++;
+               EIEIO;
+               *pbuf = *dbuf++;
+       }
+}
+#else  /* ! CONFIG_IDE_SWAP_IO */
+__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
+{
+#if defined(CONFIG_IDE_AHB)
+       ide_write_data(dev, sect_buf, words);
+#else
+       outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1);
+#endif
+}
+#endif /* CONFIG_IDE_SWAP_IO */
+
+#if defined(CONFIG_IDE_SWAP_IO)
+__weak void ide_input_data(int dev, ulong *sect_buf, int words)
+{
+       ushort *dbuf;
+       volatile ushort *pbuf;
+
+       pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       dbuf = (ushort *)sect_buf;
+
+       debug("in input data base for read is %lx\n", (unsigned long) pbuf);
+
+       while (words--) {
+               EIEIO;
+               *dbuf++ = *pbuf;
+               EIEIO;
+               *dbuf++ = *pbuf;
+       }
+}
+#else  /* ! CONFIG_IDE_SWAP_IO */
+__weak void ide_input_data(int dev, ulong *sect_buf, int words)
+{
+#if defined(CONFIG_IDE_AHB)
+       ide_read_data(dev, sect_buf, words);
+#else
+       insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1);
+#endif
+}
+
+#endif /* CONFIG_IDE_SWAP_IO */
+
+#ifdef CONFIG_BLK
+ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+              void *buffer)
+#else
+ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
+              void *buffer)
+#endif
+{
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
+       int device = block_dev->devnum;
+       ulong n = 0;
+       unsigned char c;
+       unsigned char pwrsave = 0;      /* power save */
+
+#ifdef CONFIG_LBA48
+       unsigned char lba48 = 0;
+
+       if (blknr & 0x0000fffff0000000ULL) {
+               /* more than 28 bits used, use 48bit mode */
+               lba48 = 1;
+       }
+#endif
+       debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n",
+             device, blknr, blkcnt, (ulong) buffer);
+
+       ide_led(DEVICE_LED(device), 1); /* LED on       */
+
+       /* Select device
+        */
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       c = ide_wait(device, IDE_TIME_OUT);
+
+       if (c & ATA_STAT_BUSY) {
+               printf("IDE read: device %d not ready\n", device);
+               goto IDE_READ_E;
+       }
+
+       /* first check if the drive is in Powersaving mode, if yes,
+        * increase the timeout value */
+       ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_PWR);
+       udelay(50);
+
+       c = ide_wait(device, IDE_TIME_OUT);     /* can't take over 500 ms */
+
+       if (c & ATA_STAT_BUSY) {
+               printf("IDE read: device %d not ready\n", device);
+               goto IDE_READ_E;
+       }
+       if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
+               printf("No Powersaving mode %X\n", c);
+       } else {
+               c = ide_inb(device, ATA_SECT_CNT);
+               debug("Powersaving %02X\n", c);
+               if (c == 0)
+                       pwrsave = 1;
+       }
+
+
+       while (blkcnt-- > 0) {
+               c = ide_wait(device, IDE_TIME_OUT);
+
+               if (c & ATA_STAT_BUSY) {
+                       printf("IDE read: device %d not ready\n", device);
+                       break;
+               }
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       /* write high bits */
+                       ide_outb(device, ATA_SECT_CNT, 0);
+                       ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
+#ifdef CONFIG_SYS_64BIT_LBA
+                       ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
+                       ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
+#else
+                       ide_outb(device, ATA_LBA_MID, 0);
+                       ide_outb(device, ATA_LBA_HIGH, 0);
+#endif
+               }
+#endif
+               ide_outb(device, ATA_SECT_CNT, 1);
+               ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
+               ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
+               ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
+
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       ide_outb(device, ATA_DEV_HD,
+                                ATA_LBA | ATA_DEVICE(device));
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_READ_EXT);
+
+               } else
+#endif
+               {
+                       ide_outb(device, ATA_DEV_HD, ATA_LBA |
+                                ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_READ);
+               }
+
+               udelay(50);
+
+               if (pwrsave) {
+                       /* may take up to 4 sec */
+                       c = ide_wait(device, IDE_SPIN_UP_TIME_OUT);
+                       pwrsave = 0;
+               } else {
+                       /* can't take over 500 ms */
+                       c = ide_wait(device, IDE_TIME_OUT);
+               }
+
+               if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
+                   ATA_STAT_DRQ) {
+                       printf("Error (no IRQ) dev %d blk " LBAF
+                              ": status %#02x\n", device, blknr, c);
+                       break;
+               }
+
+               ide_input_data(device, buffer, ATA_SECTORWORDS);
+               (void) ide_inb(device, ATA_STATUS);     /* clear IRQ */
+
+               ++n;
+               ++blknr;
+               buffer += ATA_BLOCKSIZE;
+       }
+IDE_READ_E:
+       ide_led(DEVICE_LED(device), 0); /* LED off      */
+       return n;
+}
+
+#ifdef CONFIG_BLK
+ulong ide_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+               const void *buffer)
+#else
+ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
+               const void *buffer)
+#endif
+{
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
+       int device = block_dev->devnum;
+       ulong n = 0;
+       unsigned char c;
+
+#ifdef CONFIG_LBA48
+       unsigned char lba48 = 0;
+
+       if (blknr & 0x0000fffff0000000ULL) {
+               /* more than 28 bits used, use 48bit mode */
+               lba48 = 1;
+       }
+#endif
+
+       ide_led(DEVICE_LED(device), 1); /* LED on       */
+
+       /* Select device
+        */
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+
+       while (blkcnt-- > 0) {
+               c = ide_wait(device, IDE_TIME_OUT);
+
+               if (c & ATA_STAT_BUSY) {
+                       printf("IDE read: device %d not ready\n", device);
+                       goto WR_OUT;
+               }
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       /* write high bits */
+                       ide_outb(device, ATA_SECT_CNT, 0);
+                       ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
+#ifdef CONFIG_SYS_64BIT_LBA
+                       ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
+                       ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
+#else
+                       ide_outb(device, ATA_LBA_MID, 0);
+                       ide_outb(device, ATA_LBA_HIGH, 0);
+#endif
+               }
+#endif
+               ide_outb(device, ATA_SECT_CNT, 1);
+               ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
+               ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
+               ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
+
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       ide_outb(device, ATA_DEV_HD,
+                                ATA_LBA | ATA_DEVICE(device));
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE_EXT);
+
+               } else
+#endif
+               {
+                       ide_outb(device, ATA_DEV_HD, ATA_LBA |
+                                ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE);
+               }
+
+               udelay(50);
+
+               /* can't take over 500 ms */
+               c = ide_wait(device, IDE_TIME_OUT);
+
+               if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
+                   ATA_STAT_DRQ) {
+                       printf("Error (no IRQ) dev %d blk " LBAF
+                              ": status %#02x\n", device, blknr, c);
+                       goto WR_OUT;
+               }
+
+               ide_output_data(device, buffer, ATA_SECTORWORDS);
+               c = ide_inb(device, ATA_STATUS);        /* clear IRQ */
+               ++n;
+               ++blknr;
+               buffer += ATA_BLOCKSIZE;
+       }
+WR_OUT:
+       ide_led(DEVICE_LED(device), 0); /* LED off      */
+       return n;
+}
+
+#if defined(CONFIG_OF_IDE_FIXUP)
+int ide_device_present(int dev)
+{
+       if (dev >= CONFIG_SYS_IDE_MAXBUS)
+               return 0;
+       return ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN ? 0 : 1;
+}
+#endif
+
+#ifdef CONFIG_BLK
+static const struct blk_ops ide_blk_ops = {
+       .read   = ide_read,
+       .write  = ide_write,
+};
+
+U_BOOT_DRIVER(ide_blk) = {
+       .name           = "ide_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &ide_blk_ops,
+};
+#else
+U_BOOT_LEGACY_BLK(ide) = {
+       .if_typename    = "ide",
+       .if_type        = IF_TYPE_IDE,
+       .max_devs       = CONFIG_SYS_IDE_MAXDEVICE,
+       .desc           = ide_dev_desc,
+};
+#endif
index 25f8a1183d58de323bc4a66af34683db48471263..c86b7c6b1182e42e3febf94caaa3604628f809c6 100644 (file)
@@ -886,9 +886,9 @@ int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
        ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
                                sizeof(uint32_t));
        if (ret) {
-               printf("Can't set '%s' property for '%s' node (%s)\n",
-                      FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
-                      fdt_strerror(ret));
+               debug("Can't set '%s' property for '%s' node (%s)\n",
+                     FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
+                     fdt_strerror(ret));
                return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1;
        }
 
diff --git a/common/sata.c b/common/sata.c
new file mode 100644 (file)
index 0000000..88f08c9
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2000-2005, DENX Software Engineering
+ *             Wolfgang Denk <wd@denx.de>
+ * Copyright (C) Procsys. All rights reserved.
+ *             Mushtaq Khan <mushtaq_k@procsys.com>
+ *                     <mushtaqk_921@yahoo.co.in>
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
+ *             Dave Liu <daveliu@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <sata.h>
+
+struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
+
+#ifdef CONFIG_PARTITIONS
+struct blk_desc *sata_get_dev(int dev)
+{
+       return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
+}
+#endif
+
+#ifdef CONFIG_BLK
+static unsigned long sata_bread(struct udevice *dev, lbaint_t start,
+                               lbaint_t blkcnt, void *dst)
+{
+       return -ENOSYS;
+}
+
+static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start,
+                                lbaint_t blkcnt, const void *buffer)
+{
+       return -ENOSYS;
+}
+#else
+static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start,
+                               lbaint_t blkcnt, void *dst)
+{
+       return sata_read(block_dev->devnum, start, blkcnt, dst);
+}
+
+static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
+                                lbaint_t blkcnt, const void *buffer)
+{
+       return sata_write(block_dev->devnum, start, blkcnt, buffer);
+}
+#endif
+
+int __sata_initialize(void)
+{
+       int rc;
+       int i;
+
+       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
+               memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
+               sata_dev_desc[i].if_type = IF_TYPE_SATA;
+               sata_dev_desc[i].devnum = i;
+               sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+               sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
+               sata_dev_desc[i].lba = 0;
+               sata_dev_desc[i].blksz = 512;
+               sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
+#ifndef CONFIG_BLK
+               sata_dev_desc[i].block_read = sata_bread;
+               sata_dev_desc[i].block_write = sata_bwrite;
+#endif
+               rc = init_sata(i);
+               if (!rc) {
+                       rc = scan_sata(i);
+                       if (!rc && sata_dev_desc[i].lba > 0 &&
+                           sata_dev_desc[i].blksz > 0)
+                               part_init(&sata_dev_desc[i]);
+               }
+       }
+
+       return rc;
+}
+int sata_initialize(void) __attribute__((weak, alias("__sata_initialize")));
+
+__weak int __sata_stop(void)
+{
+       int i, err = 0;
+
+       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++)
+               err |= reset_sata(i);
+
+       if (err)
+               printf("Could not reset some SATA devices\n");
+
+       return err;
+}
+int sata_stop(void) __attribute__((weak, alias("__sata_stop")));
+
+#ifdef CONFIG_BLK
+static const struct blk_ops sata_blk_ops = {
+       .read   = sata_bread,
+       .write  = sata_bwrite,
+};
+
+U_BOOT_DRIVER(sata_blk) = {
+       .name           = "sata_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &sata_blk_ops,
+};
+#else
+U_BOOT_LEGACY_BLK(sata) = {
+       .if_typename    = "sata",
+       .if_type        = IF_TYPE_SATA,
+       .max_devs       = CONFIG_SYS_SATA_MAX_DEVICE,
+       .desc           = sata_dev_desc,
+};
+#endif
diff --git a/common/scsi.c b/common/scsi.c
new file mode 100644 (file)
index 0000000..8ac28dd
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <inttypes.h>
+#include <pci.h>
+#include <scsi.h>
+
+#ifdef CONFIG_SCSI_DEV_LIST
+#define SCSI_DEV_LIST CONFIG_SCSI_DEV_LIST
+#else
+#ifdef CONFIG_SCSI_SYM53C8XX
+#define SCSI_VEND_ID   0x1000
+#ifndef CONFIG_SCSI_DEV_ID
+#define SCSI_DEV_ID            0x0001
+#else
+#define SCSI_DEV_ID            CONFIG_SCSI_DEV_ID
+#endif
+#elif defined CONFIG_SATA_ULI5288
+
+#define SCSI_VEND_ID 0x10b9
+#define SCSI_DEV_ID  0x5288
+
+#elif !defined(CONFIG_SCSI_AHCI_PLAT)
+#error no scsi device defined
+#endif
+#define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID}
+#endif
+
+#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
+const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST };
+#endif
+static ccb tempccb;    /* temporary scsi command buffer */
+
+static unsigned char tempbuff[512]; /* temporary data buffer */
+
+static int scsi_max_devs; /* number of highest available scsi device */
+
+static int scsi_curr_dev; /* current device */
+
+static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
+
+/* almost the maximum amount of the scsi_ext command.. */
+#define SCSI_MAX_READ_BLK 0xFFFF
+#define SCSI_LBA48_READ        0xFFFFFFF
+
+#ifdef CONFIG_SYS_64BIT_LBA
+void scsi_setup_read16(ccb *pccb, lbaint_t start, unsigned long blocks)
+{
+       pccb->cmd[0] = SCSI_READ16;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = (unsigned char)(start >> 56) & 0xff;
+       pccb->cmd[3] = (unsigned char)(start >> 48) & 0xff;
+       pccb->cmd[4] = (unsigned char)(start >> 40) & 0xff;
+       pccb->cmd[5] = (unsigned char)(start >> 32) & 0xff;
+       pccb->cmd[6] = (unsigned char)(start >> 24) & 0xff;
+       pccb->cmd[7] = (unsigned char)(start >> 16) & 0xff;
+       pccb->cmd[8] = (unsigned char)(start >> 8) & 0xff;
+       pccb->cmd[9] = (unsigned char)start & 0xff;
+       pccb->cmd[10] = 0;
+       pccb->cmd[11] = (unsigned char)(blocks >> 24) & 0xff;
+       pccb->cmd[12] = (unsigned char)(blocks >> 16) & 0xff;
+       pccb->cmd[13] = (unsigned char)(blocks >> 8) & 0xff;
+       pccb->cmd[14] = (unsigned char)blocks & 0xff;
+       pccb->cmd[15] = 0;
+       pccb->cmdlen = 16;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+       debug("scsi_setup_read16: cmd: %02X %02X startblk %02X%02X%02X%02X%02X%02X%02X%02X blccnt %02X%02X%02X%02X\n",
+             pccb->cmd[0], pccb->cmd[1],
+             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
+             pccb->cmd[6], pccb->cmd[7], pccb->cmd[8], pccb->cmd[9],
+             pccb->cmd[11], pccb->cmd[12], pccb->cmd[13], pccb->cmd[14]);
+}
+#endif
+
+void scsi_setup_read_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
+{
+       pccb->cmd[0] = SCSI_READ10;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
+       pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
+       pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
+       pccb->cmd[5] = (unsigned char)start & 0xff;
+       pccb->cmd[6] = 0;
+       pccb->cmd[7] = (unsigned char)(blocks >> 8) & 0xff;
+       pccb->cmd[8] = (unsigned char)blocks & 0xff;
+       pccb->cmd[6] = 0;
+       pccb->cmdlen = 10;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+       debug("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
+             pccb->cmd[0], pccb->cmd[1],
+             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
+             pccb->cmd[7], pccb->cmd[8]);
+}
+
+void scsi_setup_write_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
+{
+       pccb->cmd[0] = SCSI_WRITE10;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
+       pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
+       pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
+       pccb->cmd[5] = (unsigned char)start & 0xff;
+       pccb->cmd[6] = 0;
+       pccb->cmd[7] = ((unsigned char)(blocks >> 8)) & 0xff;
+       pccb->cmd[8] = (unsigned char)blocks & 0xff;
+       pccb->cmd[9] = 0;
+       pccb->cmdlen = 10;
+       pccb->msgout[0] = SCSI_IDENTIFY;  /* NOT USED */
+       debug("%s: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
+             __func__,
+             pccb->cmd[0], pccb->cmd[1],
+             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
+             pccb->cmd[7], pccb->cmd[8]);
+}
+
+void scsi_setup_read6(ccb *pccb, lbaint_t start, unsigned short blocks)
+{
+       pccb->cmd[0] = SCSI_READ6;
+       pccb->cmd[1] = pccb->lun << 5 | ((unsigned char)(start >> 16) & 0x1f);
+       pccb->cmd[2] = (unsigned char)(start >> 8) & 0xff;
+       pccb->cmd[3] = (unsigned char)start & 0xff;
+       pccb->cmd[4] = (unsigned char)blocks & 0xff;
+       pccb->cmd[5] = 0;
+       pccb->cmdlen = 6;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+       debug("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
+             pccb->cmd[0], pccb->cmd[1],
+             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4]);
+}
+
+
+void scsi_setup_inquiry(ccb *pccb)
+{
+       pccb->cmd[0] = SCSI_INQUIRY;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = 0;
+       pccb->cmd[3] = 0;
+       if (pccb->datalen > 255)
+               pccb->cmd[4] = 255;
+       else
+               pccb->cmd[4] = (unsigned char)pccb->datalen;
+       pccb->cmd[5] = 0;
+       pccb->cmdlen = 6;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+}
+
+#ifdef CONFIG_BLK
+static ulong scsi_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+                      void *buffer)
+#else
+static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
+                      lbaint_t blkcnt, void *buffer)
+#endif
+{
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
+       int device = block_dev->devnum;
+       lbaint_t start, blks;
+       uintptr_t buf_addr;
+       unsigned short smallblks = 0;
+       ccb *pccb = (ccb *)&tempccb;
+       device &= 0xff;
+
+       /* Setup device */
+       pccb->target = scsi_dev_desc[device].target;
+       pccb->lun = scsi_dev_desc[device].lun;
+       buf_addr = (unsigned long)buffer;
+       start = blknr;
+       blks = blkcnt;
+       debug("\nscsi_read: dev %d startblk " LBAF
+             ", blccnt " LBAF " buffer %lx\n",
+             device, start, blks, (unsigned long)buffer);
+       do {
+               pccb->pdata = (unsigned char *)buf_addr;
+#ifdef CONFIG_SYS_64BIT_LBA
+               if (start > SCSI_LBA48_READ) {
+                       unsigned long blocks;
+                       blocks = min_t(lbaint_t, blks, SCSI_MAX_READ_BLK);
+                       pccb->datalen = scsi_dev_desc[device].blksz * blocks;
+                       scsi_setup_read16(pccb, start, blocks);
+                       start += blocks;
+                       blks -= blocks;
+               } else
+#endif
+               if (blks > SCSI_MAX_READ_BLK) {
+                       pccb->datalen = scsi_dev_desc[device].blksz *
+                               SCSI_MAX_READ_BLK;
+                       smallblks = SCSI_MAX_READ_BLK;
+                       scsi_setup_read_ext(pccb, start, smallblks);
+                       start += SCSI_MAX_READ_BLK;
+                       blks -= SCSI_MAX_READ_BLK;
+               } else {
+                       pccb->datalen = scsi_dev_desc[device].blksz * blks;
+                       smallblks = (unsigned short)blks;
+                       scsi_setup_read_ext(pccb, start, smallblks);
+                       start += blks;
+                       blks = 0;
+               }
+               debug("scsi_read_ext: startblk " LBAF
+                     ", blccnt %x buffer %" PRIXPTR "\n",
+                     start, smallblks, buf_addr);
+               if (scsi_exec(pccb) != true) {
+                       scsi_print_error(pccb);
+                       blkcnt -= blks;
+                       break;
+               }
+               buf_addr += pccb->datalen;
+       } while (blks != 0);
+       debug("scsi_read_ext: end startblk " LBAF
+             ", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr);
+       return blkcnt;
+}
+
+/*******************************************************************************
+ * scsi_write
+ */
+
+/* Almost the maximum amount of the scsi_ext command.. */
+#define SCSI_MAX_WRITE_BLK 0xFFFF
+
+#ifdef CONFIG_BLK
+static ulong scsi_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+                       const void *buffer)
+#else
+static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
+                       lbaint_t blkcnt, const void *buffer)
+#endif
+{
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
+       int device = block_dev->devnum;
+       lbaint_t start, blks;
+       uintptr_t buf_addr;
+       unsigned short smallblks;
+       ccb *pccb = (ccb *)&tempccb;
+
+       device &= 0xff;
+
+       /* Setup device */
+       pccb->target = scsi_dev_desc[device].target;
+       pccb->lun = scsi_dev_desc[device].lun;
+       buf_addr = (unsigned long)buffer;
+       start = blknr;
+       blks = blkcnt;
+       debug("\n%s: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
+             __func__, device, start, blks, (unsigned long)buffer);
+       do {
+               pccb->pdata = (unsigned char *)buf_addr;
+               if (blks > SCSI_MAX_WRITE_BLK) {
+                       pccb->datalen = (scsi_dev_desc[device].blksz *
+                                        SCSI_MAX_WRITE_BLK);
+                       smallblks = SCSI_MAX_WRITE_BLK;
+                       scsi_setup_write_ext(pccb, start, smallblks);
+                       start += SCSI_MAX_WRITE_BLK;
+                       blks -= SCSI_MAX_WRITE_BLK;
+               } else {
+                       pccb->datalen = scsi_dev_desc[device].blksz * blks;
+                       smallblks = (unsigned short)blks;
+                       scsi_setup_write_ext(pccb, start, smallblks);
+                       start += blks;
+                       blks = 0;
+               }
+               debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
+                     __func__, start, smallblks, buf_addr);
+               if (scsi_exec(pccb) != true) {
+                       scsi_print_error(pccb);
+                       blkcnt -= blks;
+                       break;
+               }
+               buf_addr += pccb->datalen;
+       } while (blks != 0);
+       debug("%s: end startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
+             __func__, start, smallblks, buf_addr);
+       return blkcnt;
+}
+
+int scsi_get_disk_count(void)
+{
+       return scsi_max_devs;
+}
+
+#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
+void scsi_init(void)
+{
+       int busdevfunc = -1;
+       int i;
+       /*
+        * Find a device from the list, this driver will support a single
+        * controller.
+        */
+       for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
+               /* get PCI Device ID */
+#ifdef CONFIG_DM_PCI
+               struct udevice *dev;
+               int ret;
+
+               ret = dm_pci_find_device(scsi_device_list[i].vendor,
+                                        scsi_device_list[i].device, 0, &dev);
+               if (!ret) {
+                       busdevfunc = dm_pci_get_bdf(dev);
+                       break;
+               }
+#else
+               busdevfunc = pci_find_device(scsi_device_list[i].vendor,
+                                            scsi_device_list[i].device,
+                                            0);
+#endif
+               if (busdevfunc != -1)
+                       break;
+       }
+
+       if (busdevfunc == -1) {
+               printf("Error: SCSI Controller(s) ");
+               for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
+                       printf("%04X:%04X ",
+                              scsi_device_list[i].vendor,
+                              scsi_device_list[i].device);
+               }
+               printf("not found\n");
+               return;
+       }
+#ifdef DEBUG
+       else {
+               printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",
+                      scsi_device_list[i].vendor,
+                      scsi_device_list[i].device,
+                      (busdevfunc >> 16) & 0xFF,
+                      (busdevfunc >> 11) & 0x1F,
+                      (busdevfunc >> 8) & 0x7);
+       }
+#endif
+       bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
+       scsi_low_level_init(busdevfunc);
+       scsi_scan(1);
+       bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
+}
+#endif
+
+/* copy src to dest, skipping leading and trailing blanks
+ * and null terminate the string
+ */
+void scsi_ident_cpy(unsigned char *dest, unsigned char *src, unsigned int len)
+{
+       int start, end;
+
+       start = 0;
+       while (start < len) {
+               if (src[start] != ' ')
+                       break;
+               start++;
+       }
+       end = len-1;
+       while (end > start) {
+               if (src[end] != ' ')
+                       break;
+               end--;
+       }
+       for (; start <= end; start++)
+               *dest ++= src[start];
+       *dest = '\0';
+}
+
+
+/* Trim trailing blanks, and NUL-terminate string
+ */
+void scsi_trim_trail(unsigned char *str, unsigned int len)
+{
+       unsigned char *p = str + len - 1;
+
+       while (len-- > 0) {
+               *p-- = '\0';
+               if (*p != ' ')
+                       return;
+       }
+}
+
+int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
+{
+       *capacity = 0;
+
+       memset(pccb->cmd, '\0', sizeof(pccb->cmd));
+       pccb->cmd[0] = SCSI_RD_CAPAC10;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmdlen = 10;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+
+       pccb->datalen = 8;
+       if (scsi_exec(pccb) != true)
+               return 1;
+
+       *capacity = ((lbaint_t)pccb->pdata[0] << 24) |
+                   ((lbaint_t)pccb->pdata[1] << 16) |
+                   ((lbaint_t)pccb->pdata[2] << 8)  |
+                   ((lbaint_t)pccb->pdata[3]);
+
+       if (*capacity != 0xffffffff) {
+               /* Read capacity (10) was sufficient for this drive. */
+               *blksz = ((unsigned long)pccb->pdata[4] << 24) |
+                        ((unsigned long)pccb->pdata[5] << 16) |
+                        ((unsigned long)pccb->pdata[6] << 8)  |
+                        ((unsigned long)pccb->pdata[7]);
+               return 0;
+       }
+
+       /* Read capacity (10) was insufficient. Use read capacity (16). */
+       memset(pccb->cmd, '\0', sizeof(pccb->cmd));
+       pccb->cmd[0] = SCSI_RD_CAPAC16;
+       pccb->cmd[1] = 0x10;
+       pccb->cmdlen = 16;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+
+       pccb->datalen = 16;
+       if (scsi_exec(pccb) != true)
+               return 1;
+
+       *capacity = ((uint64_t)pccb->pdata[0] << 56) |
+                   ((uint64_t)pccb->pdata[1] << 48) |
+                   ((uint64_t)pccb->pdata[2] << 40) |
+                   ((uint64_t)pccb->pdata[3] << 32) |
+                   ((uint64_t)pccb->pdata[4] << 24) |
+                   ((uint64_t)pccb->pdata[5] << 16) |
+                   ((uint64_t)pccb->pdata[6] << 8)  |
+                   ((uint64_t)pccb->pdata[7]);
+
+       *blksz = ((uint64_t)pccb->pdata[8]  << 56) |
+                ((uint64_t)pccb->pdata[9]  << 48) |
+                ((uint64_t)pccb->pdata[10] << 40) |
+                ((uint64_t)pccb->pdata[11] << 32) |
+                ((uint64_t)pccb->pdata[12] << 24) |
+                ((uint64_t)pccb->pdata[13] << 16) |
+                ((uint64_t)pccb->pdata[14] << 8)  |
+                ((uint64_t)pccb->pdata[15]);
+
+       return 0;
+}
+
+
+/*
+ * Some setup (fill-in) routines
+ */
+void scsi_setup_test_unit_ready(ccb *pccb)
+{
+       pccb->cmd[0] = SCSI_TST_U_RDY;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = 0;
+       pccb->cmd[3] = 0;
+       pccb->cmd[4] = 0;
+       pccb->cmd[5] = 0;
+       pccb->cmdlen = 6;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+}
+
+/*
+ * (re)-scan the scsi bus and reports scsi device info
+ * to the user if mode = 1
+ */
+void scsi_scan(int mode)
+{
+       unsigned char i, perq, modi, lun;
+       lbaint_t capacity;
+       unsigned long blksz;
+       ccb *pccb = (ccb *)&tempccb;
+
+       if (mode == 1)
+               printf("scanning bus for devices...\n");
+       for (i = 0; i < CONFIG_SYS_SCSI_MAX_DEVICE; i++) {
+               scsi_dev_desc[i].target = 0xff;
+               scsi_dev_desc[i].lun = 0xff;
+               scsi_dev_desc[i].lba = 0;
+               scsi_dev_desc[i].blksz = 0;
+               scsi_dev_desc[i].log2blksz =
+                       LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));
+               scsi_dev_desc[i].type = DEV_TYPE_UNKNOWN;
+               scsi_dev_desc[i].vendor[0] = 0;
+               scsi_dev_desc[i].product[0] = 0;
+               scsi_dev_desc[i].revision[0] = 0;
+               scsi_dev_desc[i].removable = false;
+               scsi_dev_desc[i].if_type = IF_TYPE_SCSI;
+               scsi_dev_desc[i].devnum = i;
+               scsi_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+#ifndef CONFIG_BLK
+               scsi_dev_desc[i].block_read = scsi_read;
+               scsi_dev_desc[i].block_write = scsi_write;
+#endif
+       }
+       scsi_max_devs = 0;
+       for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
+               pccb->target = i;
+               for (lun = 0; lun < CONFIG_SYS_SCSI_MAX_LUN; lun++) {
+                       pccb->lun = lun;
+                       pccb->pdata = (unsigned char *)&tempbuff;
+                       pccb->datalen = 512;
+                       scsi_setup_inquiry(pccb);
+                       if (scsi_exec(pccb) != true) {
+                               if (pccb->contr_stat == SCSI_SEL_TIME_OUT) {
+                                       /*
+                                        * selection timeout => assuming no
+                                        * device present
+                                        */
+                                       debug("Selection timeout ID %d\n",
+                                             pccb->target);
+                                       continue;
+                               }
+                               scsi_print_error(pccb);
+                               continue;
+                       }
+                       perq = tempbuff[0];
+                       modi = tempbuff[1];
+                       if ((perq & 0x1f) == 0x1f)
+                               continue; /* skip unknown devices */
+                       if ((modi & 0x80) == 0x80) /* drive is removable */
+                               scsi_dev_desc[scsi_max_devs].removable = true;
+                       /* get info for this device */
+                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc
+                                               [scsi_max_devs].vendor[0],
+                                      &tempbuff[8], 8);
+                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc
+                                               [scsi_max_devs].product[0],
+                                      &tempbuff[16], 16);
+                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc
+                                               [scsi_max_devs].revision[0],
+                                      &tempbuff[32], 4);
+                       scsi_dev_desc[scsi_max_devs].target = pccb->target;
+                       scsi_dev_desc[scsi_max_devs].lun = pccb->lun;
+
+                       pccb->datalen = 0;
+                       scsi_setup_test_unit_ready(pccb);
+                       if (scsi_exec(pccb) != true) {
+                               if (scsi_dev_desc[scsi_max_devs].removable) {
+                                       scsi_dev_desc[scsi_max_devs].type =
+                                                       perq;
+                                       goto removable;
+                               }
+                               scsi_print_error(pccb);
+                               continue;
+                       }
+                       if (scsi_read_capacity(pccb, &capacity, &blksz)) {
+                               scsi_print_error(pccb);
+                               continue;
+                       }
+                       scsi_dev_desc[scsi_max_devs].lba = capacity;
+                       scsi_dev_desc[scsi_max_devs].blksz = blksz;
+                       scsi_dev_desc[scsi_max_devs].log2blksz =
+                               LOG2(scsi_dev_desc[scsi_max_devs].blksz);
+                       scsi_dev_desc[scsi_max_devs].type = perq;
+                       part_init(&scsi_dev_desc[scsi_max_devs]);
+removable:
+                       if (mode == 1) {
+                               printf("  Device %d: ", scsi_max_devs);
+                               dev_print(&scsi_dev_desc[scsi_max_devs]);
+                       } /* if mode */
+                       scsi_max_devs++;
+               } /* next LUN */
+       }
+       if (scsi_max_devs > 0)
+               scsi_curr_dev = 0;
+       else
+               scsi_curr_dev = -1;
+
+       printf("Found %d device(s).\n", scsi_max_devs);
+#ifndef CONFIG_SPL_BUILD
+       setenv_ulong("scsidevs", scsi_max_devs);
+#endif
+}
+
+#ifdef CONFIG_BLK
+static const struct blk_ops scsi_blk_ops = {
+       .read   = scsi_read,
+       .write  = scsi_write,
+};
+
+U_BOOT_DRIVER(scsi_blk) = {
+       .name           = "scsi_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &scsi_blk_ops,
+};
+#else
+U_BOOT_LEGACY_BLK(scsi) = {
+       .if_typename    = "sata",
+       .if_type        = IF_TYPE_SCSI,
+       .max_devs       = CONFIG_SYS_SCSI_MAX_DEVICE,
+       .desc           = scsi_dev_desc,
+};
+#endif
index 338ea2f092b8dc9b250626efc91d44e68716e199..5b0d96925ed4436a64f171b82f8a56f5e9a778f7 100644 (file)
@@ -58,7 +58,7 @@ int spl_load_image_fat(struct blk_desc *block_dev,
                goto end;
 
        err = spl_parse_image_header(header);
-       if (err <= 0)
+       if (err)
                goto end;
 
        err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0);
index 1a5c0275a70c161257b79554cbc09fe8ed04ec3f..26842ba285cea51eeae81c73fd290300f447d6ab 100644 (file)
@@ -39,8 +39,13 @@ static int spl_fit_select_fdt(const void *fdt, int images, int *fdt_offsetp)
             node >= 0;
             node = fdt_next_subnode(fdt, node)) {
                name = fdt_getprop(fdt, node, "description", &len);
-               if (!name)
+               if (!name) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+                       printf("%s: Missing FDT description in DTB\n",
+                              __func__);
+#endif
                        return -EINVAL;
+               }
                if (board_fit_config_name_match(name))
                        continue;
 
index 360c754050f2821c479056d8f32830461a957cfe..5676acdde3f282da8062d0c679c02116d590b969 100644 (file)
@@ -300,7 +300,7 @@ int spl_mmc_load_image(u32 boot_device)
                        if (part == 7)
                                part = 0;
 
-                       err = mmc_switch_part(0, part);
+                       err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
                        if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                                puts("spl: mmc partition switch failed\n");
index 1719946ec5f0d7fbc0a7e2ec2d753ed0b0a640a6..9d8cc7c2ddf7a75eb9da4c61f1ca38216277f153 100644 (file)
@@ -34,7 +34,7 @@ int spl_sata_load_image(void)
        } else {
                /* try to recognize storage devices immediately */
                scsi_scan(0);
-               stor_dev = scsi_get_dev(0);
+               stor_dev = blk_get_devnum_by_type(IF_TYPE_SCSI, 0);
                if (!stor_dev)
                        return -ENODEV;
        }
index c42848e6fc84800bc2a5f49e3380af37b16a924f..04fa66758cbc0255da1fa97632dd655aeb1dd918 100644 (file)
@@ -39,7 +39,7 @@ int spl_usb_load_image(void)
 #ifdef CONFIG_USB_STORAGE
        /* try to recognize storage devices immediately */
        usb_stor_curr_dev = usb_stor_scan(1);
-       stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, usb_stor_curr_dev);
        if (!stor_dev)
                return -ENODEV;
 #endif
index 9285c95c0553b719016f6edf38ecc6c82f486c74..7e6e52d2ec37a2383935721332a31e2636317e98 100644 (file)
@@ -136,23 +136,6 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
 #endif
 void uhci_show_temp_int_td(void);
 
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *usb_stor_get_dev(int index)
-{
-#ifdef CONFIG_BLK
-       struct udevice *dev;
-       int ret;
-
-       ret = blk_get_device(IF_TYPE_USB, index, &dev);
-       if (ret)
-               return NULL;
-       return dev_get_uclass_platdata(dev);
-#else
-       return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL;
-#endif
-}
-#endif
-
 static void usb_show_progress(void)
 {
        debug(".");
@@ -217,7 +200,6 @@ static int usb_stor_probe_device(struct usb_device *udev)
 
 #ifdef CONFIG_BLK
        struct us_data *data;
-       char dev_name[30], *str;
        int ret;
 #else
        int start;
@@ -240,14 +222,12 @@ static int usb_stor_probe_device(struct usb_device *udev)
        for (lun = 0; lun <= max_lun; lun++) {
                struct blk_desc *blkdev;
                struct udevice *dev;
+               char str[10];
 
-               snprintf(dev_name, sizeof(dev_name), "%s.lun%d",
-                        udev->dev->name, lun);
-               str = strdup(dev_name);
-               if (!str)
-                       return -ENOMEM;
-               ret = blk_create_device(udev->dev, "usb_storage_blk", str,
-                               IF_TYPE_USB, usb_max_devs, 512, 0, &dev);
+               snprintf(str, sizeof(str), "lun%d", lun);
+               ret = blk_create_devicef(udev->dev, "usb_storage_blk", str,
+                                        IF_TYPE_USB, usb_max_devs, 512, 0,
+                                        &dev);
                if (ret) {
                        debug("Cannot bind driver\n");
                        return ret;
@@ -1555,4 +1535,11 @@ U_BOOT_DRIVER(usb_storage_blk) = {
        .id             = UCLASS_BLK,
        .ops            = &usb_storage_ops,
 };
+#else
+U_BOOT_LEGACY_BLK(usb) = {
+       .if_typename    = "usb",
+       .if_type        = IF_TYPE_USB,
+       .max_devs       = USB_MAX_STOR_DEV,
+       .desc           = usb_dev_desc,
+};
 #endif
diff --git a/configs/ap121_defconfig b/configs/ap121_defconfig
new file mode 100644 (file)
index 0000000..7604e2e
--- /dev/null
@@ -0,0 +1,47 @@
+CONFIG_MIPS=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DM_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_ARCH_ATH79=y
+CONFIG_DEFAULT_DEVICE_TREE="ap121"
+CONFIG_SYS_PROMPT="ap121 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_DATAFLASH=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_AR933X_PINCTRL=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_AR933X=y
+CONFIG_DEBUG_UART_BASE=0xb8020000
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_AR933X_UART=y
+CONFIG_ATH79_SPI=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_OF_LIBFDT=y
diff --git a/configs/ap143_defconfig b/configs/ap143_defconfig
new file mode 100644 (file)
index 0000000..1aa6e5d
--- /dev/null
@@ -0,0 +1,47 @@
+CONFIG_MIPS=y
+CONFIG_SYS_MALLOC_F_LEN=0x800
+CONFIG_DM_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_ARCH_ATH79=y
+CONFIG_TARGET_AP143=y
+CONFIG_DEFAULT_DEVICE_TREE="ap143"
+CONFIG_SYS_PROMPT="ap143 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_DATAFLASH=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PINCTRL=y
+CONFIG_QCA953X_PINCTRL=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0xb8020000
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_SYS_NS16550=y
+CONFIG_ATH79_SPI=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_OF_LIBFDT=y
index 85af09eeb65ccc1d7a0f16abffbe3ca5e0f3d8d1..07a6a1855e7cecab985f94abf93212aa02054ca1 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_CLK=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SYS_NS16550=y
index aa9bf336b14fd65405d0f60b9d71530d6aad4af4..01a51432ace6d45e1ee60b1f62b85c8621958ce1 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_CLK=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SYS_NS16550=y
index cc49dc976fedca30db1aa43a020df20aac2dc709..d46cd3bfa8b6726c8d399a329c5d6d31ce62ed5c 100644 (file)
@@ -2,6 +2,7 @@ CONFIG_ARM=y
 CONFIG_ARCH_MX6=y
 CONFIG_TARGET_PICO_IMX6UL=y
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/technexion/pico-imx6ul/imximage.cfg"
+CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
index afdf4a3ba7159430cbd7b85391dbb2b0abc09521..aec2e538a19ff0f0ffb4eda211d98519cf9fb366 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_MMC=y
 CONFIG_PCI=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
 CONFIG_I8042_KEYB=y
@@ -97,6 +98,7 @@ CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_RESET=y
 CONFIG_DM_MMC=y
+CONFIG_SANDBOX_MMC=y
 CONFIG_SPI_FLASH_SANDBOX=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
new file mode 100644 (file)
index 0000000..93167c2
--- /dev/null
@@ -0,0 +1,168 @@
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_PCI=y
+CONFIG_DEFAULT_DEVICE_TREE="sandbox"
+CONFIG_I8042_KEYB=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_BOOTSTAGE_USER_COUNT=0x20
+CONFIG_BOOTSTAGE_FDT=y
+CONFIG_BOOTSTAGE_STASH=y
+CONFIG_BOOTSTAGE_STASH_ADDR=0x0
+CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
+CONFIG_CONSOLE_RECORD=y
+CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_GREPENV=y
+CONFIG_LOOPW=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MX_CYCLIC=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_DEMO=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_TFTPSRV=y
+CONFIG_CMD_RARP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CDP=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SOUND=y
+CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_TPM_TEST=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_HOSTFILE=y
+CONFIG_NETCONSOLE=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_DEVRES=y
+CONFIG_DEBUG_DEVRES=y
+CONFIG_ADC=y
+CONFIG_ADC_SANDBOX=y
+CONFIG_CLK=y
+CONFIG_CPU=y
+CONFIG_DM_DEMO=y
+CONFIG_DM_DEMO_SIMPLE=y
+CONFIG_DM_DEMO_SHAPE=y
+CONFIG_PM8916_GPIO=y
+CONFIG_SANDBOX_GPIO=y
+CONFIG_DM_I2C_COMPAT=y
+CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_I2C_CROS_EC_LDO=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_SYS_I2C_SANDBOX=y
+CONFIG_I2C_MUX=y
+CONFIG_SPL_I2C_MUX=y
+CONFIG_I2C_ARB_GPIO_CHALLENGE=y
+CONFIG_CROS_EC_KEYB=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_CMD_CROS_EC=y
+CONFIG_CROS_EC=y
+CONFIG_CROS_EC_I2C=y
+CONFIG_CROS_EC_LPC=y
+CONFIG_CROS_EC_SANDBOX=y
+CONFIG_CROS_EC_SPI=y
+CONFIG_PWRSEQ=y
+CONFIG_SPL_PWRSEQ=y
+CONFIG_RESET=y
+CONFIG_DM_MMC=y
+CONFIG_SPI_FLASH_SANDBOX=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_ETH=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_SANDBOX=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_ROCKCHIP_3036_PINCTRL=y
+CONFIG_PINCTRL_SANDBOX=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_ACT8846=y
+CONFIG_DM_PMIC_PFUZE100=y
+CONFIG_DM_PMIC_MAX77686=y
+CONFIG_PMIC_PM8916=y
+CONFIG_PMIC_RK808=y
+CONFIG_PMIC_S2MPS11=y
+CONFIG_DM_PMIC_SANDBOX=y
+CONFIG_PMIC_S5M8767=y
+CONFIG_PMIC_TPS65090=y
+CONFIG_DM_REGULATOR=y
+CONFIG_REGULATOR_ACT8846=y
+CONFIG_DM_REGULATOR_PFUZE100=y
+CONFIG_DM_REGULATOR_MAX77686=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK808=y
+CONFIG_REGULATOR_S5M8767=y
+CONFIG_DM_REGULATOR_SANDBOX=y
+CONFIG_REGULATOR_TPS65090=y
+CONFIG_RAM=y
+CONFIG_REMOTEPROC_SANDBOX=y
+CONFIG_DM_RTC=y
+CONFIG_SANDBOX_SERIAL=y
+CONFIG_SOUND=y
+CONFIG_SOUND_SANDBOX=y
+CONFIG_SANDBOX_SPI=y
+CONFIG_SPMI=y
+CONFIG_SPMI_SANDBOX=y
+CONFIG_TIMER=y
+CONFIG_TIMER_EARLY=y
+CONFIG_SANDBOX_TIMER=y
+CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EMUL=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_SYS_USB_EVENT_POLL=y
+CONFIG_DM_VIDEO=y
+CONFIG_CONSOLE_ROTATION=y
+CONFIG_CONSOLE_TRUETYPE=y
+CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
+CONFIG_VIDEO_SANDBOX_SDL=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_TPM=y
+CONFIG_LZ4=y
+CONFIG_ERRNO_STR=y
+CONFIG_UNIT_TEST=y
+CONFIG_UT_TIME=y
+CONFIG_UT_DM=y
+CONFIG_UT_ENV=y
index 9a7c0915697d4e61989f4da96efa4a55954c4875..a662e72cc7a835f771c47cc37c1da548bea88159 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index ac81854f4062b422f9d2545a5803a22fea408e99..b2933f778a0bd0c043ecf643c5b35c4c8e09722f 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index 405d9d407932f0ac70ed00c56b5fbcc513bdf6da..f197b6d2b008b2a6e2efba418fe0da5d03adf7f9 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
index 36154901aa4deb3f3996b7e394b151197d86bd3d..6624f9e07d0badea706f1396ca6aa67d4c8b762f 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
index bdc8e6b26d9581effdcec701237de71ba58df2b5..c6414f8be5397af92922b29806d3dcbe74ff8e1d 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index a17e9d0fd981459b2440f6e05ce3096631060dfd..b47a5602b80a04873996ec3ed42746162ec3ebfd 100644 (file)
@@ -34,6 +34,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index c4b215ad1f855b22565adbdc9cc4aaa746515e69..aab4498973666da8c79e224c4e863a68c16b516c 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DWAPB_GPIO=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_DM_MMC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
index af2f54486a86559dc92a9ee5cfe70b49cfe50089..db3b6ea6c507c804fb060d650b418ca8784e2aae 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 6c53e1f0b5970b5a87b7ba757bb5afec7ec92f91..ea4e8d772a3b7c18d65b1ba283cd94095989848e 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 6827701ce34c06aa86f34cf9f0144d41e2b933b3..a2b56f384a0faafd5078293746827bbeb563311f 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 477a22603355add34e29e129b6b74f4a9d120c76..173848959d6b8cfad972089df9858f3babe0b5ac 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 0991f8ecb6611a1f7c1d71ce4bcb67bcc80319ce..a6064a5d90df1261e4e1db2b9b3a82f09e8ca767 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index ef30a6785baa99d4229cf369072e08723383272a..85944c68f15ab053e66444cc8e2002558b138f65 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 6cfe22088cb66672903992b308e66fee181c17d2..48efe3d948fca128c3e04f3f8ad8b0b9fb65210d 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index c0d8edffea836872a19b49857f35db537ca691bb..8edbe0c257aceb90e4b1a66151e6ae28e6b5efa4 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index e9d14cec140a7415e94c80ef982c9e1cd1a8f306..b622f742dbfcbcb2a46c5c51ac86801000039bc7 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 2e46e641831b7cd703890b5e57ca57e361acd684..241a72acf538d73745d4b774836f4c4c09c70d90 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 8dba79ad84153056fc5ab673ca6e6e23678ce386..49d7c0439577888c211c5838678585c4bd55e090 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 7f33c78fedbca131bd84787e85ae8ae1a4aa2edb..70b3025fc52811c76b885a66d1f52337646eb0b0 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index f7d37253e0793bf3e8323da246ac71c1faae59b0..5ced0e17bd46f5b4414039493af2dd9c15844021 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 9e4125374d3e16806f3339148e9a69ced44a9aab..de75b17df51df5dc56b9a5f0817368a705092f4a 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index e61c74e5b367cc2de19fc13397bbd6af32012d68..2202d2eaf41b9d4faf1237f0c93ed048101c5bf6 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 741009349a17f61e4c4dd10bee7318aec9f82a2b..35bb0364af6790f3d26b3c8466047facb7ff786e 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index f0e041fdda4aa2e88bd511d34758f508874692f7..f54083984b28b212dc9b6d57a78a3cd69103d566 100644 (file)
@@ -9,5 +9,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index cc4067d1c3a0888cf5f15599a66e383c6134364c..de416d91a8f93eaa6e34c657d98bf6c398f8a19a 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index df2135577752d8e441a8baa0ae6c196cdf17c19c..8b6e0d0acd5a51740785bf95e0de60b5ca70907d 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
index 48140aa467e95c60331970221e34de1c88ec66bd..e8b4b0a6590c8ff2090ed74d7827f3db0d82b6e0 100644 (file)
@@ -6,5 +6,6 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
diff --git a/configs/tplink_wdr4300_defconfig b/configs/tplink_wdr4300_defconfig
new file mode 100644 (file)
index 0000000..b1af2f6
--- /dev/null
@@ -0,0 +1,43 @@
+CONFIG_MIPS=y
+CONFIG_ARCH_ATH79=y
+CONFIG_BOARD_TPLINK_WDR4300=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEFAULT_DEVICE_TREE="tplink_wdr4300"
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_NET=y
+CONFIG_CMD_NFS=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DM_ETH=y
+CONFIG_AG7XXX=y
+CONFIG_CLK=y
+CONFIG_CMD_USB=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_STORAGE=y
+CONFIG_ATH79_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_DATAFLASH=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PINCTRL=y
index 1a07b9d536ca26d07182768710fa42b9699f9d42..ace620ba3a63c328215475d033536fb13ad13156 100644 (file)
@@ -17,6 +17,7 @@ CONFIG_CMD_PING=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SYS_I2C_DW=y
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_USE_TINY_PRINTF=y
index 543cab8103204e0bc8fcba57e8b1b0474b4fe1bd..6a1c02d9fada7410c953cd144c2ea6968fb3a200 100644 (file)
 #define PRINTF(fmt,args...)
 #endif
 
-const struct block_drvr block_drvr[] = {
-#if defined(CONFIG_CMD_IDE)
-       { .name = "ide", .get_dev = ide_get_dev, },
-#endif
-#if defined(CONFIG_CMD_SATA)
-       {.name = "sata", .get_dev = sata_get_dev, },
-#endif
-#if defined(CONFIG_CMD_SCSI)
-       { .name = "scsi", .get_dev = scsi_get_dev, },
-#endif
-#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
-       { .name = "usb", .get_dev = usb_stor_get_dev, },
-#endif
-#if defined(CONFIG_MMC)
-       {
-               .name = "mmc",
-               .get_dev = mmc_get_dev,
-               .select_hwpart = mmc_select_hwpart,
-       },
-#endif
-#if defined(CONFIG_SYSTEMACE)
-       { .name = "ace", .get_dev = systemace_get_dev, },
-#endif
-#if defined(CONFIG_SANDBOX)
-       { .name = "host", .get_dev = host_get_dev, },
-#endif
-       { },
-};
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef HAVE_BLOCK_DEVICE
@@ -71,45 +42,23 @@ static struct part_driver *part_driver_lookup_type(int part_type)
 
 static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
 {
-       const struct block_drvr *drvr = block_drvr;
-       struct blk_desc* (*reloc_get_dev)(int dev);
-       int (*select_hwpart)(int dev_num, int hwpart);
-       char *name;
+       struct blk_desc *dev_desc;
        int ret;
 
-       if (!ifname)
+       dev_desc = blk_get_devnum_by_typename(ifname, dev);
+       if (!dev_desc) {
+               debug("%s: No device for iface '%s', dev %d\n", __func__,
+                     ifname, dev);
                return NULL;
-
-       name = drvr->name;
-#ifdef CONFIG_NEEDS_MANUAL_RELOC
-       name += gd->reloc_off;
-#endif
-       while (drvr->name) {
-               name = drvr->name;
-               reloc_get_dev = drvr->get_dev;
-               select_hwpart = drvr->select_hwpart;
-#ifdef CONFIG_NEEDS_MANUAL_RELOC
-               name += gd->reloc_off;
-               reloc_get_dev += gd->reloc_off;
-               if (select_hwpart)
-                       select_hwpart += gd->reloc_off;
-#endif
-               if (strncmp(ifname, name, strlen(name)) == 0) {
-                       struct blk_desc *dev_desc = reloc_get_dev(dev);
-                       if (!dev_desc)
-                               return NULL;
-                       if (hwpart == 0 && !select_hwpart)
-                               return dev_desc;
-                       if (!select_hwpart)
-                               return NULL;
-                       ret = select_hwpart(dev_desc->devnum, hwpart);
-                       if (ret < 0)
-                               return NULL;
-                       return dev_desc;
-               }
-               drvr++;
        }
-       return NULL;
+       ret = blk_dselect_hwpart(dev_desc, hwpart);
+       if (ret) {
+               debug("%s: Failed to select h/w partition: err-%d\n", __func__,
+                     ret);
+               return NULL;
+       }
+
+       return dev_desc;
 }
 
 struct blk_desc *blk_get_dev(const char *ifname, int dev)
@@ -401,7 +350,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
        if (*ep) {
                printf("** Bad device specification %s %s **\n",
                       ifname, dev_str);
-               dev = -1;
+               dev = -EINVAL;
                goto cleanup;
        }
 
@@ -410,7 +359,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
                if (*ep) {
                        printf("** Bad HW partition specification %s %s **\n",
                            ifname, hwpart_str);
-                       dev = -1;
+                       dev = -EINVAL;
                        goto cleanup;
                }
        }
@@ -418,7 +367,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
        *dev_desc = get_dev_hwpart(ifname, dev, hwpart);
        if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
                printf("** Bad device %s %s **\n", ifname, dev_hwpart_str);
-               dev = -1;
+               dev = -ENOENT;
                goto cleanup;
        }
 
diff --git a/doc/device-tree-bindings/serial/qca,ar9330-uart.txt b/doc/device-tree-bindings/serial/qca,ar9330-uart.txt
new file mode 100644 (file)
index 0000000..ec576a1
--- /dev/null
@@ -0,0 +1,24 @@
+* Qualcomm Atheros AR9330 High-Speed UART
+
+Required properties:
+
+- compatible: Must be "qca,ar9330-uart"
+
+- reg: Specifies the physical base address of the controller and
+  the length of the memory mapped region.
+
+Additional requirements:
+
+  Each UART port must have an alias correctly numbered in "aliases"
+  node.
+
+Example:
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       uart0: uart@18020000 {
+               compatible = "qca,ar9330-uart";
+               reg = <0x18020000 0x14>;
+       };
diff --git a/doc/device-tree-bindings/spi/spi-ath79.txt b/doc/device-tree-bindings/spi/spi-ath79.txt
new file mode 100644 (file)
index 0000000..3fd9d67
--- /dev/null
@@ -0,0 +1,19 @@
+Binding for Qualcomm Atheros AR7xxx/AR9xxx SPI controller
+
+Required properties:
+- compatible: has to be "qca,<soc-type>-spi", "qca,ar7100-spi" as fallback.
+- reg: Base address and size of the controllers memory area
+- #address-cells: <1>, as required by generic SPI binding.
+- #size-cells: <0>, also as required by generic SPI binding.
+
+Child nodes as per the generic SPI binding.
+
+Example:
+
+       spi@1f000000 {
+               compatible = "qca,ar9132-spi", "qca,ar7100-spi";
+               reg = <0x1f000000 0x10>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
index 6900097e79986785d3d6f1e4691f9614780073ff..99dd07fc7698f4f463840f0050ed3c138d4dbd42 100644 (file)
@@ -36,6 +36,8 @@ obj-$(CONFIG_SPL_WATCHDOG_SUPPORT) += watchdog/
 obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += usb/host/
 obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/
 obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
+obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += block/
+obj-$(CONFIG_SPL_MMC_SUPPORT) += block/
 
 else
 
index fcc9ccdd7f85e159a8886ce258db80d54e7f3c44..80eea84dc29731c96a48a2fd8814cd511375806b 100644 (file)
@@ -9,10 +9,9 @@ config BLK
          be partitioned into several areas, called 'partitions' in U-Boot.
          A filesystem can be placed in each partition.
 
-config DISK
-       bool "Support disk controllers with driver model"
+config AHCI
+       bool "Support SATA controllers with driver model"
        depends on DM
-       default y if DM
        help
          This enables a uclass for disk controllers in U-Boot. Various driver
          types can use this, such as AHCI/SATA. It does not provide any standard
index a43492f208207c915692a87206ea97b4ce8c24e8..436b79f9816562102d0b1becac7067a2d5fc329f 100644 (file)
@@ -7,7 +7,11 @@
 
 obj-$(CONFIG_BLK) += blk-uclass.o
 
-obj-$(CONFIG_DISK) += disk-uclass.o
+ifndef CONFIG_BLK
+obj-y += blk_legacy.o
+endif
+
+obj-$(CONFIG_AHCI) += ahci-uclass.o
 obj-$(CONFIG_SCSI_AHCI) += ahci.o
 obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
 obj-$(CONFIG_FSL_SATA) += fsl_sata.o
@@ -22,7 +26,7 @@ obj-$(CONFIG_SATA_MV) += sata_mv.o
 obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
 obj-$(CONFIG_SATA_SIL) += sata_sil.o
 obj-$(CONFIG_IDE_SIL680) += sil680.o
-obj-$(CONFIG_SANDBOX) += sandbox.o
+obj-$(CONFIG_SANDBOX) += sandbox.o sandbox_scsi.o sata_sandbox.o
 obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
 obj-$(CONFIG_SYSTEMACE) += systemace.o
 obj-$(CONFIG_BLOCK_CACHE) += blkcache.o
diff --git a/drivers/block/ahci-uclass.c b/drivers/block/ahci-uclass.c
new file mode 100644 (file)
index 0000000..7b8c326
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+
+UCLASS_DRIVER(ahci) = {
+       .id             = UCLASS_AHCI,
+       .name           = "ahci",
+};
index 617db226a2480e069286ab462a2c85e1c4473829..6ba1026f5818efc61f69182112a79fd60d75fa1a 100644 (file)
 #include <dm/device-internal.h>
 #include <dm/lists.h>
 
+static const char *if_typename_str[IF_TYPE_COUNT] = {
+       [IF_TYPE_IDE]           = "ide",
+       [IF_TYPE_SCSI]          = "scsi",
+       [IF_TYPE_ATAPI]         = "atapi",
+       [IF_TYPE_USB]           = "usb",
+       [IF_TYPE_DOC]           = "doc",
+       [IF_TYPE_MMC]           = "mmc",
+       [IF_TYPE_SD]            = "sd",
+       [IF_TYPE_SATA]          = "sata",
+       [IF_TYPE_HOST]          = "host",
+       [IF_TYPE_SYSTEMACE]     = "ace",
+};
+
+static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
+       [IF_TYPE_IDE]           = UCLASS_INVALID,
+       [IF_TYPE_SCSI]          = UCLASS_INVALID,
+       [IF_TYPE_ATAPI]         = UCLASS_INVALID,
+       [IF_TYPE_USB]           = UCLASS_MASS_STORAGE,
+       [IF_TYPE_DOC]           = UCLASS_INVALID,
+       [IF_TYPE_MMC]           = UCLASS_MMC,
+       [IF_TYPE_SD]            = UCLASS_INVALID,
+       [IF_TYPE_SATA]          = UCLASS_AHCI,
+       [IF_TYPE_HOST]          = UCLASS_ROOT,
+       [IF_TYPE_SYSTEMACE]     = UCLASS_INVALID,
+};
+
+static enum if_type if_typename_to_iftype(const char *if_typename)
+{
+       int i;
+
+       for (i = 0; i < IF_TYPE_COUNT; i++) {
+               if (if_typename_str[i] &&
+                   !strcmp(if_typename, if_typename_str[i]))
+                       return i;
+       }
+
+       return IF_TYPE_UNKNOWN;
+}
+
+static enum uclass_id if_type_to_uclass_id(enum if_type if_type)
+{
+       return if_type_uclass_id[if_type];
+}
+
+struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
+{
+       struct blk_desc *desc;
+       struct udevice *dev;
+       int ret;
+
+       ret = blk_get_device(if_type, devnum, &dev);
+       if (ret)
+               return NULL;
+       desc = dev_get_uclass_platdata(dev);
+
+       return desc;
+}
+
+/*
+ * This function is complicated with driver model. We look up the interface
+ * name in a local table. This gives us an interface type which we can match
+ * against the uclass of the block device's parent.
+ */
+struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
+{
+       enum uclass_id uclass_id;
+       enum if_type if_type;
+       struct udevice *dev;
+       struct uclass *uc;
+       int ret;
+
+       if_type = if_typename_to_iftype(if_typename);
+       if (if_type == IF_TYPE_UNKNOWN) {
+               debug("%s: Unknown interface type '%s'\n", __func__,
+                     if_typename);
+               return NULL;
+       }
+       uclass_id = if_type_to_uclass_id(if_type);
+       if (uclass_id == UCLASS_INVALID) {
+               debug("%s: Unknown uclass for interface type'\n",
+                     if_typename_str[if_type]);
+               return NULL;
+       }
+
+       ret = uclass_get(UCLASS_BLK, &uc);
+       if (ret)
+               return NULL;
+       uclass_foreach_dev(dev, uc) {
+               struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+               debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
+                     if_type, devnum, dev->name, desc->if_type, desc->devnum);
+               if (desc->devnum != devnum)
+                       continue;
+
+               /* Find out the parent device uclass */
+               if (device_get_uclass_id(dev->parent) != uclass_id) {
+                       debug("%s: parent uclass %d, this dev %d\n", __func__,
+                             device_get_uclass_id(dev->parent), uclass_id);
+                       continue;
+               }
+
+               if (device_probe(dev))
+                       return NULL;
+
+               debug("%s: Device desc %p\n", __func__, desc);
+               return desc;
+       }
+       debug("%s: No device found\n", __func__);
+
+       return NULL;
+}
+
+/**
+ * get_desc() - Get the block device descriptor for the given device number
+ *
+ * @if_type:   Interface type
+ * @devnum:    Device number (0 = first)
+ * @descp:     Returns block device descriptor on success
+ * @return 0 on success, -ENODEV if there is no such device and no device
+ * with a higher device number, -ENOENT if there is no such device but there
+ * is one with a higher number, or other -ve on other error.
+ */
+static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp)
+{
+       bool found_more = false;
+       struct udevice *dev;
+       struct uclass *uc;
+       int ret;
+
+       *descp = NULL;
+       ret = uclass_get(UCLASS_BLK, &uc);
+       if (ret)
+               return ret;
+       uclass_foreach_dev(dev, uc) {
+               struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+               debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
+                     if_type, devnum, dev->name, desc->if_type, desc->devnum);
+               if (desc->if_type == if_type) {
+                       if (desc->devnum == devnum) {
+                               ret = device_probe(dev);
+                               if (ret)
+                                       return ret;
+
+                       } else if (desc->devnum > devnum) {
+                               found_more = true;
+                       }
+               }
+       }
+
+       return found_more ? -ENOENT : -ENODEV;
+}
+
+int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = blk_get_device(if_type, devnum, &dev);
+       if (ret)
+               return ret;
+
+       return blk_select_hwpart(dev, hwpart);
+}
+
+int blk_list_part(enum if_type if_type)
+{
+       struct blk_desc *desc;
+       int devnum, ok;
+       int ret;
+
+       for (ok = 0, devnum = 0;; ++devnum) {
+               ret = get_desc(if_type, devnum, &desc);
+               if (ret == -ENODEV)
+                       break;
+               else if (ret)
+                       continue;
+               if (desc->part_type != PART_TYPE_UNKNOWN) {
+                       ++ok;
+                       if (devnum)
+                               putc('\n');
+                       part_print(desc);
+               }
+       }
+       if (!ok)
+               return -ENODEV;
+
+       return 0;
+}
+
+int blk_print_part_devnum(enum if_type if_type, int devnum)
+{
+       struct blk_desc *desc;
+       int ret;
+
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret)
+               return ret;
+       if (desc->type == DEV_TYPE_UNKNOWN)
+               return -ENOENT;
+       part_print(desc);
+
+       return 0;
+}
+
+void blk_list_devices(enum if_type if_type)
+{
+       struct blk_desc *desc;
+       int ret;
+       int i;
+
+       for (i = 0;; ++i) {
+               ret = get_desc(if_type, i, &desc);
+               if (ret == -ENODEV)
+                       break;
+               else if (ret)
+                       continue;
+               if (desc->type == DEV_TYPE_UNKNOWN)
+                       continue;  /* list only known devices */
+               printf("Device %d: ", i);
+               dev_print(desc);
+       }
+}
+
+int blk_print_device_num(enum if_type if_type, int devnum)
+{
+       struct blk_desc *desc;
+       int ret;
+
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret)
+               return ret;
+       printf("\nIDE device %d: ", devnum);
+       dev_print(desc);
+
+       return 0;
+}
+
+int blk_show_device(enum if_type if_type, int devnum)
+{
+       struct blk_desc *desc;
+       int ret;
+
+       printf("\nDevice %d: ", devnum);
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret == -ENODEV || ret == -ENOENT) {
+               printf("unknown device\n");
+               return -ENODEV;
+       }
+       if (ret)
+               return ret;
+       dev_print(desc);
+
+       if (desc->type == DEV_TYPE_UNKNOWN)
+               return -ENOENT;
+
+       return 0;
+}
+
+ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                     lbaint_t blkcnt, void *buffer)
+{
+       struct blk_desc *desc;
+       ulong n;
+       int ret;
+
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret)
+               return ret;
+       n = blk_dread(desc, start, blkcnt, buffer);
+       if (IS_ERR_VALUE(n))
+               return n;
+
+       /* flush cache after read */
+       flush_cache((ulong)buffer, blkcnt * desc->blksz);
+
+       return n;
+}
+
+ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                      lbaint_t blkcnt, const void *buffer)
+{
+       struct blk_desc *desc;
+       int ret;
+
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret)
+               return ret;
+       return blk_dwrite(desc, start, blkcnt, buffer);
+}
+
+int blk_select_hwpart(struct udevice *dev, int hwpart)
+{
+       const struct blk_ops *ops = blk_get_ops(dev);
+
+       if (!ops)
+               return -ENOSYS;
+       if (!ops->select_hwpart)
+               return 0;
+
+       return ops->select_hwpart(dev, hwpart);
+}
+
+int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
+{
+       return blk_select_hwpart(desc->bdev, hwpart);
+}
+
 int blk_first_device(int if_type, struct udevice **devp)
 {
        struct blk_desc *desc;
@@ -131,6 +440,26 @@ int blk_prepare_device(struct udevice *dev)
        return 0;
 }
 
+int blk_find_max_devnum(enum if_type if_type)
+{
+       struct udevice *dev;
+       int max_devnum = -ENODEV;
+       struct uclass *uc;
+       int ret;
+
+       ret = uclass_get(UCLASS_BLK, &uc);
+       if (ret)
+               return ret;
+       uclass_foreach_dev(dev, uc) {
+               struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+               if (desc->if_type == if_type && desc->devnum > max_devnum)
+                       max_devnum = desc->devnum;
+       }
+
+       return max_devnum;
+}
+
 int blk_create_device(struct udevice *parent, const char *drv_name,
                      const char *name, int if_type, int devnum, int blksz,
                      lbaint_t size, struct udevice **devp)
@@ -139,6 +468,15 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
        struct udevice *dev;
        int ret;
 
+       if (devnum == -1) {
+               ret = blk_find_max_devnum(if_type);
+               if (ret == -ENODEV)
+                       devnum = 0;
+               else if (ret < 0)
+                       return ret;
+               else
+                       devnum = ret + 1;
+       }
        ret = device_bind_driver(parent, drv_name, name, &dev);
        if (ret)
                return ret;
@@ -154,6 +492,29 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
        return 0;
 }
 
+int blk_create_devicef(struct udevice *parent, const char *drv_name,
+                      const char *name, int if_type, int devnum, int blksz,
+                      lbaint_t size, struct udevice **devp)
+{
+       char dev_name[30], *str;
+       int ret;
+
+       snprintf(dev_name, sizeof(dev_name), "%s.%s", parent->name, name);
+       str = strdup(dev_name);
+       if (!str)
+               return -ENOMEM;
+
+       ret = blk_create_device(parent, drv_name, str, if_type, devnum,
+                               blksz, size, devp);
+       if (ret) {
+               free(str);
+               return ret;
+       }
+       device_set_name_alloced(*devp);
+
+       return ret;
+}
+
 int blk_unbind_all(int if_type)
 {
        struct uclass *uc;
diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c
new file mode 100644 (file)
index 0000000..7b90a8a
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/err.h>
+
+struct blk_driver *blk_driver_lookup_type(int if_type)
+{
+       struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
+       const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
+       struct blk_driver *entry;
+
+       for (entry = drv; entry != drv + n_ents; entry++) {
+               if (if_type == entry->if_type)
+                       return entry;
+       }
+
+       /* Not found */
+       return NULL;
+}
+
+static struct blk_driver *blk_driver_lookup_typename(const char *if_typename)
+{
+       struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
+       const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
+       struct blk_driver *entry;
+
+       for (entry = drv; entry != drv + n_ents; entry++) {
+               if (!strcmp(if_typename, entry->if_typename))
+                       return entry;
+       }
+
+       /* Not found */
+       return NULL;
+}
+
+/**
+ * get_desc() - Get the block device descriptor for the given device number
+ *
+ * @drv:       Legacy block driver
+ * @devnum:    Device number (0 = first)
+ * @descp:     Returns block device descriptor on success
+ * @return 0 on success, -ENODEV if there is no such device, -ENOSYS if the
+ * driver does not provide a way to find a device, or other -ve on other
+ * error.
+ */
+static int get_desc(struct blk_driver *drv, int devnum, struct blk_desc **descp)
+{
+       if (drv->desc) {
+               if (devnum < 0 || devnum >= drv->max_devs)
+                       return -ENODEV;
+               *descp = &drv->desc[devnum];
+               return 0;
+       }
+       if (!drv->get_dev)
+               return -ENOSYS;
+
+       return drv->get_dev(devnum, descp);
+}
+
+#ifdef HAVE_BLOCK_DEVICE
+int blk_list_part(enum if_type if_type)
+{
+       struct blk_driver *drv;
+       struct blk_desc *desc;
+       int devnum, ok;
+       bool first = true;
+
+       drv = blk_driver_lookup_type(if_type);
+       if (!drv)
+               return -ENOSYS;
+       for (ok = 0, devnum = 0; devnum < drv->max_devs; ++devnum) {
+               if (get_desc(drv, devnum, &desc))
+                       continue;
+               if (desc->part_type != PART_TYPE_UNKNOWN) {
+                       ++ok;
+                       if (!first)
+                               putc('\n');
+                       part_print(desc);
+                       first = false;
+               }
+       }
+       if (!ok)
+               return -ENODEV;
+
+       return 0;
+}
+
+int blk_print_part_devnum(enum if_type if_type, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       if (desc->type == DEV_TYPE_UNKNOWN)
+               return -ENOENT;
+       part_print(desc);
+
+       return 0;
+}
+
+void blk_list_devices(enum if_type if_type)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int i;
+
+       if (!drv)
+               return;
+       for (i = 0; i < drv->max_devs; ++i) {
+               if (get_desc(drv, i, &desc))
+                       continue;
+               if (desc->type == DEV_TYPE_UNKNOWN)
+                       continue;  /* list only known devices */
+               printf("Device %d: ", i);
+               dev_print(desc);
+       }
+}
+
+int blk_print_device_num(enum if_type if_type, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       printf("\n%s device %d: ", drv->if_typename, devnum);
+       dev_print(desc);
+
+       return 0;
+}
+
+int blk_show_device(enum if_type if_type, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       printf("\nDevice %d: ", devnum);
+       if (devnum >= drv->max_devs) {
+               puts("unknown device\n");
+               return -ENODEV;
+       }
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       dev_print(desc);
+
+       if (desc->type == DEV_TYPE_UNKNOWN)
+               return -ENOENT;
+
+       return 0;
+}
+#endif /* HAVE_BLOCK_DEVICE */
+
+struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+
+       if (!drv)
+               return NULL;
+
+       if (get_desc(drv, devnum, &desc))
+               return NULL;
+
+       return desc;
+}
+
+int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(desc->if_type);
+
+       if (!drv)
+               return -ENOSYS;
+       if (drv->select_hwpart)
+               return drv->select_hwpart(desc, hwpart);
+
+       return 0;
+}
+
+struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_typename(if_typename);
+       struct blk_desc *desc;
+
+       if (!drv)
+               return NULL;
+
+       if (get_desc(drv, devnum, &desc))
+               return NULL;
+
+       return desc;
+}
+
+ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                     lbaint_t blkcnt, void *buffer)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       ulong n;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       n = desc->block_read(desc, start, blkcnt, buffer);
+       if (IS_ERR_VALUE(n))
+               return n;
+
+       /* flush cache after read */
+       flush_cache((ulong)buffer, blkcnt * desc->blksz);
+
+       return n;
+}
+
+ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                      lbaint_t blkcnt, const void *buffer)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       return desc->block_write(desc, start, blkcnt, buffer);
+}
+
+int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       return drv->select_hwpart(desc, hwpart);
+}
diff --git a/drivers/block/disk-uclass.c b/drivers/block/disk-uclass.c
deleted file mode 100644 (file)
index d665b35..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2015 Google, Inc
- * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-
-UCLASS_DRIVER(disk) = {
-       .id             = UCLASS_DISK,
-       .name           = "disk",
-};
index 2d340efd32b520492cc2ccfd20be140d8babd9a2..ac28f834724490b23670ac3a3361310f53ee5c0a 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_BLK
+static struct host_block_dev host_devices[CONFIG_HOST_MAX_DEVICES];
+
+static struct host_block_dev *find_host_device(int dev)
+{
+       if (dev >= 0 && dev < CONFIG_HOST_MAX_DEVICES)
+               return &host_devices[dev];
+
+       return NULL;
+}
+#endif
+
+#ifdef CONFIG_BLK
 static unsigned long host_block_read(struct udevice *dev,
                                     unsigned long start, lbaint_t blkcnt,
                                     void *buffer)
@@ -24,6 +37,18 @@ static unsigned long host_block_read(struct udevice *dev,
        struct host_block_dev *host_dev = dev_get_priv(dev);
        struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
 
+#else
+static unsigned long host_block_read(struct blk_desc *block_dev,
+                                    unsigned long start, lbaint_t blkcnt,
+                                    void *buffer)
+{
+       int dev = block_dev->devnum;
+       struct host_block_dev *host_dev = find_host_device(dev);
+
+       if (!host_dev)
+               return -1;
+#endif
+
        if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
                        -1) {
                printf("ERROR: Invalid block %lx\n", start);
@@ -35,12 +60,21 @@ static unsigned long host_block_read(struct udevice *dev,
        return -1;
 }
 
+#ifdef CONFIG_BLK
 static unsigned long host_block_write(struct udevice *dev,
                                      unsigned long start, lbaint_t blkcnt,
                                      const void *buffer)
 {
        struct host_block_dev *host_dev = dev_get_priv(dev);
        struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#else
+static unsigned long host_block_write(struct blk_desc *block_dev,
+                                     unsigned long start, lbaint_t blkcnt,
+                                     const void *buffer)
+{
+       int dev = block_dev->devnum;
+       struct host_block_dev *host_dev = find_host_device(dev);
+#endif
 
        if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
                        -1) {
@@ -53,6 +87,7 @@ static unsigned long host_block_write(struct udevice *dev,
        return -1;
 }
 
+#ifdef CONFIG_BLK
 int host_dev_bind(int devnum, char *filename)
 {
        struct host_block_dev *host_dev;
@@ -115,9 +150,51 @@ err:
        free(str);
        return ret;
 }
+#else
+int host_dev_bind(int dev, char *filename)
+{
+       struct host_block_dev *host_dev = find_host_device(dev);
+
+       if (!host_dev)
+               return -1;
+       if (host_dev->blk_dev.priv) {
+               os_close(host_dev->fd);
+               host_dev->blk_dev.priv = NULL;
+       }
+       if (host_dev->filename)
+               free(host_dev->filename);
+       if (filename && *filename) {
+               host_dev->filename = strdup(filename);
+       } else {
+               host_dev->filename = NULL;
+               return 0;
+       }
+
+       host_dev->fd = os_open(host_dev->filename, OS_O_RDWR);
+       if (host_dev->fd == -1) {
+               printf("Failed to access host backing file '%s'\n",
+                      host_dev->filename);
+               return 1;
+       }
+
+       struct blk_desc *blk_dev = &host_dev->blk_dev;
+       blk_dev->if_type = IF_TYPE_HOST;
+       blk_dev->priv = host_dev;
+       blk_dev->blksz = 512;
+       blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz;
+       blk_dev->block_read = host_block_read;
+       blk_dev->block_write = host_block_write;
+       blk_dev->devnum = dev;
+       blk_dev->part_type = PART_TYPE_UNKNOWN;
+       part_init(blk_dev);
+
+       return 0;
+}
+#endif
 
 int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
 {
+#ifdef CONFIG_BLK
        struct udevice *dev;
        int ret;
 
@@ -125,20 +202,22 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
        if (ret)
                return ret;
        *blk_devp = dev_get_uclass_platdata(dev);
+#else
+       struct host_block_dev *host_dev = find_host_device(devnum);
 
-       return 0;
-}
+       if (!host_dev)
+               return -ENODEV;
 
-struct blk_desc *host_get_dev(int dev)
-{
-       struct blk_desc *blk_dev;
+       if (!host_dev->blk_dev.priv)
+               return -ENOENT;
 
-       if (host_get_dev_err(dev, &blk_dev))
-               return NULL;
+       *blk_devp = &host_dev->blk_dev;
+#endif
 
-       return blk_dev;
+       return 0;
 }
 
+#ifdef CONFIG_BLK
 static const struct blk_ops sandbox_host_blk_ops = {
        .read   = host_block_read,
        .write  = host_block_write,
@@ -150,3 +229,11 @@ U_BOOT_DRIVER(sandbox_host_blk) = {
        .ops            = &sandbox_host_blk_ops,
        .priv_auto_alloc_size   = sizeof(struct host_block_dev),
 };
+#else
+U_BOOT_LEGACY_BLK(sandbox_host) = {
+       .if_typename    = "host",
+       .if_type        = IF_TYPE_HOST,
+       .max_devs       = CONFIG_HOST_MAX_DEVICES,
+       .get_dev        = host_get_dev_err,
+};
+#endif
diff --git a/drivers/block/sandbox_scsi.c b/drivers/block/sandbox_scsi.c
new file mode 100644 (file)
index 0000000..ad961bd
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * This file contains dummy implementations of SCSI functions requried so
+ * that CONFIG_SCSI can be enabled for sandbox.
+ */
+
+#include <common.h>
+#include <scsi.h>
+
+void scsi_bus_reset(void)
+{
+}
+
+void scsi_init(void)
+{
+}
+
+int scsi_exec(ccb *pccb)
+{
+       return 0;
+}
+
+void scsi_print_error(ccb *pccb)
+{
+}
diff --git a/drivers/block/sata_sandbox.c b/drivers/block/sata_sandbox.c
new file mode 100644 (file)
index 0000000..bd967d2
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+
+int init_sata(int dev)
+{
+       return 0;
+}
+
+int reset_sata(int dev)
+{
+       return 0;
+}
+
+int scan_sata(int dev)
+{
+       return 0;
+}
+
+ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
+{
+       return 0;
+}
+
+ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
+{
+       return 0;
+}
index c7c40affaed11a7cde06994238f40e3721344f3f..5daede7279837b49eec2f57c88b3e4d1ba741c73 100644 (file)
@@ -33,7 +33,7 @@
 #define PRINTF(fmt,args...)
 #endif
 
-#if defined(CONFIG_CMD_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
+#if defined(CONFIG_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
 
 #undef SCSI_SINGLE_STEP
 /*
index 09fe834e2270ef8c765e12d111d91b31ad11ab83..9392beaf052eb419ffb9f106018fd0746032c80d 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <common.h>
 #include <command.h>
-#include <systemace.h>
+#include <dm.h>
 #include <part.h>
 #include <asm/io.h>
 
@@ -69,11 +69,9 @@ static u16 ace_readw(unsigned off)
        return in16(base + off);
 }
 
-static unsigned long systemace_read(struct blk_desc *block_dev,
-                                   unsigned long start, lbaint_t blkcnt,
-                                   void *buffer);
-
+#ifndef CONFIG_BLK
 static struct blk_desc systemace_dev = { 0 };
+#endif
 
 static int get_cf_lock(void)
 {
@@ -104,42 +102,19 @@ static void release_cf_lock(void)
        ace_writew((val & 0xffff), 0x18);
 }
 
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *systemace_get_dev(int dev)
-{
-       /* The first time through this, the systemace_dev object is
-          not yet initialized. In that case, fill it in. */
-       if (systemace_dev.blksz == 0) {
-               systemace_dev.if_type = IF_TYPE_UNKNOWN;
-               systemace_dev.devnum = 0;
-               systemace_dev.part_type = PART_TYPE_UNKNOWN;
-               systemace_dev.type = DEV_TYPE_HARDDISK;
-               systemace_dev.blksz = 512;
-               systemace_dev.log2blksz = LOG2(systemace_dev.blksz);
-               systemace_dev.removable = 1;
-               systemace_dev.block_read = systemace_read;
-
-               /*
-                * Ensure the correct bus mode (8/16 bits) gets enabled
-                */
-               ace_writew(width == 8 ? 0 : 0x0001, 0);
-
-               part_init(&systemace_dev);
-
-       }
-
-       return &systemace_dev;
-}
-#endif
-
 /*
  * This function is called (by dereferencing the block_read pointer in
  * the dev_desc) to read blocks of data. The return value is the
  * number of blocks read. A zero return indicates an error.
  */
+#ifdef CONFIG_BLK
+static unsigned long systemace_read(struct udevice *dev, unsigned long start,
+                                   lbaint_t blkcnt, void *buffer)
+#else
 static unsigned long systemace_read(struct blk_desc *block_dev,
                                    unsigned long start, lbaint_t blkcnt,
                                    void *buffer)
+#endif
 {
        int retry;
        unsigned blk_countdown;
@@ -257,3 +232,72 @@ static unsigned long systemace_read(struct blk_desc *block_dev,
 
        return blkcnt;
 }
+
+#ifdef CONFIG_BLK
+static int systemace_bind(struct udevice *dev)
+{
+       struct blk_desc *bdesc;
+       struct udevice *bdev;
+       int ret;
+
+       ret = blk_create_devicef(dev, "systemace_blk", "blk", IF_TYPE_SYSTEMACE,
+                                -1, 512, 0, &bdev);
+       if (ret) {
+               debug("Cannot create block device\n");
+               return ret;
+       }
+       bdesc = dev_get_uclass_platdata(bdev);
+       bdesc->removable = 1;
+       bdesc->part_type = PART_TYPE_UNKNOWN;
+       bdesc->log2blksz = LOG2(bdesc->blksz);
+
+       /* Ensure the correct bus mode (8/16 bits) gets enabled */
+       ace_writew(width == 8 ? 0 : 0x0001, 0);
+
+       return 0;
+}
+
+static const struct blk_ops systemace_blk_ops = {
+       .read   = systemace_read,
+};
+
+U_BOOT_DRIVER(systemace_blk) = {
+       .name           = "systemace_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &systemace_blk_ops,
+       .bind           = systemace_bind,
+};
+#else
+static int systemace_get_dev(int dev, struct blk_desc **descp)
+{
+       /* The first time through this, the systemace_dev object is
+          not yet initialized. In that case, fill it in. */
+       if (systemace_dev.blksz == 0) {
+               systemace_dev.if_type = IF_TYPE_UNKNOWN;
+               systemace_dev.devnum = 0;
+               systemace_dev.part_type = PART_TYPE_UNKNOWN;
+               systemace_dev.type = DEV_TYPE_HARDDISK;
+               systemace_dev.blksz = 512;
+               systemace_dev.log2blksz = LOG2(systemace_dev.blksz);
+               systemace_dev.removable = 1;
+               systemace_dev.block_read = systemace_read;
+
+               /*
+                * Ensure the correct bus mode (8/16 bits) gets enabled
+                */
+               ace_writew(width == 8 ? 0 : 0x0001, 0);
+
+               part_init(&systemace_dev);
+       }
+       *descp = &systemace_dev;
+
+       return 0;
+}
+
+U_BOOT_LEGACY_BLK(systemace) = {
+       .if_typename    = "ace",
+       .if_type        = IF_TYPE_SYSTEMACE,
+       .max_devs       = 1,
+       .get_dev        = systemace_get_dev,
+};
+#endif
index e1714b2202b64145291eabd024206e261d57e0f3..0e56b23fbbf44b059b6e38afd1c8366ee245e764 100644 (file)
@@ -112,6 +112,8 @@ int device_unbind(struct udevice *dev)
 
        devres_release_all(dev);
 
+       if (dev->flags & DM_NAME_ALLOCED)
+               free((char *)dev->name);
        free(dev);
 
        return 0;
index 1322991d6c7b6e0599679518543da7c5cdb7c5ad..5c2dc7021fb1623347e2dfb7f27a14aa76254a1e 100644 (file)
@@ -657,8 +657,8 @@ fdt_addr_t dev_get_addr_name(struct udevice *dev, const char *name)
 #if CONFIG_IS_ENABLED(OF_CONTROL)
        int index;
 
-       index = fdt_find_string(gd->fdt_blob, dev->parent->of_offset,
-                               "reg-names", name);
+       index = fdt_find_string(gd->fdt_blob, dev->of_offset, "reg-names",
+                               name);
        if (index < 0)
                return index;
 
@@ -706,12 +706,18 @@ bool device_is_last_sibling(struct udevice *dev)
        return list_is_last(&dev->sibling_node, &parent->child_head);
 }
 
+void device_set_name_alloced(struct udevice *dev)
+{
+       dev->flags |= DM_NAME_ALLOCED;
+}
+
 int device_set_name(struct udevice *dev, const char *name)
 {
        name = strdup(name);
        if (!name)
                return -ENOMEM;
        dev->name = name;
+       device_set_name_alloced(dev);
 
        return 0;
 }
index c4fc216340d8169dde8c05cdc0f9556e7ed9815b..a72db13a119aa4241c2f5dfa42ffd9551f1e15b2 100644 (file)
@@ -171,6 +171,10 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
 
                dm_dbg("   - found match at '%s'\n", entry->name);
                ret = device_bind(parent, entry, name, NULL, offset, &dev);
+               if (ret == -ENODEV) {
+                       dm_dbg("Driver '%s' refuses to bind\n", entry->name);
+                       continue;
+               }
                if (ret) {
                        dm_warn("Error binding driver '%s': %d\n", entry->name,
                                ret);
index ee05f57f43670409297cca0df0f14c9ac1de5a00..55baad498ae52770959c0dbbf888493bec0a6572 100644 (file)
@@ -678,7 +678,7 @@ u32 ddr3_get_device_width(u32 cs)
        return (device_width == 0) ? 8 : 16;
 }
 
-float ddr3_get_device_size(u32 cs)
+static int ddr3_get_device_size(u32 cs)
 {
        u32 device_size_low, device_size_high, device_size;
        u32 data, cs_low_offset, cs_high_offset;
@@ -695,15 +695,15 @@ float ddr3_get_device_size(u32 cs)
 
        switch (device_size) {
        case 0:
-               return 2;
+               return 2048;
        case 2:
-               return 0.5;
+               return 512;
        case 3:
-               return 1;
+               return 1024;
        case 4:
-               return 4;
+               return 4096;
        case 5:
-               return 8;
+               return 8192;
        case 1:
        default:
                DEBUG_INIT_C("Error: Wrong device size of Cs: ", cs, 1);
@@ -711,13 +711,13 @@ float ddr3_get_device_size(u32 cs)
                 * Small value will give wrong emem size in
                 * ddr3_calc_mem_cs_size
                 */
-               return 0.01;
+               return 0;
        }
 }
 
 int ddr3_calc_mem_cs_size(u32 cs, u32 *cs_size)
 {
-       float cs_mem_size;
+       int cs_mem_size;
 
        /* Calculate in GiB */
        cs_mem_size = ((ddr3_get_bus_width() / ddr3_get_device_width(cs)) *
@@ -731,21 +731,12 @@ int ddr3_calc_mem_cs_size(u32 cs, u32 *cs_size)
         */
        cs_mem_size *= DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER;
 
-       if (cs_mem_size == 0.125) {
-               *cs_size = 128 << 20;
-       } else if (cs_mem_size == 0.25) {
-               *cs_size = 256 << 20;
-       } else if (cs_mem_size == 0.5) {
-               *cs_size = 512 << 20;
-       } else if (cs_mem_size == 1) {
-               *cs_size = 1 << 30;
-       } else if (cs_mem_size == 2) {
-               *cs_size = 2 << 30;
-       } else {
+       if (!cs_mem_size || (cs_mem_size == 64) || (cs_mem_size == 4096)) {
                DEBUG_INIT_C("Error: Wrong Memory size of Cs: ", cs, 1);
                return MV_BAD_VALUE;
        }
 
+       *cs_size = cs_mem_size << 20;
        return MV_OK;
 }
 
index faece8883ac0a5bcf6b11a67d3425260d1b6a1b1..78724e467b24c7f816fef09767022bd8876b42a8 100644 (file)
@@ -50,8 +50,9 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
 
        if (dfu->data.mmc.hw_partition >= 0) {
                part_num_bkp = mmc->block_dev.hwpart;
-               ret = mmc_select_hwpart(dfu->data.mmc.dev_num,
-                                       dfu->data.mmc.hw_partition);
+               ret = blk_select_hwpart_devnum(IF_TYPE_MMC,
+                                              dfu->data.mmc.dev_num,
+                                              dfu->data.mmc.hw_partition);
                if (ret)
                        return ret;
        }
@@ -75,12 +76,16 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
        if (n != blk_count) {
                error("MMC operation failed");
                if (dfu->data.mmc.hw_partition >= 0)
-                       mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
+                       blk_select_hwpart_devnum(IF_TYPE_MMC,
+                                                dfu->data.mmc.dev_num,
+                                                part_num_bkp);
                return -EIO;
        }
 
        if (dfu->data.mmc.hw_partition >= 0) {
-               ret = mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
+               ret = blk_select_hwpart_devnum(IF_TYPE_MMC,
+                                              dfu->data.mmc.dev_num,
+                                              part_num_bkp);
                if (ret)
                        return ret;
        }
diff --git a/drivers/gpio/74x164_gpio.c b/drivers/gpio/74x164_gpio.c
new file mode 100644 (file)
index 0000000..9ac10a7
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Take drivers/gpio/gpio-74x164.c as reference.
+ *
+ * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver
+ *
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <spi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * struct gen_74x164_chip - Data for 74Hx164
+ *
+ * @oe: OE pin
+ * @nregs: number of registers
+ * @buffer: buffer for chained chips
+ */
+#define GEN_74X164_NUMBER_GPIOS 8
+
+struct gen_74x164_priv {
+       struct gpio_desc oe;
+       u32 nregs;
+       /*
+        * Since the nregs are chained, every byte sent will make
+        * the previous byte shift to the next register in the
+        * chain. Thus, the first byte sent will end up in the last
+        * register at the end of the transfer. So, to have a logical
+        * numbering, store the bytes in reverse order.
+        */
+       u8 *buffer;
+};
+
+static int gen_74x164_write_conf(struct udevice *dev)
+{
+       struct gen_74x164_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = dm_spi_claim_bus(dev);
+       if (ret)
+               return ret;
+
+       ret = dm_spi_xfer(dev, priv->nregs * 8, priv->buffer, NULL,
+                         SPI_XFER_BEGIN | SPI_XFER_END);
+
+       dm_spi_release_bus(dev);
+
+       return ret;
+}
+
+static int gen_74x164_get_value(struct udevice *dev, unsigned offset)
+{
+       struct gen_74x164_priv *priv = dev_get_priv(dev);
+       uint bank = priv->nregs - 1 - offset / 8;
+       uint pin = offset % 8;
+
+       return (priv->buffer[bank] >> pin) & 0x1;
+}
+
+static int gen_74x164_set_value(struct udevice *dev, unsigned offset,
+                               int value)
+{
+       struct gen_74x164_priv *priv = dev_get_priv(dev);
+       uint bank = priv->nregs - 1 - offset / 8;
+       uint pin = offset % 8;
+       int ret;
+
+       if (value)
+               priv->buffer[bank] |= 1 << pin;
+       else
+               priv->buffer[bank] &= ~(1 << pin);
+
+       ret = gen_74x164_write_conf(dev);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int gen_74x164_direction_input(struct udevice *dev, unsigned offset)
+{
+       return -ENOSYS;
+}
+
+static int gen_74x164_direction_output(struct udevice *dev, unsigned offset,
+                                     int value)
+{
+       return gen_74x164_set_value(dev, offset, value);
+}
+
+static int gen_74x164_get_function(struct udevice *dev, unsigned offset)
+{
+       return GPIOF_OUTPUT;
+}
+
+static int gen_74x164_xlate(struct udevice *dev, struct gpio_desc *desc,
+                           struct fdtdec_phandle_args *args)
+{
+       desc->offset = args->args[0];
+       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+       return 0;
+}
+
+static const struct dm_gpio_ops gen_74x164_ops = {
+       .direction_input        = gen_74x164_direction_input,
+       .direction_output       = gen_74x164_direction_output,
+       .get_value              = gen_74x164_get_value,
+       .set_value              = gen_74x164_set_value,
+       .get_function           = gen_74x164_get_function,
+       .xlate                  = gen_74x164_xlate,
+};
+
+static int gen_74x164_probe(struct udevice *dev)
+{
+       struct gen_74x164_priv *priv = dev_get_priv(dev);
+       struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+       char *str, name[32];
+       int ret;
+       const void *fdt = gd->fdt_blob;
+       int node = dev->of_offset;
+
+       snprintf(name, sizeof(name), "%s_", dev->name);
+       str = strdup(name);
+       if (!str)
+               return -ENOMEM;
+
+       /*
+        * See Linux kernel:
+        * Documentation/devicetree/bindings/gpio/gpio-74x164.txt
+        */
+       priv->nregs = fdtdec_get_int(fdt, node, "registers-number", 1);
+       priv->buffer = calloc(priv->nregs, sizeof(u8));
+       if (!priv->buffer) {
+               ret = -ENOMEM;
+               goto free_str;
+       }
+
+       ret = fdtdec_get_byte_array(fdt, node, "registers-default",
+                                   priv->buffer, priv->nregs);
+       if (ret)
+               dev_dbg(dev, "No registers-default property\n");
+
+       ret = gpio_request_by_name(dev, "oe-gpios", 0, &priv->oe,
+                                  GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+       if (ret) {
+               dev_err(dev, "No oe-pins property\n");
+               goto free_buf;
+       }
+
+       uc_priv->bank_name = str;
+       uc_priv->gpio_count = priv->nregs * 8;
+
+       ret = gen_74x164_write_conf(dev);
+       if (ret)
+               goto free_buf;
+
+       dev_dbg(dev, "%s is ready\n", dev->name);
+
+       return 0;
+
+free_buf:
+       free(priv->buffer);
+free_str:
+       free(str);
+       return ret;
+}
+
+static const struct udevice_id gen_74x164_ids[] = {
+       { .compatible = "fairchild,74hc595" },
+       { }
+};
+
+U_BOOT_DRIVER(74x164) = {
+       .name           = "74x164",
+       .id             = UCLASS_GPIO,
+       .ops            = &gen_74x164_ops,
+       .probe          = gen_74x164_probe,
+       .priv_auto_alloc_size = sizeof(struct gen_74x164_priv),
+       .of_match       = gen_74x164_ids,
+};
index 2b4624d7f8075c166916e9edb0784d630e97886c..93a7e8c6c23088772d5a3848664cd0eb54a38d40 100644 (file)
@@ -143,4 +143,34 @@ config ZYNQ_GPIO
        help
          Supports GPIO access on Zynq SoC.
 
+config DM_74X164
+       bool "74x164 serial-in/parallel-out 8-bits shift register"
+       depends on DM_GPIO
+       help
+         Driver for 74x164 compatible serial-in/parallel-out 8-outputs
+         shift registers, such as 74lv165, 74hc595.
+         This driver can be used to provide access to more gpio outputs.
+
+config DM_PCA953X
+       bool "PCA95[357]x, PCA9698, TCA64xx, and MAX7310 I/O ports"
+       depends on DM_GPIO
+       help
+         Say yes here to provide access to several register-oriented
+         SMBus I/O expanders, made mostly by NXP or TI.  Compatible
+         models include:
+
+         4 bits:       pca9536, pca9537
+
+         8 bits:       max7310, max7315, pca6107, pca9534, pca9538, pca9554,
+                       pca9556, pca9557, pca9574, tca6408, xra1202
+
+         16 bits:      max7312, max7313, pca9535, pca9539, pca9555, pca9575,
+                       tca6416
+
+         24 bits:      tca6424
+
+         40 bits:      pca9505, pca9698
+
+         Now, max 24 bits chips and PCA953X compatible chips are
+         supported
 endmenu
index 4f071c451727e1f24862c8e0936a20e71a48eb23..ddec1ef8dee8ac4db1374c7e665847b8dba1901b 100644 (file)
@@ -11,6 +11,9 @@ obj-$(CONFIG_AXP_GPIO)                += axp_gpio.o
 endif
 obj-$(CONFIG_DM_GPIO)          += gpio-uclass.o
 
+obj-$(CONFIG_DM_PCA953X)       += pca953x_gpio.o
+obj-$(CONFIG_DM_74X164)                += 74x164_gpio.o
+
 obj-$(CONFIG_AT91_GPIO)        += at91_gpio.o
 obj-$(CONFIG_ATMEL_PIO4)       += atmel_pio4.o
 obj-$(CONFIG_INTEL_ICH6_GPIO)  += intel_ich6_gpio.o
index b58d4e64e8ad92e51c52fe76f3ae5477180c540e..732b6c2afa12ac8b99b66ee97465971defeb1f73 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <dt-bindings/gpio/gpio.h>
 #include <errno.h>
 #include <fdtdec.h>
 #include <malloc.h>
@@ -113,19 +114,33 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
        return 0;
 }
 
+int gpio_xlate_offs_flags(struct udevice *dev,
+                                        struct gpio_desc *desc,
+                                        struct fdtdec_phandle_args *args)
+{
+       if (args->args_count < 1)
+               return -EINVAL;
+
+       desc->offset = args->args[0];
+
+       if (args->args_count < 2)
+               return 0;
+
+       if (args->args[1] & GPIO_ACTIVE_LOW)
+               desc->flags = GPIOD_ACTIVE_LOW;
+
+       return 0;
+}
+
 static int gpio_find_and_xlate(struct gpio_desc *desc,
                               struct fdtdec_phandle_args *args)
 {
        struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
 
-       /* Use the first argument as the offset by default */
-       if (args->args_count > 0)
-               desc->offset = args->args[0];
+       if (ops->xlate)
+               return ops->xlate(desc->dev, desc, args);
        else
-               desc->offset = -1;
-       desc->flags = 0;
-
-       return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
+               return gpio_xlate_offs_flags(desc->dev, desc, args);
 }
 
 int dm_gpio_request(struct gpio_desc *desc, const char *label)
@@ -605,6 +620,7 @@ static int _gpio_request_by_name_nodev(const void *blob, int node,
 
        desc->dev = NULL;
        desc->offset = 0;
+       desc->flags = 0;
        ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
                                             "#gpio-cells", 0, index, &args);
        if (ret) {
index 8cf76f96c276b2c77d6c9f41daa88a336db96f9a..81ce446e1a162d1e2c624e657623b1fc96714963 100644 (file)
@@ -162,15 +162,6 @@ static int broadwell_gpio_ofdata_to_platdata(struct udevice *dev)
        return 0;
 }
 
-static int broadwell_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                               struct fdtdec_phandle_args *args)
-{
-       desc->offset = args->args[0];
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static const struct dm_gpio_ops gpio_broadwell_ops = {
        .request                = broadwell_gpio_request,
        .direction_input        = broadwell_gpio_direction_input,
@@ -178,7 +169,6 @@ static const struct dm_gpio_ops gpio_broadwell_ops = {
        .get_value              = broadwell_gpio_get_value,
        .set_value              = broadwell_gpio_set_value,
        .get_function           = broadwell_gpio_get_function,
-       .xlate                  = broadwell_gpio_xlate,
 };
 
 static const struct udevice_id intel_broadwell_gpio_ids[] = {
index 93d18e44a54eb1a5dc57604dc52c795be3b56e3a..cd960dc013f0f128be8d625aab83996e3863eb65 100644 (file)
@@ -25,7 +25,6 @@
 #include <asm/io.h>
 #include <asm/errno.h>
 #include <malloc.h>
-#include <dt-bindings/gpio/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -277,22 +276,12 @@ static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
                return GPIOF_INPUT;
 }
 
-static int omap_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                          struct fdtdec_phandle_args *args)
-{
-       desc->offset = args->args[0];
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static const struct dm_gpio_ops gpio_omap_ops = {
        .direction_input        = omap_gpio_direction_input,
        .direction_output       = omap_gpio_direction_output,
        .get_value              = omap_gpio_get_value,
        .set_value              = omap_gpio_set_value,
        .get_function           = omap_gpio_get_function,
-       .xlate                  = omap_gpio_xlate,
 };
 
 static int omap_gpio_probe(struct udevice *dev)
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
new file mode 100644 (file)
index 0000000..987d10e
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * Take linux kernel driver drivers/gpio/gpio-pca953x.c for reference.
+ *
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+/*
+ * Note:
+ * The driver's compatible table is borrowed from Linux Kernel,
+ * but now max supported gpio pins is 24 and only PCA953X_TYPE
+ * is supported. PCA957X_TYPE is not supported now.
+ * Also the Polarity Inversion feature is not supported now.
+ *
+ * TODO:
+ * 1. Support PCA957X_TYPE
+ * 2. Support max 40 gpio pins
+ * 3. Support Plolarity Inversion
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <malloc.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#define PCA953X_INPUT           0
+#define PCA953X_OUTPUT          1
+#define PCA953X_INVERT          2
+#define PCA953X_DIRECTION       3
+
+#define PCA_GPIO_MASK           0x00FF
+#define PCA_INT                 0x0100
+#define PCA953X_TYPE            0x1000
+#define PCA957X_TYPE            0x2000
+#define PCA_TYPE_MASK           0xF000
+#define PCA_CHIP_TYPE(x)        ((x) & PCA_TYPE_MASK)
+
+enum {
+       PCA953X_DIRECTION_IN,
+       PCA953X_DIRECTION_OUT,
+};
+
+#define MAX_BANK 3
+#define BANK_SZ 8
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * struct pca953x_info - Data for pca953x
+ *
+ * @dev: udevice structure for the device
+ * @addr: i2c slave address
+ * @invert: Polarity inversion or not
+ * @gpio_count: the number of gpio pins that the device supports
+ * @chip_type: indicate the chip type,PCA953X or PCA957X
+ * @bank_count: the number of banks that the device supports
+ * @reg_output: array to hold the value of output registers
+ * @reg_direction: array to hold the value of direction registers
+ */
+struct pca953x_info {
+       struct udevice *dev;
+       int addr;
+       int invert;
+       int gpio_count;
+       int chip_type;
+       int bank_count;
+       u8 reg_output[MAX_BANK];
+       u8 reg_direction[MAX_BANK];
+};
+
+static int pca953x_write_single(struct udevice *dev, int reg, u8 val,
+                               int offset)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
+       int off = offset / BANK_SZ;
+       int ret = 0;
+
+       ret = dm_i2c_write(dev, (reg << bank_shift) + off, &val, 1);
+       if (ret) {
+               dev_err(dev, "%s error\n", __func__);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int pca953x_read_single(struct udevice *dev, int reg, u8 *val,
+                              int offset)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
+       int off = offset / BANK_SZ;
+       int ret;
+       u8 byte;
+
+       ret = dm_i2c_read(dev, (reg << bank_shift) + off, &byte, 1);
+       if (ret) {
+               dev_err(dev, "%s error\n", __func__);
+               return ret;
+       }
+
+       *val = byte;
+
+       return 0;
+}
+
+static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int ret = 0;
+
+       if (info->gpio_count <= 8) {
+               ret = dm_i2c_read(dev, reg, val, 1);
+       } else if (info->gpio_count <= 16) {
+               ret = dm_i2c_read(dev, reg << 1, val, info->bank_count);
+       } else {
+               dev_err(dev, "Unsupported now\n");
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static int pca953x_is_output(struct udevice *dev, int offset)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+
+       int bank = offset / BANK_SZ;
+       int off = offset % BANK_SZ;
+
+       /*0: output; 1: input */
+       return !(info->reg_direction[bank] & (1 << off));
+}
+
+static int pca953x_get_value(struct udevice *dev, unsigned offset)
+{
+       int ret;
+       u8 val = 0;
+
+       ret = pca953x_read_single(dev, PCA953X_INPUT, &val, offset);
+       if (ret)
+               return ret;
+
+       return (val >> offset) & 0x1;
+}
+
+static int pca953x_set_value(struct udevice *dev, unsigned offset,
+                            int value)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int bank = offset / BANK_SZ;
+       int off = offset % BANK_SZ;
+       u8 val;
+       int ret;
+
+       if (value)
+               val = info->reg_output[bank] | (1 << off);
+       else
+               val = info->reg_output[bank] & ~(1 << off);
+
+       ret = pca953x_write_single(dev, PCA953X_OUTPUT, val, offset);
+       if (ret)
+               return ret;
+
+       info->reg_output[bank] = val;
+
+       return 0;
+}
+
+static int pca953x_set_direction(struct udevice *dev, unsigned offset, int dir)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int bank = offset / BANK_SZ;
+       int off = offset % BANK_SZ;
+       u8 val;
+       int ret;
+
+       if (dir == PCA953X_DIRECTION_IN)
+               val = info->reg_direction[bank] | (1 << off);
+       else
+               val = info->reg_direction[bank] & ~(1 << off);
+
+       ret = pca953x_write_single(dev, PCA953X_DIRECTION, val, offset);
+       if (ret)
+               return ret;
+
+       info->reg_direction[bank] = val;
+
+       return 0;
+}
+
+static int pca953x_direction_input(struct udevice *dev, unsigned offset)
+{
+       return pca953x_set_direction(dev, offset, PCA953X_DIRECTION_IN);
+}
+
+static int pca953x_direction_output(struct udevice *dev, unsigned offset,
+                                   int value)
+{
+       /* Configure output value. */
+       pca953x_set_value(dev, offset, value);
+
+       /* Configure direction as output. */
+       pca953x_set_direction(dev, offset, PCA953X_DIRECTION_OUT);
+
+       return 0;
+}
+
+static int pca953x_get_function(struct udevice *dev, unsigned offset)
+{
+       if (pca953x_is_output(dev, offset))
+               return GPIOF_OUTPUT;
+       else
+               return GPIOF_INPUT;
+}
+
+static int pca953x_xlate(struct udevice *dev, struct gpio_desc *desc,
+                        struct fdtdec_phandle_args *args)
+{
+       desc->offset = args->args[0];
+       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+       return 0;
+}
+
+static const struct dm_gpio_ops pca953x_ops = {
+       .direction_input        = pca953x_direction_input,
+       .direction_output       = pca953x_direction_output,
+       .get_value              = pca953x_get_value,
+       .set_value              = pca953x_set_value,
+       .get_function           = pca953x_get_function,
+       .xlate                  = pca953x_xlate,
+};
+
+static int pca953x_probe(struct udevice *dev)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+       char name[32], *str;
+       int addr;
+       ulong driver_data;
+       int ret;
+
+       if (!info) {
+               dev_err(dev, "platdata not ready\n");
+               return -ENOMEM;
+       }
+
+       if (!chip) {
+               dev_err(dev, "i2c not ready\n");
+               return -ENODEV;
+       }
+
+       addr = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", 0);
+       if (addr == 0)
+               return -ENODEV;
+
+       info->addr = addr;
+
+       driver_data = dev_get_driver_data(dev);
+
+       info->gpio_count = driver_data & PCA_GPIO_MASK;
+       if (info->gpio_count > MAX_BANK * BANK_SZ) {
+               dev_err(dev, "Max support %d pins now\n", MAX_BANK * BANK_SZ);
+               return -EINVAL;
+       }
+
+       info->chip_type = PCA_CHIP_TYPE(driver_data);
+       if (info->chip_type != PCA953X_TYPE) {
+               dev_err(dev, "Only support PCA953X chip type now.\n");
+               return -EINVAL;
+       }
+
+       info->bank_count = DIV_ROUND_UP(info->gpio_count, BANK_SZ);
+
+       ret = pca953x_read_regs(dev, PCA953X_OUTPUT, info->reg_output);
+       if (ret) {
+               dev_err(dev, "Error reading output register\n");
+               return ret;
+       }
+
+       ret = pca953x_read_regs(dev, PCA953X_DIRECTION, info->reg_direction);
+       if (ret) {
+               dev_err(dev, "Error reading direction register\n");
+               return ret;
+       }
+
+       snprintf(name, sizeof(name), "gpio@%x_", info->addr);
+       str = strdup(name);
+       if (!str)
+               return -ENOMEM;
+       uc_priv->bank_name = str;
+       uc_priv->gpio_count = info->gpio_count;
+
+       dev_dbg(dev, "%s is ready\n", str);
+
+       return 0;
+}
+
+#define OF_953X(__nrgpio, __int) (ulong)(__nrgpio | PCA953X_TYPE | __int)
+#define OF_957X(__nrgpio, __int) (ulong)(__nrgpio | PCA957X_TYPE | __int)
+
+static const struct udevice_id pca953x_ids[] = {
+       { .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_INT), },
+       { .compatible = "nxp,pca9534", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "nxp,pca9535", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "nxp,pca9536", .data = OF_953X(4, 0), },
+       { .compatible = "nxp,pca9537", .data = OF_953X(4, PCA_INT), },
+       { .compatible = "nxp,pca9538", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "nxp,pca9539", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "nxp,pca9554", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "nxp,pca9555", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "nxp,pca9556", .data = OF_953X(8, 0), },
+       { .compatible = "nxp,pca9557", .data = OF_953X(8, 0), },
+       { .compatible = "nxp,pca9574", .data = OF_957X(8, PCA_INT), },
+       { .compatible = "nxp,pca9575", .data = OF_957X(16, PCA_INT), },
+       { .compatible = "nxp,pca9698", .data = OF_953X(40, 0), },
+
+       { .compatible = "maxim,max7310", .data = OF_953X(8, 0), },
+       { .compatible = "maxim,max7312", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "maxim,max7313", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "maxim,max7315", .data = OF_953X(8, PCA_INT), },
+
+       { .compatible = "ti,pca6107", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "ti,tca6408", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
+
+       { .compatible = "onsemi,pca9654", .data = OF_953X(8, PCA_INT), },
+
+       { .compatible = "exar,xra1202", .data = OF_953X(8, 0), },
+       { }
+};
+
+U_BOOT_DRIVER(pca953x) = {
+       .name           = "pca953x",
+       .id             = UCLASS_GPIO,
+       .ops            = &pca953x_ops,
+       .probe          = pca953x_probe,
+       .platdata_auto_alloc_size = sizeof(struct pca953x_info),
+       .of_match       = pca953x_ids,
+};
index 499b4fa5ad1e8fa56d550c665de862808a8acbb0..7a037f3a77cd1009d2ca495d4cc7d9a8530721e1 100644 (file)
@@ -12,7 +12,6 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 #include <linux/compat.h>
-#include <dt-bindings/gpio/gpio.h>
 #include <mach/pic32.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -99,14 +98,6 @@ static int pic32_gpio_direction_output(struct udevice *dev,
        return 0;
 }
 
-static int pic32_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                           struct fdtdec_phandle_args *args)
-{
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static int pic32_gpio_get_function(struct udevice *dev, unsigned offset)
 {
        int ret = GPIOF_UNUSED;
@@ -131,7 +122,6 @@ static const struct dm_gpio_ops gpio_pic32_ops = {
        .get_value              = pic32_gpio_get_value,
        .set_value              = pic32_gpio_set_value,
        .get_function           = pic32_gpio_get_function,
-       .xlate                  = pic32_gpio_xlate,
 };
 
 static int pic32_gpio_probe(struct udevice *dev)
index 40e87bd1996a4249008bc649f19a1c6f55e2877b..fefe3ca20359ab0b849fe4d6735cae92a4b08c8b 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <dm/pinctrl.h>
-#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 
 enum {
@@ -98,15 +97,6 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset)
 #endif
 }
 
-static int rockchip_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                           struct fdtdec_phandle_args *args)
-{
-       desc->offset = args->args[0];
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static int rockchip_gpio_probe(struct udevice *dev)
 {
        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
@@ -135,7 +125,6 @@ static const struct dm_gpio_ops gpio_rockchip_ops = {
        .get_value              = rockchip_gpio_get_value,
        .set_value              = rockchip_gpio_set_value,
        .get_function           = rockchip_gpio_get_function,
-       .xlate                  = rockchip_gpio_xlate,
 };
 
 static const struct udevice_id rockchip_gpio_ids[] = {
index 0f22b238ba99ec09679df0d8fe840f98632f55d4..377fed467fb323a5d4beb721a1ac7efc33f2eebb 100644 (file)
@@ -13,7 +13,6 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 #include <dm/device-internal.h>
-#include <dt-bindings/gpio/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -276,22 +275,12 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset)
                return GPIOF_FUNC;
 }
 
-static int exynos_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                            struct fdtdec_phandle_args *args)
-{
-       desc->offset = args->args[0];
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static const struct dm_gpio_ops gpio_exynos_ops = {
        .direction_input        = exynos_gpio_direction_input,
        .direction_output       = exynos_gpio_direction_output,
        .get_value              = exynos_gpio_get_value,
        .set_value              = exynos_gpio_set_value,
        .get_function           = exynos_gpio_get_function,
-       .xlate                  = exynos_gpio_xlate,
 };
 
 static int gpio_exynos_probe(struct udevice *dev)
index 9324c6c9e5f3aecfe65f6dc92b2e33d2b17f5e89..6e22bbadff2d54d24fd34f8500896ce970cec325 100644 (file)
@@ -58,6 +58,13 @@ config DM_I2C_GPIO
          bindings are supported.
          Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt
 
+config SYS_I2C_FSL
+       bool "Freescale I2C bus driver"
+       depends on DM_I2C
+       help
+         Add support for Freescale I2C busses as used on MPC8240, MPC8245, and
+         MPC85xx processors.
+
 config SYS_I2C_CADENCE
        tristate "Cadence I2C Controller"
        depends on DM_I2C && (ARCH_ZYNQ || ARM64)
@@ -65,6 +72,24 @@ config SYS_I2C_CADENCE
          Say yes here to select Cadence I2C Host Controller. This controller is
          e.g. used by Xilinx Zynq.
 
+config SYS_I2C_DW
+       bool "Designware I2C Controller"
+       default n
+       help
+         Say yes here to select the Designware I2C Host Controller. This
+         controller is used in various SoCs, e.g. the ST SPEAr, Altera
+         SoCFPGA, Synopsys ARC700 and some Intel x86 SoCs.
+
+config SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
+       bool "DW I2C Enable Status Register not supported"
+       depends on SYS_I2C_DW && (TARGET_SPEAR300 || TARGET_SPEAR310 || \
+               TARGET_SPEAR320 || TARGET_SPEAR600 || TARGET_X600)
+       default y
+       help
+         Some versions of the Designware I2C controller do not support the
+         enable status register. This config option can be enabled in such
+         cases.
+
 config SYS_I2C_INTEL
        bool "Intel I2C/SMBUS driver"
        depends on DM_I2C
index 0c7cd0ba727921e2dc49acaf761036bc7e511a86..e60fd0a41903b811a98f0bcc88bf6ac8ae9519de 100644 (file)
@@ -36,6 +36,14 @@ struct dw_i2c {
        struct dw_scl_sda_cfg *scl_sda_cfg;
 };
 
+#ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
+static void dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
+{
+       u32 ena = enable ? IC_ENABLE_0B : 0;
+
+       writel(ena, &i2c_base->ic_enable);
+}
+#else
 static void dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 {
        u32 ena = enable ? IC_ENABLE_0B : 0;
@@ -56,6 +64,7 @@ static void dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 
        printf("timeout in %sabling I2C adapter\n", enable ? "en" : "dis");
 }
+#endif
 
 /*
  * i2c_set_bus_speed - Set the i2c speed
index b56a1c2541d7165fbd2cc0ac7db7affe61c640d0..b8cc647bd3900c4375dea5dbf8277556f81bf969 100644 (file)
@@ -12,6 +12,8 @@
 #include <i2c.h>               /* Functional interface */
 #include <asm/io.h>
 #include <asm/fsl_i2c.h>       /* HW definitions */
+#include <dm.h>
+#include <mapmem.h>
 
 /* The maximum number of microseconds we will wait until another master has
  * released the bus.  If not defined in the board header file, then use a
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static const struct fsl_i2c *i2c_dev[4] = {
-       (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C_OFFSET),
+#ifndef CONFIG_DM_I2C
+static const struct fsl_i2c_base *i2c_base[4] = {
+       (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C_OFFSET),
 #ifdef CONFIG_SYS_FSL_I2C2_OFFSET
-       (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C2_OFFSET),
+       (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C2_OFFSET),
 #endif
 #ifdef CONFIG_SYS_FSL_I2C3_OFFSET
-       (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C3_OFFSET),
+       (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C3_OFFSET),
 #endif
 #ifdef CONFIG_SYS_FSL_I2C4_OFFSET
-       (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C4_OFFSET)
+       (struct fsl_i2c_base *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C4_OFFSET)
 #endif
 };
+#endif
 
 /* I2C speed map for a DFSR value of 1 */
 
@@ -104,7 +108,7 @@ static const struct {
 /**
  * Set the I2C bus speed for a given I2C device
  *
- * @param dev: the I2C device
+ * @param base: the I2C device registers
  * @i2c_clk: I2C bus clock frequency
  * @speed: the desired speed of the bus
  *
@@ -112,7 +116,7 @@ static const struct {
  *
  * The return value is the actual bus speed that is set.
  */
-static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
+static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
        unsigned int i2c_clk, unsigned int speed)
 {
        unsigned short divider = min(i2c_clk / speed, (unsigned int)USHRT_MAX);
@@ -173,8 +177,8 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
        debug("divider:%d, est_div:%ld, DFSR:%d\n", divider, est_div, dfsr);
        debug("FDR:0x%.2x, speed:%d\n", fdr, speed);
 #endif
-       writeb(dfsr, &dev->dfsrr);      /* set default filter */
-       writeb(fdr, &dev->fdr);         /* set bus speed */
+       writeb(dfsr, &base->dfsrr);     /* set default filter */
+       writeb(fdr, &base->fdr);        /* set bus speed */
 #else
        unsigned int i;
 
@@ -184,7 +188,7 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
 
                        fdr = fsl_i2c_speed_map[i].fdr;
                        speed = i2c_clk / fsl_i2c_speed_map[i].divider;
-                       writeb(fdr, &dev->fdr);         /* set bus speed */
+                       writeb(fdr, &base->fdr);        /* set bus speed */
 
                        break;
                }
@@ -192,6 +196,7 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
        return speed;
 }
 
+#ifndef CONFIG_DM_I2C
 static unsigned int get_i2c_clock(int bus)
 {
        if (bus)
@@ -199,8 +204,9 @@ static unsigned int get_i2c_clock(int bus)
        else
                return gd->arch.i2c1_clk;       /* I2C1 clock */
 }
+#endif
 
-static int fsl_i2c_fixup(const struct fsl_i2c *dev)
+static int fsl_i2c_fixup(const struct fsl_i2c_base *base)
 {
        const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
        unsigned long long timeval = 0;
@@ -214,42 +220,42 @@ static int fsl_i2c_fixup(const struct fsl_i2c *dev)
                flags = I2C_CR_BIT6;
 #endif
 
-       writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
+       writeb(I2C_CR_MEN | I2C_CR_MSTA, &base->cr);
 
        timeval = get_ticks();
-       while (!(readb(&dev->sr) & I2C_SR_MBB)) {
+       while (!(readb(&base->sr) & I2C_SR_MBB)) {
                if ((get_ticks() - timeval) > timeout)
                        goto err;
        }
 
-       if (readb(&dev->sr) & I2C_SR_MAL) {
+       if (readb(&base->sr) & I2C_SR_MAL) {
                /* SDA is stuck low */
-               writeb(0, &dev->cr);
+               writeb(0, &base->cr);
                udelay(100);
-               writeb(I2C_CR_MSTA | flags, &dev->cr);
-               writeb(I2C_CR_MEN | I2C_CR_MSTA | flags, &dev->cr);
+               writeb(I2C_CR_MSTA | flags, &base->cr);
+               writeb(I2C_CR_MEN | I2C_CR_MSTA | flags, &base->cr);
        }
 
-       readb(&dev->dr);
+       readb(&base->dr);
 
        timeval = get_ticks();
-       while (!(readb(&dev->sr) & I2C_SR_MIF)) {
+       while (!(readb(&base->sr) & I2C_SR_MIF)) {
                if ((get_ticks() - timeval) > timeout)
                        goto err;
        }
        ret = 0;
 
 err:
-       writeb(I2C_CR_MEN | flags, &dev->cr);
-       writeb(0, &dev->sr);
+       writeb(I2C_CR_MEN | flags, &base->cr);
+       writeb(0, &base->sr);
        udelay(100);
 
        return ret;
 }
 
-static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
+static void __i2c_init(const struct fsl_i2c_base *base, int speed, int
+                      slaveadd, int i2c_clk, int busnum)
 {
-       const struct fsl_i2c *dev;
        const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
        unsigned long long timeval;
 
@@ -260,23 +266,21 @@ static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
        */
        i2c_init_board();
 #endif
-       dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-
-       writeb(0, &dev->cr);            /* stop I2C controller */
+       writeb(0, &base->cr);           /* stop I2C controller */
        udelay(5);                      /* let it shutdown in peace */
-       set_i2c_bus_speed(dev, get_i2c_clock(adap->hwadapnr), speed);
-       writeb(slaveadd << 1, &dev->adr);/* write slave address */
-       writeb(0x0, &dev->sr);          /* clear status register */
-       writeb(I2C_CR_MEN, &dev->cr);   /* start I2C controller */
+       set_i2c_bus_speed(base, i2c_clk, speed);
+       writeb(slaveadd << 1, &base->adr);/* write slave address */
+       writeb(0x0, &base->sr);         /* clear status register */
+       writeb(I2C_CR_MEN, &base->cr);  /* start I2C controller */
 
        timeval = get_ticks();
-       while (readb(&dev->sr) & I2C_SR_MBB) {
+       while (readb(&base->sr) & I2C_SR_MBB) {
                if ((get_ticks() - timeval) < timeout)
                        continue;
 
-               if (fsl_i2c_fixup(dev))
+               if (fsl_i2c_fixup(base))
                        debug("i2c_init: BUS#%d failed to init\n",
-                             adap->hwadapnr);
+                             busnum);
 
                break;
        }
@@ -292,13 +296,12 @@ static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 }
 
 static int
-i2c_wait4bus(struct i2c_adapter *adap)
+i2c_wait4bus(const struct fsl_i2c_base *base)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
        unsigned long long timeval = get_ticks();
        const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
 
-       while (readb(&dev->sr) & I2C_SR_MBB) {
+       while (readb(&base->sr) & I2C_SR_MBB) {
                if ((get_ticks() - timeval) > timeout)
                        return -1;
        }
@@ -306,22 +309,21 @@ i2c_wait4bus(struct i2c_adapter *adap)
        return 0;
 }
 
-static __inline__ int
-i2c_wait(struct i2c_adapter *adap, int write)
+static inline int
+i2c_wait(const struct fsl_i2c_base *base, int write)
 {
        u32 csr;
        unsigned long long timeval = get_ticks();
        const unsigned long long timeout = usec2ticks(CONFIG_I2C_TIMEOUT);
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
 
        do {
-               csr = readb(&dev->sr);
+               csr = readb(&base->sr);
                if (!(csr & I2C_SR_MIF))
                        continue;
                /* Read again to allow register to stabilise */
-               csr = readb(&dev->sr);
+               csr = readb(&base->sr);
 
-               writeb(0x0, &dev->sr);
+               writeb(0x0, &base->sr);
 
                if (csr & I2C_SR_MAL) {
                        debug("i2c_wait: MAL\n");
@@ -345,203 +347,318 @@ i2c_wait(struct i2c_adapter *adap, int write)
        return -1;
 }
 
-static __inline__ int
-i2c_write_addr(struct i2c_adapter *adap, u8 dev, u8 dir, int rsta)
+static inline int
+i2c_write_addr(const struct fsl_i2c_base *base, u8 dev, u8 dir, int rsta)
 {
-       struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-
        writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
               | (rsta ? I2C_CR_RSTA : 0),
-              &device->cr);
+              &base->cr);
 
-       writeb((dev << 1) | dir, &device->dr);
+       writeb((dev << 1) | dir, &base->dr);
 
-       if (i2c_wait(adap, I2C_WRITE_BIT) < 0)
+       if (i2c_wait(base, I2C_WRITE_BIT) < 0)
                return 0;
 
        return 1;
 }
 
-static __inline__ int
-__i2c_write(struct i2c_adapter *adap, u8 *data, int length)
+static inline int
+__i2c_write_data(const struct fsl_i2c_base *base, u8 *data, int length)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
        int i;
 
        for (i = 0; i < length; i++) {
-               writeb(data[i], &dev->dr);
+               writeb(data[i], &base->dr);
 
-               if (i2c_wait(adap, I2C_WRITE_BIT) < 0)
+               if (i2c_wait(base, I2C_WRITE_BIT) < 0)
                        break;
        }
 
        return i;
 }
 
-static __inline__ int
-__i2c_read(struct i2c_adapter *adap, u8 *data, int length)
+static inline int
+__i2c_read_data(const struct fsl_i2c_base *base, u8 *data, int length)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
        int i;
 
        writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
-              &dev->cr);
+              &base->cr);
 
        /* dummy read */
-       readb(&dev->dr);
+       readb(&base->dr);
 
        for (i = 0; i < length; i++) {
-               if (i2c_wait(adap, I2C_READ_BIT) < 0)
+               if (i2c_wait(base, I2C_READ_BIT) < 0)
                        break;
 
                /* Generate ack on last next to last byte */
                if (i == length - 2)
                        writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
-                              &dev->cr);
+                              &base->cr);
 
                /* Do not generate stop on last byte */
                if (i == length - 1)
                        writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
-                              &dev->cr);
+                              &base->cr);
 
-               data[i] = readb(&dev->dr);
+               data[i] = readb(&base->dr);
        }
 
        return i;
 }
 
 static int
-fsl_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, int alen, u8 *data,
-            int length)
+__i2c_read(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
+          u8 *data, int dlen)
 {
-       struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-       int i = -1; /* signal error */
-       u8 *a = (u8*)&addr;
-       int len = alen * -1;
+       int ret = -1; /* signal error */
 
-       if (i2c_wait4bus(adap) < 0)
+       if (i2c_wait4bus(base) < 0)
                return -1;
 
-       /* To handle the need of I2C devices that require to write few bytes
-        * (more than 4 bytes of address as in the case of else part)
-        * of data before reading, Negative equivalent of length(bytes to write)
-        * is passed, but used the +ve part of len for writing data
+       /* Some drivers use offset lengths in excess of 4 bytes. These drivers
+        * adhere to the following convention:
+        * - the offset length is passed as negative (that is, the absolute
+        *   value of olen is the actual offset length)
+        * - the offset itself is passed in data, which is overwritten by the
+        *   subsequent read operation
         */
-       if (alen < 0) {
-               /* Generate a START and send the Address and
-                * the Tx Bytes to the slave.
-                * "START: Address: Write bytes data[len]"
-                * IF part supports writing any number of bytes in contrast
-                * to the else part, which supports writing address offset
-                * of upto 4 bytes only.
-                * bytes that need to be written are passed in
-                * "data", which will eventually keep the data READ,
-                * after writing the len bytes out of it
-                */
-               if (i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0)
-                       i = __i2c_write(adap, data, len);
-
-               if (i != len)
+       if (olen < 0) {
+               if (i2c_write_addr(base, chip_addr, I2C_WRITE_BIT, 0) != 0)
+                       ret = __i2c_write_data(base, data, -olen);
+
+               if (ret != -olen)
                        return -1;
 
-               if (length && i2c_write_addr(adap, dev, I2C_READ_BIT, 1) != 0)
-                       i = __i2c_read(adap, data, length);
+               if (dlen && i2c_write_addr(base, chip_addr,
+                                          I2C_READ_BIT, 1) != 0)
+                       ret = __i2c_read_data(base, data, dlen);
        } else {
-               if ((!length || alen > 0) &&
-                   i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0  &&
-                   __i2c_write(adap, &a[4 - alen], alen) == alen)
-                       i = 0; /* No error so far */
-
-               if (length &&
-                   i2c_write_addr(adap, dev, I2C_READ_BIT, alen ? 1 : 0) != 0)
-                       i = __i2c_read(adap, data, length);
+               if ((!dlen || olen > 0) &&
+                   i2c_write_addr(base, chip_addr, I2C_WRITE_BIT, 0) != 0  &&
+                   __i2c_write_data(base, offset, olen) == olen)
+                       ret = 0; /* No error so far */
+
+               if (dlen && i2c_write_addr(base, chip_addr, I2C_READ_BIT,
+                                          olen ? 1 : 0) != 0)
+                       ret = __i2c_read_data(base, data, dlen);
        }
 
-       writeb(I2C_CR_MEN, &device->cr);
+       writeb(I2C_CR_MEN, &base->cr);
 
-       if (i2c_wait4bus(adap)) /* Wait until STOP */
+       if (i2c_wait4bus(base)) /* Wait until STOP */
                debug("i2c_read: wait4bus timed out\n");
 
-       if (i == length)
-           return 0;
+       if (ret == dlen)
+               return 0;
 
        return -1;
 }
 
 static int
-fsl_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, int alen,
-             u8 *data, int length)
+__i2c_write(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
+           u8 *data, int dlen)
 {
-       struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-       int i = -1; /* signal error */
-       u8 *a = (u8*)&addr;
+       int ret = -1; /* signal error */
 
-       if (i2c_wait4bus(adap) < 0)
+       if (i2c_wait4bus(base) < 0)
                return -1;
 
-       if (i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0 &&
-           __i2c_write(adap, &a[4 - alen], alen) == alen) {
-               i = __i2c_write(adap, data, length);
+       if (i2c_write_addr(base, chip_addr, I2C_WRITE_BIT, 0) != 0 &&
+           __i2c_write_data(base, offset, olen) == olen) {
+               ret = __i2c_write_data(base, data, dlen);
        }
 
-       writeb(I2C_CR_MEN, &device->cr);
-       if (i2c_wait4bus(adap)) /* Wait until STOP */
+       writeb(I2C_CR_MEN, &base->cr);
+       if (i2c_wait4bus(base)) /* Wait until STOP */
                debug("i2c_write: wait4bus timed out\n");
 
-       if (i == length)
-           return 0;
+       if (ret == dlen)
+               return 0;
 
        return -1;
 }
 
 static int
-fsl_i2c_probe(struct i2c_adapter *adap, uchar chip)
+__i2c_probe_chip(const struct fsl_i2c_base *base, uchar chip)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
        /* For unknow reason the controller will ACK when
         * probing for a slave with the same address, so skip
         * it.
         */
-       if (chip == (readb(&dev->adr) >> 1))
+       if (chip == (readb(&base->adr) >> 1))
                return -1;
 
-       return fsl_i2c_read(adap, chip, 0, 0, NULL, 0);
+       return __i2c_read(base, chip, 0, 0, NULL, 0);
 }
 
-static unsigned int fsl_i2c_set_bus_speed(struct i2c_adapter *adap,
-                       unsigned int speed)
+static unsigned int __i2c_set_bus_speed(const struct fsl_i2c_base *base,
+                       unsigned int speed, int i2c_clk)
 {
-       struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
-
-       writeb(0, &dev->cr);            /* stop controller */
-       set_i2c_bus_speed(dev, get_i2c_clock(adap->hwadapnr), speed);
-       writeb(I2C_CR_MEN, &dev->cr);   /* start controller */
+       writeb(0, &base->cr);           /* stop controller */
+       set_i2c_bus_speed(base, i2c_clk, speed);
+       writeb(I2C_CR_MEN, &base->cr);  /* start controller */
 
        return 0;
 }
 
+#ifndef CONFIG_DM_I2C
+static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
+{
+       __i2c_init(i2c_base[adap->hwadapnr], speed, slaveadd,
+                  get_i2c_clock(adap->hwadapnr), adap->hwadapnr);
+}
+
+static int
+fsl_i2c_probe_chip(struct i2c_adapter *adap, uchar chip)
+{
+       return __i2c_probe_chip(i2c_base[adap->hwadapnr], chip);
+}
+
+static int
+fsl_i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,
+            u8 *data, int dlen)
+{
+       u8 *o = (u8 *)&offset;
+       return __i2c_read(i2c_base[adap->hwadapnr], chip_addr, &o[4 - olen],
+                         olen, data, dlen);
+}
+
+static int
+fsl_i2c_write(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,
+             u8 *data, int dlen)
+{
+       u8 *o = (u8 *)&offset;
+       return __i2c_write(i2c_base[adap->hwadapnr], chip_addr, &o[4 - olen],
+                          olen, data, dlen);
+}
+
+static unsigned int fsl_i2c_set_bus_speed(struct i2c_adapter *adap,
+                                         unsigned int speed)
+{
+       return __i2c_set_bus_speed(i2c_base[adap->hwadapnr], speed,
+                                  get_i2c_clock(adap->hwadapnr));
+}
+
 /*
  * Register fsl i2c adapters
  */
-U_BOOT_I2C_ADAP_COMPLETE(fsl_0, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
+U_BOOT_I2C_ADAP_COMPLETE(fsl_0, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read,
                         fsl_i2c_write, fsl_i2c_set_bus_speed,
                         CONFIG_SYS_FSL_I2C_SPEED, CONFIG_SYS_FSL_I2C_SLAVE,
                         0)
 #ifdef CONFIG_SYS_FSL_I2C2_OFFSET
-U_BOOT_I2C_ADAP_COMPLETE(fsl_1, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
+U_BOOT_I2C_ADAP_COMPLETE(fsl_1, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read,
                         fsl_i2c_write, fsl_i2c_set_bus_speed,
                         CONFIG_SYS_FSL_I2C2_SPEED, CONFIG_SYS_FSL_I2C2_SLAVE,
                         1)
 #endif
 #ifdef CONFIG_SYS_FSL_I2C3_OFFSET
-U_BOOT_I2C_ADAP_COMPLETE(fsl_2, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
+U_BOOT_I2C_ADAP_COMPLETE(fsl_2, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read,
                         fsl_i2c_write, fsl_i2c_set_bus_speed,
                         CONFIG_SYS_FSL_I2C3_SPEED, CONFIG_SYS_FSL_I2C3_SLAVE,
                         2)
 #endif
 #ifdef CONFIG_SYS_FSL_I2C4_OFFSET
-U_BOOT_I2C_ADAP_COMPLETE(fsl_3, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
+U_BOOT_I2C_ADAP_COMPLETE(fsl_3, fsl_i2c_init, fsl_i2c_probe_chip, fsl_i2c_read,
                         fsl_i2c_write, fsl_i2c_set_bus_speed,
                         CONFIG_SYS_FSL_I2C4_SPEED, CONFIG_SYS_FSL_I2C4_SLAVE,
                         3)
 #endif
+#else /* CONFIG_DM_I2C */
+static int fsl_i2c_probe_chip(struct udevice *bus, u32 chip_addr,
+                             u32 chip_flags)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       return __i2c_probe_chip(dev->base, chip_addr);
+}
+
+static int fsl_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       return __i2c_set_bus_speed(dev->base, speed, dev->i2c_clk);
+}
+
+static int fsl_i2c_ofdata_to_platdata(struct udevice *bus)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       u64 reg;
+       u32 addr, size;
+
+       reg = fdtdec_get_addr(gd->fdt_blob, bus->of_offset, "reg");
+       addr = reg >> 32;
+       size = reg & 0xFFFFFFFF;
+
+       dev->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
+
+       if (!dev->base)
+               return -ENOMEM;
+
+       dev->index = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+                                   "cell-index", -1);
+       dev->slaveadd = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+                                      "u-boot,i2c-slave-addr", 0x7f);
+       dev->speed = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+                                   "clock-frequency", 400000);
+
+       dev->i2c_clk = dev->index ? gd->arch.i2c2_clk : gd->arch.i2c1_clk;
+
+       return 0;
+}
+
+static int fsl_i2c_probe(struct udevice *bus)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       __i2c_init(dev->base, dev->speed, dev->slaveadd, dev->i2c_clk,
+                  dev->index);
+       return 0;
+}
+
+static int fsl_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
+{
+       struct fsl_i2c_dev *dev = dev_get_priv(bus);
+       struct i2c_msg *dmsg, *omsg, dummy;
+
+       memset(&dummy, 0, sizeof(struct i2c_msg));
+
+       /* We expect either two messages (one with an offset and one with the
+        * actucal data) or one message (just data) */
+       if (nmsgs > 2 || nmsgs == 0) {
+               debug("%s: Only one or two messages are supported.", __func__);
+               return -1;
+       }
+
+       omsg = nmsgs == 1 ? &dummy : msg;
+       dmsg = nmsgs == 1 ? msg : msg + 1;
+
+       if (dmsg->flags & I2C_M_RD)
+               return __i2c_read(dev->base, dmsg->addr, omsg->buf, omsg->len,
+                                 dmsg->buf, dmsg->len);
+       else
+               return __i2c_write(dev->base, dmsg->addr, omsg->buf, omsg->len,
+                                  dmsg->buf, dmsg->len);
+}
+
+static const struct dm_i2c_ops fsl_i2c_ops = {
+       .xfer           = fsl_i2c_xfer,
+       .probe_chip     = fsl_i2c_probe_chip,
+       .set_bus_speed  = fsl_i2c_set_bus_speed,
+};
+
+static const struct udevice_id fsl_i2c_ids[] = {
+       { .compatible = "fsl-i2c", },
+       { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(i2c_fsl) = {
+       .name = "i2c_fsl",
+       .id = UCLASS_I2C,
+       .of_match = fsl_i2c_ids,
+       .probe = fsl_i2c_probe,
+       .ofdata_to_platdata = fsl_i2c_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct fsl_i2c_dev),
+       .ops = &fsl_i2c_ops,
+};
+
+#endif /* CONFIG_DM_I2C */
index 909cea24182efe4fd20cafba076b7b87bf6605fb..5642cd91fe2ee68bb1407f59b224d94bea302200 100644 (file)
@@ -112,48 +112,10 @@ static void cdns_i2c_debug_status(struct cdns_i2c_regs *cdns_i2c)
 
 struct i2c_cdns_bus {
        int id;
+       unsigned int input_freq;
        struct cdns_i2c_regs __iomem *regs;     /* register base */
 };
 
-
-/** cdns_i2c_probe() - Probe method
- * @dev: udevice pointer
- *
- * DM callback called when device is probed
- */
-static int cdns_i2c_probe(struct udevice *dev)
-{
-       struct i2c_cdns_bus *bus = dev_get_priv(dev);
-
-       bus->regs = (struct cdns_i2c_regs *)dev_get_addr(dev);
-       if (!bus->regs)
-               return -ENOMEM;
-
-       /* TODO: Calculate dividers based on CPU_CLK_1X */
-       /* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */
-       writel((16 << CDNS_I2C_CONTROL_DIV_B_SHIFT) |
-               (2 << CDNS_I2C_CONTROL_DIV_A_SHIFT), &bus->regs->control);
-
-       /* Enable master mode, ack, and 7-bit addressing */
-       setbits_le32(&bus->regs->control, CDNS_I2C_CONTROL_MS |
-               CDNS_I2C_CONTROL_ACKEN | CDNS_I2C_CONTROL_NEA);
-
-       debug("%s bus %d at %p\n", __func__, dev->seq, bus->regs);
-
-       return 0;
-}
-
-static int cdns_i2c_remove(struct udevice *dev)
-{
-       struct i2c_cdns_bus *bus = dev_get_priv(dev);
-
-       debug("%s bus %d at %p\n", __func__, dev->seq, bus->regs);
-
-       unmap_sysmem(bus->regs);
-
-       return 0;
-}
-
 /* Wait for an interrupt */
 static u32 cdns_i2c_wait(struct cdns_i2c_regs *cdns_i2c, u32 mask)
 {
@@ -172,14 +134,84 @@ static u32 cdns_i2c_wait(struct cdns_i2c_regs *cdns_i2c, u32 mask)
        return int_status & mask;
 }
 
+#define CDNS_I2C_DIVA_MAX      4
+#define CDNS_I2C_DIVB_MAX      64
+
+static int cdns_i2c_calc_divs(unsigned long *f, unsigned long input_clk,
+               unsigned int *a, unsigned int *b)
+{
+       unsigned long fscl = *f, best_fscl = *f, actual_fscl, temp;
+       unsigned int div_a, div_b, calc_div_a = 0, calc_div_b = 0;
+       unsigned int last_error, current_error;
+
+       /* calculate (divisor_a+1) x (divisor_b+1) */
+       temp = input_clk / (22 * fscl);
+
+       /*
+        * If the calculated value is negative or 0CDNS_I2C_DIVA_MAX,
+        * the fscl input is out of range. Return error.
+        */
+       if (!temp || (temp > (CDNS_I2C_DIVA_MAX * CDNS_I2C_DIVB_MAX)))
+               return -EINVAL;
+
+       last_error = -1;
+       for (div_a = 0; div_a < CDNS_I2C_DIVA_MAX; div_a++) {
+               div_b = DIV_ROUND_UP(input_clk, 22 * fscl * (div_a + 1));
+
+               if ((div_b < 1) || (div_b > CDNS_I2C_DIVB_MAX))
+                       continue;
+               div_b--;
+
+               actual_fscl = input_clk / (22 * (div_a + 1) * (div_b + 1));
+
+               if (actual_fscl > fscl)
+                       continue;
+
+               current_error = ((actual_fscl > fscl) ? (actual_fscl - fscl) :
+                                                       (fscl - actual_fscl));
+
+               if (last_error > current_error) {
+                       calc_div_a = div_a;
+                       calc_div_b = div_b;
+                       best_fscl = actual_fscl;
+                       last_error = current_error;
+               }
+       }
+
+       *a = calc_div_a;
+       *b = calc_div_b;
+       *f = best_fscl;
+
+       return 0;
+}
+
 static int cdns_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
 {
-       if (speed != 100000) {
-               printf("%s, failed to set clock speed to %u\n", __func__,
-                      speed);
+       struct i2c_cdns_bus *bus = dev_get_priv(dev);
+       u32 div_a = 0, div_b = 0;
+       unsigned long speed_p = speed;
+       int ret = 0;
+
+       if (speed > 400000) {
+               debug("%s, failed to set clock speed to %u\n", __func__,
+                     speed);
                return -EINVAL;
        }
 
+       ret = cdns_i2c_calc_divs(&speed_p, bus->input_freq, &div_a, &div_b);
+       if (ret)
+               return ret;
+
+       debug("%s: div_a: %d, div_b: %d, input freq: %d, speed: %d/%ld\n",
+             __func__, div_a, div_b, bus->input_freq, speed, speed_p);
+
+       writel((div_b << CDNS_I2C_CONTROL_DIV_B_SHIFT) |
+              (div_a << CDNS_I2C_CONTROL_DIV_A_SHIFT), &bus->regs->control);
+
+       /* Enable master mode, ack, and 7-bit addressing */
+       setbits_le32(&bus->regs->control, CDNS_I2C_CONTROL_MS |
+               CDNS_I2C_CONTROL_ACKEN | CDNS_I2C_CONTROL_NEA);
+
        return 0;
 }
 
@@ -313,6 +345,19 @@ static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
        return 0;
 }
 
+static int cdns_i2c_ofdata_to_platdata(struct udevice *dev)
+{
+       struct i2c_cdns_bus *i2c_bus = dev_get_priv(dev);
+
+       i2c_bus->regs = (struct cdns_i2c_regs *)dev_get_addr(dev);
+       if (!i2c_bus->regs)
+               return -ENOMEM;
+
+       i2c_bus->input_freq = 100000000; /* TODO hardcode input freq for now */
+
+       return 0;
+}
+
 static const struct dm_i2c_ops cdns_i2c_ops = {
        .xfer = cdns_i2c_xfer,
        .probe_chip = cdns_i2c_probe_chip,
@@ -328,8 +373,7 @@ U_BOOT_DRIVER(cdns_i2c) = {
        .name = "i2c-cdns",
        .id = UCLASS_I2C,
        .of_match = cdns_i2c_of_match,
-       .probe = cdns_i2c_probe,
-       .remove = cdns_i2c_remove,
+       .ofdata_to_platdata = cdns_i2c_ofdata_to_platdata,
        .priv_auto_alloc_size = sizeof(struct i2c_cdns_bus),
        .ops = &cdns_i2c_ops,
 };
index f959d9de9e8b0de2883f5174bd097aaf5576a544..48900ed2afc5c36428a6c4ce798dfe9ec2c12ccf 100644 (file)
@@ -24,3 +24,13 @@ config I2C_ARB_GPIO_CHALLENGE
          I2C multimaster arbitration scheme using GPIOs and a challenge &
          response mechanism where masters have to claim the bus by asserting
          a GPIO.
+
+config I2C_MUX_PCA954x
+       tristate "TI PCA954x I2C Mux/switches"
+       depends on I2C_MUX
+       help
+         If you say yes here you get support for the TI PCA954x
+         I2C mux/switch devices. It is x width I2C multiplexer which enables to
+         paritioning I2C bus and connect multiple devices with the same address
+         to the same I2C controller where driver handles proper routing to
+         target i2c device. PCA9544 and PCA9548 are supported.
index 47c1240d7e9ef26b041450f994a4663201315fbc..0811add4216e6e728e58176752ccac970770f717 100644 (file)
@@ -5,3 +5,4 @@
 #
 obj-$(CONFIG_I2C_ARB_GPIO_CHALLENGE) += i2c-arb-gpio-challenge.o
 obj-$(CONFIG_$(SPL_)I2C_MUX) += i2c-mux-uclass.o
+obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o
diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c
new file mode 100644 (file)
index 0000000..7e0d2da
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 - 2016 Xilinx, Inc.
+ * Written by Michal Simek
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <i2c.h>
+#include <asm/gpio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct pca954x_priv {
+       u32 addr; /* I2C mux address */
+       u32 width; /* I2C mux width - number of busses */
+};
+
+static int pca954x_deselect(struct udevice *mux, struct udevice *bus,
+                           uint channel)
+{
+       struct pca954x_priv *priv = dev_get_priv(mux);
+       uchar byte = 0;
+
+       return dm_i2c_write(mux, priv->addr, &byte, 1);
+}
+
+static int pca954x_select(struct udevice *mux, struct udevice *bus,
+                         uint channel)
+{
+       struct pca954x_priv *priv = dev_get_priv(mux);
+       uchar byte = 1 << channel;
+
+       return dm_i2c_write(mux, priv->addr, &byte, 1);
+}
+
+static const struct i2c_mux_ops pca954x_ops = {
+       .select = pca954x_select,
+       .deselect = pca954x_deselect,
+};
+
+static const struct udevice_id pca954x_ids[] = {
+       { .compatible = "nxp,pca9548", .data = (ulong)8 },
+       { .compatible = "nxp,pca9544", .data = (ulong)4 },
+       { }
+};
+
+static int pca954x_ofdata_to_platdata(struct udevice *dev)
+{
+       struct pca954x_priv *priv = dev_get_priv(dev);
+
+       priv->addr = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", 0);
+       if (!priv->addr) {
+               debug("MUX not found\n");
+               return -ENODEV;
+       }
+       priv->width = dev_get_driver_data(dev);
+
+       if (!priv->width) {
+               debug("No I2C MUX width specified\n");
+               return -EINVAL;
+       }
+
+       debug("Device %s at 0x%x with width %d\n",
+             dev->name, priv->addr, priv->width);
+
+       return 0;
+}
+
+U_BOOT_DRIVER(pca954x) = {
+       .name = "pca954x",
+       .id = UCLASS_I2C_MUX,
+       .of_match = pca954x_ids,
+       .ops = &pca954x_ops,
+       .ofdata_to_platdata = pca954x_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct pca954x_priv),
+};
index 221ff4fe7afa02b39c56a5cd12a1cf359ae975ac..bf4443287fd2977fe3a61f3f653327ab3e013323 100644 (file)
@@ -184,27 +184,18 @@ static int twsi_wait(struct i2c_adapter *adap, int expected_status)
                MVTWSI_ERROR_TIMEOUT, control, status, expected_status);
 }
 
-/*
- * These flags are ORed to any write to the control register
- * They allow global setting of TWSIEN and ACK.
- * By default none are set.
- * twsi_start() sets TWSIEN (in case the controller was disabled)
- * twsi_recv() sets ACK or resets it depending on expected status.
- */
-static u8 twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
-
 /*
  * Assert the START condition, either in a single I2C transaction
  * or inside back-to-back ones (repeated starts).
  */
-static int twsi_start(struct i2c_adapter *adap, int expected_status)
+static int twsi_start(struct i2c_adapter *adap, int expected_status, u8 *flags)
 {
        struct mvtwsi_registers *twsi = twsi_get_base(adap);
 
        /* globally set TWSIEN in case it was not */
-       twsi_control_flags |= MVTWSI_CONTROL_TWSIEN;
+       *flags |= MVTWSI_CONTROL_TWSIEN;
        /* assert START */
-       writel(twsi_control_flags | MVTWSI_CONTROL_START |
+       writel(*flags | MVTWSI_CONTROL_START |
                                    MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
        /* wait for controller to process START */
        return twsi_wait(adap, expected_status);
@@ -213,14 +204,15 @@ static int twsi_start(struct i2c_adapter *adap, int expected_status)
 /*
  * Send a byte (i2c address or data).
  */
-static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status)
+static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status,
+                    u8 *flags)
 {
        struct mvtwsi_registers *twsi = twsi_get_base(adap);
 
        /* put byte in data register for sending */
        writel(byte, &twsi->data);
        /* clear any pending interrupt -- that'll cause sending */
-       writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
+       writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
        /* wait for controller to receive byte and check ACK */
        return twsi_wait(adap, expected_status);
 }
@@ -229,18 +221,18 @@ static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status)
  * Receive a byte.
  * Global mvtwsi_control_flags variable says if we should ack or nak.
  */
-static int twsi_recv(struct i2c_adapter *adap, u8 *byte)
+static int twsi_recv(struct i2c_adapter *adap, u8 *byte, u8 *flags)
 {
        struct mvtwsi_registers *twsi = twsi_get_base(adap);
        int expected_status, status;
 
        /* compute expected status based on ACK bit in global control flags */
-       if (twsi_control_flags & MVTWSI_CONTROL_ACK)
+       if (*flags & MVTWSI_CONTROL_ACK)
                expected_status = MVTWSI_STATUS_DATA_R_ACK;
        else
                expected_status = MVTWSI_STATUS_DATA_R_NAK;
        /* acknowledge *previous state* and launch receive */
-       writel(twsi_control_flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
+       writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
        /* wait for controller to receive byte and assert ACK or NAK */
        status = twsi_wait(adap, expected_status);
        /* if we did receive expected byte then store it */
@@ -296,8 +288,7 @@ static unsigned int twsi_calc_freq(const int n, const int m)
 static void twsi_reset(struct i2c_adapter *adap)
 {
        struct mvtwsi_registers *twsi = twsi_get_base(adap);
-       /* ensure controller will be enabled by any twsi*() function */
-       twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
+
        /* reset controller */
        writel(0, &twsi->soft_reset);
        /* wait 2 ms -- this is what the Marvell LSP does */
@@ -353,7 +344,7 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
  * Expected address status will derive from direction bit (bit 0) in addr.
  */
 static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
-                    u8 addr)
+                    u8 addr, u8 *flags)
 {
        int status, expected_addr_status;
 
@@ -363,10 +354,11 @@ static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
        else /* writing */
                expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
        /* assert START */
-       status = twsi_start(adap, expected_start_status);
+       status = twsi_start(adap, expected_start_status, flags);
        /* send out the address if the start went well */
        if (status == 0)
-               status = twsi_send(adap, addr, expected_addr_status);
+               status = twsi_send(adap, addr, expected_addr_status,
+                                  flags);
        /* return ok or status of first failure to caller */
        return status;
 }
@@ -378,13 +370,14 @@ static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
 static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip)
 {
        u8 dummy_byte;
+       u8 flags = 0;
        int status;
 
        /* begin i2c read */
-       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1);
+       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1, &flags);
        /* dummy read was accepted: receive byte but NAK it. */
        if (status == 0)
-               status = twsi_recv(adap, &dummy_byte);
+               status = twsi_recv(adap, &dummy_byte, &flags);
        /* Stop transaction */
        twsi_stop(adap, 0);
        /* return 0 or status of first failure */
@@ -405,27 +398,28 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
                        int alen, uchar *data, int length)
 {
        int status;
+       u8 flags = 0;
 
        /* begin i2c write to send the address bytes */
-       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
+       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
        /* send addr bytes */
        while ((status == 0) && alen--)
                status = twsi_send(adap, addr >> (8*alen),
-                       MVTWSI_STATUS_DATA_W_ACK);
+                       MVTWSI_STATUS_DATA_W_ACK, &flags);
        /* begin i2c read to receive eeprom data bytes */
        if (status == 0)
                status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START,
-                                  (chip << 1) | 1);
+                                  (chip << 1) | 1, &flags);
        /* prepare ACK if at least one byte must be received */
        if (length > 0)
-               twsi_control_flags |= MVTWSI_CONTROL_ACK;
+               flags |= MVTWSI_CONTROL_ACK;
        /* now receive actual bytes */
        while ((status == 0) && length--) {
                /* reset NAK if we if no more to read now */
                if (length == 0)
-                       twsi_control_flags &= ~MVTWSI_CONTROL_ACK;
+                       flags &= ~MVTWSI_CONTROL_ACK;
                /* read current byte */
-               status = twsi_recv(adap, data++);
+               status = twsi_recv(adap, data++, &flags);
        }
        /* Stop transaction */
        status = twsi_stop(adap, status);
@@ -441,16 +435,18 @@ static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
                        int alen, uchar *data, int length)
 {
        int status;
+       u8 flags = 0;
 
        /* begin i2c write to send the eeprom adress bytes then data bytes */
-       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
+       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
        /* send addr bytes */
        while ((status == 0) && alen--)
                status = twsi_send(adap, addr >> (8*alen),
-                       MVTWSI_STATUS_DATA_W_ACK);
+                       MVTWSI_STATUS_DATA_W_ACK, &flags);
        /* send data bytes */
        while ((status == 0) && (length-- > 0))
-               status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK);
+               status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK,
+                                  &flags);
        /* Stop transaction */
        status = twsi_stop(adap, status);
        /* return 0 or status of first failure */
index 4d3df11a1b51e5a4bc9a8e2209b3cdcc5292820c..c80efc39a791872aab2216bd7fb518b437e270b2 100644 (file)
@@ -2,7 +2,7 @@ menu "MMC Host controller Support"
 
 config MMC
        bool "Enable MMC support"
-       depends on ARCH_SUNXI
+       depends on ARCH_SUNXI || SANDBOX
        help
          TODO: Move all architectures to use this option
 
@@ -58,4 +58,13 @@ config MMC_UNIPHIER
        help
          This selects support for the SD/MMC Host Controller on UniPhier SoCs.
 
+config SANDBOX_MMC
+       bool "Sandbox MMC support"
+       depends on MMC && SANDBOX
+       help
+         This select a dummy sandbox MMC driver. At present this does nothing
+         other than allow sandbox to be build with MMC support. This
+         improves build coverage for sandbox and makes it easier to detect
+         MMC build errors with sandbox.
+
 endmenu
index 585aaf31150140fec913cf0bee6f86637752a5f3..3da4817a189c6e00b8e780e8837509b38e3021c1 100644 (file)
@@ -5,7 +5,13 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-$(CONFIG_DM_MMC) += mmc-uclass.o
+ifdef CONFIG_DM_MMC
+obj-$(CONFIG_GENERIC_MMC) += mmc-uclass.o
+endif
+
+ifndef CONFIG_BLK
+obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
+endif
 
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o
@@ -34,7 +40,11 @@ obj-$(CONFIG_ROCKCHIP_DWMMC) += rockchip_dw_mmc.o
 obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
 obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
 obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
+ifdef CONFIG_BLK
+ifdef CONFIG_GENERIC_MMC
 obj-$(CONFIG_SANDBOX) += sandbox_mmc.o
+endif
+endif
 obj-$(CONFIG_SDHCI) += sdhci.o
 obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
index 777489f5d8e9c63750849d91b78c55f572054db4..1b967d982bc74946ccd61fe1c74ae5826662cb6f 100644 (file)
@@ -21,6 +21,112 @@ struct mmc *mmc_get_mmc_dev(struct udevice *dev)
        return upriv->mmc;
 }
 
+#ifdef CONFIG_BLK
+struct mmc *find_mmc_device(int dev_num)
+{
+       struct udevice *dev, *mmc_dev;
+       int ret;
+
+       ret = blk_get_device(IF_TYPE_MMC, dev_num, &dev);
+
+       if (ret) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+               printf("MMC Device %d not found\n", dev_num);
+#endif
+               return NULL;
+       }
+
+       mmc_dev = dev_get_parent(dev);
+
+       return mmc_get_mmc_dev(mmc_dev);
+}
+
+int get_mmc_num(void)
+{
+       return max(blk_find_max_devnum(IF_TYPE_MMC), 0);
+}
+
+int mmc_get_next_devnum(void)
+{
+       int ret;
+
+       ret = get_mmc_num();
+       if (ret < 0)
+               return ret;
+
+       return ret + 1;
+}
+
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
+{
+       struct blk_desc *desc;
+       struct udevice *dev;
+
+       device_find_first_child(mmc->dev, &dev);
+       if (!dev)
+               return NULL;
+       desc = dev_get_uclass_platdata(dev);
+
+       return desc;
+}
+
+void mmc_do_preinit(void)
+{
+       struct udevice *dev;
+       struct uclass *uc;
+       int ret;
+
+       ret = uclass_get(UCLASS_MMC, &uc);
+       if (ret)
+               return;
+       uclass_foreach_dev(dev, uc) {
+               struct mmc *m = mmc_get_mmc_dev(dev);
+
+               if (!m)
+                       continue;
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+               mmc_set_preinit(m, 1);
+#endif
+               if (m->preinit)
+                       mmc_start_init(m);
+       }
+}
+
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+void print_mmc_devices(char separator)
+{
+       struct udevice *dev;
+       char *mmc_type;
+       bool first = true;
+
+       for (uclass_first_device(UCLASS_MMC, &dev);
+            dev;
+            uclass_next_device(&dev)) {
+               struct mmc *m = mmc_get_mmc_dev(dev);
+
+               if (!first) {
+                       printf("%c", separator);
+                       if (separator != '\n')
+                               puts(" ");
+               }
+               if (m->has_init)
+                       mmc_type = IS_SD(m) ? "SD" : "eMMC";
+               else
+                       mmc_type = NULL;
+
+               printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum);
+               if (mmc_type)
+                       printf(" (%s)", mmc_type);
+       }
+
+       printf("\n");
+}
+
+#else
+void print_mmc_devices(char separator) { }
+#endif
+#endif /* CONFIG_BLK */
+
 U_BOOT_DRIVER(mmc) = {
        .name   = "mmc",
        .id     = UCLASS_MMC,
index d3c22abfd5a8c198499308cb4b8e24f161f9be3d..74b3d68f871ccfc24c33e2fded971e5bba5c4739 100644 (file)
@@ -21,9 +21,6 @@
 #include <div64.h>
 #include "mmc_private.h"
 
-static struct list_head mmc_devices;
-static int cur_dev_num = -1;
-
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
        return -1;
@@ -178,25 +175,6 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
        return mmc_send_cmd(mmc, &cmd, NULL);
 }
 
-struct mmc *find_mmc_device(int dev_num)
-{
-       struct mmc *m;
-       struct list_head *entry;
-
-       list_for_each(entry, &mmc_devices) {
-               m = list_entry(entry, struct mmc, link);
-
-               if (m->block_dev.devnum == dev_num)
-                       return m;
-       }
-
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
-       printf("MMC Device %d not found\n", dev_num);
-#endif
-
-       return NULL;
-}
-
 static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
                           lbaint_t blkcnt)
 {
@@ -238,9 +216,17 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
        return blkcnt;
 }
 
+#ifdef CONFIG_BLK
+static ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+                      void *dst)
+#else
 static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
                       lbaint_t blkcnt, void *dst)
+#endif
 {
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
        int dev_num = block_dev->devnum;
        int err;
        lbaint_t cur, blocks_todo = blkcnt;
@@ -252,14 +238,14 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
        if (!mmc)
                return 0;
 
-       err = mmc_select_hwpart(dev_num, block_dev->hwpart);
+       err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
        if (err < 0)
                return 0;
 
-       if ((start + blkcnt) > mmc->block_dev.lba) {
+       if ((start + blkcnt) > block_dev->lba) {
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
-                       start + blkcnt, mmc->block_dev.lba);
+                       start + blkcnt, block_dev->lba);
 #endif
                return 0;
        }
@@ -577,58 +563,73 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
                return -1;
        }
 
-       mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
+       mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
 
        return 0;
 }
 
-int mmc_select_hwpart(int dev_num, int hwpart)
+static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 {
-       struct mmc *mmc = find_mmc_device(dev_num);
        int ret;
 
-       if (!mmc)
-               return -ENODEV;
+       ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
+                        (mmc->part_config & ~PART_ACCESS_MASK)
+                        | (part_num & PART_ACCESS_MASK));
 
-       if (mmc->block_dev.hwpart == hwpart)
+       /*
+        * Set the capacity if the switch succeeded or was intended
+        * to return to representing the raw device.
+        */
+       if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
+               ret = mmc_set_capacity(mmc, part_num);
+               mmc_get_blk_desc(mmc)->hwpart = part_num;
+       }
+
+       return ret;
+}
+
+#ifdef CONFIG_BLK
+static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
+{
+       struct udevice *mmc_dev = dev_get_parent(bdev);
+       struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
+       struct blk_desc *desc = dev_get_uclass_platdata(bdev);
+       int ret;
+
+       if (desc->hwpart == hwpart)
                return 0;
 
-       if (mmc->part_config == MMCPART_NOAVAILABLE) {
-               printf("Card doesn't support part_switch\n");
+       if (mmc->part_config == MMCPART_NOAVAILABLE)
                return -EMEDIUMTYPE;
-       }
 
-       ret = mmc_switch_part(dev_num, hwpart);
+       ret = mmc_switch_part(mmc, hwpart);
        if (ret)
                return ret;
 
        return 0;
 }
-
-
-int mmc_switch_part(int dev_num, unsigned int part_num)
+#else
+static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
 {
-       struct mmc *mmc = find_mmc_device(dev_num);
+       struct mmc *mmc = find_mmc_device(desc->devnum);
        int ret;
 
        if (!mmc)
-               return -1;
+               return -ENODEV;
 
-       ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
-                        (mmc->part_config & ~PART_ACCESS_MASK)
-                        | (part_num & PART_ACCESS_MASK));
+       if (mmc->block_dev.hwpart == hwpart)
+               return 0;
 
-       /*
-        * Set the capacity if the switch succeeded or was intended
-        * to return to representing the raw device.
-        */
-       if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
-               ret = mmc_set_capacity(mmc, part_num);
-               mmc->block_dev.hwpart = part_num;
-       }
+       if (mmc->part_config == MMCPART_NOAVAILABLE)
+               return -EMEDIUMTYPE;
 
-       return ret;
+       ret = mmc_switch_part(mmc, hwpart);
+       if (ret)
+               return ret;
+
+       return 0;
 }
+#endif
 
 int mmc_hwpart_config(struct mmc *mmc,
                      const struct mmc_hwpart_conf *conf,
@@ -1039,6 +1040,7 @@ static int mmc_startup(struct mmc *mmc)
        int timeout = 1000;
        bool has_parts = false;
        bool part_completed;
+       struct blk_desc *bdesc;
 
 #ifdef CONFIG_MMC_SPI_CRC_ON
        if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
@@ -1335,7 +1337,7 @@ static int mmc_startup(struct mmc *mmc)
                mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
        }
 
-       err = mmc_set_capacity(mmc, mmc->block_dev.hwpart);
+       err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
        if (err)
                return err;
 
@@ -1475,31 +1477,32 @@ static int mmc_startup(struct mmc *mmc)
        }
 
        /* fill in device description */
-       mmc->block_dev.lun = 0;
-       mmc->block_dev.hwpart = 0;
-       mmc->block_dev.type = 0;
-       mmc->block_dev.blksz = mmc->read_bl_len;
-       mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
-       mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
+       bdesc = mmc_get_blk_desc(mmc);
+       bdesc->lun = 0;
+       bdesc->hwpart = 0;
+       bdesc->type = 0;
+       bdesc->blksz = mmc->read_bl_len;
+       bdesc->log2blksz = LOG2(bdesc->blksz);
+       bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
 #if !defined(CONFIG_SPL_BUILD) || \
                (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
                !defined(CONFIG_USE_TINY_PRINTF))
-       sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
+       sprintf(bdesc->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,
+       sprintf(bdesc->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,
+       sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
                (mmc->cid[2] >> 16) & 0xf);
 #else
-       mmc->block_dev.vendor[0] = 0;
-       mmc->block_dev.product[0] = 0;
-       mmc->block_dev.revision[0] = 0;
+       bdesc->vendor[0] = 0;
+       bdesc->product[0] = 0;
+       bdesc->revision[0] = 0;
 #endif
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
-       part_init(&mmc->block_dev);
+       part_init(bdesc);
 #endif
 
        return 0;
@@ -1537,8 +1540,55 @@ int __deprecated mmc_register(struct mmc *mmc)
        return -1;
 }
 
+#ifdef CONFIG_BLK
+int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
+{
+       struct blk_desc *bdesc;
+       struct udevice *bdev;
+       int ret;
+
+       ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, -1, 512,
+                                0, &bdev);
+       if (ret) {
+               debug("Cannot create block device\n");
+               return ret;
+       }
+       bdesc = dev_get_uclass_platdata(bdev);
+       mmc->cfg = cfg;
+       mmc->priv = dev;
+
+       /* the following chunk was from mmc_register() */
+
+       /* Setup dsr related values */
+       mmc->dsr_imp = 0;
+       mmc->dsr = 0xffffffff;
+       /* Setup the universal parts of the block interface just once */
+       bdesc->removable = 1;
+
+       /* setup initial part type */
+       bdesc->part_type = mmc->cfg->part_type;
+       mmc->dev = dev;
+
+       return 0;
+}
+
+int mmc_unbind(struct udevice *dev)
+{
+       struct udevice *bdev;
+
+       device_find_first_child(dev, &bdev);
+       if (bdev) {
+               device_remove(bdev);
+               device_unbind(bdev);
+       }
+
+       return 0;
+}
+
+#else
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
 {
+       struct blk_desc *bdesc;
        struct mmc *mmc;
 
        /* quick validation */
@@ -1559,19 +1609,17 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
        mmc->dsr_imp = 0;
        mmc->dsr = 0xffffffff;
        /* Setup the universal parts of the block interface just once */
-       mmc->block_dev.if_type = IF_TYPE_MMC;
-       mmc->block_dev.devnum = cur_dev_num++;
-       mmc->block_dev.removable = 1;
-       mmc->block_dev.block_read = mmc_bread;
-       mmc->block_dev.block_write = mmc_bwrite;
-       mmc->block_dev.block_erase = mmc_berase;
+       bdesc = mmc_get_blk_desc(mmc);
+       bdesc->if_type = IF_TYPE_MMC;
+       bdesc->removable = 1;
+       bdesc->devnum = mmc_get_next_devnum();
+       bdesc->block_read = mmc_bread;
+       bdesc->block_write = mmc_bwrite;
+       bdesc->block_erase = mmc_berase;
 
        /* setup initial part type */
-       mmc->block_dev.part_type = mmc->cfg->part_type;
-
-       INIT_LIST_HEAD(&mmc->link);
-
-       list_add_tail(&mmc->link, &mmc_devices);
+       bdesc->part_type = mmc->cfg->part_type;
+       mmc_list_add(mmc);
 
        return mmc;
 }
@@ -1581,15 +1629,23 @@ void mmc_destroy(struct mmc *mmc)
        /* only freeing memory for now */
        free(mmc);
 }
+#endif
 
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *mmc_get_dev(int dev)
+#ifndef CONFIG_BLK
+static int mmc_get_dev(int dev, struct blk_desc **descp)
 {
        struct mmc *mmc = find_mmc_device(dev);
-       if (!mmc || mmc_init(mmc))
-               return NULL;
+       int ret;
 
-       return &mmc->block_dev;
+       if (!mmc)
+               return -ENODEV;
+       ret = mmc_init(mmc);
+       if (ret)
+               return ret;
+
+       *descp = &mmc->block_dev;
+
+       return 0;
 }
 #endif
 
@@ -1636,7 +1692,7 @@ int mmc_start_init(struct mmc *mmc)
                return err;
 
        /* The internal partition reset to user partition(0) at every CMD0*/
-       mmc->block_dev.hwpart = 0;
+       mmc_get_blk_desc(mmc)->hwpart = 0;
 
        /* Test for SD version 2 */
        err = mmc_send_if_cond(mmc);
@@ -1683,7 +1739,11 @@ int mmc_init(struct mmc *mmc)
 {
        int err = 0;
        unsigned start;
+#ifdef CONFIG_DM_MMC
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
 
+       upriv->mmc = mmc;
+#endif
        if (mmc->has_init)
                return 0;
 
@@ -1716,66 +1776,11 @@ __weak int board_mmc_init(bd_t *bis)
        return -1;
 }
 
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
-
-void print_mmc_devices(char separator)
-{
-       struct mmc *m;
-       struct list_head *entry;
-       char *mmc_type;
-
-       list_for_each(entry, &mmc_devices) {
-               m = list_entry(entry, struct mmc, link);
-
-               if (m->has_init)
-                       mmc_type = IS_SD(m) ? "SD" : "eMMC";
-               else
-                       mmc_type = NULL;
-
-               printf("%s: %d", m->cfg->name, m->block_dev.devnum);
-               if (mmc_type)
-                       printf(" (%s)", mmc_type);
-
-               if (entry->next != &mmc_devices) {
-                       printf("%c", separator);
-                       if (separator != '\n')
-                               puts (" ");
-               }
-       }
-
-       printf("\n");
-}
-
-#else
-void print_mmc_devices(char separator) { }
-#endif
-
-int get_mmc_num(void)
-{
-       return cur_dev_num;
-}
-
 void mmc_set_preinit(struct mmc *mmc, int preinit)
 {
        mmc->preinit = preinit;
 }
 
-static void do_preinit(void)
-{
-       struct mmc *m;
-       struct list_head *entry;
-
-       list_for_each(entry, &mmc_devices) {
-               m = list_entry(entry, struct mmc, link);
-
-#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
-               mmc_set_preinit(m, 1);
-#endif
-               if (m->preinit)
-                       mmc_start_init(m);
-       }
-}
-
 #if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
 static int mmc_probe(bd_t *bis)
 {
@@ -1828,9 +1833,9 @@ int mmc_initialize(bd_t *bis)
                return 0;
        initialized = 1;
 
-       INIT_LIST_HEAD (&mmc_devices);
-       cur_dev_num = 0;
-
+#ifndef CONFIG_BLK
+       mmc_list_init();
+#endif
        ret = mmc_probe(bis);
        if (ret)
                return ret;
@@ -1839,7 +1844,7 @@ int mmc_initialize(bd_t *bis)
        print_mmc_devices(',');
 #endif
 
-       do_preinit();
+       mmc_do_preinit();
        return 0;
 }
 
@@ -1965,3 +1970,25 @@ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
                          enable);
 }
 #endif
+
+#ifdef CONFIG_BLK
+static const struct blk_ops mmc_blk_ops = {
+       .read   = mmc_bread,
+       .write  = mmc_bwrite,
+       .select_hwpart  = mmc_select_hwpart,
+};
+
+U_BOOT_DRIVER(mmc_blk) = {
+       .name           = "mmc_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &mmc_blk_ops,
+};
+#else
+U_BOOT_LEGACY_BLK(mmc) = {
+       .if_typename    = "mmc",
+       .if_type        = IF_TYPE_MMC,
+       .max_devs       = -1,
+       .get_dev        = mmc_get_dev,
+       .select_hwpart  = mmc_select_hwpartp,
+};
+#endif
diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c
new file mode 100644 (file)
index 0000000..3ec649f
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <mmc.h>
+
+static struct list_head mmc_devices;
+static int cur_dev_num = -1;
+
+struct mmc *find_mmc_device(int dev_num)
+{
+       struct mmc *m;
+       struct list_head *entry;
+
+       list_for_each(entry, &mmc_devices) {
+               m = list_entry(entry, struct mmc, link);
+
+               if (m->block_dev.devnum == dev_num)
+                       return m;
+       }
+
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+       printf("MMC Device %d not found\n", dev_num);
+#endif
+
+       return NULL;
+}
+
+int mmc_get_next_devnum(void)
+{
+       return cur_dev_num++;
+}
+
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
+{
+       return &mmc->block_dev;
+}
+
+int get_mmc_num(void)
+{
+       return cur_dev_num;
+}
+
+void mmc_do_preinit(void)
+{
+       struct mmc *m;
+       struct list_head *entry;
+
+       list_for_each(entry, &mmc_devices) {
+               m = list_entry(entry, struct mmc, link);
+
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+               mmc_set_preinit(m, 1);
+#endif
+               if (m->preinit)
+                       mmc_start_init(m);
+       }
+}
+
+void mmc_list_init(void)
+{
+       INIT_LIST_HEAD(&mmc_devices);
+       cur_dev_num = 0;
+}
+
+void mmc_list_add(struct mmc *mmc)
+{
+       INIT_LIST_HEAD(&mmc->link);
+
+       list_add_tail(&mmc->link, &mmc_devices);
+}
+
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+void print_mmc_devices(char separator)
+{
+       struct mmc *m;
+       struct list_head *entry;
+       char *mmc_type;
+
+       list_for_each(entry, &mmc_devices) {
+               m = list_entry(entry, struct mmc, link);
+
+               if (m->has_init)
+                       mmc_type = IS_SD(m) ? "SD" : "eMMC";
+               else
+                       mmc_type = NULL;
+
+               printf("%s: %d", m->cfg->name, m->block_dev.devnum);
+               if (mmc_type)
+                       printf(" (%s)", mmc_type);
+
+               if (entry->next != &mmc_devices) {
+                       printf("%c", separator);
+                       if (separator != '\n')
+                               puts(" ");
+               }
+       }
+
+       printf("\n");
+}
+
+#else
+void print_mmc_devices(char separator) { }
+#endif
index d3f6bfe123cdde8930ad0b40e5307efd83274dab..27b9e5f56f8c284d489e817d9a7e33fc5dc3f8b2 100644 (file)
@@ -25,8 +25,13 @@ void mmc_adapter_card_type_ident(void);
 unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
                         lbaint_t blkcnt);
 
-unsigned long mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
-                        lbaint_t blkcnt, const void *src);
+#ifdef CONFIG_BLK
+ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+                const void *src);
+#else
+ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
+                const void *src);
+#endif
 
 #else /* CONFIG_SPL_BUILD */
 
@@ -46,4 +51,28 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
 
 #endif /* CONFIG_SPL_BUILD */
 
+/**
+ * mmc_get_next_devnum() - Get the next available MMC device number
+ *
+ * @return next available device number (0 = first), or -ve on error
+ */
+int mmc_get_next_devnum(void);
+
+/**
+ * mmc_do_preinit() - Get an MMC device ready for use
+ */
+void mmc_do_preinit(void);
+
+/**
+ * mmc_list_init() - Set up the list of MMC devices
+ */
+void mmc_list_init(void);
+
+/**
+ * mmc_list_add() - Add a new MMC device to the list of devices
+ *
+ * @mmc:       Device to add
+ */
+void mmc_list_add(struct mmc *mmc);
+
 #endif /* _MMC_PRIVATE_H_ */
index 7b186f8500d70c754b8237519c498741447e1f78..0f8b5c79d7c6073d47964e25140b1991b119cbc4 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <config.h>
 #include <common.h>
+#include <dm.h>
 #include <part.h>
 #include <div64.h>
 #include <linux/math64.h>
@@ -78,7 +79,8 @@ unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
        if (!mmc)
                return -1;
 
-       err = mmc_select_hwpart(dev_num, block_dev->hwpart);
+       err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num,
+                                      block_dev->hwpart);
        if (err < 0)
                return -1;
 
@@ -121,9 +123,9 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
        struct mmc_data data;
        int timeout = 1000;
 
-       if ((start + blkcnt) > mmc->block_dev.lba) {
+       if ((start + blkcnt) > mmc_get_blk_desc(mmc)->lba) {
                printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
-                      start + blkcnt, mmc->block_dev.lba);
+                      start + blkcnt, mmc_get_blk_desc(mmc)->lba);
                return 0;
        }
 
@@ -171,9 +173,17 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
        return blkcnt;
 }
 
+#ifdef CONFIG_BLK
+ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+                const void *src)
+#else
 ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
                 const void *src)
+#endif
 {
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
        int dev_num = block_dev->devnum;
        lbaint_t cur, blocks_todo = blkcnt;
        int err;
@@ -182,7 +192,7 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
        if (!mmc)
                return 0;
 
-       err = mmc_select_hwpart(dev_num, block_dev->hwpart);
+       err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, block_dev->hwpart);
        if (err < 0)
                return 0;
 
index 85a832bd420f6d706df9912b0eb3c161915c2469..be34057ea2cef9108cd842c7237fc70726d853a8 100644 (file)
@@ -825,6 +825,7 @@ static int omap_hsmmc_probe(struct udevice *dev)
        gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN);
 #endif
 
+       mmc->dev = dev;
        upriv->mmc = mmc;
 
        return 0;
index e03d6dd51730f1579769986103fea8ff3bb8e043..abe74293edfdb609dde6fa0d308ff81e17b798bf 100644 (file)
@@ -41,7 +41,12 @@ static int pic32_sdhci_probe(struct udevice *dev)
                return ret;
        }
 
-       return add_sdhci(host, f_min_max[1], f_min_max[0]);
+       ret = add_sdhci(host, f_min_max[1], f_min_max[0]);
+       if (ret)
+               return ret;
+       host->mmc->dev = dev;
+
+       return 0;
 }
 
 static const struct udevice_id pic32_sdhci_ids[] = {
index cb9e1048d0351041e54817e0dc4ab4130ada53ac..0a261c51a84b897139679b9b967d30405ea6cac8 100644 (file)
@@ -104,6 +104,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
        if (ret)
                return ret;
 
+       host->mmc->dev = dev;
        upriv->mmc = host->mmc;
 
        return 0;
index f4646a824fa148e683cb258cf314e84d8dc2a946..7da059c43cd69650911572183b777d85fdb23612 100644 (file)
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <fdtdec.h>
 #include <mmc.h>
 #include <asm/test.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+struct sandbox_mmc_plat {
+       struct mmc_config cfg;
+       struct mmc mmc;
+};
+
+/**
+ * sandbox_mmc_send_cmd() - Emulate SD commands
+ *
+ * This emulate an SD card version 2. Single-block reads result in zero data.
+ * Multiple-block reads return a test string.
+ */
+static int sandbox_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+                               struct mmc_data *data)
+{
+       switch (cmd->cmdidx) {
+       case MMC_CMD_ALL_SEND_CID:
+               break;
+       case SD_CMD_SEND_RELATIVE_ADDR:
+               cmd->response[0] = 0 << 16; /* mmc->rca */
+       case MMC_CMD_GO_IDLE_STATE:
+               break;
+       case SD_CMD_SEND_IF_COND:
+               cmd->response[0] = 0xaa;
+               break;
+       case MMC_CMD_SEND_STATUS:
+               cmd->response[0] = MMC_STATUS_RDY_FOR_DATA;
+               break;
+       case MMC_CMD_SELECT_CARD:
+               break;
+       case MMC_CMD_SEND_CSD:
+               cmd->response[0] = 0;
+               cmd->response[1] = 10 << 16;    /* 1 << block_len */
+               break;
+       case SD_CMD_SWITCH_FUNC: {
+               u32 *resp = (u32 *)data->dest;
+
+               resp[7] = cpu_to_be32(SD_HIGHSPEED_BUSY);
+               break;
+       }
+       case MMC_CMD_READ_SINGLE_BLOCK:
+               memset(data->dest, '\0', data->blocksize);
+               break;
+       case MMC_CMD_READ_MULTIPLE_BLOCK:
+               strcpy(data->dest, "this is a test");
+               break;
+       case MMC_CMD_STOP_TRANSMISSION:
+               break;
+       case SD_CMD_APP_SEND_OP_COND:
+               cmd->response[0] = OCR_BUSY | OCR_HCS;
+               cmd->response[1] = 0;
+               cmd->response[2] = 0;
+               break;
+       case MMC_CMD_APP_CMD:
+               break;
+       case MMC_CMD_SET_BLOCKLEN:
+               debug("block len %d\n", cmd->cmdarg);
+               break;
+       case SD_CMD_APP_SEND_SCR: {
+               u32 *scr = (u32 *)data->dest;
+
+               scr[0] = cpu_to_be32(2 << 24 | 1 << 15);  /* SD version 3 */
+               break;
+       }
+       default:
+               debug("%s: Unknown command %d\n", __func__, cmd->cmdidx);
+               break;
+       }
+
+       return 0;
+}
+
+static void sandbox_mmc_set_ios(struct mmc *mmc)
+{
+}
+
+static int sandbox_mmc_init(struct mmc *mmc)
+{
+       return 0;
+}
+
+static int sandbox_mmc_getcd(struct mmc *mmc)
+{
+       return 1;
+}
+
+static const struct mmc_ops sandbox_mmc_ops = {
+       .send_cmd = sandbox_mmc_send_cmd,
+       .set_ios = sandbox_mmc_set_ios,
+       .init = sandbox_mmc_init,
+       .getcd = sandbox_mmc_getcd,
+};
+
+int sandbox_mmc_probe(struct udevice *dev)
+{
+       struct sandbox_mmc_plat *plat = dev_get_platdata(dev);
+
+       return mmc_init(&plat->mmc);
+}
+
+int sandbox_mmc_bind(struct udevice *dev)
+{
+       struct sandbox_mmc_plat *plat = dev_get_platdata(dev);
+       struct mmc_config *cfg = &plat->cfg;
+       int ret;
+
+       cfg->name = dev->name;
+       cfg->ops = &sandbox_mmc_ops;
+       cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_8BIT;
+       cfg->voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
+       cfg->f_min = 1000000;
+       cfg->f_max = 52000000;
+       cfg->b_max = U32_MAX;
+
+       ret = mmc_bind(dev, &plat->mmc, cfg);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+int sandbox_mmc_unbind(struct udevice *dev)
+{
+       mmc_unbind(dev);
+
+       return 0;
+}
+
 static const struct udevice_id sandbox_mmc_ids[] = {
        { .compatible = "sandbox,mmc" },
        { }
 };
 
-U_BOOT_DRIVER(warm_mmc_sandbox) = {
+U_BOOT_DRIVER(mmc_sandbox) = {
        .name           = "mmc_sandbox",
        .id             = UCLASS_MMC,
        .of_match       = sandbox_mmc_ids,
+       .bind           = sandbox_mmc_bind,
+       .unbind         = sandbox_mmc_unbind,
+       .probe          = sandbox_mmc_probe,
+       .platdata_auto_alloc_size = sizeof(struct sandbox_mmc_plat),
 };
index 097db81b05131a63d030983def8c593beac0dfe8..6a0e9719b8a49cb354b46ed711350e2bb47a2293 100644 (file)
@@ -108,6 +108,7 @@ static int socfpga_dwmmc_probe(struct udevice *dev)
                return ret;
 
        upriv->mmc = host->mmc;
+       host->mmc->dev = dev;
 
        return 0;
 }
index 81a80cdbc2ca98728a28ea8466b4bd9c8dfb6bd9..4978cca76d898f712b6091409d7084a77817902d 100644 (file)
@@ -725,6 +725,7 @@ int uniphier_sd_probe(struct udevice *dev)
                return -EIO;
 
        upriv->mmc = priv->mmc;
+       priv->mmc->dev = dev;
 
        return 0;
 }
index b59feca80b5cf1d649e4b03a81eb232ecee38bf6..d405929b64140fa4355bf7c399850ab76a3da645 100644 (file)
@@ -35,6 +35,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
                  CONFIG_ZYNQ_SDHCI_MIN_FREQ);
 
        upriv->mmc = host->mmc;
+       host->mmc->dev = dev;
 
        return 0;
 }
index c58841e7d87dcc495a3369972ff99c12db1091c5..390e9e4ea3f64fa953f68751ea8f1a8c1b073bcd 100644 (file)
@@ -28,6 +28,13 @@ config ALTERA_QSPI
          NOR flash to parallel flash interface. Please find details on the
          "Embedded Peripherals IP User Guide" of Altera.
 
+config FLASH_PIC32
+       bool "Microchip PIC32 Flash driver"
+       depends on MACH_PIC32 && MTD
+       help
+         This enables access to Microchip PIC32 internal non-CFI flash
+         chips through PIC32 Non-Volatile-Memory Controller.
+
 endmenu
 
 source "drivers/mtd/nand/Kconfig"
index 703700aae0b4ff391f67254e74558309d57e8fd9..bd680a784f53d2348d89a1ef582c8554c4dc6de1 100644 (file)
@@ -19,5 +19,6 @@ obj-$(CONFIG_HAS_DATAFLASH) += dataflash.o
 obj-$(CONFIG_FTSMC020) += ftsmc020.o
 obj-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o
 obj-$(CONFIG_MW_EEPROM) += mw_eeprom.o
+obj-$(CONFIG_FLASH_PIC32) += pic32_flash.o
 obj-$(CONFIG_ST_SMI) += st_smi.o
 obj-$(CONFIG_STM32_FLASH) += stm32_flash.o
diff --git a/drivers/mtd/pic32_flash.c b/drivers/mtd/pic32_flash.c
new file mode 100644 (file)
index 0000000..9166fcd
--- /dev/null
@@ -0,0 +1,444 @@
+/*
+ * Copyright (C) 2015
+ * Cristian Birsan <cristian.birsan@microchip.com>
+ * Purna Chandra Mandal <purna.mandal@microchip.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdt_support.h>
+#include <flash.h>
+#include <mach/pic32.h>
+#include <wait_bit.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* NVM Controller registers */
+struct pic32_reg_nvm {
+       struct pic32_reg_atomic ctrl;
+       struct pic32_reg_atomic key;
+       struct pic32_reg_atomic addr;
+       struct pic32_reg_atomic data;
+};
+
+/* NVM operations */
+#define NVMOP_NOP              0
+#define NVMOP_WORD_WRITE       1
+#define NVMOP_PAGE_ERASE       4
+
+/* NVM control bits */
+#define NVM_WR                 BIT(15)
+#define NVM_WREN               BIT(14)
+#define NVM_WRERR              BIT(13)
+#define NVM_LVDERR             BIT(12)
+
+/* NVM programming unlock register */
+#define LOCK_KEY               0x0
+#define UNLOCK_KEY1            0xaa996655
+#define UNLOCK_KEY2            0x556699aa
+
+/*
+ * PIC32 flash banks consist of number of pages, each page
+ * into number of rows and rows into number of words.
+ * Here we will maintain page information instead of sector.
+ */
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
+static struct pic32_reg_nvm *nvm_regs_p;
+
+static inline void flash_initiate_operation(u32 nvmop)
+{
+       /* set operation */
+       writel(nvmop, &nvm_regs_p->ctrl.raw);
+
+       /* enable flash write */
+       writel(NVM_WREN, &nvm_regs_p->ctrl.set);
+
+       /* unlock sequence */
+       writel(LOCK_KEY, &nvm_regs_p->key.raw);
+       writel(UNLOCK_KEY1, &nvm_regs_p->key.raw);
+       writel(UNLOCK_KEY2, &nvm_regs_p->key.raw);
+
+       /* initiate operation */
+       writel(NVM_WR, &nvm_regs_p->ctrl.set);
+}
+
+static int flash_wait_till_busy(const char *func, ulong timeout)
+{
+       int ret = wait_for_bit(__func__, &nvm_regs_p->ctrl.raw,
+                              NVM_WR, false, timeout, false);
+
+       return ret ? ERR_TIMOUT : ERR_OK;
+}
+
+static inline int flash_complete_operation(void)
+{
+       u32 tmp;
+
+       tmp = readl(&nvm_regs_p->ctrl.raw);
+       if (tmp & NVM_WRERR) {
+               printf("Error in Block Erase - Lock Bit may be set!\n");
+               flash_initiate_operation(NVMOP_NOP);
+               return ERR_PROTECTED;
+       }
+
+       if (tmp & NVM_LVDERR) {
+               printf("Error in Block Erase - low-vol detected!\n");
+               flash_initiate_operation(NVMOP_NOP);
+               return ERR_NOT_ERASED;
+       }
+
+       /* disable flash write or erase operation */
+       writel(NVM_WREN, &nvm_regs_p->ctrl.clr);
+
+       return ERR_OK;
+}
+
+/*
+ * Erase flash sectors, returns:
+ * ERR_OK - OK
+ * ERR_INVAL - invalid sector arguments
+ * ERR_TIMOUT - write timeout
+ * ERR_NOT_ERASED - Flash not erased
+ * ERR_UNKNOWN_FLASH_VENDOR - incorrect flash
+ */
+int flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+       ulong sect_start, sect_end, flags;
+       int prot, sect;
+       int rc;
+
+       if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_MCHP) {
+               printf("Can't erase unknown flash type %08lx - aborted\n",
+                      info->flash_id);
+               return ERR_UNKNOWN_FLASH_VENDOR;
+       }
+
+       if ((s_first < 0) || (s_first > s_last)) {
+               printf("- no sectors to erase\n");
+               return ERR_INVAL;
+       }
+
+       prot = 0;
+       for (sect = s_first; sect <= s_last; ++sect) {
+               if (info->protect[sect])
+                       prot++;
+       }
+
+       if (prot)
+               printf("- Warning: %d protected sectors will not be erased!\n",
+                      prot);
+       else
+               printf("\n");
+
+       /* erase on unprotected sectors */
+       for (sect = s_first; sect <= s_last; sect++) {
+               if (info->protect[sect])
+                       continue;
+
+               /* disable interrupts */
+               flags = disable_interrupts();
+
+               /* write destination page address (physical) */
+               sect_start = CPHYSADDR(info->start[sect]);
+               writel(sect_start, &nvm_regs_p->addr.raw);
+
+               /* page erase */
+               flash_initiate_operation(NVMOP_PAGE_ERASE);
+
+               /* wait */
+               rc = flash_wait_till_busy(__func__,
+                                         CONFIG_SYS_FLASH_ERASE_TOUT);
+
+               /* re-enable interrupts if necessary */
+               if (flags)
+                       enable_interrupts();
+
+               if (rc != ERR_OK)
+                       return rc;
+
+               rc = flash_complete_operation();
+               if (rc != ERR_OK)
+                       return rc;
+
+               /*
+                * flash content is updated but cache might contain stale
+                * data, so invalidate dcache.
+                */
+               sect_end = info->start[sect] + info->size / info->sector_count;
+               invalidate_dcache_range(info->start[sect], sect_end);
+       }
+
+       printf(" done\n");
+       return ERR_OK;
+}
+
+int page_erase(flash_info_t *info, int sect)
+{
+       return 0;
+}
+
+/* Write a word to flash */
+static int write_word(flash_info_t *info, ulong dest, ulong word)
+{
+       ulong flags;
+       int rc;
+
+       /* read flash to check if it is sufficiently erased */
+       if ((readl((void __iomem *)dest) & word) != word) {
+               printf("Error, Flash not erased!\n");
+               return ERR_NOT_ERASED;
+       }
+
+       /* disable interrupts */
+       flags = disable_interrupts();
+
+       /* update destination page address (physical) */
+       writel(CPHYSADDR(dest), &nvm_regs_p->addr.raw);
+       writel(word, &nvm_regs_p->data.raw);
+
+       /* word write */
+       flash_initiate_operation(NVMOP_WORD_WRITE);
+
+       /* wait for operation to complete */
+       rc = flash_wait_till_busy(__func__, CONFIG_SYS_FLASH_WRITE_TOUT);
+
+       /* re-enable interrupts if necessary */
+       if (flags)
+               enable_interrupts();
+
+       if (rc != ERR_OK)
+               return rc;
+
+       return flash_complete_operation();
+}
+
+/*
+ * Copy memory to flash, returns:
+ * ERR_OK - OK
+ * ERR_TIMOUT - write timeout
+ * ERR_NOT_ERASED - Flash not erased
+ */
+int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+       ulong dst, tmp_le, len = cnt;
+       int i, l, rc;
+       uchar *cp;
+
+       /* get lower word aligned address */
+       dst = (addr & ~3);
+
+       /* handle unaligned start bytes */
+       l = addr - dst;
+       if (l != 0) {
+               tmp_le = 0;
+               for (i = 0, cp = (uchar *)dst; i < l; ++i, ++cp)
+                       tmp_le |= *cp << (i * 8);
+
+               for (; (i < 4) && (cnt > 0); ++i, ++src, --cnt, ++cp)
+                       tmp_le |= *src << (i * 8);
+
+               for (; (cnt == 0) && (i < 4); ++i, ++cp)
+                       tmp_le |= *cp << (i * 8);
+
+               rc = write_word(info, dst, tmp_le);
+               if (rc)
+                       goto out;
+
+               dst += 4;
+       }
+
+       /* handle word aligned part */
+       while (cnt >= 4) {
+               tmp_le = src[0] | src[1] << 8 | src[2] << 16 | src[3] << 24;
+               rc = write_word(info, dst, tmp_le);
+               if (rc)
+                       goto out;
+               src += 4;
+               dst += 4;
+               cnt -= 4;
+       }
+
+       if (cnt == 0) {
+               rc = ERR_OK;
+               goto out;
+       }
+
+       /* handle unaligned tail bytes */
+       tmp_le = 0;
+       for (i = 0, cp = (uchar *)dst; (i < 4) && (cnt > 0); ++i, ++cp) {
+               tmp_le |= *src++ << (i * 8);
+               --cnt;
+       }
+
+       for (; i < 4; ++i, ++cp)
+               tmp_le |= *cp << (i * 8);
+
+       rc = write_word(info, dst, tmp_le);
+out:
+       /*
+        * flash content updated by nvm controller but CPU cache might
+        * have stale data, so invalidate dcache.
+        */
+       invalidate_dcache_range(addr, addr + len);
+
+       printf(" done\n");
+       return rc;
+}
+
+void flash_print_info(flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_MCHP:
+               printf("Microchip Technology ");
+               break;
+       default:
+               printf("Unknown Vendor ");
+               break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_MCHP100T:
+               printf("Internal (8 Mbit, 64 x 16k)\n");
+               break;
+       default:
+               printf("Unknown Chip Type\n");
+               break;
+       }
+
+       printf("  Size: %ld MB in %d Sectors\n",
+              info->size >> 20, info->sector_count);
+
+       printf("  Sector Start Addresses:");
+       for (i = 0; i < info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf("\n   ");
+
+               printf(" %08lX%s", info->start[i],
+                      info->protect[i] ? " (RO)" : "     ");
+       }
+       printf("\n");
+}
+
+unsigned long flash_init(void)
+{
+       unsigned long size = 0;
+       struct udevice *dev;
+       int bank;
+
+       /* probe every MTD device */
+       for (uclass_first_device(UCLASS_MTD, &dev); dev;
+            uclass_next_device(&dev)) {
+               /* nop */
+       }
+
+       /* calc total flash size */
+       for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank)
+               size += flash_info[bank].size;
+
+       return size;
+}
+
+static void pic32_flash_bank_init(flash_info_t *info,
+                                 ulong base, ulong size)
+{
+       ulong sect_size;
+       int sect;
+
+       /* device & manufacturer code */
+       info->flash_id = FLASH_MAN_MCHP | FLASH_MCHP100T;
+       info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
+       info->size = size;
+
+       /* update sector (i.e page) info */
+       sect_size = info->size / info->sector_count;
+       for (sect = 0; sect < info->sector_count; sect++) {
+               info->start[sect] = base;
+               /* protect each sector by default */
+               info->protect[sect] = 1;
+               base += sect_size;
+       }
+}
+
+static int pic32_flash_probe(struct udevice *dev)
+{
+       void *blob = (void *)gd->fdt_blob;
+       int node = dev->of_offset;
+       const char *list, *end;
+       const fdt32_t *cell;
+       unsigned long addr, size;
+       int parent, addrc, sizec;
+       flash_info_t *info;
+       int len, idx;
+
+       /*
+        * decode regs. there are multiple reg tuples, and they need to
+        * match with reg-names.
+        */
+       parent = fdt_parent_offset(blob, node);
+       of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+       list = fdt_getprop(blob, node, "reg-names", &len);
+       if (!list)
+               return -ENOENT;
+
+       end = list + len;
+       cell = fdt_getprop(blob, node, "reg", &len);
+       if (!cell)
+               return -ENOENT;
+
+       for (idx = 0, info = &flash_info[0]; list < end;) {
+               addr = fdt_translate_address((void *)blob, node, cell + idx);
+               size = fdt_addr_to_cpu(cell[idx + addrc]);
+               len = strlen(list);
+               if (!strncmp(list, "nvm", len)) {
+                       /* NVM controller */
+                       nvm_regs_p = ioremap(addr, size);
+               } else if (!strncmp(list, "bank", 4)) {
+                       /* Flash bank: use kseg0 cached address */
+                       pic32_flash_bank_init(info, CKSEG0ADDR(addr), size);
+                       info++;
+               }
+               idx += addrc + sizec;
+               list += len + 1;
+       }
+
+       /* disable flash write/erase operations */
+       writel(NVM_WREN, &nvm_regs_p->ctrl.clr);
+
+#if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
+       /* monitor protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CONFIG_SYS_MONITOR_BASE,
+                     CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
+                     &flash_info[0]);
+#endif
+
+#ifdef CONFIG_ENV_IS_IN_FLASH
+       /* ENV protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CONFIG_ENV_ADDR,
+                     CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
+                     &flash_info[0]);
+#endif
+       return 0;
+}
+
+static const struct udevice_id pic32_flash_ids[] = {
+       { .compatible = "microchip,pic32mzda-flash" },
+       {}
+};
+
+U_BOOT_DRIVER(pic32_flash) = {
+       .name   = "pic32_flash",
+       .id     = UCLASS_MTD,
+       .of_match = pic32_flash_ids,
+       .probe  = pic32_flash_probe,
+};
index 461908941de2ef7f6220a22e9a7ab2e69c082f48..4b73a0ff9cb273cd3f01d7aeaff1bfc8b537bfca 100644 (file)
@@ -175,11 +175,7 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
        int bus;
 
        for (hose = pci_get_hose_head(); hose; hose = hose->next) {
-#ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
-               for (bus = hose->last_busno; bus >= hose->first_busno; bus--) {
-#else
                for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
-#endif
                        bdf = pci_hose_find_devices(hose, bus, ids, &index);
                        if (bdf != -1)
                                return bdf;
index 2a69babec441966da37b0874fd014516a1fe8518..567b7662d00d915e309fb029316ba52a60aa8271 100644 (file)
@@ -105,6 +105,24 @@ config SPL_PINCONF
 
 if PINCTRL || SPL_PINCTRL
 
+config AR933X_PINCTRL
+       bool "QCA/Athores ar933x pin control driver"
+       depends on DM && SOC_AR933X
+       help
+         Support pin multiplexing control on QCA/Athores ar933x SoCs.
+         The driver is controlled by a device tree node which contains
+         both the GPIO definitions and pin control functions for each
+         available multiplex function.
+
+config QCA953X_PINCTRL
+       bool "QCA/Athores qca953x pin control driver"
+       depends on DM && SOC_QCA953X
+       help
+         Support pin multiplexing control on QCA/Athores qca953x SoCs.
+         The driver is controlled by a device tree node which contains
+         both the GPIO definitions and pin control functions for each
+         available multiplex function.
+
 config ROCKCHIP_PINCTRL
        bool "Rockchip pin control driver"
        depends on DM
index 37dc904640e417bc92a5ec0ba043ad49ca862c90..b99ed2f1916f338baafdc7abd252f22bcd52b976 100644 (file)
@@ -6,6 +6,7 @@ obj-y                                   += pinctrl-uclass.o
 obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC)   += pinctrl-generic.o
 
 obj-y                                  += nxp/
+obj-$(CONFIG_ARCH_ATH79) += ath79/
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
 obj-$(CONFIG_PINCTRL_SANDBOX)  += pinctrl-sandbox.o
 
diff --git a/drivers/pinctrl/ath79/Makefile b/drivers/pinctrl/ath79/Makefile
new file mode 100644 (file)
index 0000000..dcea10a
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_AR933X_PINCTRL) += pinctrl_ar933x.o
+obj-$(CONFIG_QCA953x_PINCTRL) += pinctrl_qca953x.o
diff --git a/drivers/pinctrl/ath79/pinctrl_ar933x.c b/drivers/pinctrl/ath79/pinctrl_ar933x.c
new file mode 100644 (file)
index 0000000..e3f64b6
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/pinctrl.h>
+#include <mach/ar71xx_regs.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum periph_id {
+       PERIPH_ID_UART0,
+       PERIPH_ID_SPI0,
+       PERIPH_ID_NONE = -1,
+};
+
+struct ar933x_pinctrl_priv {
+       void __iomem *regs;
+};
+
+static void pinctrl_ar933x_spi_config(struct ar933x_pinctrl_priv *priv, int cs)
+{
+       switch (cs) {
+       case 0:
+               clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
+                               AR933X_GPIO(4), AR933X_GPIO(3) |
+                               AR933X_GPIO(5) | AR933X_GPIO(2));
+               setbits_be32(priv->regs + AR71XX_GPIO_REG_FUNC,
+                            AR933X_GPIO_FUNC_SPI_EN |
+                            AR933X_GPIO_FUNC_RES_TRUE);
+               break;
+       }
+}
+
+static void pinctrl_ar933x_uart_config(struct ar933x_pinctrl_priv *priv, int uart_id)
+{
+       switch (uart_id) {
+       case PERIPH_ID_UART0:
+               clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
+                               AR933X_GPIO(9), AR933X_GPIO(10));
+               setbits_be32(priv->regs + AR71XX_GPIO_REG_FUNC,
+                            AR933X_GPIO_FUNC_UART_EN |
+                            AR933X_GPIO_FUNC_RES_TRUE);
+               break;
+       }
+}
+
+static int ar933x_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+       struct ar933x_pinctrl_priv *priv = dev_get_priv(dev);
+
+       debug("%s: func=%x, flags=%x\n", __func__, func, flags);
+       switch (func) {
+       case PERIPH_ID_SPI0:
+               pinctrl_ar933x_spi_config(priv, flags);
+               break;
+       case PERIPH_ID_UART0:
+               pinctrl_ar933x_uart_config(priv, func);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int ar933x_pinctrl_get_periph_id(struct udevice *dev,
+                                       struct udevice *periph)
+{
+       u32 cell[2];
+       int ret;
+
+       ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+                                  "interrupts", cell, ARRAY_SIZE(cell));
+       if (ret < 0)
+               return -EINVAL;
+
+       switch (cell[0]) {
+       case 128:
+               return PERIPH_ID_UART0;
+       case 129:
+               return PERIPH_ID_SPI0;
+       }
+       return -ENOENT;
+}
+
+static int ar933x_pinctrl_set_state_simple(struct udevice *dev,
+                                          struct udevice *periph)
+{
+       int func;
+
+       func = ar933x_pinctrl_get_periph_id(dev, periph);
+       if (func < 0)
+               return func;
+       return ar933x_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops ar933x_pinctrl_ops = {
+       .set_state_simple       = ar933x_pinctrl_set_state_simple,
+       .request        = ar933x_pinctrl_request,
+       .get_periph_id  = ar933x_pinctrl_get_periph_id,
+};
+
+static int ar933x_pinctrl_probe(struct udevice *dev)
+{
+       struct ar933x_pinctrl_priv *priv = dev_get_priv(dev);
+       fdt_addr_t addr;
+
+       addr = dev_get_addr(dev);
+       if (addr == FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       priv->regs = map_physmem(addr,
+                                AR71XX_GPIO_SIZE,
+                                MAP_NOCACHE);
+       return 0;
+}
+
+static const struct udevice_id ar933x_pinctrl_ids[] = {
+       { .compatible = "qca,ar933x-pinctrl" },
+       { }
+};
+
+U_BOOT_DRIVER(pinctrl_ar933x) = {
+       .name           = "pinctrl_ar933x",
+       .id             = UCLASS_PINCTRL,
+       .of_match       = ar933x_pinctrl_ids,
+       .priv_auto_alloc_size = sizeof(struct ar933x_pinctrl_priv),
+       .ops            = &ar933x_pinctrl_ops,
+       .probe          = ar933x_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/ath79/pinctrl_qca953x.c b/drivers/pinctrl/ath79/pinctrl_qca953x.c
new file mode 100644 (file)
index 0000000..d02597e
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/pinctrl.h>
+#include <mach/ar71xx_regs.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum periph_id {
+       PERIPH_ID_UART0,
+       PERIPH_ID_SPI0,
+       PERIPH_ID_NONE = -1,
+};
+
+struct qca953x_pinctrl_priv {
+       void __iomem *regs;
+};
+
+static void pinctrl_qca953x_spi_config(struct qca953x_pinctrl_priv *priv, int cs)
+{
+       switch (cs) {
+       case 0:
+               clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
+                               QCA953X_GPIO(5) | QCA953X_GPIO(6) |
+                               QCA953X_GPIO(7), QCA953X_GPIO(8));
+
+               clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_OUT_FUNC1,
+                               QCA953X_GPIO_MUX_MASK(8) |
+                               QCA953X_GPIO_MUX_MASK(16) |
+                               QCA953X_GPIO_MUX_MASK(24),
+                               (QCA953X_GPIO_OUT_MUX_SPI_CS0 << 8) |
+                               (QCA953X_GPIO_OUT_MUX_SPI_CLK << 16) |
+                               (QCA953X_GPIO_OUT_MUX_SPI_MOSI << 24));
+
+               clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_IN_ENABLE0,
+                               QCA953X_GPIO_MUX_MASK(0),
+                               QCA953X_GPIO_IN_MUX_SPI_DATA_IN);
+
+               setbits_be32(priv->regs + AR71XX_GPIO_REG_OUT,
+                            QCA953X_GPIO(8));
+               break;
+       }
+}
+
+static void pinctrl_qca953x_uart_config(struct qca953x_pinctrl_priv *priv, int uart_id)
+{
+       switch (uart_id) {
+       case PERIPH_ID_UART0:
+               clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
+                               QCA953X_GPIO(9), QCA953X_GPIO(10));
+
+               clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_OUT_FUNC2,
+                               QCA953X_GPIO_MUX_MASK(16),
+                               QCA953X_GPIO_OUT_MUX_UART0_SOUT << 16);
+
+               clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_IN_ENABLE0,
+                               QCA953X_GPIO_MUX_MASK(8),
+                               QCA953X_GPIO_IN_MUX_UART0_SIN << 8);
+
+               setbits_be32(priv->regs + AR71XX_GPIO_REG_OUT,
+                            QCA953X_GPIO(10));
+               break;
+       }
+}
+
+static int qca953x_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+       struct qca953x_pinctrl_priv *priv = dev_get_priv(dev);
+
+       debug("%s: func=%x, flags=%x\n", __func__, func, flags);
+       switch (func) {
+       case PERIPH_ID_SPI0:
+               pinctrl_qca953x_spi_config(priv, flags);
+               break;
+       case PERIPH_ID_UART0:
+               pinctrl_qca953x_uart_config(priv, func);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int qca953x_pinctrl_get_periph_id(struct udevice *dev,
+                                       struct udevice *periph)
+{
+       u32 cell[2];
+       int ret;
+
+       ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+                                  "interrupts", cell, ARRAY_SIZE(cell));
+       if (ret < 0)
+               return -EINVAL;
+
+       switch (cell[0]) {
+       case 128:
+               return PERIPH_ID_UART0;
+       case 129:
+               return PERIPH_ID_SPI0;
+       }
+       return -ENOENT;
+}
+
+static int qca953x_pinctrl_set_state_simple(struct udevice *dev,
+                                          struct udevice *periph)
+{
+       int func;
+
+       func = qca953x_pinctrl_get_periph_id(dev, periph);
+       if (func < 0)
+               return func;
+       return qca953x_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops qca953x_pinctrl_ops = {
+       .set_state_simple       = qca953x_pinctrl_set_state_simple,
+       .request        = qca953x_pinctrl_request,
+       .get_periph_id  = qca953x_pinctrl_get_periph_id,
+};
+
+static int qca953x_pinctrl_probe(struct udevice *dev)
+{
+       struct qca953x_pinctrl_priv *priv = dev_get_priv(dev);
+       fdt_addr_t addr;
+
+       addr = dev_get_addr(dev);
+       if (addr == FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       priv->regs = map_physmem(addr,
+                                AR71XX_GPIO_SIZE,
+                                MAP_NOCACHE);
+       return 0;
+}
+
+static const struct udevice_id qca953x_pinctrl_ids[] = {
+       { .compatible = "qca,qca953x-pinctrl" },
+       { }
+};
+
+U_BOOT_DRIVER(pinctrl_qca953x) = {
+       .name           = "pinctrl_qca953x",
+       .id             = UCLASS_PINCTRL,
+       .of_match       = qca953x_pinctrl_ids,
+       .priv_auto_alloc_size = sizeof(struct qca953x_pinctrl_priv),
+       .ops            = &qca953x_pinctrl_ops,
+       .probe          = qca953x_pinctrl_probe,
+};
index a9a5d475dd728d6162889a4772519a5c97c757da..2497ae90a09051b2fa055b8e2f5d53c06cca23cb 100644 (file)
@@ -89,6 +89,15 @@ config DEBUG_UART_ALTERA_UART
          You will need to provide parameters to make this work. The driver will
          be available until the real driver model serial is running.
 
+config DEBUG_UART_AR933X
+       bool "QCA/Atheros ar933x"
+       depends on AR933X_UART
+       help
+         Select this to enable a debug UART using the ar933x uart driver.
+         You will need to provide parameters to make this work. The
+         driver will be available until the real driver model serial is
+         running.
+
 config DEBUG_UART_NS16550
        bool "ns16550"
        help
@@ -263,6 +272,15 @@ config ALTERA_UART
          Select this to enable an UART for Altera devices. Please find
          details on the "Embedded Peripherals IP User Guide" of Altera.
 
+config AR933X_UART
+       bool "QCA/Atheros ar933x UART support"
+       depends on DM_SERIAL && SOC_AR933X
+       help
+         Select this to enable UART support for QCA/Atheros ar933x
+         devices. This driver uses driver model and requires a device
+         tree binding to operate, please refer to the document at
+         doc/device-tree-bindings/serial/qca,ar9330-uart.txt.
+
 config FSL_LPUART
        bool "Freescale LPUART support"
        help
index b0ac9d8a5639ca05a4dcdc54c4cd7a5e8ca2274b..9def128e8908e22fa0624d492ac847c95b33cd2c 100644 (file)
@@ -17,6 +17,7 @@ endif
 
 obj-$(CONFIG_ALTERA_UART) += altera_uart.o
 obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
+obj-$(CONFIG_AR933X_UART) += serial_ar933x.o
 obj-$(CONFIG_ARM_DCC) += arm_dcc.o
 obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
 obj-$(CONFIG_EFI_APP) += serial_efi.o
index 407354fc4cdf2acac18fee8d014e4d92f63078f3..059cb0fc6e549d6e088374667ca0f9f9a3e4dbdc 100644 (file)
@@ -2,6 +2,9 @@
  * (C) Copyright 2004-2007 Freescale Semiconductor, Inc.
  * TsiChung Liew, Tsi-Chung.Liew@freescale.com.
  *
+ * Modified to add device model (DM) support
+ * (C) Copyright 2015  Angelo Dureghello <angelo@sysam.it>
+ *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
  */
 
 #include <common.h>
+#include <dm.h>
+#include <dm/platform_data/serial_coldfire.h>
 #include <serial.h>
 #include <linux/compiler.h>
-
 #include <asm/immap.h>
 #include <asm/uart.h>
 
@@ -21,91 +25,110 @@ DECLARE_GLOBAL_DATA_PTR;
 
 extern void uart_port_conf(int port);
 
-static int mcf_serial_init(void)
+static int mcf_serial_init_common(uart_t *uart, int port_idx, int baudrate)
 {
-       volatile uart_t *uart;
        u32 counter;
 
-       uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
-
-       uart_port_conf(CONFIG_SYS_UART_PORT);
+       uart_port_conf(port_idx);
 
        /* write to SICR: SIM2 = uart mode,dcd does not affect rx */
-       uart->ucr = UART_UCR_RESET_RX;
-       uart->ucr = UART_UCR_RESET_TX;
-       uart->ucr = UART_UCR_RESET_ERROR;
-       uart->ucr = UART_UCR_RESET_MR;
+       writeb(UART_UCR_RESET_RX, &uart->ucr);
+       writeb(UART_UCR_RESET_TX, &uart->ucr);
+       writeb(UART_UCR_RESET_ERROR, &uart->ucr);
+       writeb(UART_UCR_RESET_MR, &uart->ucr);
        __asm__("nop");
 
-       uart->uimr = 0;
+       writeb(0, &uart->uimr);
 
        /* write to CSR: RX/TX baud rate from timers */
-       uart->ucsr = (UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK);
+       writeb(UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK, &uart->ucsr);
 
-       uart->umr = (UART_UMR_BC_8 | UART_UMR_PM_NONE);
-       uart->umr = UART_UMR_SB_STOP_BITS_1;
+       writeb(UART_UMR_BC_8 | UART_UMR_PM_NONE, &uart->umr);
+       writeb(UART_UMR_SB_STOP_BITS_1, &uart->umr);
 
        /* Setting up BaudRate */
-       counter = (u32) ((gd->bus_clk / 32) + (gd->baudrate / 2));
-       counter = counter / gd->baudrate;
+       counter = (u32) ((gd->bus_clk / 32) + (baudrate / 2));
+       counter = counter / baudrate;
 
        /* write to CTUR: divide counter upper byte */
-       uart->ubg1 = (u8) ((counter & 0xff00) >> 8);
+       writeb((u8)((counter & 0xff00) >> 8), &uart->ubg1);
        /* write to CTLR: divide counter lower byte */
-       uart->ubg2 = (u8) (counter & 0x00ff);
+       writeb((u8)(counter & 0x00ff), &uart->ubg2);
 
-       uart->ucr = (UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED);
+       writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr);
 
        return (0);
 }
 
+static void mcf_serial_setbrg_common(uart_t *uart, int baudrate)
+{
+       u32 counter;
+
+       /* Setting up BaudRate */
+       counter = (u32) ((gd->bus_clk / 32) + (baudrate / 2));
+       counter = counter / baudrate;
+
+       /* write to CTUR: divide counter upper byte */
+       writeb(((counter & 0xff00) >> 8), &uart->ubg1);
+       /* write to CTLR: divide counter lower byte */
+       writeb((counter & 0x00ff), &uart->ubg2);
+
+       writeb(UART_UCR_RESET_RX, &uart->ucr);
+       writeb(UART_UCR_RESET_TX, &uart->ucr);
+
+       writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr);
+}
+
+#ifndef CONFIG_DM_SERIAL
+
+static int mcf_serial_init(void)
+{
+       uart_t *uart_base;
+       int port_idx;
+
+       uart_base = (uart_t *)CONFIG_SYS_UART_BASE;
+       port_idx = CONFIG_SYS_UART_PORT;
+
+       return mcf_serial_init_common(uart_base, port_idx, gd->baudrate);
+}
+
 static void mcf_serial_putc(const char c)
 {
-       volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
+       uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
 
        if (c == '\n')
                serial_putc('\r');
 
        /* Wait for last character to go. */
-       while (!(uart->usr & UART_USR_TXRDY)) ;
+       while (!(readb(&uart->usr) & UART_USR_TXRDY))
+               ;
 
-       uart->utb = c;
+       writeb(c, &uart->utb);
 }
 
 static int mcf_serial_getc(void)
 {
-       volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
+       uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
 
        /* Wait for a character to arrive. */
-       while (!(uart->usr & UART_USR_RXRDY)) ;
-       return uart->urb;
-}
-
-static int mcf_serial_tstc(void)
-{
-       volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
+       while (!(readb(&uart->usr) & UART_USR_RXRDY))
+               ;
 
-       return (uart->usr & UART_USR_RXRDY);
+       return readb(&uart->urb);
 }
 
 static void mcf_serial_setbrg(void)
 {
-       volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
-       u32 counter;
-
-       /* Setting up BaudRate */
-       counter = (u32) ((gd->bus_clk / 32) + (gd->baudrate / 2));
-       counter = counter / gd->baudrate;
+       uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
 
-       /* write to CTUR: divide counter upper byte */
-       uart->ubg1 = ((counter & 0xff00) >> 8);
-       /* write to CTLR: divide counter lower byte */
-       uart->ubg2 = (counter & 0x00ff);
+       mcf_serial_setbrg_common(uart, gd->baudrate);
+}
 
-       uart->ucr = UART_UCR_RESET_RX;
-       uart->ucr = UART_UCR_RESET_TX;
+static int mcf_serial_tstc(void)
+{
+       uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
 
-       uart->ucr = UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED;
+       return readb(&uart->usr) & UART_USR_RXRDY;
 }
 
 static struct serial_device mcf_serial_drv = {
@@ -128,3 +151,80 @@ __weak struct serial_device *default_serial_console(void)
 {
        return &mcf_serial_drv;
 }
+
+#endif
+
+#ifdef CONFIG_DM_SERIAL
+
+static int coldfire_serial_probe(struct udevice *dev)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+
+       return mcf_serial_init_common((uart_t *)plat->base,
+                                               plat->port, plat->baudrate);
+}
+
+static int coldfire_serial_putc(struct udevice *dev, const char ch)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+       uart_t *uart = (uart_t *)plat->base;
+
+       /* Wait for last character to go. */
+       if (!(readb(&uart->usr) & UART_USR_TXRDY))
+               return -EAGAIN;
+
+       writeb(ch, &uart->utb);
+
+       return 0;
+}
+
+static int coldfire_serial_getc(struct udevice *dev)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+       uart_t *uart = (uart_t *)(plat->base);
+
+       /* Wait for a character to arrive. */
+       if (!(readb(&uart->usr) & UART_USR_RXRDY))
+               return -EAGAIN;
+
+       return readb(&uart->urb);
+}
+
+int coldfire_serial_setbrg(struct udevice *dev, int baudrate)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+       uart_t *uart = (uart_t *)(plat->base);
+
+       mcf_serial_setbrg_common(uart, baudrate);
+
+       return 0;
+}
+
+static int coldfire_serial_pending(struct udevice *dev, bool input)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+       uart_t *uart = (uart_t *)(plat->base);
+
+       if (input)
+               return readb(&uart->usr) & UART_USR_RXRDY ? 1 : 0;
+       else
+               return readb(&uart->usr) & UART_USR_TXRDY ? 0 : 1;
+
+       return 0;
+}
+
+static const struct dm_serial_ops coldfire_serial_ops = {
+       .putc = coldfire_serial_putc,
+       .pending = coldfire_serial_pending,
+       .getc = coldfire_serial_getc,
+       .setbrg = coldfire_serial_setbrg,
+};
+
+U_BOOT_DRIVER(serial_coldfire) = {
+       .name = "serial_coldfire",
+       .id = UCLASS_SERIAL,
+       .probe = coldfire_serial_probe,
+       .ops = &coldfire_serial_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
+#endif
diff --git a/drivers/serial/serial_ar933x.c b/drivers/serial/serial_ar933x.c
new file mode 100644 (file)
index 0000000..aae66dc
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <div64.h>
+#include <errno.h>
+#include <serial.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <dm/pinctrl.h>
+#include <mach/ar71xx_regs.h>
+
+#define AR933X_UART_DATA_REG            0x00
+#define AR933X_UART_CS_REG              0x04
+#define AR933X_UART_CLK_REG             0x08
+
+#define AR933X_UART_DATA_TX_RX_MASK     0xff
+#define AR933X_UART_DATA_RX_CSR         BIT(8)
+#define AR933X_UART_DATA_TX_CSR         BIT(9)
+#define AR933X_UART_CS_IF_MODE_S        2
+#define AR933X_UART_CS_IF_MODE_M        0x3
+#define AR933X_UART_CS_IF_MODE_DTE      1
+#define AR933X_UART_CS_IF_MODE_DCE      2
+#define AR933X_UART_CS_TX_RDY_ORIDE     BIT(7)
+#define AR933X_UART_CS_RX_RDY_ORIDE     BIT(8)
+#define AR933X_UART_CLK_STEP_M          0xffff
+#define AR933X_UART_CLK_SCALE_M         0xfff
+#define AR933X_UART_CLK_SCALE_S         16
+#define AR933X_UART_CLK_STEP_S          0
+
+struct ar933x_serial_priv {
+       void __iomem *regs;
+};
+
+/*
+ * Baudrate algorithm come from Linux/drivers/tty/serial/ar933x_uart.c
+ * baudrate = (clk / (scale + 1)) * (step * (1 / 2^17))
+ */
+static u32 ar933x_serial_get_baud(u32 clk, u32 scale, u32 step)
+{
+       u64 t;
+       u32 div;
+
+       div = (2 << 16) * (scale + 1);
+       t = clk;
+       t *= step;
+       t += (div / 2);
+       do_div(t, div);
+
+       return t;
+}
+
+static void ar933x_serial_get_scale_step(u32 clk, u32 baud,
+                                        u32 *scale, u32 *step)
+{
+       u32 tscale, baudrate;
+       long min_diff;
+
+       *scale = 0;
+       *step = 0;
+
+       min_diff = baud;
+       for (tscale = 0; tscale < AR933X_UART_CLK_SCALE_M; tscale++) {
+               u64 tstep;
+               int diff;
+
+               tstep = baud * (tscale + 1);
+               tstep *= (2 << 16);
+               do_div(tstep, clk);
+
+               if (tstep > AR933X_UART_CLK_STEP_M)
+                       break;
+
+               baudrate = ar933x_serial_get_baud(clk, tscale, tstep);
+               diff = abs(baudrate - baud);
+               if (diff < min_diff) {
+                       min_diff = diff;
+                       *scale = tscale;
+                       *step = tstep;
+               }
+       }
+}
+
+static int ar933x_serial_setbrg(struct udevice *dev, int baudrate)
+{
+       struct ar933x_serial_priv *priv = dev_get_priv(dev);
+       u32 val, scale, step;
+
+       val = get_serial_clock();
+       ar933x_serial_get_scale_step(val, baudrate, &scale, &step);
+
+       val  = (scale & AR933X_UART_CLK_SCALE_M)
+                       << AR933X_UART_CLK_SCALE_S;
+       val |= (step & AR933X_UART_CLK_STEP_M)
+                       << AR933X_UART_CLK_STEP_S;
+       writel(val, priv->regs + AR933X_UART_CLK_REG);
+
+       return 0;
+}
+
+static int ar933x_serial_putc(struct udevice *dev, const char c)
+{
+       struct ar933x_serial_priv *priv = dev_get_priv(dev);
+       u32 data;
+
+       data = readl(priv->regs + AR933X_UART_DATA_REG);
+       if (!(data & AR933X_UART_DATA_TX_CSR))
+               return -EAGAIN;
+
+       data  = (u32)c | AR933X_UART_DATA_TX_CSR;
+       writel(data, priv->regs + AR933X_UART_DATA_REG);
+
+       return 0;
+}
+
+static int ar933x_serial_getc(struct udevice *dev)
+{
+       struct ar933x_serial_priv *priv = dev_get_priv(dev);
+       u32 data;
+
+       data = readl(priv->regs + AR933X_UART_DATA_REG);
+       if (!(data & AR933X_UART_DATA_RX_CSR))
+               return -EAGAIN;
+
+       writel(AR933X_UART_DATA_RX_CSR, priv->regs + AR933X_UART_DATA_REG);
+       return data & AR933X_UART_DATA_TX_RX_MASK;
+}
+
+static int ar933x_serial_pending(struct udevice *dev, bool input)
+{
+       struct ar933x_serial_priv *priv = dev_get_priv(dev);
+       u32 data;
+
+       data = readl(priv->regs + AR933X_UART_DATA_REG);
+       if (input)
+               return (data & AR933X_UART_DATA_RX_CSR) ? 1 : 0;
+       else
+               return (data & AR933X_UART_DATA_TX_CSR) ? 0 : 1;
+}
+
+static int ar933x_serial_probe(struct udevice *dev)
+{
+       struct ar933x_serial_priv *priv = dev_get_priv(dev);
+       fdt_addr_t addr;
+       u32 val;
+
+       addr = dev_get_addr(dev);
+       if (addr == FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       priv->regs = map_physmem(addr, AR933X_UART_SIZE,
+                                MAP_NOCACHE);
+
+       /*
+        * UART controller configuration:
+        * - no DMA
+        * - no interrupt
+        * - DCE mode
+        * - no flow control
+        * - set RX ready oride
+        * - set TX ready oride
+        */
+       val = (AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S) |
+             AR933X_UART_CS_TX_RDY_ORIDE | AR933X_UART_CS_RX_RDY_ORIDE;
+       writel(val, priv->regs + AR933X_UART_CS_REG);
+       return 0;
+}
+
+static const struct dm_serial_ops ar933x_serial_ops = {
+       .putc = ar933x_serial_putc,
+       .pending = ar933x_serial_pending,
+       .getc = ar933x_serial_getc,
+       .setbrg = ar933x_serial_setbrg,
+};
+
+static const struct udevice_id ar933x_serial_ids[] = {
+       { .compatible = "qca,ar9330-uart" },
+       { }
+};
+
+U_BOOT_DRIVER(serial_ar933x) = {
+       .name   = "serial_ar933x",
+       .id = UCLASS_SERIAL,
+       .of_match = ar933x_serial_ids,
+       .priv_auto_alloc_size = sizeof(struct ar933x_serial_priv),
+       .probe = ar933x_serial_probe,
+       .ops    = &ar933x_serial_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
+
+#ifdef CONFIG_DEBUG_UART_AR933X
+
+#include <debug_uart.h>
+
+static inline void _debug_uart_init(void)
+{
+       void __iomem *regs = (void *)CONFIG_DEBUG_UART_BASE;
+       u32 val, scale, step;
+
+       /*
+        * UART controller configuration:
+        * - no DMA
+        * - no interrupt
+        * - DCE mode
+        * - no flow control
+        * - set RX ready oride
+        * - set TX ready oride
+        */
+       val = (AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S) |
+             AR933X_UART_CS_TX_RDY_ORIDE | AR933X_UART_CS_RX_RDY_ORIDE;
+       writel(val, regs + AR933X_UART_CS_REG);
+
+       ar933x_serial_get_scale_step(CONFIG_DEBUG_UART_CLOCK,
+                                    CONFIG_BAUDRATE, &scale, &step);
+
+       val  = (scale & AR933X_UART_CLK_SCALE_M)
+                       << AR933X_UART_CLK_SCALE_S;
+       val |= (step & AR933X_UART_CLK_STEP_M)
+                       << AR933X_UART_CLK_STEP_S;
+       writel(val, regs + AR933X_UART_CLK_REG);
+}
+
+static inline void _debug_uart_putc(int c)
+{
+       void __iomem *regs = (void *)CONFIG_DEBUG_UART_BASE;
+       u32 data;
+
+       do {
+               data = readl(regs + AR933X_UART_DATA_REG);
+       } while (!(data & AR933X_UART_DATA_TX_CSR));
+
+       data  = (u32)c | AR933X_UART_DATA_TX_CSR;
+       writel(data, regs + AR933X_UART_DATA_REG);
+}
+
+DEBUG_UART_FUNCS
+
+#endif
index f0258f84afeb64a0ac8c1e7ecbe9ee52fc99c0ea..b7fd8e53a2f62d6cd1f7aefa91f82e89c7fe5aea 100644 (file)
@@ -23,6 +23,15 @@ config ALTERA_SPI
          IP core. Please find details on the "Embedded Peripherals IP
          User Guide" of Altera.
 
+config ATH79_SPI
+       bool "Atheros SPI driver"
+       depends on ARCH_ATH79
+       help
+         Enable the Atheros ar7xxx/ar9xxx SoC SPI driver, it was used
+         to access SPI NOR flash and other SPI peripherals. This driver
+         uses driver model and requires a device tree binding to operate.
+         please refer to doc/device-tree-bindings/spi/spi-ath79.txt.
+
 config CADENCE_QSPI
        bool "Cadence QSPI driver"
        help
index 3eca7456d6a6bf865726fe27216365f30e6c1327..7fb2926e78135129939dbad3e789a8d8a0d67ed9 100644 (file)
@@ -17,6 +17,7 @@ endif
 
 obj-$(CONFIG_ALTERA_SPI) += altera_spi.o
 obj-$(CONFIG_ARMADA100_SPI) += armada100_spi.o
+obj-$(CONFIG_ATH79_SPI) += ath79_spi.o
 obj-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
 obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
 obj-$(CONFIG_BFIN_SPI) += bfin_spi.o
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
new file mode 100644 (file)
index 0000000..b18c733
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <dm.h>
+#include <div64.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <dm/pinctrl.h>
+#include <mach/ar71xx_regs.h>
+
+/* CLOCK_DIVIDER = 3 (SPI clock = 200 / 8 ~ 25 MHz) */
+#define ATH79_SPI_CLK_DIV(x)           (((x) >> 1) - 1)
+#define ATH79_SPI_RRW_DELAY_FACTOR     12000
+#define ATH79_SPI_MHZ                  (1000 * 1000)
+
+struct ath79_spi_priv {
+       void __iomem *regs;
+       u32 rrw_delay;
+};
+
+static void spi_cs_activate(struct udevice *dev)
+{
+       struct udevice *bus = dev_get_parent(dev);
+       struct ath79_spi_priv *priv = dev_get_priv(bus);
+
+       writel(AR71XX_SPI_FS_GPIO, priv->regs + AR71XX_SPI_REG_FS);
+       writel(AR71XX_SPI_IOC_CS_ALL, priv->regs + AR71XX_SPI_REG_IOC);
+}
+
+static void spi_cs_deactivate(struct udevice *dev)
+{
+       struct udevice *bus = dev_get_parent(dev);
+       struct ath79_spi_priv *priv = dev_get_priv(bus);
+
+       writel(AR71XX_SPI_IOC_CS_ALL, priv->regs + AR71XX_SPI_REG_IOC);
+       writel(0, priv->regs + AR71XX_SPI_REG_FS);
+}
+
+static int ath79_spi_claim_bus(struct udevice *dev)
+{
+       return 0;
+}
+
+static int ath79_spi_release_bus(struct udevice *dev)
+{
+       return 0;
+}
+
+static int ath79_spi_xfer(struct udevice *dev, unsigned int bitlen,
+               const void *dout, void *din, unsigned long flags)
+{
+       struct udevice *bus = dev_get_parent(dev);
+       struct ath79_spi_priv *priv = dev_get_priv(bus);
+       struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
+       u8 *rx = din;
+       const u8 *tx = dout;
+       u8 curbyte, curbitlen, restbits;
+       u32 bytes = bitlen / 8;
+       u32 out, in;
+       u64 tick;
+
+       if (flags & SPI_XFER_BEGIN)
+               spi_cs_activate(dev);
+
+       restbits = (bitlen % 8);
+       if (restbits)
+               bytes++;
+
+       out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
+       while (bytes > 0) {
+               bytes--;
+               curbyte = 0;
+               if (tx)
+                       curbyte = *tx++;
+
+               if (restbits && !bytes) {
+                       curbitlen = restbits;
+                       curbyte <<= 8 - restbits;
+               } else {
+                       curbitlen = 8;
+               }
+
+               for (curbyte <<= (8 - curbitlen); curbitlen; curbitlen--) {
+                       if (curbyte & 0x80)
+                               out |= AR71XX_SPI_IOC_DO;
+                       else
+                               out &= ~(AR71XX_SPI_IOC_DO);
+
+                       writel(out, priv->regs + AR71XX_SPI_REG_IOC);
+
+                       /* delay for low level */
+                       if (priv->rrw_delay) {
+                               tick = get_ticks() + priv->rrw_delay;
+                               while (get_ticks() < tick)
+                                       /*NOP*/;
+                       }
+
+                       writel(out | AR71XX_SPI_IOC_CLK,
+                              priv->regs + AR71XX_SPI_REG_IOC);
+
+                       /* delay for high level */
+                       if (priv->rrw_delay) {
+                               tick = get_ticks() + priv->rrw_delay;
+                               while (get_ticks() < tick)
+                                       /*NOP*/;
+                       }
+
+                       curbyte <<= 1;
+               }
+
+               if (!bytes)
+                       writel(out, priv->regs + AR71XX_SPI_REG_IOC);
+
+               in = readl(priv->regs + AR71XX_SPI_REG_RDS);
+               if (rx) {
+                       if (restbits && !bytes)
+                               *rx++ = (in << (8 - restbits));
+                       else
+                               *rx++ = in;
+               }
+       }
+
+       if (flags & SPI_XFER_END)
+               spi_cs_deactivate(dev);
+
+       return 0;
+}
+
+
+static int ath79_spi_set_speed(struct udevice *bus, uint speed)
+{
+       struct ath79_spi_priv *priv = dev_get_priv(bus);
+       u32 val, div = 0;
+       u64 time;
+
+       if (speed)
+               div = get_bus_freq(0) / speed;
+
+       if (div > 63)
+               div = 63;
+
+       if (div < 5)
+               div = 5;
+
+       /* calculate delay */
+       time = get_tbclk();
+       do_div(time, speed / 2);
+       val = get_bus_freq(0) / ATH79_SPI_MHZ;
+       val = ATH79_SPI_RRW_DELAY_FACTOR / val;
+       if (time > val)
+               priv->rrw_delay = time - val + 1;
+       else
+               priv->rrw_delay = 0;
+
+       writel(AR71XX_SPI_FS_GPIO, priv->regs + AR71XX_SPI_REG_FS);
+       clrsetbits_be32(priv->regs + AR71XX_SPI_REG_CTRL,
+                       AR71XX_SPI_CTRL_DIV_MASK,
+                       ATH79_SPI_CLK_DIV(div));
+       writel(0, priv->regs + AR71XX_SPI_REG_FS);
+       return 0;
+}
+
+static int ath79_spi_set_mode(struct udevice *bus, uint mode)
+{
+       return 0;
+}
+
+static int ath79_spi_probe(struct udevice *bus)
+{
+       struct ath79_spi_priv *priv = dev_get_priv(bus);
+       fdt_addr_t addr;
+
+       addr = dev_get_addr(bus);
+       if (addr == FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       priv->regs = map_physmem(addr,
+                                AR71XX_SPI_SIZE,
+                                MAP_NOCACHE);
+
+       /* Init SPI Hardware, disable remap, set clock */
+       writel(AR71XX_SPI_FS_GPIO, priv->regs + AR71XX_SPI_REG_FS);
+       writel(AR71XX_SPI_CTRL_RD | ATH79_SPI_CLK_DIV(8),
+              priv->regs + AR71XX_SPI_REG_CTRL);
+       writel(0, priv->regs + AR71XX_SPI_REG_FS);
+
+       return 0;
+}
+
+static int ath79_cs_info(struct udevice *bus, uint cs,
+                          struct spi_cs_info *info)
+{
+       /* Always allow activity on CS 0/1/2 */
+       if (cs >= 3)
+               return -ENODEV;
+
+       return 0;
+}
+
+static const struct dm_spi_ops ath79_spi_ops = {
+       .claim_bus  = ath79_spi_claim_bus,
+       .release_bus    = ath79_spi_release_bus,
+       .xfer       = ath79_spi_xfer,
+       .set_speed  = ath79_spi_set_speed,
+       .set_mode   = ath79_spi_set_mode,
+       .cs_info    = ath79_cs_info,
+};
+
+static const struct udevice_id ath79_spi_ids[] = {
+       { .compatible = "qca,ar7100-spi" },
+       {}
+};
+
+U_BOOT_DRIVER(ath79_spi) = {
+       .name   = "ath79_spi",
+       .id = UCLASS_SPI,
+       .of_match = ath79_spi_ids,
+       .ops    = &ath79_spi_ops,
+       .priv_auto_alloc_size = sizeof(struct ath79_spi_priv),
+       .probe  = ath79_spi_probe,
+};
index 2fe34c9a14a8e569a1989b5f87f5d5adef09f8e0..60e9d6e82552c8d18711a3667508d794545b880b 100644 (file)
@@ -35,6 +35,12 @@ DECLARE_GLOBAL_DATA_PTR;
 #define OMAP3_MCSPI4_BASE      0x480BA000
 #endif
 
+#define OMAP4_MCSPI_REG_OFFSET 0x100
+
+struct omap2_mcspi_platform_config {
+       unsigned int regs_offset;
+};
+
 /* per-register bitmasks */
 #define OMAP3_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3)
 #define OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2)
@@ -623,7 +629,10 @@ static int omap3_spi_probe(struct udevice *dev)
        const void *blob = gd->fdt_blob;
        int node = dev->of_offset;
 
-       priv->regs = (struct mcspi *)dev_get_addr(dev);
+       struct omap2_mcspi_platform_config* data =
+               (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
+
+       priv->regs = (struct mcspi *)(dev_get_addr(dev) + data->regs_offset);
        priv->pin_dir = fdtdec_get_uint(blob, node, "ti,pindir-d0-out-d1-in",
                                            MCSPI_PINDIR_D0_IN_D1_OUT);
        priv->wordlen = SPI_DEFAULT_WORDLEN;
@@ -662,9 +671,17 @@ static const struct dm_spi_ops omap3_spi_ops = {
         */
 };
 
+static struct omap2_mcspi_platform_config omap2_pdata = {
+       .regs_offset = 0,
+};
+
+static struct omap2_mcspi_platform_config omap4_pdata = {
+       .regs_offset = OMAP4_MCSPI_REG_OFFSET,
+};
+
 static const struct udevice_id omap3_spi_ids[] = {
-       { .compatible = "ti,omap2-mcspi" },
-       { .compatible = "ti,omap4-mcspi" },
+       { .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata },
+       { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },
        { }
 };
 
index aa4abcc3d24ddc0ab011126fe9f42b13ad4c28b0..d23dc81a211edc865b516f07a1e8e3a45f9e4993 100644 (file)
@@ -26,15 +26,20 @@ struct soft_spi_platdata {
        struct gpio_desc mosi;
        struct gpio_desc miso;
        int spi_delay_us;
+       int flags;
 };
 
+#define SPI_MASTER_NO_RX        BIT(0)
+#define SPI_MASTER_NO_TX        BIT(1)
+
 struct soft_spi_priv {
        unsigned int mode;
 };
 
 static int soft_spi_scl(struct udevice *dev, int bit)
 {
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
 
        dm_gpio_set_value(&plat->sclk, bit);
 
@@ -43,7 +48,8 @@ static int soft_spi_scl(struct udevice *dev, int bit)
 
 static int soft_spi_sda(struct udevice *dev, int bit)
 {
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
 
        dm_gpio_set_value(&plat->mosi, bit);
 
@@ -52,7 +58,8 @@ static int soft_spi_sda(struct udevice *dev, int bit)
 
 static int soft_spi_cs_activate(struct udevice *dev)
 {
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
 
        dm_gpio_set_value(&plat->cs, 0);
        dm_gpio_set_value(&plat->sclk, 0);
@@ -63,7 +70,8 @@ static int soft_spi_cs_activate(struct udevice *dev)
 
 static int soft_spi_cs_deactivate(struct udevice *dev)
 {
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
 
        dm_gpio_set_value(&plat->cs, 0);
 
@@ -100,8 +108,9 @@ static int soft_spi_release_bus(struct udevice *dev)
 static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
                         const void *dout, void *din, unsigned long flags)
 {
-       struct soft_spi_priv *priv = dev_get_priv(dev);
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_priv *priv = dev_get_priv(bus);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
        uchar           tmpdin  = 0;
        uchar           tmpdout = 0;
        const u8        *txd = dout;
@@ -134,14 +143,16 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
 
                if (!cpha)
                        soft_spi_scl(dev, 0);
-               soft_spi_sda(dev, tmpdout & 0x80);
+               if ((plat->flags & SPI_MASTER_NO_TX) == 0)
+                       soft_spi_sda(dev, !!(tmpdout & 0x80));
                udelay(plat->spi_delay_us);
                if (cpha)
                        soft_spi_scl(dev, 0);
                else
                        soft_spi_scl(dev, 1);
                tmpdin  <<= 1;
-               tmpdin  |= dm_gpio_get_value(&plat->miso);
+               if ((plat->flags & SPI_MASTER_NO_RX) == 0)
+                       tmpdin  |= dm_gpio_get_value(&plat->miso);
                tmpdout <<= 1;
                udelay(plat->spi_delay_us);
                if (cpha)
@@ -203,24 +214,36 @@ static int soft_spi_probe(struct udevice *dev)
        struct spi_slave *slave = dev_get_parent_priv(dev);
        struct soft_spi_platdata *plat = dev->platdata;
        int cs_flags, clk_flags;
+       int ret;
 
        cs_flags = (slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW;
        clk_flags = (slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0;
-       if (gpio_request_by_name(dev, "cs-gpio", 0, &plat->cs,
+
+       if (gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs,
                                 GPIOD_IS_OUT | cs_flags) ||
-           gpio_request_by_name(dev, "sclk-gpio", 0, &plat->sclk,
-                                GPIOD_IS_OUT | clk_flags) ||
-           gpio_request_by_name(dev, "mosi-gpio", 0, &plat->mosi,
-                                GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE) ||
-           gpio_request_by_name(dev, "miso-gpio", 0, &plat->miso,
-                                GPIOD_IS_IN))
+           gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk,
+                                GPIOD_IS_OUT | clk_flags))
+               return -EINVAL;
+
+       ret = gpio_request_by_name(dev, "gpio-mosi", 0, &plat->mosi,
+                                  GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+       if (ret)
+               plat->flags |= SPI_MASTER_NO_TX;
+
+       ret = gpio_request_by_name(dev, "gpio-miso", 0, &plat->miso,
+                                  GPIOD_IS_IN);
+       if (ret)
+               plat->flags |= SPI_MASTER_NO_RX;
+
+       if ((plat->flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX)) ==
+           (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX))
                return -EINVAL;
 
        return 0;
 }
 
 static const struct udevice_id soft_spi_ids[] = {
-       { .compatible = "u-boot,soft-spi" },
+       { .compatible = "spi-gpio" },
        { }
 };
 
index 5561f36762f9c6e45eff240c5e377920b96a0482..84b6786517cc667ebd04d6542003bac26dc85175 100644 (file)
@@ -45,12 +45,12 @@ static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)
        return 0;
 }
 
-int spi_claim_bus(struct spi_slave *slave)
+int dm_spi_claim_bus(struct udevice *dev)
 {
-       struct udevice *dev = slave->dev;
        struct udevice *bus = dev->parent;
        struct dm_spi_ops *ops = spi_get_ops(bus);
        struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
+       struct spi_slave *slave = dev_get_parent_priv(dev);
        int speed;
        int ret;
 
@@ -73,9 +73,8 @@ int spi_claim_bus(struct spi_slave *slave)
        return ops->claim_bus ? ops->claim_bus(dev) : 0;
 }
 
-void spi_release_bus(struct spi_slave *slave)
+void dm_spi_release_bus(struct udevice *dev)
 {
-       struct udevice *dev = slave->dev;
        struct udevice *bus = dev->parent;
        struct dm_spi_ops *ops = spi_get_ops(bus);
 
@@ -83,10 +82,9 @@ void spi_release_bus(struct spi_slave *slave)
                ops->release_bus(dev);
 }
 
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-            const void *dout, void *din, unsigned long flags)
+int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
+               const void *dout, void *din, unsigned long flags)
 {
-       struct udevice *dev = slave->dev;
        struct udevice *bus = dev->parent;
 
        if (bus->uclass->uc_drv->id != UCLASS_SPI)
@@ -95,6 +93,22 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
 }
 
+int spi_claim_bus(struct spi_slave *slave)
+{
+       return dm_spi_claim_bus(slave->dev);
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       dm_spi_release_bus(slave->dev);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+            const void *dout, void *din, unsigned long flags)
+{
+       return dm_spi_xfer(slave->dev, bitlen, dout, din, flags);
+}
+
 static int spi_post_bind(struct udevice *dev)
 {
        /* Scan the bus for devices */
index 2f3d43d9395c3f2b2c546eadb6cab4c91f659163..2f46d38d2b31ec9c82ca371954f45155923d7264 100644 (file)
@@ -3,5 +3,6 @@
 # SPDX-License-Identifier:      GPL-2.0+
 #
 
+obj-$(CONFIG_DM_USB) += common.o
 obj-$(CONFIG_USB_EHCI_FSL) += fsl-dt-fixup.o
 obj-$(CONFIG_USB_XHCI_FSL) += fsl-dt-fixup.o
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
new file mode 100644 (file)
index 0000000..35c2dc1
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Provides code common for host and device side USB.
+ *
+ * (C) Copyright 2016
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <linux/usb/otg.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char *const usb_dr_modes[] = {
+       [USB_DR_MODE_UNKNOWN]           = "",
+       [USB_DR_MODE_HOST]              = "host",
+       [USB_DR_MODE_PERIPHERAL]        = "peripheral",
+       [USB_DR_MODE_OTG]               = "otg",
+};
+
+enum usb_dr_mode usb_get_dr_mode(int node)
+{
+       const void *fdt = gd->fdt_blob;
+       const char *dr_mode;
+       int i;
+
+       dr_mode = fdt_getprop(fdt, node, "dr_mode", NULL);
+       if (!dr_mode) {
+               error("usb dr_mode not found\n");
+               return USB_DR_MODE_UNKNOWN;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
+               if (!strcmp(dr_mode, usb_dr_modes[i]))
+                       return i;
+
+       return USB_DR_MODE_UNKNOWN;
+}
index 7fd10e6af35e9b80f624c6f6aec04ffb906e1e1f..c01809e89e142a0de3a3b609e478e55c19f03bbb 100644 (file)
@@ -620,6 +620,13 @@ static int tegra_lcd_ofdata_to_platdata(struct udevice *dev)
 static int tegra_lcd_bind(struct udevice *dev)
 {
        struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+       const void *blob = gd->fdt_blob;
+       int node = dev->of_offset;
+       int rgb;
+
+       rgb = fdt_subnode_offset(blob, node, "rgb");
+       if ((rgb < 0) || !fdtdec_get_is_enabled(blob, rgb))
+               return -ENODEV;
 
        plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
                (1 << LCD_MAX_LOG2_BPP) / 8;
index d5850093539d20b076a0c02b0859bdef4d3c12f9..c56c1299c09f65e445e80fe1da6e12516b74834c 100644 (file)
@@ -62,6 +62,7 @@ config DEFAULT_DEVICE_TREE
 config OF_LIST
        string "List of device tree files to include for DT control"
        depends on SPL_LOAD_FIT
+       default DEFAULT_DEVICE_TREE
        help
          This option specifies a list of device tree files to use for DT
          control. These will be packaged into a FIT. At run-time, SPL will
index 4e9b8ea17dcc6ffd49c34de6ec6a0febd2e36028..6cffee74652f944d9d9bc9ed812b4177432f98af 100644 (file)
@@ -11,8 +11,12 @@ ifeq ($(ARCH),arm)
 LOAD_ADDR = 0x1000000
 endif
 ifeq ($(ARCH),mips)
+ifdef CONFIG_64BIT
+LOAD_ADDR = 0xffffffff80200000
+else
 LOAD_ADDR = 0x80200000
 endif
+endif
 
 # Resulting ELF and binary exectuables will be named demo and demo.bin
 extra-y = demo
index ced2c82e5ffcacb5702cd0a9a841a559cad8d74e..5a7049d6b4b721f71a85948364d24217e93030ec 100644 (file)
@@ -41,28 +41,29 @@ syscall:
        ldr     pc, [ip]
 
 #elif defined(CONFIG_MIPS)
+#include <asm/asm.h>
        .text
        .globl __start
        .ent __start
 __start:
-       sw      $sp, search_hint
+       PTR_S   $sp, search_hint
        b       main
        .end __start
 
        .globl syscall
        .ent syscall
 syscall:
-       sw      $ra, return_addr
-       lw      $t9, syscall_ptr
+       PTR_S   $ra, return_addr
+       PTR_L   $t9, syscall_ptr
        jalr    $t9
        nop
-       lw      $ra, return_addr
+       PTR_L   $ra, return_addr
        jr      $ra
        nop
        .end syscall
 
 return_addr:
-       .align 4
+       .align 8
        .long 0
 #else
 #error No support for this arch!
@@ -70,7 +71,7 @@ return_addr:
 
        .globl syscall_ptr
 syscall_ptr:
-       .align  4
+       .align  8
        .long   0
 
        .globl search_hint
index d619518d42a64a19c0ba6ea61e0c0b1c9cd930f6..8aabf32c899acb2e3c8990db52e16f235f68c0a2 100644 (file)
@@ -77,7 +77,7 @@ int ub_getc(void)
 {
        int c;
 
-       if (!syscall(API_GETC, NULL, (uint32_t)&c))
+       if (!syscall(API_GETC, NULL, &c))
                return -1;
 
        return c;
@@ -87,7 +87,7 @@ int ub_tstc(void)
 {
        int t;
 
-       if (!syscall(API_TSTC, NULL, (uint32_t)&t))
+       if (!syscall(API_TSTC, NULL, &t))
                return -1;
 
        return t;
@@ -95,12 +95,12 @@ int ub_tstc(void)
 
 void ub_putc(char c)
 {
-       syscall(API_PUTC, NULL, (uint32_t)&c);
+       syscall(API_PUTC, NULL, &c);
 }
 
 void ub_puts(const char *s)
 {
-       syscall(API_PUTS, NULL, (uint32_t)s);
+       syscall(API_PUTS, NULL, s);
 }
 
 /****************************************
@@ -126,7 +126,7 @@ struct sys_info * ub_get_sys_info(void)
        si.mr_no = UB_MAX_MR;
        memset(&mr, 0, sizeof(mr));
 
-       if (!syscall(API_GET_SYS_INFO, &err, (u_int32_t)&si))
+       if (!syscall(API_GET_SYS_INFO, &err, &si))
                return NULL;
 
        return ((err) ? NULL : &si);
@@ -344,7 +344,7 @@ char * ub_env_get(const char *name)
 {
        char *value;
 
-       if (!syscall(API_ENV_GET, NULL, (uint32_t)name, (uint32_t)&value))
+       if (!syscall(API_ENV_GET, NULL, name, &value))
                return NULL;
 
        return value;
@@ -352,7 +352,7 @@ char * ub_env_get(const char *name)
 
 void ub_env_set(const char *name, char *value)
 {
-       syscall(API_ENV_SET, NULL, (uint32_t)name, (uint32_t)value);
+       syscall(API_ENV_SET, NULL, name, value);
 }
 
 static char env_name[256];
@@ -369,7 +369,7 @@ const char * ub_env_enum(const char *last)
         * 'name=val' string), since the API_ENUM_ENV call uses envmatch()
         * internally, which handles such case
         */
-       if (!syscall(API_ENV_ENUM, NULL, (uint32_t)last, (uint32_t)&env))
+       if (!syscall(API_ENV_ENUM, NULL, last, &env))
                return NULL;
 
        if (!env)
@@ -396,7 +396,7 @@ int ub_display_get_info(int type, struct display_info *di)
 {
        int err = 0;
 
-       if (!syscall(API_DISPLAY_GET_INFO, &err, (uint32_t)type, (uint32_t)di))
+       if (!syscall(API_DISPLAY_GET_INFO, &err, type, di))
                return API_ESYSC;
 
        return err;
index 920a0a9cf3b4ae96c2ba3aa21394dde4fd50318b..0d62067e03be4cbf97e1cd8c38adf503f9120700 100644 (file)
@@ -65,6 +65,23 @@ gd_t *global_data;
        : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "ip");
 #endif
 #elif defined(CONFIG_MIPS)
+#ifdef CONFIG_CPU_MIPS64
+/*
+ * k0 ($26) holds the pointer to the global_data; t9 ($25) is a call-
+ * clobbered register that is also used to set gp ($26). Note that the
+ * jr instruction also executes the instruction immediately following
+ * it; however, GCC/mips generates an additional `nop' after each asm
+ * statement
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+       asm volatile (                  \
+"      .globl " #x "\n"                \
+#x ":\n"                               \
+"      ld      $25, %0($26)\n"         \
+"      ld      $25, %1($25)\n"         \
+"      jr      $25\n"                  \
+        : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t9");
+#else
 /*
  * k0 ($26) holds the pointer to the global_data; t9 ($25) is a call-
  * clobbered register that is also used to set gp ($26). Note that the
@@ -80,6 +97,7 @@ gd_t *global_data;
 "      lw      $25, %1($25)\n"         \
 "      jr      $25\n"                  \
        : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t9");
+#endif
 #elif defined(CONFIG_NIOS2)
 /*
  * gp holds the pointer to the global_data, r8 is call-clobbered
index 600a90e30922621c03c1db8c65119b7fbe85f50a..826bd852860aed9a078a75ad618f5d204cdef9f1 100644 (file)
@@ -1254,7 +1254,7 @@ int file_fat_detectfs(void)
 
 #if defined(CONFIG_CMD_IDE) || \
     defined(CONFIG_CMD_SATA) || \
-    defined(CONFIG_CMD_SCSI) || \
+    defined(CONFIG_SCSI) || \
     defined(CONFIG_CMD_USB) || \
     defined(CONFIG_MMC)
        printf("Interface:  ");
index 68b5f0b3c28248110377f2209b84c12e103f56bc..2500c10450062542b0b9ba2262adb6af6a7a5c6a 100644 (file)
@@ -206,6 +206,16 @@ int gpio_requestf(unsigned gpio, const char *fmt, ...)
 
 struct fdtdec_phandle_args;
 
+/**
+ * gpio_xlate_offs_flags() - implementation for common use of dm_gpio_ops.xlate
+ *
+ * This routine sets the offset field to args[0] and the flags field to
+ * GPIOD_ACTIVE_LOW if the GPIO_ACTIVE_LOW flag is present in args[1].
+ *
+ */
+int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
+                         struct fdtdec_phandle_args *args);
+
 /**
  * struct struct dm_gpio_ops - Driver model GPIO operations
  *
@@ -258,12 +268,11 @@ struct dm_gpio_ops {
         *
         *   @desc->dev to @dev
         *   @desc->flags to 0
-        *   @desc->offset to the value of the first argument in args, if any,
-        *              otherwise -1 (which is invalid)
+        *   @desc->offset to 0
         *
-        * This method is optional so if the above defaults suit it can be
-        * omitted. Typical behaviour is to set up the GPIOD_ACTIVE_LOW flag
-        * in desc->flags.
+        * This method is optional and defaults to gpio_xlate_offs_flags,
+        * which will parse offset and the GPIO_ACTIVE_LOW flag in the first
+        * two arguments.
         *
         * Note that @dev is passed in as a parameter to follow driver model
         * uclass conventions, even though it is already available as
index 9d6f59c97bfaae7ea8482eb03468533465901d9c..dde377c99ec92423093733c24008c1508ddcd915 100644 (file)
 
 #define ATA_BLOCKSIZE  512     /* bytes */
 #define ATA_BLOCKSHIFT 9       /* 2 ^ ATA_BLOCKSIZESHIFT = 512 */
-#define ATA_SECTORWORDS        (512 / sizeof(unsigned long))
+#define ATA_SECTORWORDS        (512 / sizeof(uint32_t))
 
 #ifndef ATA_RESET_TIME
 #define ATA_RESET_TIME 60      /* spec allows up to 31 seconds */
index f62467105a203f51bc0a2758f49de1cc293f5fd3..66a1c55cc8b69c256e9caf214642bbc60c439406 100644 (file)
@@ -30,6 +30,7 @@ enum if_type {
        IF_TYPE_SD,
        IF_TYPE_SATA,
        IF_TYPE_HOST,
+       IF_TYPE_SYSTEMACE,
 
        IF_TYPE_COUNT,                  /* Number of interface types */
 };
@@ -62,6 +63,11 @@ struct blk_desc {
        char            product[20+1];  /* IDE Serial no, SCSI product */
        char            revision[8+1];  /* firmware revision */
 #ifdef CONFIG_BLK
+       /*
+        * For now we have a few functions which take struct blk_desc as a
+        * parameter. This field allows them to look up the associated
+        * device. Once these functions are removed we can drop this field.
+        */
        struct udevice *bdev;
 #else
        unsigned long   (*block_read)(struct blk_desc *block_dev,
@@ -210,6 +216,25 @@ struct blk_ops {
         */
        unsigned long (*erase)(struct udevice *dev, lbaint_t start,
                               lbaint_t blkcnt);
+
+       /**
+        * select_hwpart() - select a particular hardware partition
+        *
+        * Some devices (e.g. MMC) can support partitioning at the hardware
+        * level. This is quite separate from the normal idea of
+        * software-based partitions. MMC hardware partitions must be
+        * explicitly selected. Once selected only the region of the device
+        * covered by that partition is accessible.
+        *
+        * The MMC standard provides for two boot partitions (numbered 1 and 2),
+        * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
+        *
+        * @desc:       Block device to update
+        * @hwpart:     Hardware partition number to select. 0 means the raw
+        *              device, 1 is the first partition, 2 is the second, etc.
+        * @return 0 if OK, -ve on error
+        */
+       int (*select_hwpart)(struct udevice *dev, int hwpart);
 };
 
 #define blk_get_ops(dev)       ((struct blk_ops *)(dev)->driver->ops)
@@ -269,7 +294,8 @@ int blk_next_device(struct udevice **devp);
  * @drv_name:  Driver name to use for the block device
  * @name:      Name for the device
  * @if_type:   Interface type (enum if_type_t)
- * @devnum:    Device number, specific to the interface type
+ * @devnum:    Device number, specific to the interface type, or -1 to
+ *             allocate the next available number
  * @blksz:     Block size of the device in bytes (typically 512)
  * @size:      Total size of the device in bytes
  * @devp:      the new device (which has not been probed)
@@ -278,6 +304,23 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
                      const char *name, int if_type, int devnum, int blksz,
                      lbaint_t size, struct udevice **devp);
 
+/**
+ * blk_create_devicef() - Create a new named block device
+ *
+ * @parent:    Parent of the new device
+ * @drv_name:  Driver name to use for the block device
+ * @name:      Name for the device (parent name is prepended)
+ * @if_type:   Interface type (enum if_type_t)
+ * @devnum:    Device number, specific to the interface type, or -1 to
+ *             allocate the next available number
+ * @blksz:     Block size of the device in bytes (typically 512)
+ * @size:      Total size of the device in bytes
+ * @devp:      the new device (which has not been probed)
+ */
+int blk_create_devicef(struct udevice *parent, const char *drv_name,
+                      const char *name, int if_type, int devnum, int blksz,
+                      lbaint_t size, struct udevice **devp);
+
 /**
  * blk_prepare_device() - Prepare a block device for use
  *
@@ -298,6 +341,29 @@ int blk_prepare_device(struct udevice *dev);
  */
 int blk_unbind_all(int if_type);
 
+/**
+ * blk_find_max_devnum() - find the maximum device number for an interface type
+ *
+ * Finds the last allocated device number for an interface type @if_type. The
+ * next number is safe to use for a newly allocated device.
+ *
+ * @if_type:   Interface type to scan
+ * @return maximum device number found, or -ENODEV if none, or other -ve on
+ * error
+ */
+int blk_find_max_devnum(enum if_type if_type);
+
+/**
+ * blk_select_hwpart() - select a hardware partition
+ *
+ * Select a hardware partition if the device supports it (typically MMC does)
+ *
+ * @dev:       Device to update
+ * @hwpart:    Partition number to select
+ * @return 0 if OK, -ve on error
+ */
+int blk_select_hwpart(struct udevice *dev, int hwpart);
+
 #else
 #include <errno.h>
 /*
@@ -340,6 +406,201 @@ static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start,
        blkcache_invalidate(block_dev->if_type, block_dev->devnum);
        return block_dev->block_erase(block_dev, start, blkcnt);
 }
+
+/**
+ * struct blk_driver - Driver for block interface types
+ *
+ * This provides access to the block devices for each interface type. One
+ * driver should be provided using U_BOOT_LEGACY_BLK() for each interface
+ * type that is to be supported.
+ *
+ * @if_typename:       Interface type name
+ * @if_type:           Interface type
+ * @max_devs:          Maximum number of devices supported
+ * @desc:              Pointer to list of devices for this interface type,
+ *                     or NULL to use @get_dev() instead
+ */
+struct blk_driver {
+       const char *if_typename;
+       enum if_type if_type;
+       int max_devs;
+       struct blk_desc *desc;
+       /**
+        * get_dev() - get a pointer to a block device given its number
+        *
+        * Each interface allocates its own devices and typically
+        * struct blk_desc is contained with the interface's data structure.
+        * There is no global numbering for block devices. This method allows
+        * the device for an interface type to be obtained when @desc is NULL.
+        *
+        * @devnum:     Device number (0 for first device on that interface,
+        *              1 for second, etc.
+        * @descp:      Returns pointer to the block device on success
+        * @return 0 if OK, -ve on error
+        */
+       int (*get_dev)(int devnum, struct blk_desc **descp);
+
+       /**
+        * select_hwpart() - Select a hardware partition
+        *
+        * Some devices (e.g. MMC) can support partitioning at the hardware
+        * level. This is quite separate from the normal idea of
+        * software-based partitions. MMC hardware partitions must be
+        * explicitly selected. Once selected only the region of the device
+        * covered by that partition is accessible.
+        *
+        * The MMC standard provides for two boot partitions (numbered 1 and 2),
+        * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
+        * Partition 0 is the main user-data partition.
+        *
+        * @desc:       Block device descriptor
+        * @hwpart:     Hardware partition number to select. 0 means the main
+        *              user-data partition, 1 is the first partition, 2 is
+        *              the second, etc.
+        * @return 0 if OK, other value for an error
+        */
+       int (*select_hwpart)(struct blk_desc *desc, int hwpart);
+};
+
+/*
+ * Declare a new U-Boot legacy block driver. New drivers should use driver
+ * model (UCLASS_BLK).
+ */
+#define U_BOOT_LEGACY_BLK(__name)                                      \
+       ll_entry_declare(struct blk_driver, __name, blk_driver)
+
+struct blk_driver *blk_driver_lookup_type(int if_type);
+
 #endif /* !CONFIG_BLK */
 
+/**
+ * blk_get_devnum_by_typename() - Get a block device by type and number
+ *
+ * This looks through the available block devices of the given type, returning
+ * the one with the given @devnum.
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @return point to block device descriptor, or NULL if not found
+ */
+struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum);
+
+/**
+ * blk_get_devnum_by_type() - Get a block device by type name, and number
+ *
+ * This looks up the block device type based on @if_typename, then calls
+ * blk_get_devnum_by_type().
+ *
+ * @if_typename:       Block device type name
+ * @devnum:            Device number
+ * @return point to block device descriptor, or NULL if not found
+ */
+struct blk_desc *blk_get_devnum_by_typename(const char *if_typename,
+                                           int devnum);
+
+/**
+ * blk_dselect_hwpart() - select a hardware partition
+ *
+ * This selects a hardware partition (such as is supported by MMC). The block
+ * device size may change as this effectively points the block device to a
+ * partition at the hardware level. See the select_hwpart() method above.
+ *
+ * @desc:      Block device descriptor for the device to select
+ * @hwpart:    Partition number to select
+ * @return 0 if OK, -ve on error
+ */
+int blk_dselect_hwpart(struct blk_desc *desc, int hwpart);
+
+/**
+ * blk_list_part() - list the partitions for block devices of a given type
+ *
+ * This looks up the partition type for each block device of type @if_type,
+ * then displays a list of partitions.
+ *
+ * @if_type:   Block device type
+ * @return 0 if OK, -ENODEV if there is none of that type
+ */
+int blk_list_part(enum if_type if_type);
+
+/**
+ * blk_list_devices() - list the block devices of a given type
+ *
+ * This lists each block device of the type @if_type, showing the capacity
+ * as well as type-specific information.
+ *
+ * @if_type:   Block device type
+ */
+void blk_list_devices(enum if_type if_type);
+
+/**
+ * blk_show_device() - show information about a given block device
+ *
+ * This shows the block device capacity as well as type-specific information.
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @return 0 if OK, -ENODEV for invalid device number
+ */
+int blk_show_device(enum if_type if_type, int devnum);
+
+/**
+ * blk_print_device_num() - show information about a given block device
+ *
+ * This is similar to blk_show_device() but returns an error if the block
+ * device type is unknown.
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @return 0 if OK, -ENODEV for invalid device number, -ENOENT if the block
+ * device is not connected
+ */
+int blk_print_device_num(enum if_type if_type, int devnum);
+
+/**
+ * blk_print_part_devnum() - print the partition information for a device
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @return 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if
+ * the interface type is not supported, other -ve on other error
+ */
+int blk_print_part_devnum(enum if_type if_type, int devnum);
+
+/**
+ * blk_read_devnum() - read blocks from a device
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @blkcnt:    Number of blocks to read
+ * @buffer:    Address to write data to
+ * @return number of blocks read, or -ve error number on error
+ */
+ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                     lbaint_t blkcnt, void *buffer);
+
+/**
+ * blk_write_devnum() - write blocks to a device
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @blkcnt:    Number of blocks to write
+ * @buffer:    Address to read data from
+ * @return number of blocks written, or -ve error number on error
+ */
+ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                      lbaint_t blkcnt, const void *buffer);
+
+/**
+ * blk_select_hwpart_devnum() - select a hardware partition
+ *
+ * This is similar to blk_dselect_hwpart() but it looks up the interface and
+ * device number.
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @hwpart:    Partition number to select
+ * @return 0 if OK, -ve on error
+ */
+int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart);
+
 #endif
index ed502a191ff6cebc9b077d27e63c6cf8d0c6a769..b5fd6c68e8fefbde16fcff2f9c8f2cf91222be5e 100644 (file)
@@ -45,7 +45,7 @@
 #define CONFIG_CMD_READ                /* Read data from partition     */
 #define CONFIG_CMD_SANDBOX     /* sb command to access sandbox features */
 #define CONFIG_CMD_SAVES       /* save S record dump           */
-#define CONFIG_CMD_SCSI                /* SCSI Support                 */
+#define CONFIG_SCSI            /* SCSI Support                 */
 #define CONFIG_CMD_SDRAM       /* SDRAM DIMM SPD info printout */
 #define CONFIG_CMD_TERMINAL    /* built-in Serial Terminal     */
 #define CONFIG_CMD_UBI         /* UBI Support                  */
index 7f673448c92d0cb71d894b203e05bc9ba3df9482..5a8d7f270867c8bad06145d6c5f393515060e11d 100644 (file)
        BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_CMD_SATA
 #endif
 
-#ifdef CONFIG_CMD_SCSI
+#ifdef CONFIG_SCSI
 #define BOOTENV_RUN_SCSI_INIT "run scsi_init; "
 #define BOOTENV_SET_SCSI_NEED_INIT "setenv scsi_need_init; "
 #define BOOTENV_SHARED_SCSI \
 #define BOOTENV_SET_SCSI_NEED_INIT
 #define BOOTENV_SHARED_SCSI
 #define BOOTENV_DEV_SCSI \
-       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_CMD_SCSI
+       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_SCSI
 #define BOOTENV_DEV_NAME_SCSI \
-       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_CMD_SCSI
+       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_SCSI
 #endif
 
 #ifdef CONFIG_CMD_IDE
index 266619186643f82abd7bffd1d2343ce7eade19eb..2ad54b7bf6611106b770d0f3b495ba7f4ce32a8f 100644 (file)
@@ -45,7 +45,7 @@
 /* Rather than repeat this expression each time, add a define for it */
 #if defined(CONFIG_CMD_IDE) || \
        defined(CONFIG_CMD_SATA) || \
-       defined(CONFIG_CMD_SCSI) || \
+       defined(CONFIG_SCSI) || \
        defined(CONFIG_CMD_USB) || \
        defined(CONFIG_CMD_PART) || \
        defined(CONFIG_CMD_GPT) || \
index 26d92daff1d96f45b2a497bb3957ef8d2950e3b2..f3036c1dc2638a4ed3006d0b3f42b0fe7f2e022c 100644 (file)
@@ -373,7 +373,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 
 #if defined(CONFIG_PCI)
     #define CONFIG_CMD_PCI
-    #define CONFIG_CMD_SCSI
+    #define CONFIG_SCSI
 #endif
 
 /*
index 8c4e5e21ca9814eff22d40eb9fdc808bffd5f78c..bb7f38e34a530e27b8eba9fb6d6421fde39dc88c 100644 (file)
 
 #if defined(CONFIG_PCI)
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #endif
 
 /*
index e7f01d00d1d7663879944dde01a69f1b477e6e2f..f6d45a9e40a8ff8183e37f40e8ff0460e90dc242 100644 (file)
 
 #if defined(CONFIG_PCI)
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #endif
 
 #define CONFIG_WATCHDOG                        /* watchdog enabled */
index 2f94c8214eb0d6ed304a66d195594245d177bc38..9b2623c72620a54ec23b585286f5fc4b477a6bd9 100644 (file)
@@ -354,8 +354,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup */
 
-#undef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
-
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play */
 
 #undef CONFIG_EEPRO100
@@ -612,7 +610,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 
 #if defined(CONFIG_PCI)
     #define CONFIG_CMD_PCI
-    #define CONFIG_CMD_SCSI
+    #define CONFIG_SCSI
 #endif
 
 #undef CONFIG_WATCHDOG                 /* watchdog disabled */
index 4bd06a45bf6dbd1b24b4c657015b51d4a734352b..4506d86eee7671a3d2c91f6cc0a8f1a07333f06c 100644 (file)
@@ -43,7 +43,7 @@
 #define CONFIG_CMD_EEPROM
 #define CONFIG_CMD_REGINFO
 #define CONFIG_CMD_FDC
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_CMD_DATE
 #define CONFIG_CMD_SDRAM
 #define CONFIG_CMD_SAVES
index 32d7d4d0bd0aa015a345203607a7bf3373fad525..d53b0fdd89c44a8e866d46a76cc36761a5596eaf 100644 (file)
@@ -75,7 +75,7 @@
 
 /* SATA */
 #define CONFIG_BOARD_LATE_INIT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
diff --git a/include/configs/ap121.h b/include/configs/ap121.h
new file mode 100644 (file)
index 0000000..2beffa4
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_SYS_TEXT_BASE            0x9f000000
+
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_EARLY_INIT_F
+
+#define CONFIG_SYS_HZ                   1000
+#define CONFIG_SYS_MHZ                  200
+#define CONFIG_SYS_MIPS_TIMER_FREQ      (CONFIG_SYS_MHZ * 1000000)
+
+/* Cache Configuration */
+#define CONFIG_SYS_DCACHE_SIZE          0x8000
+#define CONFIG_SYS_ICACHE_SIZE          0x10000
+#define CONFIG_SYS_CACHELINE_SIZE       32
+
+#define CONFIG_SYS_MONITOR_BASE         CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_MALLOC_LEN           0x40000
+#define CONFIG_SYS_BOOTPARAMS_LEN       0x20000
+
+#define CONFIG_SYS_SDRAM_BASE           0x80000000
+#define CONFIG_SYS_LOAD_ADDR            0x81000000
+
+#define CONFIG_SYS_NO_FLASH
+
+#define CONFIG_SYS_INIT_RAM_ADDR        0xbd000000
+#define CONFIG_SYS_INIT_RAM_SIZE        0x8000
+#define CONFIG_SYS_INIT_SP_ADDR \
+       (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE - 1)
+
+#define CONFIG_BAUDRATE                 115200
+#define CONFIG_SYS_BAUDRATE_TABLE \
+       {9600, 19200, 38400, 57600, 115200}
+
+#define CONFIG_BOOTDELAY                3
+#define CONFIG_BOOTARGS                 "console=ttyS0,115200 " \
+                                       "root=/dev/mtdblock2 " \
+                                       "rootfstype=squashfs"
+#define CONFIG_BOOTCOMMAND              "sf probe;" \
+                                       "mtdparts default;" \
+                                       "bootm 0x9f300000"
+#define CONFIG_LZMA
+
+#define MTDIDS_DEFAULT                  "nor0=spi-flash.0"
+#define MTDPARTS_DEFAULT                "mtdparts=spi-flash.0:" \
+                                       "256k(u-boot),64k(u-boot-env)," \
+                                       "2752k(rootfs),896k(uImage)," \
+                                       "64k(NVRAM),64k(ART)"
+
+#define CONFIG_ENV_SPI_MAX_HZ           25000000
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_OFFSET               0x40000
+#define CONFIG_ENV_SECT_SIZE            0x10000
+#define CONFIG_ENV_SIZE                 0x10000
+
+/*
+ * Command
+ */
+#define CONFIG_CMD_MTDPARTS
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_CBSIZE               256
+#define CONFIG_SYS_MAXARGS              16
+#define CONFIG_SYS_PBSIZE               (CONFIG_SYS_CBSIZE + \
+                                       sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_AUTO_COMPLETE
+
+/*
+ * Diagnostics
+ */
+#define CONFIG_SYS_MEMTEST_START        0x80100000
+#define CONFIG_SYS_MEMTEST_END          0x83f00000
+#define CONFIG_CMD_MEMTEST
+
+#endif  /* __CONFIG_H */
diff --git a/include/configs/ap143.h b/include/configs/ap143.h
new file mode 100644 (file)
index 0000000..7b69e10
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_SYS_TEXT_BASE            0x9f000000
+
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_EARLY_INIT_F
+
+#define CONFIG_SYS_HZ                   1000
+#define CONFIG_SYS_MHZ                  325
+#define CONFIG_SYS_MIPS_TIMER_FREQ      (CONFIG_SYS_MHZ * 1000000)
+
+/* Cache Configuration */
+#define CONFIG_SYS_DCACHE_SIZE          0x8000
+#define CONFIG_SYS_ICACHE_SIZE          0x10000
+#define CONFIG_SYS_CACHELINE_SIZE       32
+
+#define CONFIG_SYS_MONITOR_BASE         CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_MALLOC_LEN           0x40000
+#define CONFIG_SYS_BOOTPARAMS_LEN       0x20000
+
+#define CONFIG_SYS_SDRAM_BASE           0x80000000
+#define CONFIG_SYS_LOAD_ADDR            0x81000000
+
+#define CONFIG_SYS_NO_FLASH
+
+#define CONFIG_SYS_INIT_RAM_ADDR        0xbd000000
+#define CONFIG_SYS_INIT_RAM_SIZE        0x2000
+#define CONFIG_SYS_INIT_SP_ADDR \
+       (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE - 1)
+
+/*
+ * Serial Port
+ */
+#define CONFIG_SYS_NS16550_CLK          25000000
+#define CONFIG_BAUDRATE                 115200
+#define CONFIG_SYS_BAUDRATE_TABLE \
+       {9600, 19200, 38400, 57600, 115200}
+
+#define CONFIG_BOOTDELAY                3
+#define CONFIG_BOOTARGS                 "console=ttyS0,115200 " \
+                                       "root=/dev/mtdblock2 " \
+                                       "rootfstype=squashfs"
+#define CONFIG_BOOTCOMMAND              "sf probe;" \
+                                       "mtdparts default;" \
+                                       "bootm 0x9f300000"
+#define CONFIG_LZMA
+
+#define MTDIDS_DEFAULT                  "nor0=spi-flash.0"
+#define MTDPARTS_DEFAULT                "mtdparts=spi-flash.0:" \
+                                       "256k(u-boot),64k(u-boot-env)," \
+                                       "2752k(rootfs),896k(uImage)," \
+                                       "64k(NVRAM),64k(ART)"
+
+#define CONFIG_ENV_SPI_MAX_HZ           25000000
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_OFFSET               0x40000
+#define CONFIG_ENV_SECT_SIZE            0x10000
+#define CONFIG_ENV_SIZE                 0x10000
+
+/*
+ * Command
+ */
+#define CONFIG_CMD_MTDPARTS
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_CBSIZE               256
+#define CONFIG_SYS_MAXARGS              16
+#define CONFIG_SYS_PBSIZE               (CONFIG_SYS_CBSIZE + \
+                                       sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_AUTO_COMPLETE
+
+/*
+ * Diagnostics
+ */
+#define CONFIG_SYS_MEMTEST_START        0x80100000
+#define CONFIG_SYS_MEMTEST_END          0x83f00000
+#define CONFIG_CMD_MEMTEST
+
+#endif  /* __CONFIG_H */
index 1bd472969fdba87f230488ab99be418928e45695..05d2d45b251ac5f48915deb6d0365d1a56e061a3 100644 (file)
@@ -59,7 +59,6 @@
  * I2C configuration
  */
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_DW
 #define CONFIG_I2C_ENV_EEPROM_BUS      2
 #define CONFIG_SYS_I2C_SPEED           100000
 #define CONFIG_SYS_I2C_SPEED1          100000
index 9a125529c6de370bd9b9c077c5b849dde9cccae9..1f20ec3c6d2b555e1b748a959585e4d98e0bfb14 100644 (file)
 #define CONFIG_VIDEO_LOGO
 #define CONFIG_VIDEO_BMP_LOGO
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v2, v3"
+
 #endif /* __CONFIG_CM_FX6_H */
index c4f1d4f43889cc83fae6827f42ae5fa36fdc155c..6dbc9e980c9b1e2152561f57581acddc33559ec8 100644 (file)
 #define STATUS_LED_PERIOD              (CONFIG_SYS_HZ / 2)
 #define STATUS_LED_BOOT                        0
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v2, v3"
+
 #ifndef CONFIG_SPL_BUILD
 /*
  * Enable PCA9555 at I2C0-0x26.
index 5d581162cbe70d2553e96b1c046c3b2630fe4b6e..0fb853002c08abe3efd200bc476bde12f9a1441c 100644 (file)
 #define CONFIG_SYS_SPL_MALLOC_START    0x80208000
 #define CONFIG_SYS_SPL_MALLOC_SIZE     0x100000
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "legacy, v1, v2, v3"
+
 #endif /* __CONFIG_H */
index 7cedb6736dae610f1454c7852bf6c4c6faa2a7a4..7c087c6f5d1ba46cb9780ec5ef29a0739f4bb41d 100644 (file)
 
 #define CONFIG_OMAP3_SPI
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v1, v2, v3"
+
 #endif /* __CONFIG_H */
index ee818ede267eedab950066c5753a0536ad78fe9d..c2dbd31803a20e427d8b283d2eb17c584f5b4e7a 100644 (file)
 #define CONFIG_SPL_I2C_SUPPORT
 #define CONFIG_SPL_POWER_SUPPORT
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v2, v3"
+
 #endif /* __CONFIG_CM_T43_H */
index 9b13aa6b5ac309b37ed894159fb56dbf75e6c2e6..ff63d7a7756830fb5695945eda3a13a122630e3f 100644 (file)
@@ -60,7 +60,7 @@
 #define CONFIG_SPL_SATA_BOOT_DEVICE            0
 #define CONFIG_SYS_SATA_FAT_BOOT_PARTITION     1
 
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
 
 /* Enabled commands */
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v2, v3"
+
 /* USB Networking options */
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_SMSC95XX
index d84dde39c104ac4bac910cdda1484d5f0b44752b..3539a62790f75508aeb4652787bf5a156f280681 100644 (file)
@@ -27,7 +27,7 @@
 #define CONFIG_SYS_NO_FLASH            /* Declare no flash (NOR/SPI) */
 #define CONFIG_CMD_ENV
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 
 /* I2C */
 #define CONFIG_SYS_I2C
index 79b6c0995120d506867ee218d0c07c9eb41ffe82..8a0cd66cd0fac6fe4c884a2a3a42a7ee5bbc0565 100644 (file)
 
 /* SATA */
 #define CONFIG_BOARD_LATE_INIT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 6dd0b32daef964a8107d14c130d392647ba327b1..95e46c558d2c1722fbd983f73b0b97ef9b1c777b 100644 (file)
@@ -18,7 +18,7 @@
 #undef CONFIG_VIDEO
 #undef CONFIG_CFB_CONSOLE
 #undef CONFIG_SCSI_AHCI
-#undef CONFIG_CMD_SCSI
+#undef CONFIG_SCSI
 #undef CONFIG_INTEL_ICH6_GPIO
 #undef CONFIG_USB_EHCI_PCI
 
index 2f1f6d44554581fed366d253438645ff4fae9531..40f7fba833b1d7408e4202dea8b88dbde29fe8a1 100644 (file)
@@ -29,7 +29,7 @@
 
 /* SATA is not supported in Quark SoC */
 #undef CONFIG_SCSI_AHCI
-#undef CONFIG_CMD_SCSI
+#undef CONFIG_SCSI
 
 /* Video is not supported in Quark SoC */
 #undef CONFIG_VIDEO
index 3bce12bbb85713b9d7f154f081890cd30e3096c8..5cefddc2e0eedbdafa6ca099b415b2648e8522d9 100644 (file)
@@ -51,7 +51,7 @@
 /*
  * Command line configuration.
  */
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 
 #define CONFIG_BOOT_RETRY_TIME         -1
 #define CONFIG_RESET_TO_RETRY
index d71a229c6133550f03623226a246265b82c2526b..af1f73dbaa8ba260fc9a889787d3649c6722f0c0 100644 (file)
@@ -108,7 +108,7 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_DOS_PARTITION
 #define CONFIG_BOARD_LATE_INIT
 
index 2d7567f394fca161701d77500d295434cc5f7efe..f8c9e51ae7fe547914db21ffe25e38ae96b99f4f 100644 (file)
@@ -44,7 +44,7 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_DOS_PARTITION
 #define CONFIG_BOARD_LATE_INIT
 
index 5bec5099af78b463b9dfe6315b9726ebdbf2a20c..4577919ca121492537fe98c3d961ca2d5d19a066 100644 (file)
@@ -62,7 +62,7 @@ unsigned long get_board_sys_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_DOS_PARTITION
 #define CONFIG_BOARD_LATE_INIT
 
index 86cefa3b8f88e5094b502f5fd0e66ff716e20f89..4ddc49211267235ddda14f26919e03c4bfc731b2 100644 (file)
 /* Max time to hold reset on this board, see doc/README.omap-reset-time */
 #define CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC       16296
 
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index a7cd00350d4daa8ee2cd70524d5053597935a841..702967c4e8e5cdf93afca6851b13e5d5e60059f6 100644 (file)
 #define CONFIG_CMD_IDE
 #define CONFIG_DOS_PARTITION
 
+#ifdef CONFIG_SYS_BIG_ENDIAN
+#define CONFIG_IDE_SWAP_IO
+#endif
+
 #define CONFIG_SYS_IDE_MAXBUS          2
 #define CONFIG_SYS_ATA_IDE0_OFFSET     0x1f0
 #define CONFIG_SYS_ATA_IDE1_OFFSET     0x170
index 394382c4587fdbae552f1b3a4ef8e9fb72ace72f..239454984ae046ea10d25555ed4b307434c84561 100644 (file)
 #define CONFIG_CMD_IDE
 #define CONFIG_DOS_PARTITION
 
+#ifdef CONFIG_SYS_BIG_ENDIAN
+#define CONFIG_IDE_SWAP_IO
+#endif
+
 #define CONFIG_SYS_IDE_MAXBUS          2
 #define CONFIG_SYS_ATA_IDE0_OFFSET     0x1f0
 #define CONFIG_SYS_ATA_IDE1_OFFSET     0x170
index b0d2ffe5b4c842b9086072c2463abb00d35c2eb7..476d37d4bce93ce9abc0ca5021f22118b099526f 100644 (file)
@@ -43,7 +43,7 @@
 #define CONFIG_ATAPI
 
 #undef CONFIG_SCSI_AHCI
-#undef CONFIG_CMD_SCSI
+#undef CONFIG_SCSI
 #else
 #define CONFIG_SCSI_DEV_LIST           \
        {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_AHCI}
index 9790a14b02b0fce4f0f25e851311ea9c1b563ba4..23a0c40ca528a8377416d4036f6d46ffdeff29e2 100644 (file)
 #define CONFIG_CMD_LZMADEC
 #define CONFIG_CMD_DATE
 
+#define CONFIG_CMD_IDE
+#define CONFIG_SYS_IDE_MAXBUS          1
+#define CONFIG_SYS_ATA_IDE0_OFFSET     0
+#define CONFIG_SYS_IDE_MAXDEVICE       2
+#define CONFIG_SYS_ATA_BASE_ADDR       0x100
+#define CONFIG_SYS_ATA_DATA_OFFSET     0
+#define CONFIG_SYS_ATA_REG_OFFSET      1
+#define CONFIG_SYS_ATA_ALT_OFFSET      2
+#define CONFIG_SYS_ATA_STRIDE          4
+
+#define CONFIG_SCSI
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SCSI_MAX_DEVICE     2
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID    8
+#define CONFIG_SYS_SCSI_MAX_LUN                4
+
+#define CONFIG_CMD_SATA
+#define CONFIG_SYS_SATA_MAX_DEVICE     2
+
+#define CONFIG_SYSTEMACE
+#define CONFIG_SYS_SYSTEMACE_WIDTH     16
+#define CONFIG_SYS_SYSTEMACE_BASE      0
+
+#define CONFIG_GENERIC_MMC
+
 #endif
index a7c7aef71ab9414cb9c43fdd38a47cd520a0430b..c9970f1f3e2a103f9450c79ba775b8e456310224 100644 (file)
 
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup */
 
-#undef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
-
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play */
 
 #undef CONFIG_EEPRO100
index 4fdc09a3ce7cc263a71af051c738260d7f72f056..f6577668a1dd6f31fc94fe794d2914604c13b12f 100644 (file)
  * I2C support
  */
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_DW
 #define CONFIG_SYS_I2C_BUS_MAX         4
 #define CONFIG_SYS_I2C_BASE            SOCFPGA_I2C0_ADDRESS
 #define CONFIG_SYS_I2C_BASE1           SOCFPGA_I2C1_ADDRESS
index c4b6234096e134a60d1eb6200fee111584181424..7b2d262b4bb71f83ea52a6dabfc78ef8ffdaccba 100644 (file)
@@ -35,7 +35,6 @@
 
 /* I2C driver configuration */
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_DW
 #if defined(CONFIG_SPEAR600)
 #define CONFIG_SYS_I2C_BASE                    0xD0200000
 #elif defined(CONFIG_SPEAR300)
index 2406115e3e21774837af1c953ead070008807664..ac2d93114b53567e1ac47bdea0d6982fa20c7ee2 100644 (file)
 #define CONFIG_SYS_SCSI_MAX_LUN                1
 #define CONFIG_SYS_SCSI_MAX_DEVICE     (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
                                         CONFIG_SYS_SCSI_MAX_LUN)
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #endif
 
 #define CONFIG_SETUP_MEMORY_TAGS
index 1caa8588560d8d9bb89dbe9889d459d57711594a..dda70c5c818fcf1b83c2f4647baff5c46de285b9 100644 (file)
@@ -64,6 +64,7 @@
 #define PHY_ANEG_TIMEOUT       8000    /* PHY needs a longer aneg time */
 
 #define CONFIG_SYS_CONSOLE_INFO_QUIET  /* don't print console @ startup */
+#define CONFIG_ZERO_BOOTDELAY_CHECK    /* check for keypress on bootdelay==0 */
 #define CONFIG_SYS_ALT_MEMTEST
 #define CONFIG_PREBOOT
 
diff --git a/include/configs/tplink_wdr4300.h b/include/configs/tplink_wdr4300.h
new file mode 100644 (file)
index 0000000..2b9e92e
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_SYS_TEXT_BASE           0xa1000000
+
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_EARLY_INIT_F
+
+#define CONFIG_SYS_HZ                  1000
+#define CONFIG_SYS_MHZ                 280
+#define CONFIG_SYS_MIPS_TIMER_FREQ     (CONFIG_SYS_MHZ * 1000000)
+
+/* Cache Configuration */
+#define CONFIG_SYS_DCACHE_SIZE         0x8000
+#define CONFIG_SYS_ICACHE_SIZE         0x10000
+#define CONFIG_SYS_CACHELINE_SIZE      32
+
+#define CONFIG_SYS_MONITOR_BASE                CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_MALLOC_LEN          0x40000
+#define CONFIG_SYS_BOOTPARAMS_LEN      0x20000
+
+#define CONFIG_SYS_SDRAM_BASE          0xa0000000
+#define CONFIG_SYS_LOAD_ADDR           0xa1000000
+#define CONFIG_LOADADDR                        CONFIG_SYS_LOAD_ADDR
+
+#define CONFIG_SYS_NO_FLASH
+
+#define CONFIG_SYS_INIT_RAM_ADDR       0xbd000000
+#define CONFIG_SYS_INIT_RAM_SIZE       0x8000
+#define CONFIG_SYS_INIT_SP_ADDR                \
+       (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE)
+
+/*
+ * Serial Port
+ */
+#define CONFIG_SYS_NS16550_CLK         40000000
+#define CONFIG_BAUDRATE                        115200
+#define CONFIG_SYS_BAUDRATE_TABLE \
+       {9600, 19200, 38400, 57600, 115200}
+
+#define CONFIG_BOOTDELAY               3
+#define CONFIG_BOOTARGS                        \
+       "console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=squashfs"
+#define CONFIG_BOOTCOMMAND             \
+       "dhcp 192.168.1.1:wdr4300.fit && bootm $loadaddr"
+#define CONFIG_LZMA
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE                        0x10000
+
+/*
+ * Command
+ */
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_CBSIZE      1024            /* Console I/O buffer size */
+#define CONFIG_SYS_MAXARGS     32              /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE                        /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE                   /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING                 /* Command history etc */
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2     "> "
+
+/* USB, USB storage, USB ethernet */
+#define CONFIG_EHCI_MMIO_BIG_ENDIAN
+#define CONFIG_EHCI_DESC_BIG_ENDIAN
+#define CONFIG_EHCI_IS_TDI
+
+#define CONFIG_DOS_PARTITION
+
+/*
+ * Diagnostics
+ */
+#define CONFIG_SYS_MEMTEST_START       0x80100000
+#define CONFIG_SYS_MEMTEST_END         0x83f00000
+#define CONFIG_CMD_MEMTEST
+
+#define CONFIG_USE_PRIVATE_LIBGCC
+
+#define CONFIG_CMD_MII
+#define CONFIG_PHY_GIGE
+
+#endif  /* __CONFIG_H */
index d7da0b295b6b7ae61d7414c06722380091e12689..5fdd2bee049e7927fd3a3ff6944b767cb35f68f1 100644 (file)
@@ -85,7 +85,6 @@
 
 /* I2C config options */
 #define CONFIG_SYS_I2C
-#define CONFIG_SYS_I2C_DW
 #define CONFIG_SYS_I2C_BASE                    0xD0200000
 #define CONFIG_SYS_I2C_SPEED                   400000
 #define CONFIG_SYS_I2C_SLAVE                   0x02
index a2822e01146f938440d93bcfe8988d4f053b2cbb..b79f47baf3fefa52adf8c4e1cb23a942ca913ffd 100644 (file)
 #define CONFIG_CMD_IRQ
 #define CONFIG_CMD_PCI
 #define CONFIG_CMD_GETTIME
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 
 #define CONFIG_CMD_ZBOOT
 
index 060bca985e058d4457c4941ab2dee5a79468dd80..6b8e3ea8657d453d20277f4eb72c59cb20ce376a 100644 (file)
 #define CONFIG_SYS_SCSI_MAX_LUN                1
 #define CONFIG_SYS_SCSI_MAX_DEVICE     (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
                                         CONFIG_SYS_SCSI_MAX_LUN)
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #endif
 
 #define CONFIG_SYS_BOOTM_LEN   (60 * 1024 * 1024)
index 8970fc015c7eb1158644110338d8e6f181181d1d..e9a8ec72c90eba36d93b365e9afe49c2298df7a5 100644 (file)
@@ -41,6 +41,9 @@ struct driver_info;
 /* Device is bound */
 #define DM_FLAG_BOUND                  (1 << 6)
 
+/* Device name is allocated and should be freed on unbind() */
+#define DM_NAME_ALLOCED                        (1 << 7)
+
 /**
  * struct udevice - An instance of a driver
  *
@@ -523,6 +526,9 @@ bool device_is_last_sibling(struct udevice *dev);
  * this is unnecessary but for probed devices which don't get a useful name
  * this function can be helpful.
  *
+ * The name is allocated and will be freed automatically when the device is
+ * unbound.
+ *
  * @dev:       Device to update
  * @name:      New name (this string is allocated new memory and attached to
  *             the device)
@@ -531,6 +537,16 @@ bool device_is_last_sibling(struct udevice *dev);
  */
 int device_set_name(struct udevice *dev, const char *name);
 
+/**
+ * device_set_name_alloced() - note that a device name is allocated
+ *
+ * This sets the DM_NAME_ALLOCED flag for the device, so that when it is
+ * unbound the name will be freed. This avoids memory leaks.
+ *
+ * @dev:       Device to update
+ */
+void device_set_name_alloced(struct udevice *dev);
+
 /**
  * device_is_on_pci_bus - Test if a device is on a PCI bus
  *
diff --git a/include/dm/platform_data/serial_coldfire.h b/include/dm/platform_data/serial_coldfire.h
new file mode 100644 (file)
index 0000000..5d86456
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2015  Angelo Dureghello <angelo@sysam.it>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __serial_coldfire_h
+#define __serial_coldfire_h
+
+/*
+ * struct coldfire_serial_platdata - information about a coldfire port
+ *
+ * @base:               Uart port base register address
+ * @port:               Uart port index, for cpu with pinmux for uart / gpio
+ * baudrtatre:          Uart port baudrate
+ */
+struct coldfire_serial_platdata {
+       unsigned long base;
+       int port;
+       int baudrate;
+};
+
+#endif /* __serial_coldfire_h */
index cbf9b2ca235190714b81fc1c07460d997e5e95d5..a5cf6e201c0b1f1de0d74f3de004eef2c1f0db98 100644 (file)
@@ -26,11 +26,11 @@ enum uclass_id {
 
        /* U-Boot uclasses start here - in alphabetical order */
        UCLASS_ADC,             /* Analog-to-digital converter */
+       UCLASS_AHCI,            /* SATA disk controller */
        UCLASS_BLK,             /* Block device */
        UCLASS_CLK,             /* Clock source, e.g. used by peripherals */
        UCLASS_CPU,             /* CPU, typically part of an SoC */
        UCLASS_CROS_EC,         /* Chrome OS EC */
-       UCLASS_DISK,            /* Disk controller, e.g. SATA */
        UCLASS_DISPLAY,         /* Display (e.g. DisplayPort, HDMI) */
        UCLASS_DMA,             /* Direct Memory Access */
        UCLASS_RAM,             /* RAM controller */
diff --git a/include/eeprom_field.h b/include/eeprom_field.h
new file mode 100644 (file)
index 0000000..94e259f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2009-2016 CompuLab, Ltd.
+ *
+ * Authors: Nikita Kiryanov <nikita@compulab.co.il>
+ *         Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _FIELD_
+#define _FIELD_
+
+#define PRINT_FIELD_SEGMENT    "%-30s"
+
+struct eeprom_field {
+       char *name;
+       int size;
+       unsigned char *buf;
+
+       void (*print)(const struct eeprom_field *eeprom_field);
+       int (*update)(struct eeprom_field *eeprom_field, char *value);
+};
+
+void eeprom_field_print_bin(const struct eeprom_field *field);
+int eeprom_field_update_bin(struct eeprom_field *field, char *value);
+
+void eeprom_field_print_bin_rev(const struct eeprom_field *field);
+int eeprom_field_update_bin_rev(struct eeprom_field *field, char *value);
+
+void eeprom_field_print_mac(const struct eeprom_field *field);
+int eeprom_field_update_mac(struct eeprom_field *field, char *value);
+
+void eeprom_field_print_ascii(const struct eeprom_field *field);
+int eeprom_field_update_ascii(struct eeprom_field *field, char *value);
+
+void eeprom_field_print_reserved(const struct eeprom_field *field);
+int eeprom_field_update_reserved(struct eeprom_field *field, char *value);
+
+#endif
diff --git a/include/eeprom_layout.h b/include/eeprom_layout.h
new file mode 100644 (file)
index 0000000..459b99d
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2009-2016 CompuLab, Ltd.
+ *
+ * Authors: Nikita Kiryanov <nikita@compulab.co.il>
+ *         Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _LAYOUT_
+#define _LAYOUT_
+
+#define RESERVED_FIELDS                        NULL
+#define LAYOUT_VERSION_UNRECOGNIZED    -1
+#define LAYOUT_VERSION_AUTODETECT      -2
+
+struct eeprom_layout {
+       struct eeprom_field *fields;
+       int num_of_fields;
+       int layout_version;
+       unsigned char *data;
+       int data_size;
+       void (*print)(const struct eeprom_layout *eeprom_layout);
+       int (*update)(struct eeprom_layout *eeprom_layout, char *field_name,
+                     char *new_data);
+};
+
+void eeprom_layout_setup(struct eeprom_layout *layout, unsigned char *buf,
+                        unsigned int buf_size, int layout_version);
+__weak void __eeprom_layout_assign(struct eeprom_layout *layout,
+                                  int layout_version);
+
+#endif
index c6321a02ef8e5d4f89f5288f1910bad888e37d60..2a5e13a13d380b9c131a74c97900e4663d11e7b0 100644 (file)
@@ -400,6 +400,9 @@ extern flash_info_t *flash_get_info(ulong base);
 #define FLASH_STM800DT 0x00D7          /* STM M29W800DT (1M = 64K x 16, top)   */
 #define FLASH_STM800DB 0x005B          /* STM M29W800DB (1M = 64K x 16, bottom)*/
 
+#define FLASH_MCHP100T 0x0060          /* MCHP internal (1M = 64K x 16) */
+#define FLASH_MCHP100B 0x0061          /* MCHP internal (1M = 64K x 16) */
+
 #define FLASH_28F400_T 0x0062          /* MT  28F400B3 ID (  4M = 256K x 16 )  */
 #define FLASH_28F400_B 0x0063          /* MT  28F400B3 ID (  4M = 256K x 16 )  */
 
@@ -486,7 +489,7 @@ extern flash_info_t *flash_get_info(ulong base);
 #define FLASH_MAN_SHARP 0x00500000
 #define FLASH_MAN_ATM  0x00600000
 #define FLASH_MAN_CFI  0x01000000
-
+#define FLASH_MAN_MCHP 0x02000000      /* Microchip Technology         */
 
 #define FLASH_TYPEMASK 0x0000FFFF      /* extract FLASH type   information     */
 #define FLASH_VENDMASK 0xFFFF0000      /* extract FLASH vendor information     */
index a4e65cf2a9420dbc7523c6d2ae9b91ce6c87209e..9b0a4a96fa5d64a5598e498aa2bd7b649004fdb6 100644 (file)
@@ -34,10 +34,18 @@ void ide_led(uchar led, uchar status);
 
 void ide_init(void);
 struct blk_desc;
+struct udevice;
+#ifdef CONFIG_BLK
+ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+              void *buffer);
+ulong ide_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+               const void *buffer);
+#else
 ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
               void *buffer);
 ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
                const void *buffer);
+#endif
 
 #ifdef CONFIG_IDE_PREINIT
 int ide_preinit(void);
index 9bd1f167abe5ea3c4a9d61df1338af7fb6f28b81..e4ceb6180537ed62ce4ae96f60ca56268ab9f5e8 100644 (file)
 #define writew(val, addr)      iotrace_writew(val, (const void *)(addr))
 
 #undef readb
-#define readb(addr)    iotrace_readb((const void *)(addr))
+#define readb(addr)    iotrace_readb((const void *)(uintptr_t)addr)
 
 #undef writeb
-#define writeb(val, addr)      iotrace_writeb(val, (const void *)(addr))
+#define writeb(val, addr) \
+       iotrace_writeb(val, (const void *)(uintptr_t)addr)
 
 #endif
 
index 7ec5550f4bfaed064b175f90ddbb5c8aea430b69..8f8ac6aeefe3ea72c9ce191ee800aeb1426cabbb 100644 (file)
@@ -17,4 +17,13 @@ enum usb_dr_mode {
        USB_DR_MODE_OTG,
 };
 
+/**
+ * usb_get_dr_mode() - Get dual role mode for given device
+ * @node: Node offset to the given device
+ *
+ * The function gets phy interface string from property 'dr_mode',
+ * and returns the correspondig enum usb_dr_mode
+ */
+enum usb_dr_mode usb_get_dr_mode(int node);
+
 #endif /* __LINUX_USB_OTG_H */
index cdb56e7ac14eaaeef3d952876756beb6359ad0bb..a5c6573ddd6efcf7fbd76903089b5c06e278cefd 100644 (file)
@@ -344,7 +344,9 @@ struct mmc_config {
 
 /* TODO struct mmc should be in mmc_private but it's hard to fix right now */
 struct mmc {
+#ifndef CONFIG_BLK
        struct list_head link;
+#endif
        const struct mmc_config *cfg;   /* provided configuration */
        uint version;
        void *priv;
@@ -376,11 +378,16 @@ struct mmc {
        u64 capacity_gp[4];
        u64 enh_user_start;
        u64 enh_user_size;
+#ifndef CONFIG_BLK
        struct blk_desc block_dev;
+#endif
        char op_cond_pending;   /* 1 if we are waiting on an op_cond command */
        char init_in_progress;  /* 1 if we have done mmc_start_init() */
        char preinit;           /* start init as early as possible */
        int ddr_mode;
+#ifdef CONFIG_DM_MMC
+       struct udevice *dev;    /* Device for this MMC controller */
+#endif
 };
 
 struct mmc_hwpart_conf {
@@ -406,7 +413,29 @@ enum mmc_hwpart_conf_mode {
 
 int mmc_register(struct mmc *mmc);
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv);
+
+/**
+ * mmc_bind() - Set up a new MMC device ready for probing
+ *
+ * A child block device is bound with the IF_TYPE_MMC interface type. This
+ * allows the device to be used with CONFIG_BLK
+ *
+ * @dev:       MMC device to set up
+ * @mmc:       MMC struct
+ * @cfg:       MMC configuration
+ * @return 0 if OK, -ve on error
+ */
+int mmc_bind(struct udevice *dev, struct mmc *mmc,
+            const struct mmc_config *cfg);
 void mmc_destroy(struct mmc *mmc);
+
+/**
+ * mmc_unbind() - Unbind a MMC device's child block device
+ *
+ * @dev:       MMC device
+ * @return 0 if OK, -ve on error
+ */
+int mmc_unbind(struct udevice *dev);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
@@ -415,7 +444,6 @@ struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
-int mmc_switch_part(int dev_num, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
                      enum mmc_hwpart_conf_mode mode);
 int mmc_getcd(struct mmc *mmc);
@@ -498,4 +526,12 @@ int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported);
 #define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
 #endif
 
+/**
+ * mmc_get_blk_desc() - Get the block descriptor for an MMC device
+ *
+ * @mmc:       MMC device
+ * @return block device if found, else NULL
+ */
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc);
+
 #endif /* _MMC_H_ */
index e3811c68de8a31c3bf3daddad1d87f9e3187334a..226b5be9df26384818e0299fde0d5f0e9d782646 100644 (file)
@@ -12,7 +12,6 @@
 
 struct block_drvr {
        char *name;
-       struct blk_desc* (*get_dev)(int dev);
        int (*select_hwpart)(int dev_num, int hwpart);
 };
 
@@ -73,32 +72,8 @@ typedef struct disk_partition {
  *        error occurred.
  */
 struct blk_desc *blk_get_dev(const char *ifname, int dev);
-struct blk_desc *ide_get_dev(int dev);
-struct blk_desc *sata_get_dev(int dev);
-struct blk_desc *scsi_get_dev(int dev);
-struct blk_desc *usb_stor_get_dev(int dev);
-struct blk_desc *mmc_get_dev(int dev);
 
-/**
- * mmc_select_hwpart() - Select the MMC hardware partiion on an MMC device
- *
- * MMC devices can support partitioning at the hardware level. This is quite
- * separate from the normal idea of software-based partitions. MMC hardware
- * partitions must be explicitly selected. Once selected only the region of
- * the device covered by that partition is accessible.
- *
- * The MMC standard provides for two boot partitions (numbered 1 and 2),
- * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
- *
- * @dev_num:   Block device number (struct blk_desc->dev value)
- * @hwpart:    Hardware partition number to select. 0 means the raw device,
- *             1 is the first partition, 2 is the second, etc.
- * @return 0 if OK, other value for an error
- */
-int mmc_select_hwpart(int dev_num, int hwpart);
-struct blk_desc *systemace_get_dev(int dev);
 struct blk_desc *mg_disk_get_dev(int dev);
-struct blk_desc *host_get_dev(int dev);
 int host_get_dev_err(int dev, struct blk_desc **blk_devp);
 
 /* disk/part.c */
@@ -175,15 +150,7 @@ extern const struct block_drvr block_drvr[];
 #else
 static inline struct blk_desc *blk_get_dev(const char *ifname, int dev)
 { return NULL; }
-static inline struct blk_desc *ide_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *sata_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *scsi_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *usb_stor_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *mmc_get_dev(int dev) { return NULL; }
-static inline int mmc_select_hwpart(int dev_num, int hwpart) { return -1; }
-static inline struct blk_desc *systemace_get_dev(int dev) { return NULL; }
 static inline struct blk_desc *mg_disk_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *host_get_dev(int dev) { return NULL; }
 
 static inline int part_get_info(struct blk_desc *dev_desc, int part,
                                disk_partition_t *info) { return -1; }
index 4b88d3986e78cea0e3bf117a5b6351f88c011146..ca96fa4b31b6cda4cdbbca9b0fcbe25406f6e5b7 100644 (file)
@@ -612,6 +612,58 @@ int sandbox_spi_get_emul(struct sandbox_state *state,
                         struct udevice *bus, struct udevice *slave,
                         struct udevice **emulp);
 
+/**
+ * Claim the bus and prepare it for communication with a given slave.
+ *
+ * This must be called before doing any transfers with a SPI slave. It
+ * will enable and initialize any SPI hardware as necessary, and make
+ * sure that the SCK line is in the correct idle state. It is not
+ * allowed to claim the same bus for several slaves without releasing
+ * the bus in between.
+ *
+ * @dev:       The SPI slave device
+ *
+ * Returns: 0 if the bus was claimed successfully, or a negative value
+ * if it wasn't.
+ */
+int dm_spi_claim_bus(struct udevice *dev);
+
+/**
+ * Release the SPI bus
+ *
+ * This must be called once for every call to dm_spi_claim_bus() after
+ * all transfers have finished. It may disable any SPI hardware as
+ * appropriate.
+ *
+ * @slave:     The SPI slave device
+ */
+void dm_spi_release_bus(struct udevice *dev);
+
+/**
+ * SPI transfer
+ *
+ * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
+ * "bitlen" bits in the SPI MISO port.  That's just the way SPI works.
+ *
+ * The source of the outgoing bits is the "dout" parameter and the
+ * destination of the input bits is the "din" parameter.  Note that "dout"
+ * and "din" can point to the same memory location, in which case the
+ * input data overwrites the output data (since both are buffered by
+ * temporary variables, this is OK).
+ *
+ * dm_spi_xfer() interface:
+ * @dev:       The SPI slave device which will be sending/receiving the data.
+ * @bitlen:    How many bits to write and read.
+ * @dout:      Pointer to a string of bits to send out.  The bits are
+ *             held in a byte array and are sent MSB first.
+ * @din:       Pointer to a string of bits that will be filled in.
+ * @flags:     A bitwise combination of SPI_XFER_* flags.
+ *
+ * Returns: 0 on success, not 0 on failure
+ */
+int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
+               const void *dout, void *din, unsigned long flags);
+
 /* Access the operations for a SPI device */
 #define spi_get_ops(dev)       ((struct dm_spi_ops *)(dev)->driver->ops)
 #define spi_emul_get_ops(dev)  ((struct dm_spi_emul_ops *)(dev)->driver->ops)
diff --git a/include/systemace.h b/include/systemace.h
deleted file mode 100644 (file)
index 3b6ec7d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __SYSTEMACE_H
-#define __SYSTEMACE_H
-/*
- * Copyright (c) 2004 Picture Elements, Inc.
- *    Stephen Williams (steve@picturel.com)
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifdef CONFIG_SYSTEMACE
-
-# include  <part.h>
-
-struct blk_desc *systemace_get_dev(int dev);
-
-#endif /* CONFIG_SYSTEMACE */
-#endif /* __SYSTEMACE_H */
index 5adad368380897eadae2ac6d39b7934aefa1bd82..02a0ccdd77b370b4bd62d858a2c797e926fd03f2 100644 (file)
@@ -228,7 +228,6 @@ int board_usb_cleanup(int index, enum usb_init_type init);
 #ifdef CONFIG_USB_STORAGE
 
 #define USB_MAX_STOR_DEV 7
-struct blk_desc *usb_stor_get_dev(int index);
 int usb_stor_scan(int mode);
 int usb_stor_info(void);
 
index 28e5b7fce59ce1b4470b4c82fd7e5d5c09899b52..075fd3401450d41320353d2db42ad9fdb03ccc59 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <blk.h>
 #include <efi_loader.h>
 #include <inttypes.h>
 #include <part.h>
@@ -142,7 +143,7 @@ static const struct efi_block_io block_io_disk_template = {
 };
 
 static void efi_disk_add_dev(char *name,
-                            const struct block_drvr *cur_drvr,
+                            const struct blk_driver *cur_drvr,
                             const struct blk_desc *desc,
                             int dev_index,
                             lbaint_t offset)
@@ -160,7 +161,7 @@ static void efi_disk_add_dev(char *name,
        diskobj->parent.protocols[1].open = efi_disk_open_dp;
        diskobj->parent.handle = diskobj;
        diskobj->ops = block_io_disk_template;
-       diskobj->ifname = cur_drvr->name;
+       diskobj->ifname = cur_drvr->if_typename;
        diskobj->dev_index = dev_index;
        diskobj->offset = offset;
 
@@ -189,7 +190,7 @@ static void efi_disk_add_dev(char *name,
 }
 
 static int efi_disk_create_eltorito(struct blk_desc *desc,
-                                   const struct block_drvr *cur_drvr,
+                                   const struct blk_driver *cur_drvr,
                                    int diskid)
 {
        int disks = 0;
@@ -202,8 +203,8 @@ static int efi_disk_create_eltorito(struct blk_desc *desc,
                return 0;
 
        while (!part_get_info(desc, part, &info)) {
-               snprintf(devname, sizeof(devname), "%s%d:%d", cur_drvr->name,
-                        diskid, part);
+               snprintf(devname, sizeof(devname), "%s%d:%d",
+                        cur_drvr->if_typename, diskid, part);
                efi_disk_add_dev(devname, cur_drvr, desc, diskid, info.start);
                part++;
                disks++;
@@ -222,25 +223,29 @@ static int efi_disk_create_eltorito(struct blk_desc *desc,
  */
 int efi_disk_register(void)
 {
-       const struct block_drvr *cur_drvr;
-       int i;
+       const struct blk_driver *cur_drvr;
+       int i, if_type;
        int disks = 0;
 
        /* Search for all available disk devices */
-       for (cur_drvr = block_drvr; cur_drvr->name; cur_drvr++) {
-               printf("Scanning disks on %s...\n", cur_drvr->name);
+       for (if_type = 0; if_type < IF_TYPE_COUNT; if_type++) {
+               cur_drvr = blk_driver_lookup_type(if_type);
+               if (!cur_drvr)
+                       continue;
+
+               printf("Scanning disks on %s...\n", cur_drvr->if_typename);
                for (i = 0; i < 4; i++) {
                        struct blk_desc *desc;
                        char devname[32] = { 0 }; /* dp->str is u16[32] long */
 
-                       desc = blk_get_dev(cur_drvr->name, i);
+                       desc = blk_get_devnum_by_type(if_type, i);
                        if (!desc)
                                continue;
                        if (desc->type == DEV_TYPE_UNKNOWN)
                                continue;
 
                        snprintf(devname, sizeof(devname), "%s%d",
-                                cur_drvr->name, i);
+                                cur_drvr->if_typename, i);
                        efi_disk_add_dev(devname, cur_drvr, desc, i, 0);
                        disks++;
 
index e8e8c7756deb09e00ec7cb48e3dd0ad628e3c6cc..9bd0de2490748730e750dbf8797a3ae19c431c95 100644 (file)
@@ -296,7 +296,11 @@ static void do_config_file(const char *filename)
                perror(filename);
                exit(2);
        }
-       fstat(fd, &st);
+       if (fstat(fd, &st) < 0) {
+               fprintf(stderr, "fixdep: error fstat'ing config file: ");
+               perror(filename);
+               exit(2);
+       }
        if (st.st_size == 0) {
                close(fd);
                return;
index f4ea32e83e514095d277046bf8a0d249f8235c6a..012bf4cab56ef43fbfa605c7bac9a32eebd4baa1 100644 (file)
@@ -83,12 +83,12 @@ static int dm_test_blk_usb(struct unit_test_state *uts)
        ut_asserteq_ptr(usb_dev, dev_get_parent(dev));
 
        /* Check we have one block device for each mass storage device */
-       ut_asserteq(3, count_blk_devices());
+       ut_asserteq(4, count_blk_devices());
 
        /* Now go around again, making sure the old devices were unbound */
        ut_assertok(usb_stop());
        ut_assertok(usb_init());
-       ut_asserteq(3, count_blk_devices());
+       ut_asserteq(4, count_blk_devices());
        ut_assertok(usb_stop());
 
        return 0;
index 046142322da2c70f697f84bd61087f95a5e2dcbb..5bca4b79d597b43fe2ea0ffde788d422e5b2fa93 100644 (file)
@@ -25,3 +25,22 @@ static int dm_test_mmc_base(struct unit_test_state *uts)
        return 0;
 }
 DM_TEST(dm_test_mmc_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static int dm_test_mmc_blk(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+       struct blk_desc *dev_desc;
+       char cmp[1024];
+
+       ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
+       ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));
+
+       /* Read a few blocks and look for the string we expect */
+       ut_asserteq(512, dev_desc->blksz);
+       memset(cmp, '\0', sizeof(cmp));
+       ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
+       ut_assertok(strcmp(cmp, "this is a test"));
+
+       return 0;
+}
+DM_TEST(dm_test_mmc_blk, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
index 4705d2644b8f075da0a83802bbb42a908fde8e0b..26755c5955e21c5f0cb89ba59cb1c890fa011502 100644 (file)
@@ -898,6 +898,48 @@ when using the -b flag. For example:
 will build commits in us-buildman that are not in upstream/master.
 
 
+Building Faster
+===============
+
+By default, buildman executes 'make mrproper' prior to building the first
+commit for each board. This causes everything to be built from scratch. If you
+trust the build system's incremental build capabilities, you can pass the -I
+flag to skip the 'make mproper' invocation, which will reduce the amount of
+work 'make' does, and hence speed up the build. This flag will speed up any
+buildman invocation, since it reduces the amount of work done on any build.
+
+One possible application of buildman is as part of a continual edit, build,
+edit, build, ... cycle; repeatedly applying buildman to the same change or
+series of changes while making small incremental modifications to the source
+each time. This provides quick feedback regarding the correctness of recent
+modifications. In this scenario, buildman's default choice of build directory
+causes more build work to be performed than strictly necessary.
+
+By default, each buildman thread uses a single directory for all builds. When a
+thread builds multiple boards, the configuration built in this directory will
+cycle through various different configurations, one per board built by the
+thread. Variations in the configuration will force a rebuild of affected source
+files when a thread switches between boards. Ideally, such buildman-induced
+rebuilds would not happen, thus allowing the build to operate as efficiently as
+the build system and source changes allow. buildman's -P flag may be used to
+enable this; -P causes each board to be built in a separate (board-specific)
+directory, thus avoiding any buildman-induced configuration changes in any
+build directory.
+
+U-Boot's build system embeds information such as a build timestamp into the
+final binary. This information varies each time U-Boot is built. This causes
+various files to be rebuilt even if no source changes are made, which in turn
+requires that the final U-Boot binary be re-linked. This unnecessary work can
+be avoided by turning off the timestamp feature. This can be achieved by
+setting the SOURCE_DATE_EPOCH environment variable to 0.
+
+Combining all of these options together yields the command-line shown below.
+This will provide the quickest possible feedback regarding the current content
+of the source tree, thus allowing rapid tested evolution of the code.
+
+    SOURCE_DATE_EPOCH=0 ./tools/buildman/buildman -I -P tegra
+
+
 Other options
 =============
 
index 141bf6469136aa7f5f18bb6e07701dfcfd5d135d..8ec3551729015ed7a6b2a3cb9bea134251ced4f6 100644 (file)
@@ -205,7 +205,8 @@ class Builder:
 
     def __init__(self, toolchains, base_dir, git_dir, num_threads, num_jobs,
                  gnu_make='make', checkout=True, show_unknown=True, step=1,
-                 no_subdirs=False, full_path=False, verbose_build=False):
+                 no_subdirs=False, full_path=False, verbose_build=False,
+                 incremental=False, per_board_out_dir=False):
         """Create a new Builder object
 
         Args:
@@ -224,6 +225,10 @@ class Builder:
             full_path: Return the full path in CROSS_COMPILE and don't set
                 PATH
             verbose_build: Run build with V=1 and don't use 'make -s'
+            incremental: Always perform incremental builds; don't run make
+                mrproper when configuring
+            per_board_out_dir: Build in a separate persistent directory per
+                board rather than a thread-specific directory
         """
         self.toolchains = toolchains
         self.base_dir = base_dir
@@ -263,7 +268,8 @@ class Builder:
         self.queue = Queue.Queue()
         self.out_queue = Queue.Queue()
         for i in range(self.num_threads):
-            t = builderthread.BuilderThread(self, i)
+            t = builderthread.BuilderThread(self, i, incremental,
+                    per_board_out_dir)
             t.setDaemon(True)
             t.start()
             self.threads.append(t)
index cf25bb8f1a7e325192b8410d3081cea27c864bf0..c512d3b521f755d0945030e4cb6cc958170c24a9 100644 (file)
@@ -80,11 +80,13 @@ class BuilderThread(threading.Thread):
         thread_num: Our thread number (0-n-1), used to decide on a
                 temporary directory
     """
-    def __init__(self, builder, thread_num):
+    def __init__(self, builder, thread_num, incremental, per_board_out_dir):
         """Set up a new builder thread"""
         threading.Thread.__init__(self)
         self.builder = builder
         self.thread_num = thread_num
+        self.incremental = incremental
+        self.per_board_out_dir = per_board_out_dir
 
     def Make(self, commit, brd, stage, cwd, *args, **kwargs):
         """Run 'make' on a particular commit and board.
@@ -136,7 +138,11 @@ class BuilderThread(threading.Thread):
         if self.builder.in_tree:
             out_dir = work_dir
         else:
-            out_dir = os.path.join(work_dir, 'build')
+            if self.per_board_out_dir:
+                out_rel_dir = os.path.join('..', brd.target)
+            else:
+                out_rel_dir = 'build'
+            out_dir = os.path.join(work_dir, out_rel_dir)
 
         # Check if the job was already completed last time
         done_file = self.builder.GetDoneFile(commit_upto, brd.target)
@@ -197,12 +203,12 @@ class BuilderThread(threading.Thread):
                         #
                         # Symlinks can confuse U-Boot's Makefile since
                         # we may use '..' in our path, so remove them.
-                        work_dir = os.path.realpath(work_dir)
-                        args.append('O=%s/build' % work_dir)
+                        out_dir = os.path.realpath(out_dir)
+                        args.append('O=%s' % out_dir)
                         cwd = None
                         src_dir = os.getcwd()
                     else:
-                        args.append('O=build')
+                        args.append('O=%s' % out_rel_dir)
                 if self.builder.verbose_build:
                     args.append('V=1')
                 else:
@@ -215,9 +221,11 @@ class BuilderThread(threading.Thread):
 
                 # If we need to reconfigure, do that now
                 if do_config:
-                    result = self.Make(commit, brd, 'mrproper', cwd,
-                            'mrproper', *args, env=env)
-                    config_out = result.combined
+                    config_out = ''
+                    if not self.incremental:
+                        result = self.Make(commit, brd, 'mrproper', cwd,
+                                'mrproper', *args, env=env)
+                        config_out += result.combined
                     result = self.Make(commit, brd, 'config', cwd,
                             *(args + config_args), env=env)
                     config_out += result.combined
index 8341ab145cfa1f5eb1776ef1a821cd2ab95e8972..3e3bd63e32c771e6439faa803ad0e7dc9cb520f8 100644 (file)
@@ -49,6 +49,8 @@ def ParseArgs():
     parser.add_option('-i', '--in-tree', dest='in_tree',
           action='store_true', default=False,
           help='Build in the source tree instead of a separate directory')
+    parser.add_option('-I', '--incremental', action='store_true',
+          default=False, help='Do not run make mrproper (when reconfiguring)')
     parser.add_option('-j', '--jobs', dest='jobs', type='int',
           default=None, help='Number of jobs to run at once (passed to make)')
     parser.add_option('-k', '--keep-outputs', action='store_true',
@@ -70,6 +72,8 @@ def ParseArgs():
           default=False, help='Do a rough build, with limited warning resolution')
     parser.add_option('-p', '--full-path', action='store_true',
           default=False, help="Use full toolchain path in CROSS_COMPILE")
+    parser.add_option('-P', '--per-board-out-dir', action='store_true',
+          default=False, help="Use an O= (output) directory per board rather than per thread")
     parser.add_option('-s', '--summary', action='store_true',
           default=False, help='Show a build summary')
     parser.add_option('-S', '--show-sizes', action='store_true',
index c2c54bf0e81b63676279391cec512358ee10bdcd..aeb128a6a3e92cd5b0649ff6967d0f3bd67a3eeb 100644 (file)
@@ -250,7 +250,9 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
             options.threads, options.jobs, gnu_make=gnu_make, checkout=True,
             show_unknown=options.show_unknown, step=options.step,
             no_subdirs=options.no_subdirs, full_path=options.full_path,
-            verbose_build=options.verbose_build)
+            verbose_build=options.verbose_build,
+            incremental=options.incremental,
+            per_board_out_dir=options.per_board_out_dir,)
     builder.force_config_on_failure = not options.quick
     if make_func:
         builder.do_make = make_func
index 916ab964d553e2d214be17a58f1f8f86b7a36ffe..08d191d9f894a6b86afd867de33ec4026c2286f2 100644 (file)
@@ -51,7 +51,8 @@ int imagetool_verify_print_header(
                                 * successful
                                 */
                                if ((*curr)->print_header) {
-                                       (*curr)->print_header(ptr);
+                                       if (!params->quiet)
+                                               (*curr)->print_header(ptr);
                                } else {
                                        fprintf(stderr,
                                                "%s: print_header undefined for %s\n",
index 24f8f4b2f6352fbfb6e86388236be1fb0f501e3c..a3ed0f43d6afa21caa6d8755536b17d8a3f27ba2 100644 (file)
@@ -73,6 +73,7 @@ struct image_tool_params {
        struct content_info *content_head;      /* List of files to include */
        struct content_info *content_tail;
        bool external_data;     /* Store data outside the FIT */
+       bool quiet;             /* Don't output text in normal operation */
 };
 
 /*
index 93d1c16c7ce0e8afa580ccfb84bc8e454b163f54..aefe22f19b219a7d339dbfdc6f92ca1afe8b1831 100644 (file)
@@ -136,7 +136,7 @@ static void process_args(int argc, char **argv)
        int opt;
 
        while ((opt = getopt(argc, argv,
-                            "a:A:b:cC:d:D:e:Ef:Fk:K:ln:O:rR:sT:vVx")) != -1) {
+                            "a:A:b:cC:d:D:e:Ef:Fk:K:ln:O:rR:qsT:vVx")) != -1) {
                switch (opt) {
                case 'a':
                        params.addr = strtoull(optarg, &ptr, 16);
@@ -216,6 +216,9 @@ static void process_args(int argc, char **argv)
                        if (params.os < 0)
                                usage("Invalid operating system");
                        break;
+               case 'q':
+                       params.quiet = 1;
+                       break;
                case 'r':
                        params.require_keys = 1;
                        break;