]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-x86
authorTom Rini <trini@konsulko.com>
Tue, 12 Jul 2016 12:15:17 +0000 (08:15 -0400)
committerTom Rini <trini@konsulko.com>
Tue, 12 Jul 2016 12:15:17 +0000 (08:15 -0400)
58 files changed:
arch/Kconfig
arch/arm/Kconfig
arch/arm/dts/dra7-evm.dts
arch/arm/dts/dra72-evm.dts
arch/arm/dts/k2e-evm.dts
arch/arm/dts/k2g-evm.dts
arch/arm/dts/k2g.dtsi
arch/arm/dts/k2hk-evm.dts
arch/arm/dts/k2l-evm.dts
arch/arm/dts/keystone.dtsi
arch/arm/mach-rockchip/Kconfig
arch/powerpc/include/asm/arch-mpc85xx/gpio.h
arch/x86/cpu/ivybridge/lpc.c
board/evb_rk3036/evb_rk3036/MAINTAINERS
board/kylin/kylin_rk3036/MAINTAINERS
cmd/sf.c
common/env_sf.c
common/fb_mmc.c
common/spl/spl_mmc.c
configs/dragonboard410c_defconfig
configs/k2e_evm_defconfig
configs/k2g_evm_defconfig
configs/k2hk_evm_defconfig
configs/k2l_evm_defconfig
configs/sandbox_defconfig
drivers/core/device.c
drivers/dfu/dfu_mmc.c
drivers/gpio/mpc85xx_gpio.c
drivers/misc/cros_ec_sandbox.c
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/dw_mmc.c
drivers/mmc/mmc-uclass.c
drivers/mmc/mmc.c
drivers/mmc/mmc_boot.c [new file with mode: 0644]
drivers/mmc/mmc_legacy.c
drivers/mmc/mmc_private.h
drivers/mmc/msm_sdhci.c
drivers/mmc/rockchip_dw_mmc.c
drivers/mmc/sandbox_mmc.c
drivers/mmc/sdhci.c
drivers/spi/cadence_qspi.c
drivers/spi/cadence_qspi.h
drivers/spi/cadence_qspi_apb.c
drivers/spi/davinci_spi.c
drivers/spi/spi-uclass.c
include/configs/k2g_evm.h
include/configs/rk3036_common.h
include/configs/rk3288_common.h
include/configs/ti_armv7_keystone2.h
include/dm/device.h
include/dm/uclass-id.h
include/dwmmc.h
include/fdtdec.h
include/mmc.h
include/sdhci.h
lib/fdtdec.c
tools/patman/patchstream.py

index 566f04430890e212fcd16331d7fd51dbe0103d0c..c43787c63962af2c9b2d9d8ab381de2a67a8e2cb 100644 (file)
@@ -63,6 +63,7 @@ config SANDBOX
        select DM_I2C
        select DM_SPI
        select DM_GPIO
+       select DM_MMC
 
 config SH
        bool "SuperH architecture"
index 3237a74f722358bdb76207fa0244eeb1fb3a403f..585b408ee37001107203ad277c6b7bf442048355 100644 (file)
@@ -842,7 +842,18 @@ config ARCH_ROCKCHIP
        select SPL
        select OF_CONTROL
        select CPU_V7
+       select BLK
        select DM
+       select SPL_DM
+       select SYS_MALLOC_F
+       select SPL_SYS_MALLOC_SIMPLE
+       select DM_GPIO
+       select DM_I2C
+       select DM_MMC
+       select DM_MMC_OPS
+       select DM_SERIAL
+       select DM_SPI
+       select DM_SPI_FLASH
 
 config TARGET_THUNDERX_88XX
        bool "Support ThunderX 88xx"
index 08ef04e177b038bb500b4b134d783788fba0ab4b..429b9edc1b2b4f547fa844a92a97e0fa4123003f 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&qspi1_pins>;
 
-       spi-max-frequency = <48000000>;
+       spi-max-frequency = <64000000>;
        m25p80@0 {
                compatible = "s25fl256s1","spi-flash";
-               spi-max-frequency = <48000000>;
+               spi-max-frequency = <64000000>;
                reg = <0>;
                spi-tx-bus-width = <1>;
                spi-rx-bus-width = <4>;
-               spi-cpol;
-               spi-cpha;
                #address-cells = <1>;
                #size-cells = <1>;
 
index 205103e2b0e1ab0a62096bb055ae1f2d4a13d106..ced2f1166d8c2ddb5d57e33fcf853a91daf9cf5e 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&qspi1_pins>;
 
-       spi-max-frequency = <48000000>;
+       spi-max-frequency = <64000000>;
        m25p80@0 {
                compatible = "s25fl256s1","spi-flash";
-               spi-max-frequency = <48000000>;
+               spi-max-frequency = <64000000>;
                reg = <0>;
                spi-tx-bus-width = <1>;
                spi-rx-bus-width = <4>;
-               spi-cpol;
-               spi-cpha;
                #address-cells = <1>;
                #size-cells = <1>;
 
index 50c83c21d9118baa9b4f0ec2a2e30c20f8d64981..e2c3fb49102adfcbcabe71fc357975379b24b150 100644 (file)
 };
 
 &spi0 {
+       status = "okay";
        nor_flash: n25q128a11@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "Micron,n25q128a11";
+               compatible = "Micron,n25q128a11", "spi-flash";
                spi-max-frequency = <54000000>;
                m25p,fast-read;
                reg = <0>;
index 0ca36ef39ad307c149ea79c31736a61105ee91b2..e95efd4767076caf3373e68879092642678cbcc6 100644 (file)
 &gbe0 {
        phy-handle = <&ethphy0>;
 };
+
+&spi1 {
+       status = "okay";
+
+       spi_nor: flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spi-flash";
+               spi-max-frequency = <50000000>;
+               m25p,fast-read;
+               reg = <0>;
+
+               partition@0 {
+                       label = "u-boot-spl";
+                       reg = <0x0 0x80000>;
+                       read-only;
+               };
+
+               partition@1 {
+                       label = "misc";
+                       reg = <0x80000 0xf80000>;
+               };
+       };
+};
+
+&qspi {
+       status = "okay";
+
+        flash0: m25p80@0 {
+                compatible = "s25fl512s","spi-flash";
+                reg = <0>;
+                spi-tx-bus-width = <1>;
+                spi-rx-bus-width = <4>;
+                spi-max-frequency = <96000000>;
+                #address-cells = <1>;
+                #size-cells = <1>;
+                tshsl-ns = <392>;
+                tsd2d-ns = <392>;
+                tchsh-ns = <100>;
+                tslch-ns = <100>;
+               block-size = <18>;
+
+
+                partition@0 {
+                        label = "QSPI.u-boot-spl-os";
+                        reg = <0x00000000 0x00100000>;
+                };
+                partition@1 {
+                        label = "QSPI.u-boot-env";
+                        reg = <0x00100000 0x00040000>;
+                };
+                partition@2 {
+                        label = "QSPI.skern";
+                        reg = <0x00140000 0x0040000>;
+                };
+                partition@3 {
+                        label = "QSPI.pmmc-firmware";
+                        reg = <0x00180000 0x0040000>;
+                };
+                partition@4 {
+                        label = "QSPI.kernel";
+                        reg = <0x001C0000 0x0800000>;
+                };
+                partition@5 {
+                        label = "QSPI.file-system";
+                        reg = <0x009C0000 0x3640000>;
+                };
+        };
+};
index a3ed444d3c31892e72fbe8e26121aaa59f584273..00cd492973366e0c0f6108486148cc645c7209fc 100644 (file)
 
        aliases {
                serial0 = &uart0;
+               spi0 = &spi0;
+               spi1 = &spi1;
+               spi2 = &spi2;
+               spi3 = &spi3;
+               spi4 = &qspi;
        };
 
        memory {
                        bus_freq = <2500000>;
                };
 
+               qspi: qspi@2940000 {
+                       compatible =  "cadence,qspi";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x02940000 0x1000>,
+                             <0x24000000 0x4000000>;
+                       interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_RISING>;
+                       num-cs = <4>;
+                       fifo-depth = <256>;
+                       sram-size = <256>;
+                       status = "disabled";
+               };
+
                #include "k2g-netcp.dtsi"
 
                pmmc: pmmc@2900000 {
                        ti,lpsc_module = <1>;
                };
 
+               spi0: spi@21805400 {
+                       compatible = "ti,keystone-spi", "ti,dm6441-spi";
+                       reg = <0x21805400 0x200>;
+                       num-cs = <4>;
+                       ti,davinci-spi-intr-line = <0>;
+                       interrupts = <GIC_SPI 64 IRQ_TYPE_EDGE_RISING>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi1: spi@21805800 {
+                       compatible = "ti,keystone-spi", "ti,dm6441-spi";
+                       reg = <0x21805800 0x200>;
+                       num-cs = <4>;
+                       ti,davinci-spi-intr-line = <0>;
+                       interrupts = <GIC_SPI 66 IRQ_TYPE_EDGE_RISING>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi2: spi@21805c00 {
+                       compatible = "ti,keystone-spi", "ti,dm6441-spi";
+                       reg = <0x21805C00 0x200>;
+                       num-cs = <4>;
+                       ti,davinci-spi-intr-line = <0>;
+                       interrupts = <GIC_SPI 68 IRQ_TYPE_EDGE_RISING>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi3: spi@21806000 {
+                       compatible = "ti,keystone-spi", "ti,dm6441-spi";
+                       reg = <0x21806000 0x200>;
+                       num-cs = <4>;
+                       ti,davinci-spi-intr-line = <0>;
+                       interrupts = <GIC_SPI 70 IRQ_TYPE_EDGE_RISING>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
        };
 };
index 660ebf58d547cf4f3f18396159fb7cd5ed7da550..c5cad2c9da80a6a826f2d55fadf2e2f382dc9596 100644 (file)
 };
 
 &spi0 {
+       status = "okay";
        nor_flash: n25q128a11@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "Micron,n25q128a11";
+               compatible = "Micron,n25q128a11", "spi-flash";
                spi-max-frequency = <54000000>;
                m25p,fast-read;
                reg = <0>;
index 9a69a6b553748bb5752bd12c7dbe9c251e8b7705..da0661ba3e8a058840b2e5e71438c008dea02a52 100644 (file)
 };
 
 &spi0 {
+       status ="okay";
        nor_flash: n25q128a11@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "Micron,n25q128a11";
+               compatible = "Micron,n25q128a11", "spi-flash";
                spi-max-frequency = <54000000>;
                m25p,fast-read;
                reg = <0>;
index f39b969f8d437054255b3c4debbba8072a7559f6..be97f3f21f926e95b799dd24d2943ca1a7223652 100644 (file)
@@ -19,6 +19,9 @@
 
        aliases {
                serial0 = &uart0;
+               spi0 = &spi0;
+               spi1 = &spi1;
+               spi2 = &spi2;
        };
 
        chosen {
index 2a8afac5e125b30c5f041bcfa229c46830206321..c49cc19be3bd7a9fa639906a79c41fd2a56ebe74 100644 (file)
@@ -17,33 +17,6 @@ config ROCKCHIP_RK3036
          and video codec support. Peripherals include Gigabit Ethernet,
          USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
 
-config SYS_MALLOC_F
-       default y
-
-config SPL_SYS_MALLOC_SIMPLE
-       default y
-
-config SPL_DM
-       default y
-
-config DM_SERIAL
-       default y
-
-config DM_SPI
-       default y
-
-config DM_SPI_FLASH
-       default y
-
-config DM_I2C
-       default y
-
-config DM_GPIO
-       default y
-
-config BLK
-       default y
-
 source "arch/arm/mach-rockchip/rk3288/Kconfig"
 source "arch/arm/mach-rockchip/rk3036/Kconfig"
 endif
index 41b6677bba38836bc4a29381f0f193380f66266a..76faa22c8b437012ce9bbd72fde83e3c686e5736 100644 (file)
 #include <asm/mpc85xx_gpio.h>
 #endif
 
+struct mpc85xx_gpio_plat {
+       ulong addr;
+       unsigned long size;
+       uint ngpios;
+};
+
 #endif
index ff1faa501472ec75de6d9ae17acee6af58f3094d..4e0be2a88b907b41beacfe5d0d8e199eb23c8538 100644 (file)
@@ -424,8 +424,6 @@ static void set_spi_speed(void)
 static int lpc_init_extra(struct udevice *dev)
 {
        struct udevice *pch = dev->parent;
-       const void *blob = gd->fdt_blob;
-       int node;
 
        debug("pch: lpc_init\n");
        dm_pci_write_bar32(pch, 0, 0);
@@ -434,10 +432,6 @@ static int lpc_init_extra(struct udevice *dev)
        dm_pci_write_bar32(pch, 3, 0x800);
        dm_pci_write_bar32(pch, 4, 0x900);
 
-       node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH);
-       if (node < 0)
-               return -ENOENT;
-
        /* Set the value for PCI command register. */
        dm_pci_write_config16(pch, PCI_COMMAND, 0x000f);
 
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..152d31ce50962bac3f6bbba8fd80c4bf74da84cf 100644 (file)
@@ -0,0 +1,6 @@
+EVB-RK3036
+M:      huang lin <hl@rock-chips.com>
+S:      Maintained
+F:      board/evb/evb-rk3036
+F:      include/configs/evb-rk3036.h
+F:      configs/evb-rk3036_defconfig
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f8ee83437745cd51f25d136ef815743559d597c0 100644 (file)
@@ -0,0 +1,6 @@
+KYLIN-RK3036
+M:      huang lin <hl@rock-chips.com>
+S:      Maintained
+F:      board/kylin/kylin-rk3036
+F:      include/configs/kylin-rk3036.h
+F:      configs/kylin-rk3036_defconfig
index 42862d9d921a9e0121169bb9c552a388cbf56fb8..286906c3a151c916d549df6938ad73a0273aec94 100644 (file)
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -88,6 +88,8 @@ static int do_spi_flash_probe(int argc, char * const argv[])
 #ifdef CONFIG_DM_SPI_FLASH
        struct udevice *new, *bus_dev;
        int ret;
+       /* In DM mode defaults will be taken from DT */
+       speed = 0, mode = 0;
 #else
        struct spi_flash *new;
 #endif
index 273098ceb605a6b2059dadc44d45f37c392b2c68..c53200f5c6fef36d0f7e8c248161b4dbffda0f8e 100644 (file)
@@ -55,9 +55,9 @@ int saveenv(void)
 #ifdef CONFIG_DM_SPI_FLASH
        struct udevice *new;
 
+       /* speed and mode will be read from DT */
        ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
-                                    CONFIG_ENV_SPI_MAX_HZ,
-                                    CONFIG_ENV_SPI_MODE, &new);
+                                    0, 0, &new);
        if (ret) {
                set_default_env("!spi_flash_probe_bus_cs() failed");
                return 1;
@@ -245,9 +245,9 @@ int saveenv(void)
 #ifdef CONFIG_DM_SPI_FLASH
        struct udevice *new;
 
+       /* speed and mode will be read from DT */
        ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
-                                    CONFIG_ENV_SPI_MAX_HZ,
-                                    CONFIG_ENV_SPI_MODE, &new);
+                                    0, 0, &new);
        if (ret) {
                set_default_env("!spi_flash_probe_bus_cs() failed");
                return 1;
index c739651009b0f806b68bcc998f96d7fa3bd6a757..8d0524da78f39c5b829bc71813c7549007482ccb 100644 (file)
@@ -191,7 +191,7 @@ void fb_mmc_erase(const char *cmd)
        printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
               blks_start, blks_start + blks_size);
 
-       blks = dev_desc->block_erase(dev_desc, blks_start, blks_size);
+       blks = blk_derase(dev_desc, blks_start, blks_size);
        if (blks != blks_size) {
                error("failed erasing from device %d", dev_desc->devnum);
                fastboot_fail("failed erasing from device");
index c44f1b5dc84299639802e3a306f4a7ca3603ba68..6b3e9e4a17a0e6be63179c9a944fb98313d3d76e 100644 (file)
@@ -184,7 +184,7 @@ static int mmc_load_image_raw_os(struct mmc *mmc)
        unsigned long count;
        int ret;
 
-       count = mmc->block_dev.block_read(&mmc->block_dev,
+       count = blk_dread(mmc_get_blk_desc(mmc),
                CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
                CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
                (void *) CONFIG_SYS_SPL_ARGS_ADDR);
@@ -225,13 +225,13 @@ int spl_mmc_do_fs_boot(struct mmc *mmc)
 
 #ifdef CONFIG_SPL_FAT_SUPPORT
        if (!spl_start_uboot()) {
-               err = spl_load_image_fat_os(&mmc->block_dev,
+               err = spl_load_image_fat_os(mmc_get_blk_desc(mmc),
                        CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
                if (!err)
                        return err;
        }
 #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
-       err = spl_load_image_fat(&mmc->block_dev,
+       err = spl_load_image_fat(mmc_get_blk_desc(mmc),
                                 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
                                 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
        if (!err)
index 37c5ea7761c964eed6d2e2f1c0f3e52d9751a97a..ad2e8b86900ec2633843585c6248e8b336fc24a6 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_CMD_EXT2=y
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_BLK=y
 CONFIG_CLK=y
 CONFIG_MSM_GPIO=y
 CONFIG_PM8916_GPIO=y
@@ -25,6 +26,7 @@ CONFIG_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_SYSRESET=y
 CONFIG_DM_MMC=y
+CONFIG_DM_MMC_OPS=y
 CONFIG_MSM_SDHCI=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_PM8916=y
index 9fcdfe9b9fa75d444fe04996cde4d5bf39fa1399..65561b1393eed21cd3f65135f94030ba37dc0725 100644 (file)
@@ -28,6 +28,8 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
 CONFIG_TI_AEMIF=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_DM_ETH=y
index 8efa58c8c43af3a52240e74688d2ff949f7dbe1c..5d44e8deb3d1c59a043ed317f75521ea2557e95a 100644 (file)
@@ -27,6 +27,8 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_DM_ETH=y
@@ -35,3 +37,5 @@ CONFIG_SYS_NS16550=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_BAR=y
index 278eaf32fd8de26c59b646782edc0b26c80fcf87..8623e1ca88d5d87ce7fcbe4986da4b9da73b1252 100644 (file)
@@ -28,6 +28,8 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
 CONFIG_TI_AEMIF=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_DM_ETH=y
index 8417e0ab0758703038c172f4840e8fa92469d4db..9aa429cf5fc0a8c68e75564431299869edb6e692 100644 (file)
@@ -28,6 +28,8 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
 CONFIG_TI_AEMIF=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_DM_ETH=y
index 94253a65e4f9667edaa10dc283b6e763bffa5b07..6a1874afb49663b01a02fd8dddaab10c2d9d2161 100644 (file)
@@ -1,5 +1,4 @@
 CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_BLK=y
 CONFIG_MMC=y
 CONFIG_PCI=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
@@ -71,6 +70,7 @@ CONFIG_DEVRES=y
 CONFIG_DEBUG_DEVRES=y
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
+CONFIG_BLK=y
 CONFIG_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
@@ -101,7 +101,7 @@ CONFIG_CROS_EC_SPI=y
 CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_SYSRESET=y
-CONFIG_DM_MMC=y
+CONFIG_DM_MMC_OPS=y
 CONFIG_SANDBOX_MMC=y
 CONFIG_SPI_FLASH_SANDBOX=y
 CONFIG_SPI_FLASH=y
index eb75b1734f9b973e406c8cfca80c8f6a9231c0e9..f7fb0cc0fa7c60000153897316b1ef7ff5ae8e95 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <asm/io.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
 #include <malloc.h>
@@ -697,6 +698,16 @@ void *dev_get_addr_ptr(struct udevice *dev)
        return (void *)(uintptr_t)dev_get_addr_index(dev, 0);
 }
 
+void *dev_map_physmem(struct udevice *dev, unsigned long size)
+{
+       fdt_addr_t addr = dev_get_addr(dev);
+
+       if (addr == FDT_ADDR_T_NONE)
+               return NULL;
+
+       return map_physmem(addr, size, MAP_NOCACHE);
+}
+
 bool device_has_children(struct udevice *dev)
 {
        return !list_empty(&dev->child_head);
index 78724e467b24c7f816fef09767022bd8876b42a8..926ccbd2ef5e9eac95d2083f6047c9abcee2ef0a 100644 (file)
@@ -49,7 +49,7 @@ 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;
+               part_num_bkp = mmc_get_blk_desc(mmc)->hwpart;
                ret = blk_select_hwpart_devnum(IF_TYPE_MMC,
                                               dfu->data.mmc.dev_num,
                                               dfu->data.mmc.hw_partition);
@@ -62,12 +62,11 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
              dfu->data.mmc.dev_num, blk_start, blk_count, buf);
        switch (op) {
        case DFU_OP_READ:
-               n = mmc->block_dev.block_read(&mmc->block_dev, blk_start,
-                                             blk_count, buf);
+               n = blk_dread(mmc_get_blk_desc(mmc), blk_start, blk_count, buf);
                break;
        case DFU_OP_WRITE:
-               n = mmc->block_dev.block_write(&mmc->block_dev, blk_start,
-                                              blk_count, buf);
+               n = blk_dwrite(mmc_get_blk_desc(mmc), blk_start, blk_count,
+                              buf);
                break;
        default:
                error("Operation not supported\n");
@@ -356,7 +355,7 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s)
 
        } else if (!strcmp(entity_type, "part")) {
                disk_partition_t partinfo;
-               struct blk_desc *blk_dev = &mmc->block_dev;
+               struct blk_desc *blk_dev = mmc_get_blk_desc(mmc);
                int mmcdev = second_arg;
                int mmcpart = third_arg;
 
index 04773e2b31c3074e322dff41debfb5bc63522f4f..3754a8215c3630db7c33cc50a13eff8959fa6b04 100644 (file)
@@ -163,23 +163,41 @@ static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio)
        return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
 }
 
+#if CONFIG_IS_ENABLED(OF_CONTROL)
 static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) {
-       struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+       struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev);
        fdt_addr_t addr;
        fdt_size_t size;
 
        addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset,
                                                  "reg", 0, &size);
 
-       data->addr = addr;
-       data->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
+       plat->addr = addr;
+       plat->size = size;
+       plat->ngpios = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+                                                 "ngpios", 32);
 
-       if (!data->base)
+       return 0;
+}
+#endif
+
+static int mpc85xx_gpio_platdata_to_priv(struct udevice *dev)
+{
+       struct mpc85xx_gpio_data *priv = dev_get_priv(dev);
+       struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev);
+       unsigned long size = plat->size;
+
+       if (size == 0)
+               size = 0x100;
+
+       priv->addr = plat->addr;
+       priv->base = map_sysmem(CONFIG_SYS_IMMR + plat->addr, size);
+
+       if (!priv->base)
                return -ENOMEM;
 
-       data->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
-                                         "ngpios", 32);
-       data->dat_shadow = 0;
+       priv->gpio_count = plat->ngpios;
+       priv->dat_shadow = 0;
 
        return 0;
 }
@@ -190,6 +208,8 @@ static int mpc85xx_gpio_probe(struct udevice *dev)
        struct mpc85xx_gpio_data *data = dev_get_priv(dev);
        char name[32], *str;
 
+       mpc85xx_gpio_platdata_to_priv(dev);
+
        snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
        str = strdup(name);
 
@@ -221,8 +241,11 @@ U_BOOT_DRIVER(gpio_mpc85xx) = {
        .name   = "gpio_mpc85xx",
        .id     = UCLASS_GPIO,
        .ops    = &gpio_mpc85xx_ops,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
        .ofdata_to_platdata = mpc85xx_gpio_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct mpc85xx_gpio_plat),
        .of_match = mpc85xx_gpio_ids,
+#endif
        .probe  = mpc85xx_gpio_probe,
        .priv_auto_alloc_size = sizeof(struct mpc85xx_gpio_data),
 };
index 98f19a68bf6fb4b0650e69dcf06bcfebc2c349e8..c4fbca0d3ae129a260d3073fe7387b4f6688ff6b 100644 (file)
@@ -517,6 +517,7 @@ int cros_ec_probe(struct udevice *dev)
        struct ec_state *ec = dev->priv;
        struct cros_ec_dev *cdev = dev->uclass_priv;
        const void *blob = gd->fdt_blob;
+       struct udevice *keyb_dev;
        int node;
        int err;
 
@@ -525,7 +526,15 @@ int cros_ec_probe(struct udevice *dev)
        if (err)
                return err;
 
-       node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC_KEYB);
+       node = -1;
+       for (device_find_first_child(dev, &keyb_dev);
+            keyb_dev;
+            device_find_next_child(&keyb_dev)) {
+               if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) {
+                       node = keyb_dev->of_offset;
+                       break;
+               }
+       }
        if (node < 0) {
                debug("%s: No cros_ec keyboard found\n", __func__);
        } else if (keyscan_read_fdt_matrix(ec, blob, node)) {
index c80efc39a791872aab2216bd7fb518b437e270b2..79cf18f14f81faff739ebff41bd88a3c4ce1a435 100644 (file)
@@ -16,9 +16,18 @@ config DM_MMC
          appear as block devices in U-Boot and can support filesystems such
          as EXT4 and FAT.
 
+config DM_MMC_OPS
+       bool "Support MMC controller operations using Driver Model"
+       depends on DM_MMC
+       help
+         Driver model provides a means of supporting device operations. This
+         option moves MMC operations under the control of driver model. The
+         option will be removed as soon as all DM_MMC drivers use it, as it
+         will the only supported behaviour.
+
 config MSM_SDHCI
        bool "Qualcomm SDHCI controller"
-       depends on DM_MMC
+       depends on DM_MMC && BLK && DM_MMC_OPS
        help
          Enables support for SDHCI 2.0 controller present on some Qualcomm
           Snapdragon devices. This device is compatible with eMMC v4.5 and
index 3da4817a189c6e00b8e780e8837509b38e3021c1..b44a12e606b63d6a6c98b7ce25d796b82d900494 100644 (file)
@@ -25,6 +25,9 @@ obj-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 obj-$(CONFIG_FTSDC010) += ftsdc010_mci.o
 obj-$(CONFIG_FTSDC021) += ftsdc021_sdhci.o
 obj-$(CONFIG_GENERIC_MMC) += mmc.o
+ifdef CONFIG_SUPPORT_EMMC_BOOT
+obj-$(CONFIG_GENERIC_MMC) += mmc_boot.o
+endif
 obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
 obj-$(CONFIG_KONA_SDHCI) += kona_sdhci.o
 obj-$(CONFIG_MMC_SPI) += mmc_spi.o
index af6e04aa28b6926006a408ee5a3efabdad31b825..2cf7bae79232dac03f45ca30e293097179537870 100644 (file)
@@ -181,9 +181,16 @@ static int dwmci_set_transfer_mode(struct dwmci_host *host,
        return mode;
 }
 
+#ifdef CONFIG_DM_MMC_OPS
+int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+                  struct mmc_data *data)
+{
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
 static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                struct mmc_data *data)
 {
+#endif
        struct dwmci_host *host = mmc->priv;
        ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
                                 data ? DIV_ROUND_UP(data->blocks, 8) : 0);
@@ -373,8 +380,14 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
        return 0;
 }
 
+#ifdef CONFIG_DM_MMC_OPS
+int dwmci_set_ios(struct udevice *dev)
+{
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
 static void dwmci_set_ios(struct mmc *mmc)
 {
+#endif
        struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
        u32 ctype, regs;
 
@@ -405,6 +418,9 @@ static void dwmci_set_ios(struct mmc *mmc)
 
        if (host->clksel)
                host->clksel(host);
+#ifdef CONFIG_DM_MMC_OPS
+       return 0;
+#endif
 }
 
 static int dwmci_init(struct mmc *mmc)
@@ -448,17 +464,34 @@ static int dwmci_init(struct mmc *mmc)
        return 0;
 }
 
+#ifdef CONFIG_DM_MMC_OPS
+int dwmci_probe(struct udevice *dev)
+{
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+       return dwmci_init(mmc);
+}
+
+const struct dm_mmc_ops dm_dwmci_ops = {
+       .send_cmd       = dwmci_send_cmd,
+       .set_ios        = dwmci_set_ios,
+};
+
+#else
 static const struct mmc_ops dwmci_ops = {
        .send_cmd       = dwmci_send_cmd,
        .set_ios        = dwmci_set_ios,
        .init           = dwmci_init,
 };
+#endif
 
 void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
                     uint caps, u32 max_clk, u32 min_clk)
 {
        cfg->name = name;
+#ifndef CONFIG_DM_MMC_OPS
        cfg->ops = &dwmci_ops;
+#endif
        cfg->f_min = min_clk;
        cfg->f_max = max_clk;
 
index 1b967d982bc74946ccd61fe1c74ae5826662cb6f..38ced4102e1073c146759d9d030e6d930514e944 100644 (file)
@@ -8,8 +8,76 @@
 #include <common.h>
 #include <mmc.h>
 #include <dm.h>
+#include <dm/device-internal.h>
 #include <dm/lists.h>
 #include <dm/root.h>
+#include "mmc_private.h"
+
+#ifdef CONFIG_DM_MMC_OPS
+int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+                   struct mmc_data *data)
+{
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+       struct dm_mmc_ops *ops = mmc_get_ops(dev);
+       int ret;
+
+       mmmc_trace_before_send(mmc, cmd);
+       if (ops->send_cmd)
+               ret = ops->send_cmd(dev, cmd, data);
+       else
+               ret = -ENOSYS;
+       mmmc_trace_after_send(mmc, cmd, ret);
+
+       return ret;
+}
+
+int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+{
+       return dm_mmc_send_cmd(mmc->dev, cmd, data);
+}
+
+int dm_mmc_set_ios(struct udevice *dev)
+{
+       struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+       if (!ops->set_ios)
+               return -ENOSYS;
+       return ops->set_ios(dev);
+}
+
+int mmc_set_ios(struct mmc *mmc)
+{
+       return dm_mmc_set_ios(mmc->dev);
+}
+
+int dm_mmc_get_wp(struct udevice *dev)
+{
+       struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+       if (!ops->get_wp)
+               return -ENOSYS;
+       return ops->get_wp(dev);
+}
+
+int mmc_getwp(struct mmc *mmc)
+{
+       return dm_mmc_get_wp(mmc->dev);
+}
+
+int dm_mmc_get_cd(struct udevice *dev)
+{
+       struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+       if (!ops->get_cd)
+               return -ENOSYS;
+       return ops->get_cd(dev);
+}
+
+int mmc_getcd(struct mmc *mmc)
+{
+       return dm_mmc_get_cd(mmc->dev);
+}
+#endif
 
 struct mmc *mmc_get_mmc_dev(struct udevice *dev)
 {
@@ -125,6 +193,84 @@ void print_mmc_devices(char separator)
 #else
 void print_mmc_devices(char separator) { }
 #endif
+
+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 = 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;
+}
+
+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)
+               return -EMEDIUMTYPE;
+
+       ret = mmc_switch_part(mmc, hwpart);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static const struct blk_ops mmc_blk_ops = {
+       .read   = mmc_bread,
+#ifndef CONFIG_SPL_BUILD
+       .write  = mmc_bwrite,
+#endif
+       .select_hwpart  = mmc_select_hwpart,
+};
+
+U_BOOT_DRIVER(mmc_blk) = {
+       .name           = "mmc_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &mmc_blk_ops,
+};
 #endif /* CONFIG_BLK */
 
 U_BOOT_DRIVER(mmc) = {
index aabfc711e5d6fe40d001c3b6eabec9e37f43000b..f8e5f7a6089667434d363b12000df19961d5e733 100644 (file)
@@ -21,6 +21,7 @@
 #include <div64.h>
 #include "mmc_private.h"
 
+#ifndef CONFIG_DM_MMC_OPS
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
        return -1;
@@ -46,18 +47,20 @@ __weak int board_mmc_getcd(struct mmc *mmc)
 {
        return -1;
 }
+#endif
 
-int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+#ifdef CONFIG_MMC_TRACE
+void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
 {
-       int ret;
+       printf("CMD_SEND:%d\n", cmd->cmdidx);
+       printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
+}
 
-#ifdef CONFIG_MMC_TRACE
+void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
+{
        int i;
        u8 *ptr;
 
-       printf("CMD_SEND:%d\n", cmd->cmdidx);
-       printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
-       ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
        if (ret) {
                printf("\t\tRET\t\t\t %d\n", ret);
        } else {
@@ -103,19 +106,34 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
                        break;
                }
        }
-#else
-       ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
+}
+
+void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
+{
+       int status;
+
+       status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
+       printf("CURR STATE:%d\n", status);
+}
 #endif
+
+#ifndef CONFIG_DM_MMC_OPS
+int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+{
+       int ret;
+
+       mmmc_trace_before_send(mmc, cmd);
+       ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
+       mmmc_trace_after_send(mmc, cmd, ret);
+
        return ret;
 }
+#endif
 
 int mmc_send_status(struct mmc *mmc, int timeout)
 {
        struct mmc_cmd cmd;
        int err, retries = 5;
-#ifdef CONFIG_MMC_TRACE
-       int status;
-#endif
 
        cmd.cmdidx = MMC_CMD_SEND_STATUS;
        cmd.resp_type = MMC_RSP_R1;
@@ -145,10 +163,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
                udelay(1000);
        }
 
-#ifdef CONFIG_MMC_TRACE
-       status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
-       printf("CURR STATE:%d\n", status);
-#endif
+       mmc_trace_state(mmc, &cmd);
        if (timeout <= 0) {
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("Timeout waiting card ready\n");
@@ -215,11 +230,10 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
 }
 
 #ifdef CONFIG_BLK
-static ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
-                      void *dst)
+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)
+ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
+               void *dst)
 #endif
 {
 #ifdef CONFIG_BLK
@@ -464,8 +478,7 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
        return err;
 }
 
-
-static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
+int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
 {
        struct mmc_cmd cmd;
        int timeout = 1000;
@@ -566,7 +579,7 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
        return 0;
 }
 
-static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 {
        int ret;
 
@@ -586,49 +599,6 @@ static int mmc_switch_part(struct mmc *mmc, unsigned int 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)
-               return -EMEDIUMTYPE;
-
-       ret = mmc_switch_part(mmc, hwpart);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-#else
-static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
-{
-       struct mmc *mmc = find_mmc_device(desc->devnum);
-       int ret;
-
-       if (!mmc)
-               return -ENODEV;
-
-       if (mmc->block_dev.hwpart == hwpart)
-               return 0;
-
-       if (mmc->part_config == MMCPART_NOAVAILABLE)
-               return -EMEDIUMTYPE;
-
-       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,
                      enum mmc_hwpart_conf_mode mode)
@@ -823,6 +793,7 @@ int mmc_hwpart_config(struct mmc *mmc,
        return 0;
 }
 
+#ifndef CONFIG_DM_MMC_OPS
 int mmc_getcd(struct mmc *mmc)
 {
        int cd;
@@ -838,6 +809,7 @@ int mmc_getcd(struct mmc *mmc)
 
        return cd;
 }
+#endif
 
 static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
 {
@@ -1001,11 +973,13 @@ static const u8 multipliers[] = {
        80,
 };
 
+#ifndef CONFIG_DM_MMC_OPS
 static void mmc_set_ios(struct mmc *mmc)
 {
        if (mmc->cfg->ops->set_ios)
                mmc->cfg->ops->set_ios(mmc);
 }
+#endif
 
 void mmc_set_clock(struct mmc *mmc, uint clock)
 {
@@ -1532,115 +1506,6 @@ static int mmc_send_if_cond(struct mmc *mmc)
        return 0;
 }
 
-#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 = 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 */
-       if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
-                       cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
-               return NULL;
-
-       mmc = calloc(1, sizeof(*mmc));
-       if (mmc == NULL)
-               return NULL;
-
-       mmc->cfg = cfg;
-       mmc->priv = priv;
-
-       /* the following chunk was mmc_register() */
-
-       /* Setup dsr related values */
-       mmc->dsr_imp = 0;
-       mmc->dsr = 0xffffffff;
-       /* Setup the universal parts of the block interface just once */
-       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 */
-       bdesc->part_type = mmc->cfg->part_type;
-       mmc_list_add(mmc);
-
-       return mmc;
-}
-
-void mmc_destroy(struct mmc *mmc)
-{
-       /* only freeing memory for now */
-       free(mmc);
-}
-#endif
-
-#ifndef CONFIG_BLK
-static int mmc_get_dev(int dev, struct blk_desc **descp)
-{
-       struct mmc *mmc = find_mmc_device(dev);
-       int ret;
-
-       if (!mmc)
-               return -ENODEV;
-       ret = mmc_init(mmc);
-       if (ret)
-               return ret;
-
-       *descp = &mmc->block_dev;
-
-       return 0;
-}
-#endif
-
 /* board-specific MMC power initializations. */
 __weak void board_mmc_power_init(void)
 {
@@ -1648,10 +1513,15 @@ __weak void board_mmc_power_init(void)
 
 int mmc_start_init(struct mmc *mmc)
 {
+       bool no_card;
        int err;
 
        /* we pretend there's no card when init is NULL */
-       if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
+       no_card = mmc_getcd(mmc) == 0;
+#ifndef CONFIG_DM_MMC_OPS
+       no_card = no_card || (mmc->cfg->ops->init == NULL);
+#endif
+       if (no_card) {
                mmc->has_init = 0;
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("MMC: no card present\n");
@@ -1667,12 +1537,14 @@ int mmc_start_init(struct mmc *mmc)
 #endif
        board_mmc_power_init();
 
+#ifdef CONFIG_DM_MMC_OPS
+       /* The device has already been probed ready for use */
+#else
        /* made sure it's not NULL earlier */
        err = mmc->cfg->ops->init(mmc);
-
        if (err)
                return err;
-
+#endif
        mmc->ddr_mode = 0;
        mmc_set_bus_width(mmc, 1);
        mmc_set_clock(mmc, 1);
@@ -1839,148 +1711,3 @@ int mmc_initialize(bd_t *bis)
        mmc_do_preinit();
        return 0;
 }
-
-#ifdef CONFIG_SUPPORT_EMMC_BOOT
-/*
- * This function changes the size of boot partition and the size of rpmb
- * partition present on EMMC devices.
- *
- * Input Parameters:
- * struct *mmc: pointer for the mmc device strcuture
- * bootsize: size of boot partition
- * rpmbsize: size of rpmb partition
- *
- * Returns 0 on success.
- */
-
-int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
-                               unsigned long rpmbsize)
-{
-       int err;
-       struct mmc_cmd cmd;
-
-       /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
-       cmd.cmdidx = MMC_CMD_RES_MAN;
-       cmd.resp_type = MMC_RSP_R1b;
-       cmd.cmdarg = MMC_CMD62_ARG1;
-
-       err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err) {
-               debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
-               return err;
-       }
-
-       /* Boot partition changing mode */
-       cmd.cmdidx = MMC_CMD_RES_MAN;
-       cmd.resp_type = MMC_RSP_R1b;
-       cmd.cmdarg = MMC_CMD62_ARG2;
-
-       err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err) {
-               debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
-               return err;
-       }
-       /* boot partition size is multiple of 128KB */
-       bootsize = (bootsize * 1024) / 128;
-
-       /* Arg: boot partition size */
-       cmd.cmdidx = MMC_CMD_RES_MAN;
-       cmd.resp_type = MMC_RSP_R1b;
-       cmd.cmdarg = bootsize;
-
-       err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err) {
-               debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
-               return err;
-       }
-       /* RPMB partition size is multiple of 128KB */
-       rpmbsize = (rpmbsize * 1024) / 128;
-       /* Arg: RPMB partition size */
-       cmd.cmdidx = MMC_CMD_RES_MAN;
-       cmd.resp_type = MMC_RSP_R1b;
-       cmd.cmdarg = rpmbsize;
-
-       err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err) {
-               debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
-               return err;
-       }
-       return 0;
-}
-
-/*
- * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
- * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
- * and BOOT_MODE.
- *
- * Returns 0 on success.
- */
-int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
-{
-       int err;
-
-       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
-                        EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
-                        EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
-                        EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
-
-       if (err)
-               return err;
-       return 0;
-}
-
-/*
- * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
- * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
- * PARTITION_ACCESS.
- *
- * Returns 0 on success.
- */
-int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
-{
-       int err;
-
-       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
-                        EXT_CSD_BOOT_ACK(ack) |
-                        EXT_CSD_BOOT_PART_NUM(part_num) |
-                        EXT_CSD_PARTITION_ACCESS(access));
-
-       if (err)
-               return err;
-       return 0;
-}
-
-/*
- * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
- * for enable.  Note that this is a write-once field for non-zero values.
- *
- * Returns 0 on success.
- */
-int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
-{
-       return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
-                         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_boot.c b/drivers/mmc/mmc_boot.c
new file mode 100644 (file)
index 0000000..756a982
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Amar <amarendra.xt@samsung.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <mmc.h>
+#include "mmc_private.h"
+
+/*
+ * This function changes the size of boot partition and the size of rpmb
+ * partition present on EMMC devices.
+ *
+ * Input Parameters:
+ * struct *mmc: pointer for the mmc device strcuture
+ * bootsize: size of boot partition
+ * rpmbsize: size of rpmb partition
+ *
+ * Returns 0 on success.
+ */
+
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+                               unsigned long rpmbsize)
+{
+       int err;
+       struct mmc_cmd cmd;
+
+       /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = MMC_CMD62_ARG1;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
+               return err;
+       }
+
+       /* Boot partition changing mode */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = MMC_CMD62_ARG2;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
+               return err;
+       }
+       /* boot partition size is multiple of 128KB */
+       bootsize = (bootsize * 1024) / 128;
+
+       /* Arg: boot partition size */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = bootsize;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
+               return err;
+       }
+       /* RPMB partition size is multiple of 128KB */
+       rpmbsize = (rpmbsize * 1024) / 128;
+       /* Arg: RPMB partition size */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = rpmbsize;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
+               return err;
+       }
+       return 0;
+}
+
+/*
+ * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
+ * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
+ * and BOOT_MODE.
+ *
+ * Returns 0 on success.
+ */
+int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
+{
+       int err;
+
+       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
+                        EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
+                        EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
+                        EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
+
+       if (err)
+               return err;
+       return 0;
+}
+
+/*
+ * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
+ * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
+ * PARTITION_ACCESS.
+ *
+ * Returns 0 on success.
+ */
+int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
+{
+       int err;
+
+       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
+                        EXT_CSD_BOOT_ACK(ack) |
+                        EXT_CSD_BOOT_PART_NUM(part_num) |
+                        EXT_CSD_PARTITION_ACCESS(access));
+
+       if (err)
+               return err;
+       return 0;
+}
+
+/*
+ * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
+ * for enable.  Note that this is a write-once field for non-zero values.
+ *
+ * Returns 0 on success.
+ */
+int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
+{
+       return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
+                         enable);
+}
index 3ec649f2b82d391b4f359c5e9d866d3459394112..040728b45d3c9f415b31bdb330f506319457e45a 100644 (file)
@@ -6,7 +6,9 @@
  */
 
 #include <common.h>
+#include <malloc.h>
 #include <mmc.h>
+#include "mmc_private.h"
 
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
@@ -106,3 +108,92 @@ void print_mmc_devices(char separator)
 #else
 void print_mmc_devices(char separator) { }
 #endif
+
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
+{
+       struct blk_desc *bdesc;
+       struct mmc *mmc;
+
+       /* quick validation */
+       if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
+           cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
+               return NULL;
+
+       mmc = calloc(1, sizeof(*mmc));
+       if (mmc == NULL)
+               return NULL;
+
+       mmc->cfg = cfg;
+       mmc->priv = priv;
+
+       /* the following chunk was mmc_register() */
+
+       /* Setup dsr related values */
+       mmc->dsr_imp = 0;
+       mmc->dsr = 0xffffffff;
+       /* Setup the universal parts of the block interface just once */
+       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 */
+       bdesc->part_type = mmc->cfg->part_type;
+       mmc_list_add(mmc);
+
+       return mmc;
+}
+
+void mmc_destroy(struct mmc *mmc)
+{
+       /* only freeing memory for now */
+       free(mmc);
+}
+
+static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
+{
+       struct mmc *mmc = find_mmc_device(desc->devnum);
+       int ret;
+
+       if (!mmc)
+               return -ENODEV;
+
+       if (mmc->block_dev.hwpart == hwpart)
+               return 0;
+
+       if (mmc->part_config == MMCPART_NOAVAILABLE)
+               return -EMEDIUMTYPE;
+
+       ret = mmc_switch_part(mmc, hwpart);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int mmc_get_dev(int dev, struct blk_desc **descp)
+{
+       struct mmc *mmc = find_mmc_device(dev);
+       int ret;
+
+       if (!mmc)
+               return -ENODEV;
+       ret = mmc_init(mmc);
+       if (ret)
+               return ret;
+
+       *descp = &mmc->block_dev;
+
+       return 0;
+}
+
+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,
+};
index 9f0d5c2384a8a8a06c3e388e75ff3c9b3386c55b..49ec022a9e9cd96ebaf9404a3de1959c4dfb245d 100644 (file)
@@ -20,6 +20,14 @@ extern int mmc_set_blocklen(struct mmc *mmc, int len);
 void mmc_adapter_card_type_ident(void);
 #endif
 
+#ifdef CONFIG_BLK
+ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+               void *dst);
+#else
+ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
+               void *dst);
+#endif
+
 #ifndef CONFIG_SPL_BUILD
 
 unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
@@ -65,6 +73,25 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
 
 #endif /* CONFIG_SPL_BUILD */
 
+#ifdef CONFIG_MMC_TRACE
+void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd);
+void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret);
+void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd);
+#else
+static inline void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
+{
+}
+
+static inline void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd,
+                                        int ret)
+{
+}
+
+static inline void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
+{
+}
+#endif
+
 /**
  * mmc_get_next_devnum() - Get the next available MMC device number
  *
@@ -89,4 +116,24 @@ void mmc_list_init(void);
  */
 void mmc_list_add(struct mmc *mmc);
 
+/**
+ * mmc_switch_part() - Switch to a new MMC hardware partition
+ *
+ * @mmc:       MMC device
+ * @part_num:  Hardware partition number
+ * @return 0 if OK, -ve on error
+ */
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
+
+/**
+ * mmc_switch() - Issue and MMC switch mode command
+ *
+ * @mmc:       MMC device
+ * @set:       Unused
+ * @index:     Cmdarg index
+ * @value:     Cmdarg value
+ * @return 0 if OK, -ve on error
+ */
+int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value);
+
 #endif /* _MMC_PRIVATE_H_ */
index 96dcdbec5196106cfebf93878436c4fda06a2bd6..70a8d96eeef33d6c59d8723bef69fdd903256f72 100644 (file)
 /* Non standard (?) SDHCI register */
 #define SDHCI_VENDOR_SPEC_CAPABILITIES0  0x11c
 
+struct msm_sdhc_plat {
+       struct mmc_config cfg;
+       struct mmc mmc;
+};
+
 struct msm_sdhc {
        struct sdhci_host host;
        void *base;
@@ -81,9 +86,12 @@ static int msm_sdc_clk_init(struct udevice *dev)
 
 static int msm_sdc_probe(struct udevice *dev)
 {
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       struct msm_sdhc_plat *plat = dev_get_platdata(dev);
        struct msm_sdhc *prv = dev_get_priv(dev);
        struct sdhci_host *host = &prv->host;
        u32 core_version, core_minor, core_major;
+       u32 caps;
        int ret;
 
        host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B;
@@ -127,7 +135,7 @@ static int msm_sdc_probe(struct udevice *dev)
         * controller versions and must be explicitly enabled.
         */
        if (core_major >= 1 && core_minor != 0x11 && core_minor != 0x12) {
-               u32 caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+               caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
                caps |= SDHCI_CAN_VDD_300 | SDHCI_CAN_DO_8BIT;
                writel(caps, host->ioaddr + SDHCI_VENDOR_SPEC_CAPABILITIES0);
        }
@@ -135,13 +143,17 @@ static int msm_sdc_probe(struct udevice *dev)
        /* Set host controller version */
        host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
 
-       /* automatically detect max and min speed */
-       ret =  add_sdhci(host, 0, 0);
+       caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+       ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width,
+                             caps, 0, 0, host->version, host->quirks, 0);
+       host->mmc = &plat->mmc;
        if (ret)
                return ret;
+       host->mmc->priv = &prv->host;
        host->mmc->dev = dev;
+       upriv->mmc = host->mmc;
 
-       return 0;
+       return sdhci_probe(dev);
 }
 
 static int msm_sdc_remove(struct udevice *dev)
@@ -176,6 +188,18 @@ static int msm_ofdata_to_platdata(struct udevice *dev)
        return 0;
 }
 
+static int msm_sdc_bind(struct udevice *dev)
+{
+       struct msm_sdhc_plat *plat = dev_get_platdata(dev);
+       int ret;
+
+       ret = sdhci_bind(dev, &plat->mmc, &plat->cfg);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static const struct udevice_id msm_mmc_ids[] = {
        { .compatible = "qcom,sdhci-msm-v4" },
        { }
@@ -186,7 +210,10 @@ U_BOOT_DRIVER(msm_sdc_drv) = {
        .id             = UCLASS_MMC,
        .of_match       = msm_mmc_ids,
        .ofdata_to_platdata = msm_ofdata_to_platdata,
+       .ops            = &sdhci_ops,
+       .bind           = msm_sdc_bind,
        .probe          = msm_sdc_probe,
        .remove         = msm_sdc_remove,
        .priv_auto_alloc_size = sizeof(struct msm_sdhc),
+       .platdata_auto_alloc_size = sizeof(struct msm_sdhc_plat),
 };
index d41d60ce3582767b96cb874d51d59448e4377484..691a51557de4e89b41f3b975618fe6ba28a7c111 100644 (file)
@@ -66,9 +66,7 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
 
 static int rockchip_dwmmc_probe(struct udevice *dev)
 {
-#ifdef CONFIG_BLK
        struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
-#endif
        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
        struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
        struct dwmci_host *host = &priv->host;
@@ -106,33 +104,24 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
                        return ret;
        }
 #endif
-#ifdef CONFIG_BLK
        dwmci_setup_cfg(&plat->cfg, dev->name, host->buswidth, host->caps,
                        minmax[1], minmax[0]);
        host->mmc = &plat->mmc;
-#else
-       ret = add_dwmci(host, minmax[1], minmax[0]);
-       if (ret)
-               return ret;
-
-#endif
        host->mmc->priv = &priv->host;
        host->mmc->dev = dev;
        upriv->mmc = host->mmc;
 
-       return 0;
+       return dwmci_probe(dev);
 }
 
 static int rockchip_dwmmc_bind(struct udevice *dev)
 {
-#ifdef CONFIG_BLK
        struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
        int ret;
 
        ret = dwmci_bind(dev, &plat->mmc, &plat->cfg);
        if (ret)
                return ret;
-#endif
 
        return 0;
 }
@@ -147,6 +136,7 @@ U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
        .id             = UCLASS_MMC,
        .of_match       = rockchip_dwmmc_ids,
        .ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata,
+       .ops            = &dm_dwmci_ops,
        .bind           = rockchip_dwmmc_bind,
        .probe          = rockchip_dwmmc_probe,
        .priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv),
index 7da059c43cd69650911572183b777d85fdb23612..5f1333b7480ce174763101b65e83fe6484d48326 100644 (file)
@@ -25,7 +25,7 @@ struct sandbox_mmc_plat {
  * 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,
+static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
                                struct mmc_data *data)
 {
        switch (cmd->cmdidx) {
@@ -85,25 +85,20 @@ static int sandbox_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        return 0;
 }
 
-static void sandbox_mmc_set_ios(struct mmc *mmc)
-{
-}
-
-static int sandbox_mmc_init(struct mmc *mmc)
+static int sandbox_mmc_set_ios(struct udevice *dev)
 {
        return 0;
 }
 
-static int sandbox_mmc_getcd(struct mmc *mmc)
+static int sandbox_mmc_get_cd(struct udevice *dev)
 {
        return 1;
 }
 
-static const struct mmc_ops sandbox_mmc_ops = {
+static const struct dm_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,
+       .get_cd = sandbox_mmc_get_cd,
 };
 
 int sandbox_mmc_probe(struct udevice *dev)
@@ -120,7 +115,6 @@ int sandbox_mmc_bind(struct udevice *dev)
        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;
@@ -150,6 +144,7 @@ U_BOOT_DRIVER(mmc_sandbox) = {
        .name           = "mmc_sandbox",
        .id             = UCLASS_MMC,
        .of_match       = sandbox_mmc_ids,
+       .ops            = &sandbox_mmc_ops,
        .bind           = sandbox_mmc_bind,
        .unbind         = sandbox_mmc_unbind,
        .probe          = sandbox_mmc_probe,
index 604f18dcc96f764d8ff05ec67ccf2d5fc43a349e..de8d8ea70c447a4bdff18f7e0273d6db761f1c19 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <errno.h>
 #include <malloc.h>
 #include <mmc.h>
 #include <sdhci.h>
@@ -129,9 +130,17 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
 #define CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT       100
 #define SDHCI_READ_STATUS_TIMEOUT              1000
 
+#ifdef CONFIG_DM_MMC_OPS
+static int sdhci_send_command(struct udevice *dev, struct mmc_cmd *cmd,
+                             struct mmc_data *data)
+{
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+#else
 static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
-                      struct mmc_data *data)
+                             struct mmc_data *data)
 {
+#endif
        struct sdhci_host *host = mmc->priv;
        unsigned int stat = 0;
        int ret = 0;
@@ -389,8 +398,14 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
        sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
 }
 
+#ifdef CONFIG_DM_MMC_OPS
+static int sdhci_set_ios(struct udevice *dev)
+{
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
 static void sdhci_set_ios(struct mmc *mmc)
 {
+#endif
        u32 ctrl;
        struct sdhci_host *host = mmc->priv;
 
@@ -426,6 +441,9 @@ static void sdhci_set_ios(struct mmc *mmc)
                ctrl &= ~SDHCI_CTRL_HISPD;
 
        sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+#ifdef CONFIG_DM_MMC_OPS
+       return 0;
+#endif
 }
 
 static int sdhci_init(struct mmc *mmc)
@@ -472,80 +490,110 @@ static int sdhci_init(struct mmc *mmc)
        return 0;
 }
 
+#ifdef CONFIG_DM_MMC_OPS
+int sdhci_probe(struct udevice *dev)
+{
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+       return sdhci_init(mmc);
+}
 
+const struct dm_mmc_ops sdhci_ops = {
+       .send_cmd       = sdhci_send_command,
+       .set_ios        = sdhci_set_ios,
+};
+#else
 static const struct mmc_ops sdhci_ops = {
        .send_cmd       = sdhci_send_command,
        .set_ios        = sdhci_set_ios,
        .init           = sdhci_init,
 };
+#endif
 
-int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
+int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+                   uint caps, u32 max_clk, u32 min_clk, uint version,
+                   uint quirks, uint host_caps)
 {
-       unsigned int caps;
-
-       host->cfg.name = host->name;
-       host->cfg.ops = &sdhci_ops;
-
-       caps = sdhci_readl(host, SDHCI_CAPABILITIES);
-#ifdef CONFIG_MMC_SDMA
-       if (!(caps & SDHCI_CAN_DO_SDMA)) {
-               printf("%s: Your controller doesn't support SDMA!!\n",
-                      __func__);
-               return -1;
-       }
+       cfg->name = name;
+#ifndef CONFIG_DM_MMC_OPS
+       cfg->ops = &sdhci_ops;
 #endif
-
        if (max_clk)
-               host->cfg.f_max = max_clk;
+               cfg->f_max = max_clk;
        else {
-               if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
-                       host->cfg.f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK)
-                               >> SDHCI_CLOCK_BASE_SHIFT;
+               if (version >= SDHCI_SPEC_300)
+                       cfg->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK) >>
+                               SDHCI_CLOCK_BASE_SHIFT;
                else
-                       host->cfg.f_max = (caps & SDHCI_CLOCK_BASE_MASK)
-                               >> SDHCI_CLOCK_BASE_SHIFT;
-               host->cfg.f_max *= 1000000;
-       }
-       if (host->cfg.f_max == 0) {
-               printf("%s: Hardware doesn't specify base clock frequency\n",
-                      __func__);
-               return -1;
+                       cfg->f_max = (caps & SDHCI_CLOCK_BASE_MASK) >>
+                               SDHCI_CLOCK_BASE_SHIFT;
+               cfg->f_max *= 1000000;
        }
+       if (cfg->f_max == 0)
+               return -EINVAL;
        if (min_clk)
-               host->cfg.f_min = min_clk;
+               cfg->f_min = min_clk;
        else {
-               if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
-                       host->cfg.f_min = host->cfg.f_max /
-                               SDHCI_MAX_DIV_SPEC_300;
+               if (version >= SDHCI_SPEC_300)
+                       cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_300;
                else
-                       host->cfg.f_min = host->cfg.f_max /
-                               SDHCI_MAX_DIV_SPEC_200;
+                       cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_200;
        }
-
-       host->cfg.voltages = 0;
+       cfg->voltages = 0;
        if (caps & SDHCI_CAN_VDD_330)
-               host->cfg.voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
+               cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
        if (caps & SDHCI_CAN_VDD_300)
-               host->cfg.voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
+               cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
        if (caps & SDHCI_CAN_VDD_180)
-               host->cfg.voltages |= MMC_VDD_165_195;
+               cfg->voltages |= MMC_VDD_165_195;
 
-       if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
-               host->cfg.voltages |= host->voltages;
-
-       host->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
-       if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
+       cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
+       if (version >= SDHCI_SPEC_300) {
                if (caps & SDHCI_CAN_DO_8BIT)
-                       host->cfg.host_caps |= MMC_MODE_8BIT;
+                       cfg->host_caps |= MMC_MODE_8BIT;
        }
 
-       if (host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)
-               host->cfg.host_caps &= ~(MMC_MODE_HS | MMC_MODE_HS_52MHz);
+       if (quirks & SDHCI_QUIRK_NO_HISPD_BIT)
+               cfg->host_caps &= ~(MMC_MODE_HS | MMC_MODE_HS_52MHz);
 
-       if (host->host_caps)
-               host->cfg.host_caps |= host->host_caps;
+       if (host_caps)
+               cfg->host_caps |= host_caps;
 
-       host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+       cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+       return 0;
+}
+
+#ifdef CONFIG_BLK
+int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
+{
+       return mmc_bind(dev, mmc, cfg);
+}
+#else
+int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
+{
+       unsigned int caps;
+
+       caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+#ifdef CONFIG_MMC_SDMA
+       if (!(caps & SDHCI_CAN_DO_SDMA)) {
+               printf("%s: Your controller doesn't support SDMA!!\n",
+                      __func__);
+               return -1;
+       }
+#endif
+
+       if (sdhci_setup_cfg(&host->cfg, host->name, host->bus_width, caps,
+                           max_clk, min_clk, SDHCI_GET_VERSION(host),
+                           host->quirks, host->host_caps)) {
+               printf("%s: Hardware doesn't specify base clock frequency\n",
+                      __func__);
+               return -EINVAL;
+       }
+
+       if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
+               host->cfg.voltages |= host->voltages;
 
        sdhci_reset(host, SDHCI_RESET_ALL);
 
@@ -557,3 +605,4 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
 
        return 0;
 }
+#endif
index 4f7fd5253220882c7074ac62bdcb5e4461a48b07..a5244fff4d9506b339b20bb5ec0bed933527f6e6 100644 (file)
@@ -191,6 +191,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
        struct udevice *bus = dev->parent;
        struct cadence_spi_platdata *plat = bus->platdata;
        struct cadence_spi_priv *priv = dev_get_priv(bus);
+       struct dm_spi_slave_platdata *dm_plat = dev_get_parent_platdata(dev);
        void *base = priv->regbase;
        u8 *cmd_buf = priv->cmd_buf;
        size_t data_bytes;
@@ -250,7 +251,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
                break;
                case CQSPI_INDIRECT_READ:
                        err = cadence_qspi_apb_indirect_read_setup(plat,
-                               priv->cmd_len, cmd_buf);
+                               priv->cmd_len, dm_plat->mode_rx, cmd_buf);
                        if (!err) {
                                err = cadence_qspi_apb_indirect_read_execute
                                (plat, data_bytes, din);
index 2912e36a53f7601f1d1251a1888c922ab6a7532c..a849f7b199736eb2ba445b1c490f1238e6703172 100644 (file)
@@ -53,7 +53,7 @@ int cadence_qspi_apb_command_write(void *reg_base_addr,
        unsigned int txlen,  const u8 *txbuf);
 
 int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
-       unsigned int cmdlen, const u8 *cmdbuf);
+       unsigned int cmdlen, unsigned int rx_width, const u8 *cmdbuf);
 int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
        unsigned int rxlen, u8 *rxbuf);
 int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
index a71531d3093594e2b2d2109de202aef9049c470a..1a35d558a6df0c76eaf96d57e3217cbdaf294a30 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/io.h>
 #include <asm/errno.h>
 #include <wait_bit.h>
+#include <spi.h>
 #include "cadence_qspi.h"
 
 #define CQSPI_REG_POLL_US                      (1) /* 1us */
@@ -45,7 +46,6 @@
 #define CQSPI_INST_TYPE_QUAD                   (2)
 
 #define CQSPI_STIG_DATA_LEN_MAX                        (8)
-#define CQSPI_INDIRECTTRIGGER_ADDR_MASK                (0xFFFFF)
 
 #define CQSPI_DUMMY_CLKS_PER_BYTE              (8)
 #define CQSPI_DUMMY_BYTES_MAX                  (4)
@@ -549,7 +549,7 @@ int cadence_qspi_apb_command_write(void *reg_base, unsigned int cmdlen,
 
 /* Opcode + Address (3/4 bytes) + dummy bytes (0-4 bytes) */
 int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
-       unsigned int cmdlen, const u8 *cmdbuf)
+       unsigned int cmdlen, unsigned int rx_width, const u8 *cmdbuf)
 {
        unsigned int reg;
        unsigned int rd_reg;
@@ -573,16 +573,15 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
                addr_bytes = cmdlen - 1;
 
        /* Setup the indirect trigger address */
-       writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK),
+       writel((u32)plat->ahbbase,
               plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
 
        /* Configure the opcode */
        rd_reg = cmdbuf[0] << CQSPI_REG_RD_INSTR_OPCODE_LSB;
 
-#if (CONFIG_SPI_FLASH_QUAD == 1)
-       /* Instruction and address at DQ0, data at DQ0-3. */
-       rd_reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB;
-#endif
+       if (rx_width & SPI_RX_QUAD)
+               /* Instruction and address at DQ0, data at DQ0-3. */
+               rd_reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB;
 
        /* Get address */
        addr_value = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
@@ -714,7 +713,7 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
                return -EINVAL;
        }
        /* Setup the indirect trigger address */
-       writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK),
+       writel((u32)plat->ahbbase,
               plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
 
        /* Configure the opcode */
index 0bd4f88926f142bd264625a8ede2f84128f554d7..20aa99a451dc7cab03e33625d8da6e291e3f8bf8 100644 (file)
@@ -14,6 +14,7 @@
 #include <malloc.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
+#include <dm.h>
 
 /* SPIGCR0 */
 #define SPIGCR0_SPIENA_MASK    0x1
@@ -51,6 +52,7 @@
 /* SPIDEF */
 #define SPIDEF_CSDEF0_MASK     BIT(0)
 
+#ifndef CONFIG_DM_SPI
 #define SPI0_BUS               0
 #define SPI0_BASE              CONFIG_SYS_SPI_BASE
 /*
@@ -83,6 +85,9 @@
 #define SPI2_NUM_CS            CONFIG_SYS_SPI2_NUM_CS
 #define SPI2_BASE              CONFIG_SYS_SPI2_BASE
 #endif
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
 
 /* davinci spi register set */
 struct davinci_spi_regs {
@@ -114,16 +119,17 @@ struct davinci_spi_regs {
 
 /* davinci spi slave */
 struct davinci_spi_slave {
+#ifndef CONFIG_DM_SPI
        struct spi_slave slave;
+#endif
        struct davinci_spi_regs *regs;
-       unsigned int freq;
+       unsigned int freq; /* current SPI bus frequency */
+       unsigned int mode; /* current SPI mode used */
+       u8 num_cs;         /* total no. of CS available */
+       u8 cur_cs;         /* CS of current slave */
+       bool half_duplex;  /* true, if master is half-duplex only */
 };
 
-static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave)
-{
-       return container_of(slave, struct davinci_spi_slave, slave);
-}
-
 /*
  * This functions needs to act like a macro to avoid pipeline reloads in the
  * loops below. Use always_inline. This gains us about 160KiB/s and the bloat
@@ -144,15 +150,14 @@ static inline u32 davinci_spi_xfer_data(struct davinci_spi_slave *ds, u32 data)
        return buf_reg_val;
 }
 
-static int davinci_spi_read(struct spi_slave *slave, unsigned int len,
+static int davinci_spi_read(struct davinci_spi_slave *ds, unsigned int len,
                            u8 *rxp, unsigned long flags)
 {
-       struct davinci_spi_slave *ds = to_davinci_spi(slave);
        unsigned int data1_reg_val;
 
        /* enable CS hold, CS[n] and clear the data bits */
        data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
-                        (slave->cs << SPIDAT1_CSNR_SHIFT));
+                        (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
 
        /* wait till TXFULL is deasserted */
        while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
@@ -175,15 +180,14 @@ static int davinci_spi_read(struct spi_slave *slave, unsigned int len,
        return 0;
 }
 
-static int davinci_spi_write(struct spi_slave *slave, unsigned int len,
+static int davinci_spi_write(struct davinci_spi_slave *ds, unsigned int len,
                             const u8 *txp, unsigned long flags)
 {
-       struct davinci_spi_slave *ds = to_davinci_spi(slave);
        unsigned int data1_reg_val;
 
        /* enable CS hold and clear the data bits */
        data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
-                        (slave->cs << SPIDAT1_CSNR_SHIFT));
+                        (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
 
        /* wait till TXFULL is deasserted */
        while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
@@ -209,16 +213,15 @@ static int davinci_spi_write(struct spi_slave *slave, unsigned int len,
        return 0;
 }
 
-#ifndef CONFIG_SPI_HALF_DUPLEX
-static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len,
-                                 u8 *rxp, const u8 *txp, unsigned long flags)
+static int davinci_spi_read_write(struct davinci_spi_slave *ds, unsigned
+                                 int len, u8 *rxp, const u8 *txp,
+                                 unsigned long flags)
 {
-       struct davinci_spi_slave *ds = to_davinci_spi(slave);
        unsigned int data1_reg_val;
 
        /* enable CS hold and clear the data bits */
        data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
-                        (slave->cs << SPIDAT1_CSNR_SHIFT));
+                        (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
 
        /* wait till TXFULL is deasserted */
        while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
@@ -237,7 +240,115 @@ static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len,
 
        return 0;
 }
-#endif
+
+
+static int __davinci_spi_claim_bus(struct davinci_spi_slave *ds, int cs)
+{
+       unsigned int mode = 0, scalar;
+
+       /* Enable the SPI hardware */
+       writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
+       udelay(1000);
+       writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0);
+
+       /* Set master mode, powered up and not activated */
+       writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
+
+       /* CS, CLK, SIMO and SOMI are functional pins */
+       writel(((1 << cs) | SPIPC0_CLKFUN_MASK |
+               SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
+
+       /* setup format */
+       scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF;
+
+       /*
+        * Use following format:
+        *   character length = 8,
+        *   MSB shifted out first
+        */
+       if (ds->mode & SPI_CPOL)
+               mode |= SPI_CPOL;
+       if (!(ds->mode & SPI_CPHA))
+               mode |= SPI_CPHA;
+       writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) |
+               (mode << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0);
+
+       /*
+        * Including a minor delay. No science here. Should be good even with
+        * no delay
+        */
+       writel((50 << SPI_C2TDELAY_SHIFT) |
+               (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay);
+
+       /* default chip select register */
+       writel(SPIDEF_CSDEF0_MASK, &ds->regs->def);
+
+       /* no interrupts */
+       writel(0, &ds->regs->int0);
+       writel(0, &ds->regs->lvl);
+
+       /* enable SPI */
+       writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
+
+       return 0;
+}
+
+static int __davinci_spi_release_bus(struct davinci_spi_slave *ds)
+{
+       /* Disable the SPI hardware */
+       writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
+
+       return 0;
+}
+
+static int __davinci_spi_xfer(struct davinci_spi_slave *ds,
+               unsigned int bitlen,  const void *dout, void *din,
+               unsigned long flags)
+{
+       unsigned int len;
+
+       if (bitlen == 0)
+               /* Finish any previously submitted transfers */
+               goto out;
+
+       /*
+        * It's not clear how non-8-bit-aligned transfers are supposed to be
+        * represented as a stream of bytes...this is a limitation of
+        * the current SPI interface - here we terminate on receiving such a
+        * transfer request.
+        */
+       if (bitlen % 8) {
+               /* Errors always terminate an ongoing transfer */
+               flags |= SPI_XFER_END;
+               goto out;
+       }
+
+       len = bitlen / 8;
+
+       if (!dout)
+               return davinci_spi_read(ds, len, din, flags);
+       if (!din)
+               return davinci_spi_write(ds, len, dout, flags);
+       if (!ds->half_duplex)
+               return davinci_spi_read_write(ds, len, din, dout, flags);
+
+       printf("SPI full duplex not supported\n");
+       flags |= SPI_XFER_END;
+
+out:
+       if (flags & SPI_XFER_END) {
+               u8 dummy = 0;
+               davinci_spi_write(ds, 1, &dummy, flags);
+       }
+       return 0;
+}
+
+#ifndef CONFIG_DM_SPI
+
+static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave)
+{
+       return container_of(slave, struct davinci_spi_slave, slave);
+}
 
 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 {
@@ -313,6 +424,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        }
 
        ds->freq = max_hz;
+       ds->mode = mode;
 
        return &ds->slave;
 }
@@ -324,104 +436,143 @@ void spi_free_slave(struct spi_slave *slave)
        free(ds);
 }
 
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+            const void *dout, void *din, unsigned long flags)
+{
+       struct davinci_spi_slave *ds = to_davinci_spi(slave);
+
+       ds->cur_cs = slave->cs;
+
+       return __davinci_spi_xfer(ds, bitlen, dout, din, flags);
+}
+
 int spi_claim_bus(struct spi_slave *slave)
 {
        struct davinci_spi_slave *ds = to_davinci_spi(slave);
-       unsigned int scalar;
 
-       /* Enable the SPI hardware */
-       writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
-       udelay(1000);
-       writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0);
+#ifdef CONFIG_SPI_HALF_DUPLEX
+       ds->half_duplex = true;
+#else
+       ds->half_duplex = false;
+#endif
+       return __davinci_spi_claim_bus(ds, ds->slave.cs);
+}
 
-       /* Set master mode, powered up and not activated */
-       writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
+void spi_release_bus(struct spi_slave *slave)
+{
+       struct davinci_spi_slave *ds = to_davinci_spi(slave);
 
-       /* CS, CLK, SIMO and SOMI are functional pins */
-       writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
-               SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
+       __davinci_spi_release_bus(ds);
+}
 
-       /* setup format */
-       scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF;
+#else
+static int davinci_spi_set_speed(struct udevice *bus, uint max_hz)
+{
+       struct davinci_spi_slave *ds = dev_get_priv(bus);
 
-       /*
-        * Use following format:
-        *   character length = 8,
-        *   clock signal delayed by half clk cycle,
-        *   clock low in idle state - Mode 0,
-        *   MSB shifted out first
-        */
-       writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) |
-               (1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0);
+       debug("%s speed %u\n", __func__, max_hz);
+       if (max_hz > CONFIG_SYS_SPI_CLK / 2)
+               return -EINVAL;
 
-       /*
-        * Including a minor delay. No science here. Should be good even with
-        * no delay
-        */
-       writel((50 << SPI_C2TDELAY_SHIFT) |
-               (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay);
+       ds->freq = max_hz;
 
-       /* default chip select register */
-       writel(SPIDEF_CSDEF0_MASK, &ds->regs->def);
+       return 0;
+}
 
-       /* no interrupts */
-       writel(0, &ds->regs->int0);
-       writel(0, &ds->regs->lvl);
+static int davinci_spi_set_mode(struct udevice *bus, uint mode)
+{
+       struct davinci_spi_slave *ds = dev_get_priv(bus);
 
-       /* enable SPI */
-       writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
+       debug("%s mode %u\n", __func__, mode);
+       ds->mode = mode;
 
        return 0;
 }
 
-void spi_release_bus(struct spi_slave *slave)
+static int davinci_spi_claim_bus(struct udevice *dev)
 {
-       struct davinci_spi_slave *ds = to_davinci_spi(slave);
+       struct dm_spi_slave_platdata *slave_plat =
+               dev_get_parent_platdata(dev);
+       struct udevice *bus = dev->parent;
+       struct davinci_spi_slave *ds = dev_get_priv(bus);
+
+       if (slave_plat->cs >= ds->num_cs) {
+               printf("Invalid SPI chipselect\n");
+               return -EINVAL;
+       }
+       ds->half_duplex = slave_plat->mode & SPI_PREAMBLE;
 
-       /* Disable the SPI hardware */
-       writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
+       return __davinci_spi_claim_bus(ds, slave_plat->cs);
 }
 
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-            const void *dout, void *din, unsigned long flags)
+static int davinci_spi_release_bus(struct udevice *dev)
 {
-       unsigned int len;
+       struct davinci_spi_slave *ds = dev_get_priv(dev->parent);
 
-       if (bitlen == 0)
-               /* Finish any previously submitted transfers */
-               goto out;
+       return __davinci_spi_release_bus(ds);
+}
 
-       /*
-        * It's not clear how non-8-bit-aligned transfers are supposed to be
-        * represented as a stream of bytes...this is a limitation of
-        * the current SPI interface - here we terminate on receiving such a
-        * transfer request.
-        */
-       if (bitlen % 8) {
-               /* Errors always terminate an ongoing transfer */
-               flags |= SPI_XFER_END;
-               goto out;
+static int davinci_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                           const void *dout, void *din,
+                           unsigned long flags)
+{
+       struct dm_spi_slave_platdata *slave =
+               dev_get_parent_platdata(dev);
+       struct udevice *bus = dev->parent;
+       struct davinci_spi_slave *ds = dev_get_priv(bus);
+
+       if (slave->cs >= ds->num_cs) {
+               printf("Invalid SPI chipselect\n");
+               return -EINVAL;
        }
+       ds->cur_cs = slave->cs;
 
-       len = bitlen / 8;
+       return __davinci_spi_xfer(ds, bitlen, dout, din, flags);
+}
 
-       if (!dout)
-               return davinci_spi_read(slave, len, din, flags);
-       else if (!din)
-               return davinci_spi_write(slave, len, dout, flags);
-#ifndef CONFIG_SPI_HALF_DUPLEX
-       else
-               return davinci_spi_read_write(slave, len, din, dout, flags);
-#else
-       printf("SPI full duplex transaction requested with "
-              "CONFIG_SPI_HALF_DUPLEX defined.\n");
-       flags |= SPI_XFER_END;
-#endif
+static int davinci_spi_probe(struct udevice *bus)
+{
+       /* Nothing to do */
+       return 0;
+}
 
-out:
-       if (flags & SPI_XFER_END) {
-               u8 dummy = 0;
-               davinci_spi_write(slave, 1, &dummy, flags);
+static int davinci_ofdata_to_platadata(struct udevice *bus)
+{
+       struct davinci_spi_slave *ds = dev_get_priv(bus);
+       const void *blob = gd->fdt_blob;
+       int node = bus->of_offset;
+
+       ds->regs = dev_map_physmem(bus, sizeof(struct davinci_spi_regs));
+       if (!ds->regs) {
+               printf("%s: could not map device address\n", __func__);
+               return -EINVAL;
        }
+       ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
        return 0;
 }
+
+static const struct dm_spi_ops davinci_spi_ops = {
+       .claim_bus      = davinci_spi_claim_bus,
+       .release_bus    = davinci_spi_release_bus,
+       .xfer           = davinci_spi_xfer,
+       .set_speed      = davinci_spi_set_speed,
+       .set_mode       = davinci_spi_set_mode,
+};
+
+static const struct udevice_id davinci_spi_ids[] = {
+       { .compatible = "ti,keystone-spi" },
+       { .compatible = "ti,dm6441-spi" },
+       { }
+};
+
+U_BOOT_DRIVER(davinci_spi) = {
+       .name = "davinci_spi",
+       .id = UCLASS_SPI,
+       .of_match = davinci_spi_ids,
+       .ops = &davinci_spi_ops,
+       .ofdata_to_platdata = davinci_ofdata_to_platadata,
+       .priv_auto_alloc_size = sizeof(struct davinci_spi_slave),
+       .probe = davinci_spi_probe,
+};
+#endif
index 84b6786517cc667ebd04d6542003bac26dc85175..8003f9bfc8635cb32d0f7808f7c5a3e11bf2c2ed 100644 (file)
@@ -278,6 +278,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
                       struct udevice **busp, struct spi_slave **devp)
 {
        struct udevice *bus, *dev;
+       struct dm_spi_slave_platdata *plat;
        bool created = false;
        int ret;
 
@@ -294,8 +295,6 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
         * SPI flash chip - we will bind to the correct driver.
         */
        if (ret == -ENODEV && drv_name) {
-               struct dm_spi_slave_platdata *plat;
-
                debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
                      __func__, dev_name, busnum, cs, drv_name);
                ret = device_bind_driver(bus, drv_name, dev_name, &dev);
@@ -322,6 +321,11 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
                slave->dev = dev;
        }
 
+       plat = dev_get_parent_platdata(dev);
+       if (!speed) {
+               speed = plat->max_hz;
+               mode = plat->mode;
+       }
        ret = spi_set_speed_mode(bus, speed, mode);
        if (ret)
                goto err;
@@ -333,7 +337,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
        return 0;
 
 err:
-       debug("%s: Error path, credted=%d, device '%s'\n", __func__,
+       debug("%s: Error path, created=%d, device '%s'\n", __func__,
              created, dev->name);
        if (created) {
                device_remove(dev);
index f8bba6710dba82b3b173c96c8eb5671891a10695..71b00378ffb6f15edc03466384521a0b0a696b9a 100644 (file)
 #define CONFIG_SF_DEFAULT_BUS          1
 #define CONFIG_SF_DEFAULT_CS           0
 
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_CADENCE_QSPI
+#define CONFIG_CQSPI_REF_CLK 384000000
+#define CONFIG_CQSPI_DECODER 0x0
+#endif
+
 #endif /* __CONFIG_K2G_EVM_H */
index 1bdcf9d0248a9afb5b0eaf3cfa689a31e1c35ddf..ae4b101e444df558a26b7301ab9d202752e9f292 100644 (file)
@@ -45,7 +45,6 @@
 /* MMC/SD IP block */
 #define CONFIG_MMC
 #define CONFIG_GENERIC_MMC
-#define CONFIG_SDHCI
 #define CONFIG_DWMMC
 #define CONFIG_BOUNCE_BUFFER
 
index 9d50d834db493340da8fff90941ab153a161c9e3..8adc26fc8b4458bd740e8fbab69ceb59598f1eb8 100644 (file)
@@ -51,7 +51,6 @@
 /* MMC/SD IP block */
 #define CONFIG_MMC
 #define CONFIG_GENERIC_MMC
-#define CONFIG_SDHCI
 #define CONFIG_DWMMC
 #define CONFIG_BOUNCE_BUFFER
 
index 2ee26c40367077d67d88d717ea6b232358c48f9a..4aa262e1a8710dec3fb6f9812da431deff5864ab 100644 (file)
 #define CONFIG_SYS_SPI2
 #define CONFIG_SYS_SPI2_BASE           KS2_SPI2_BASE
 #define CONFIG_SYS_SPI2_NUM_CS         4
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_DM_SPI
+#undef CONFIG_DM_SPI_FLASH
+#endif
 
 /* Network Configuration */
 #define CONFIG_PHYLIB
index f03bcd3b49ee45f962126f67272587364ec52356..1bfcf3bcbc012ae0994625b78ce166a5070ca897 100644 (file)
@@ -466,6 +466,19 @@ fdt_addr_t dev_get_addr(struct udevice *dev);
  */
 void *dev_get_addr_ptr(struct udevice *dev);
 
+/**
+ * dev_map_physmem() - Read device address from reg property of the
+ *                     device node and map the address into CPU address
+ *                     space.
+ *
+ * @dev: Pointer to device
+ * @size: size of the memory to map
+ *
+ * @return  mapped address, or NULL if the device does not have reg
+ *          property.
+ */
+void *dev_map_physmem(struct udevice *dev, unsigned long size);
+
 /**
  * dev_get_addr_index() - Get the indexed reg property of a device
  *
index b768660e85679b53450fca4cff99d76e91972f65..c5cdfc79d101103f153cdc039e01c739818cbd17 100644 (file)
@@ -33,7 +33,6 @@ enum uclass_id {
        UCLASS_CROS_EC,         /* Chrome OS EC */
        UCLASS_DISPLAY,         /* Display (e.g. DisplayPort, HDMI) */
        UCLASS_DMA,             /* Direct Memory Access */
-       UCLASS_RAM,             /* RAM controller */
        UCLASS_ETH,             /* Ethernet device */
        UCLASS_GPIO,            /* Bank of general-purpose I/O pins */
        UCLASS_I2C,             /* I2C bus */
@@ -56,11 +55,12 @@ enum uclass_id {
        UCLASS_PCH,             /* x86 platform controller hub */
        UCLASS_PCI,             /* PCI bus */
        UCLASS_PCI_GENERIC,     /* Generic PCI bus device */
-       UCLASS_PINCTRL,         /* Pinctrl (pin muxing/configuration) device */
        UCLASS_PINCONFIG,       /* Pin configuration node device */
+       UCLASS_PINCTRL,         /* Pinctrl (pin muxing/configuration) device */
        UCLASS_PMIC,            /* PMIC I/O device */
        UCLASS_PWM,             /* Pulse-width modulator */
        UCLASS_PWRSEQ,          /* Power sequence device */
+       UCLASS_RAM,             /* RAM controller */
        UCLASS_REGULATOR,       /* Regulator device */
        UCLASS_REMOTEPROC,      /* Remote Processor device */
        UCLASS_RESET,           /* Reset controller device */
index 335af51fdf42e72f4e19058cfdff4a1f29dfe520..6aebe96b97bc795b711e51ef33a4d2d5434fca5c 100644 (file)
@@ -224,9 +224,82 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg)
        return readb(host->ioaddr + reg);
 }
 
+#ifdef CONFIG_BLK
+/**
+ * dwmci_setup_cfg() - Set up the configuration for DWMMC
+ *
+ * This is used to set up a DWMMC device when you are using CONFIG_BLK.
+ *
+ * This should be called from your MMC driver's probe() method once you have
+ * the information required.
+ *
+ * Generally your driver will have a platform data structure which holds both
+ * the configuration (struct mmc_config) and the MMC device info (struct mmc).
+ * For example:
+ *
+ * struct rockchip_mmc_plat {
+ *     struct mmc_config cfg;
+ *     struct mmc mmc;
+ * };
+ *
+ * ...
+ *
+ * Inside U_BOOT_DRIVER():
+ *     .platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
+ *
+ * To access platform data:
+ *     struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
+ *
+ * See rockchip_dw_mmc.c for an example.
+ *
+ * @cfg:       Configuration structure to fill in (generally &plat->mmc)
+ * @name:      Device name (normally dev->name)
+ * @buswidth:  Bus width (in bits, such as 4 or 8)
+ * @caps:      Host capabilities (MMC_MODE_...)
+ * @max_clk:   Maximum supported clock speed in HZ (e.g. 400000)
+ * @min_clk:   Minimum supported clock speed in HZ (e.g. 150000000)
+ */
 void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
                     uint caps, u32 max_clk, u32 min_clk);
+
+/**
+ * dwmci_bind() - Set up a new MMC block device
+ *
+ * This is used to set up a DWMMC block device when you are using CONFIG_BLK.
+ * It should be called from your driver's bind() method.
+ *
+ * See rockchip_dw_mmc.c for an example.
+ *
+ * @dev:       Device to set up
+ * @mmc:       Pointer to mmc structure (normally &plat->mmc)
+ * @cfg:       Empty configuration structure (generally &plat->cfg). This is
+ *             normally all zeroes at this point. The only purpose of passing
+ *             this in is to set mmc->cfg to it.
+ * @return 0 if OK, -ve if the block device could not be created
+ */
 int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
 
+#else
+/**
+ * add_dwmci() - Add a new DWMMC interface
+ *
+ * This is used when you are not using CONFIG_BLK. Convert your driver over!
+ *
+ * @host:      DWMMC host structure
+ * @max_clk:   Maximum supported clock speed in HZ (e.g. 400000)
+ * @min_clk:   Minimum supported clock speed in HZ (e.g. 150000000)
+ * @return 0 if OK, -ve on error
+ */
 int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk);
+#endif /* !CONFIG_BLK */
+
+#ifdef CONFIG_DM_MMC_OPS
+/* Export the operations to drivers */
+int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+                  struct mmc_data *data);
+int dwmci_set_ios(struct udevice *dev);
+int dwmci_probe(struct udevice *dev);
+extern const struct dm_mmc_ops dm_dwmci_ops;
+#endif
+
 #endif /* __DWMMC_HW_H */
index 05d70c4b9b3ec208ebfb3c15a4bdd7de5b97d201..151c590ed1cc366aeb9c6be0d7b3dc039af209c6 100644 (file)
@@ -134,13 +134,10 @@ enum fdt_compat_id {
        COMPAT_SAMSUNG_S3C2440_I2C,     /* Exynos I2C Controller */
        COMPAT_SAMSUNG_EXYNOS5_SOUND,   /* Exynos Sound */
        COMPAT_WOLFSON_WM8994_CODEC,    /* Wolfson WM8994 Sound Codec */
-       COMPAT_GOOGLE_CROS_EC_KEYB,     /* Google CROS_EC Keyboard */
        COMPAT_SAMSUNG_EXYNOS_USB_PHY,  /* Exynos phy controller for usb2.0 */
        COMPAT_SAMSUNG_EXYNOS5_USB3_PHY,/* Exynos phy controller for usb3.0 */
        COMPAT_SAMSUNG_EXYNOS_TMU,      /* Exynos TMU */
-       COMPAT_SAMSUNG_EXYNOS_FIMD,     /* Exynos Display controller */
        COMPAT_SAMSUNG_EXYNOS_MIPI_DSI, /* Exynos mipi dsi */
-       COMPAT_SAMSUNG_EXYNOS5_DP,      /* Exynos Display port controller */
        COMPAT_SAMSUNG_EXYNOS_DWMMC,    /* Exynos DWMMC controller */
        COMPAT_SAMSUNG_EXYNOS_MMC,      /* Exynos MMC controller */
        COMPAT_MAXIM_MAX77686_PMIC,     /* MAX77686 PMIC */
@@ -149,14 +146,9 @@ enum fdt_compat_id {
        COMPAT_SAMSUNG_EXYNOS5_I2C,     /* Exynos5 High Speed I2C Controller */
        COMPAT_SAMSUNG_EXYNOS_SYSMMU,   /* Exynos sysmmu */
        COMPAT_INTEL_MICROCODE,         /* Intel microcode update */
-       COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */
-       COMPAT_INTEL_MODEL_206AX,       /* Intel Model 206AX CPU */
-       COMPAT_INTEL_GMA,               /* Intel Graphics Media Accelerator */
        COMPAT_AMS_AS3722,              /* AMS AS3722 PMIC */
-       COMPAT_INTEL_ICH_SPI,           /* Intel ICH7/9 SPI controller */
        COMPAT_INTEL_QRK_MRC,           /* Intel Quark MRC */
        COMPAT_SOCIONEXT_XHCI,          /* Socionext UniPhier xHCI */
-       COMPAT_INTEL_PCH,               /* Intel PCH */
        COMPAT_ALTERA_SOCFPGA_DWMAC,    /* SoCFPGA Ethernet controller */
        COMPAT_ALTERA_SOCFPGA_DWMMC,    /* SoCFPGA DWMMC controller */
        COMPAT_ALTERA_SOCFPGA_DWC2USB,  /* SoCFPGA DWC2 USB controller */
index f383925ade2c5a846952175158997591035e357a..8f309f1f71c510b10b6ed81403b2b00bcf4b9c52 100644 (file)
@@ -323,6 +323,58 @@ struct mmc_data {
 /* forward decl. */
 struct mmc;
 
+#ifdef CONFIG_DM_MMC_OPS
+struct dm_mmc_ops {
+       /**
+        * send_cmd() - Send a command to the MMC device
+        *
+        * @dev:        Device to receive the command
+        * @cmd:        Command to send
+        * @data:       Additional data to send/receive
+        * @return 0 if OK, -ve on error
+        */
+       int (*send_cmd)(struct udevice *dev, struct mmc_cmd *cmd,
+                       struct mmc_data *data);
+
+       /**
+        * set_ios() - Set the I/O speed/width for an MMC device
+        *
+        * @dev:        Device to update
+        * @return 0 if OK, -ve on error
+        */
+       int (*set_ios)(struct udevice *dev);
+
+       /**
+        * get_cd() - See whether a card is present
+        *
+        * @dev:        Device to check
+        * @return 0 if not present, 1 if present, -ve on error
+        */
+       int (*get_cd)(struct udevice *dev);
+
+       /**
+        * get_wp() - See whether a card has write-protect enabled
+        *
+        * @dev:        Device to check
+        * @return 0 if write-enabled, 1 if write-protected, -ve on error
+        */
+       int (*get_wp)(struct udevice *dev);
+};
+
+#define mmc_get_ops(dev)        ((struct dm_mmc_ops *)(dev)->driver->ops)
+
+int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+                   struct mmc_data *data);
+int dm_mmc_set_ios(struct udevice *dev);
+int dm_mmc_get_cd(struct udevice *dev);
+int dm_mmc_get_wp(struct udevice *dev);
+
+/* Transition functions for compatibility */
+int mmc_set_ios(struct mmc *mmc);
+int mmc_getcd(struct mmc *mmc);
+int mmc_getwp(struct mmc *mmc);
+
+#else
 struct mmc_ops {
        int (*send_cmd)(struct mmc *mmc,
                        struct mmc_cmd *cmd, struct mmc_data *data);
@@ -331,10 +383,13 @@ struct mmc_ops {
        int (*getcd)(struct mmc *mmc);
        int (*getwp)(struct mmc *mmc);
 };
+#endif
 
 struct mmc_config {
        const char *name;
+#ifndef CONFIG_DM_MMC_OPS
        const struct mmc_ops *ops;
+#endif
        uint host_caps;
        uint voltages;
        uint f_min;
@@ -343,7 +398,12 @@ struct mmc_config {
        unsigned char part_type;
 };
 
-/* TODO struct mmc should be in mmc_private but it's hard to fix right now */
+/*
+ * With CONFIG_DM_MMC enabled, struct mmc can be accessed from the MMC device
+ * with mmc_get_mmc_dev().
+ *
+ * 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;
@@ -446,10 +506,14 @@ void print_mmc_devices(char separator);
 int get_mmc_num(void);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
                      enum mmc_hwpart_conf_mode mode);
+
+#ifndef CONFIG_DM_MMC_OPS
 int mmc_getcd(struct mmc *mmc);
 int board_mmc_getcd(struct mmc *mmc);
 int mmc_getwp(struct mmc *mmc);
 int board_mmc_getwp(struct mmc *mmc);
+#endif
+
 int mmc_set_dsr(struct mmc *mmc, u16 val);
 /* Function to change the size of boot partition and rpmb partitions */
 int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
index e0f66670b6a926aa4feacdf26fa467eed0149eb6..c4d3b552d19dd8f30b2f0e757fe29a3fcae55461 100644 (file)
@@ -338,5 +338,85 @@ static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
 }
 #endif
 
+#ifdef CONFIG_BLK
+/**
+ * sdhci_setup_cfg() - Set up the configuration for DWMMC
+ *
+ * This is used to set up an SDHCI device when you are using CONFIG_BLK.
+ *
+ * This should be called from your MMC driver's probe() method once you have
+ * the information required.
+ *
+ * Generally your driver will have a platform data structure which holds both
+ * the configuration (struct mmc_config) and the MMC device info (struct mmc).
+ * For example:
+ *
+ * struct msm_sdhc_plat {
+ *     struct mmc_config cfg;
+ *     struct mmc mmc;
+ * };
+ *
+ * ...
+ *
+ * Inside U_BOOT_DRIVER():
+ *     .platdata_auto_alloc_size = sizeof(struct msm_sdhc_plat),
+ *
+ * To access platform data:
+ *     struct msm_sdhc_plat *plat = dev_get_platdata(dev);
+ *
+ * See msm_sdhci.c for an example.
+ *
+ * @cfg:       Configuration structure to fill in (generally &plat->mmc)
+ * @name:      Device name (normally dev->name)
+ * @buswidth:  Bus width (in bits, such as 4 or 8)
+ * @caps:      Host capabilities (MMC_MODE_...)
+ * @max_clk:   Maximum supported clock speed in HZ (0 for default)
+ * @min_clk:   Minimum supported clock speed in HZ (0 for default)
+ * @version:   Host controller version (generally read from the
+ *             SDHCI_HOST_VERSION register)
+ * @quirks:    Quick flags (SDHCI_QUIRK_...)
+ * @host_caps: Additional host capabilities (0 if none)
+ */
+int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+                   uint caps, u32 max_clk, u32 min_clk, uint version,
+                   uint quirks, uint host_caps);
+
+/**
+ * sdhci_bind() - Set up a new MMC block device
+ *
+ * This is used to set up an SDHCI block device when you are using CONFIG_BLK.
+ * It should be called from your driver's bind() method.
+ *
+ * See msm_sdhci.c for an example.
+ *
+ * @dev:       Device to set up
+ * @mmc:       Pointer to mmc structure (normally &plat->mmc)
+ * @cfg:       Empty configuration structure (generally &plat->cfg). This is
+ *             normally all zeroes at this point. The only purpose of passing
+ *             this in is to set mmc->cfg to it.
+ * @return 0 if OK, -ve if the block device could not be created
+ */
+int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+#else
+
+/**
+ * add_sdhci() - Add a new SDHCI interface
+ *
+ * This is used when you are not using CONFIG_BLK. Convert your driver over!
+ *
+ * @host:      SDHCI host structure
+ * @max_clk:   Maximum supported clock speed in HZ (0 for default)
+ * @min_clk:   Minimum supported clock speed in HZ (0 for default)
+ * @return 0 if OK, -ve on error
+ */
 int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk);
+#endif /* !CONFIG_BLK */
+
+#ifdef CONFIG_DM_MMC_OPS
+/* Export the operations to drivers */
+int sdhci_probe(struct udevice *dev);
+extern const struct dm_mmc_ops sdhci_ops;
+#else
+#endif
+
 #endif /* __SDHCI_HW_H */
index 0534c0b767d8d548e07cacd37a02eba7aa52bd41..c2bcbde258a0aebead4f3cc70cb3a601eab40d51 100644 (file)
@@ -19,6 +19,11 @@ DECLARE_GLOBAL_DATA_PTR;
  * Here are the type we know about. One day we might allow drivers to
  * register. For now we just put them here. The COMPAT macro allows us to
  * turn this into a sparse list later, and keeps the ID with the name.
+ *
+ * NOTE: This list is basically a TODO list for things that need to be
+ * converted to driver model. So don't add new things here unless there is a
+ * good reason why driver-model conversion is infeasible. Examples include
+ * things which are used before driver model is available.
  */
 #define COMPAT(id, name) name
 static const char * const compat_names[COMPAT_COUNT] = {
@@ -39,13 +44,10 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),
        COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"),
        COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"),
-       COMPAT(GOOGLE_CROS_EC_KEYB, "google,cros-ec-keyb"),
        COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
        COMPAT(SAMSUNG_EXYNOS5_USB3_PHY, "samsung,exynos5250-usb3-phy"),
        COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"),
-       COMPAT(SAMSUNG_EXYNOS_FIMD, "samsung,exynos-fimd"),
        COMPAT(SAMSUNG_EXYNOS_MIPI_DSI, "samsung,exynos-mipi-dsi"),
-       COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
        COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"),
        COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"),
        COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686"),
@@ -54,20 +56,15 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
        COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
        COMPAT(INTEL_MICROCODE, "intel,microcode"),
-       COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),
-       COMPAT(INTEL_MODEL_206AX, "intel,model-206ax"),
-       COMPAT(INTEL_GMA, "intel,gma"),
        COMPAT(AMS_AS3722, "ams,as3722"),
-       COMPAT(INTEL_ICH_SPI, "intel,ich-spi"),
        COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
        COMPAT(SOCIONEXT_XHCI, "socionext,uniphier-xhci"),
-       COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"),
        COMPAT(ALTERA_SOCFPGA_DWMAC, "altr,socfpga-stmmac"),
        COMPAT(ALTERA_SOCFPGA_DWMMC, "altr,socfpga-dw-mshc"),
        COMPAT(ALTERA_SOCFPGA_DWC2USB, "snps,dwc2"),
-       COMPAT(COMPAT_INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"),
-       COMPAT(COMPAT_INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"),
-       COMPAT(COMPAT_INTEL_IVYBRIDGE_FSP, "intel,ivybridge-fsp"),
+       COMPAT(INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"),
+       COMPAT(INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"),
+       COMPAT(INTEL_IVYBRIDGE_FSP, "intel,ivybridge-fsp"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
index 27d031ef59c19472c800eec6f73ff4e3e81b7b22..69d5cfb7a8ea8fc66572180d02334e5a8b7d8654 100644 (file)
@@ -112,6 +112,14 @@ class PatchStream:
         if self.commit and self.is_log:
             self.series.AddCommit(self.commit)
             self.commit = None
+        # If 'END' is missing in a 'Cover-letter' section, and that section
+        # happens to show up at the very end of the commit message, this is
+        # the chance for us to fix it up.
+        if self.in_section == 'cover' and self.is_log:
+            self.series.cover = self.section
+            self.in_section = None
+            self.skip_blank = True
+            self.section = []
 
     def ProcessLine(self, line):
         """Process a single line of a patch file or commit log
@@ -150,6 +158,7 @@ class PatchStream:
         # Handle state transition and skipping blank lines
         series_tag_match = re_series_tag.match(line)
         commit_tag_match = re_commit_tag.match(line)
+        cover_match = re_cover.match(line)
         cover_cc_match = re_cover_cc.match(line)
         signoff_match = re_signoff.match(line)
         tag_match = None
@@ -168,6 +177,33 @@ class PatchStream:
         elif commit_match:
             self.state = STATE_MSG_HEADER
 
+        # If a tag is detected, or a new commit starts
+        if series_tag_match or commit_tag_match or \
+           cover_match or cover_cc_match or signoff_match or \
+           self.state == STATE_MSG_HEADER:
+            # but we are already in a section, this means 'END' is missing
+            # for that section, fix it up.
+            if self.in_section:
+                self.warn.append("Missing 'END' in section '%s'" % self.in_section)
+                if self.in_section == 'cover':
+                    self.series.cover = self.section
+                elif self.in_section == 'notes':
+                    if self.is_log:
+                        self.series.notes += self.section
+                elif self.in_section == 'commit-notes':
+                    if self.is_log:
+                        self.commit.notes += self.section
+                else:
+                    self.warn.append("Unknown section '%s'" % self.in_section)
+                self.in_section = None
+                self.skip_blank = True
+                self.section = []
+            # but we are already in a change list, that means a blank line
+            # is missing, fix it up.
+            if self.in_change:
+                self.warn.append("Missing 'blank line' in section 'Series-changes'")
+                self.in_change = 0
+
         # If we are in a section, keep collecting lines until we see END
         if self.in_section:
             if line == 'END':
@@ -203,7 +239,7 @@ class PatchStream:
             self.skip_blank = False
 
         # Detect the start of a cover letter section
-        elif re_cover.match(line):
+        elif cover_match:
             self.in_section = 'cover'
             self.skip_blank = False